<template>
    <view class="login">
        <!-- 装饰背景 -->
        <view class="bg-blob blob-a"></view>
        <view class="bg-blob blob-b"></view>
        <view class="bg-blob blob-c"></view>

        <!-- 主内容 -->
        <view class="content">
            <!-- 品牌区 -->
            <view class="brand">
                <view class="brand-logo" @click="onLogoTap">
                    <view class="brand-logo-glow"></view>
                    <image :src="logoUrl" mode="aspectFit" class="brand-logo-img" />
                </view>
                <view class="brand-name">灵犀学<text class="brand-name-ai">AI</text></view>
                <view class="brand-slogan">智能学习助手 · 让学习更轻松</view>
            </view>

            <!-- 角色切换 -->
            <view class="role-switch">
                <view class="role-switch-bg" :class="role"></view>
                <view
                    v-for="item in roleOptions"
                    :key="item.value"
                    :class="['role-tab', { active: role === item.value }]"
                    @click="switchRole(item.value)"
                >
                    <text>{{ item.label }}</text>
                </view>
            </view>

            <!-- 表单：key 确保切换角色时微信小程序重新渲染 -->
            <view class="form" :key="role">
                <block v-if="isParentLogin">
                    <block v-if="parentStage === 'bind'">
                        <view class="form-item" :class="{ focus: focus === 'phone' }">
                            <view class="form-icon">
                                <svg viewBox="0 0 24 24" fill="none">
                                    <rect x="6" y="3" width="12" height="18" rx="2.5" stroke="#0891B2" stroke-width="1.6" />
                                    <path d="M10 18h4" stroke="#0891B2" stroke-width="1.6" stroke-linecap="round" />
                                </svg>
                            </view>
                            <input
                                v-model="phone"
                                class="form-input"
                                type="number"
                                maxlength="11"
                                placeholder="请输入手机号"
                                placeholder-class="form-placeholder"
                                :adjust-position="false"
                                @focus="focus = 'phone'"
                                @blur="focus = ''"
                                @confirm="onLogin"
                            />
                        </view>

                        <view class="form-item" :class="{ focus: focus === 'code' }">
                            <view class="form-icon">
                                <svg viewBox="0 0 24 24" fill="none">
                                    <rect x="4" y="9" width="16" height="12" rx="2" stroke="#0891B2" stroke-width="1.6" />
                                    <path d="M8 9V7a4 4 0 1 1 8 0v2" stroke="#0891B2" stroke-width="1.6" />
                                </svg>
                            </view>
                            <input
                                v-model="smsCode"
                                class="form-input"
                                type="number"
                                maxlength="6"
                                placeholder="请输入验证码"
                                placeholder-class="form-placeholder"
                                :adjust-position="false"
                                @focus="focus = 'code'"
                                @blur="focus = ''"
                                @confirm="onLogin"
                            />
                            <view
                                class="sms-btn"
                                :class="{ disabled: smsCountdown > 0 || sendingCode }"
                                @click="onSendCode"
                            >
                                <text>{{ smsBtnText }}</text>
                            </view>
                        </view>
                    </block>
                </block>

                <block v-else>
                    <view class="form-item" :class="{ focus: focus === 'account' }">
                        <view class="form-icon">
                            <svg viewBox="0 0 24 24" fill="none">
                                <circle cx="12" cy="8" r="4" stroke="#4F46E5" stroke-width="1.6" />
                                <path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8" stroke="#4F46E5" stroke-width="1.6"
                                    stroke-linecap="round" />
                            </svg>
                        </view>
                        <input
                            v-model="account"
                            class="form-input"
                            placeholder="请输入账号"
                            placeholder-class="form-placeholder"
                            :adjust-position="false"
                            @focus="focus = 'account'"
                            @blur="focus = ''"
                            @confirm="onLogin"
                        />
                    </view>

                    <view class="form-item" :class="{ focus: focus === 'password' }">
                        <view class="form-icon">
                            <svg viewBox="0 0 24 24" fill="none">
                                <rect x="4" y="11" width="16" height="9" rx="2" stroke="#4F46E5" stroke-width="1.6" />
                                <path d="M8 11V8a4 4 0 0 1 8 0v3" stroke="#4F46E5" stroke-width="1.6" />
                            </svg>
                        </view>
                        <input
                            v-model="password"
                            class="form-input"
                            :password="hidePassword"
                            placeholder="请输入密码"
                            placeholder-class="form-placeholder"
                            :adjust-position="false"
                            @focus="focus = 'password'"
                            @blur="focus = ''"
                            @confirm="onLogin"
                        />
                        <view class="form-eye" @click="hidePassword = !hidePassword">
                            <svg v-if="hidePassword" viewBox="0 0 24 24" fill="none">
                                <path d="m2 2 20 20M10 5c.7-.1 1.3-.1 2-.1 7 0 10 7 10 7-.6 1.4-1.5 2.6-2.5 3.6M6.6 6.6C3.5 8.6 2 12 2 12s3 7 10 7c1.4 0 2.6-.3 3.7-.7"
                                    stroke="#94A3B8" stroke-width="1.6" stroke-linecap="round" />
                            </svg>
                            <svg v-else viewBox="0 0 24 24" fill="none">
                                <path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z" stroke="#4F46E5"
                                    stroke-width="1.6" />
                                <circle cx="12" cy="12" r="3" stroke="#4F46E5" stroke-width="1.6" />
                            </svg>
                        </view>
                    </view>
                </block>
            </view>

            <!-- <view class="agreement">
                <text>登录即表示同意</text>
                <text class="link" @click="openAgreement('user')">《用户协议》</text>
                <text>与</text>
                <text class="link" @click="openAgreement('privacy')">《隐私政策》</text>
            </view> -->

            <!-- 登录按钮 -->
            <block v-if="isParentLogin && parentStage === 'authorize'">
                <view :class="['btn-login', 'btn-wx', { loading: submitting }]" @click="onParentAuthorize">
                    <text v-if="!submitting">手机号快捷登录</text>
                    <view v-else class="btn-loader">
                        <view class="btn-loader-dot"></view>
                        <view class="btn-loader-dot"></view>
                        <view class="btn-loader-dot"></view>
                    </view>
                </view>
            </block>
            <block v-else>
                <view :class="['btn-login', { loading: submitting, parent: isParentLogin }]" @click="onLogin">
                    <text v-if="!submitting">登 录</text>
                    <view v-else class="btn-loader">
                        <view class="btn-loader-dot"></view>
                        <view class="btn-loader-dot"></view>
                        <view class="btn-loader-dot"></view>
                    </view>
                </view>
            </block>

            <view class="hint">
                <text v-if="isParentLogin && parentStage === 'authorize'">授权后将自动检测绑定关系</text>
                <text v-else-if="isParentLogin">未绑定将需要手机号验证绑定</text>
                <text v-else>登录账号由学校老师统一发放</text>
            </view>
        </view>
    </view>
</template>

<script setup lang="ts">
import { computed, onUnmounted, ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { parentMpLogin, sendParentLoginCode } from '@/api/login';
import { useUserStore } from '@/state/modules/user';
import { useTeacherStore } from '@/state/modules/teacher';
import { setCache, getCache } from '@/utils/cache';
import { cacheWxOpenid } from '@/utils/wxOpenid';
import { redirectToRoleHomeIfNeeded } from '@/utils/roleHome';

const OSS_URL = 'https://xxl-1313840333.cos.ap-guangzhou.myqcloud.com';
const logoUrl = `https://lxx-web-1313840333.cos.ap-chengdu.myqcloud.com/urm/mode.png`;

const PHONE_REG = /^1[3-9]\d{9}$/;

const account = ref('');
const password = ref('');
const phone = ref('');
const smsCode = ref('');
const hidePassword = ref(true);
const redirect = ref('');
const submitting = ref(false);
const sendingCode = ref(false);
const smsCountdown = ref(0);
const focus = ref<string>('');
let smsTimer: ReturnType<typeof setInterval> | null = null;
type LoginRole = 'student' | 'teacher' | 'parent';
const role = ref<LoginRole>('student');
const enterDebug = ref(0);
const roleOptions: { value: LoginRole; label: string }[] = [
    { value: 'student', label: '学生' },
    { value: 'teacher', label: '老师' },
    { value: 'parent', label: '家长' },
];

const userStore = useUserStore();
const teacherStore = useTeacherStore();

const isParentLogin = computed(() => role.value === 'parent');
type ParentStage = 'authorize' | 'bind';
const parentStage = ref<ParentStage>('authorize');
/** mpLogin 返回的微信 openid，绑定手机号时传给 smsLogin */
const parentWxOpenid = ref('');

const smsBtnText = computed(() => {
    if (smsCountdown.value > 0) return `${smsCountdown.value}s`;
    return '获取验证码';
});

const switchRole = (value: LoginRole) => {
    if (role.value === value) return;
    role.value = value;
    focus.value = '';

    if (value === 'parent') {
        parentStage.value = 'authorize';
        parentWxOpenid.value = '';
        phone.value = '';
        smsCode.value = '';
        smsCountdown.value = 0;
        sendingCode.value = false;
        if (smsTimer) {
            clearInterval(smsTimer);
            smsTimer = null;
        }
    }
};

const isValidPhone = (value: string) => PHONE_REG.test(value.trim());

const startSmsCountdown = (seconds = 60) => {
    if (smsTimer) {
        clearInterval(smsTimer);
        smsTimer = null;
    }
    smsCountdown.value = seconds;
    smsTimer = setInterval(() => {
        if (smsCountdown.value <= 1) {
            smsCountdown.value = 0;
            if (smsTimer) {
                clearInterval(smsTimer);
                smsTimer = null;
            }
            return;
        }
        smsCountdown.value -= 1;
    }, 1000);
};

onUnmounted(() => {
    if (smsTimer) {
        clearInterval(smsTimer);
        smsTimer = null;
    }
});

onLoad((options: any) => {
    const cachedRole = getCache('role');
    if (cachedRole === 'teacher' || cachedRole === 'student' || cachedRole === 'parent') {
        role.value = cachedRole;
    }
    if (options?.redirect) {
        redirect.value = decodeURIComponent(options.redirect);
    }
    if (options?.a) {
        account.value = options.a;
    }
    if (redirectToRoleHomeIfNeeded()) return;
});

const onLogoTap = () => {
    enterDebug.value++;
    if (enterDebug.value >= 8) {
        enterDebug.value = 0;
        uni.showToast({ title: 'Debug 模式', icon: 'none' });
    }
};

const openAgreement = (type: 'user' | 'privacy') => {
    const url = type === 'user'
        ? '/pages/agreement/user/index'
        : '/pages/agreement/privacy/index';
    uni.navigateTo({ url });
};

const getLoginTargetUrl = () => {
    const teacherHome = '/pages/teacher/index/index';
    const parentHome = '/pages/parent/home/index';
    const studentHome = '/pages/index/index';
    const value = redirect.value.trim();

    if (role.value === 'teacher') {
        if (!value) return teacherHome;
        if (value === 'teacher-home' || value === '/pages/teacher') return teacherHome;
        return value.startsWith('/pages/teacher/') ? value : teacherHome;
    }

    if (isParentLogin.value) {
        if (!value) return parentHome;
        if (value === 'parent-home' || value === '/pages/parent') return parentHome;
        return value.startsWith('/pages/parent/') ? value : parentHome;
    }

    if (!value) return studentHome;
    if (value === 'home') return studentHome;
    return value.startsWith('/pages/teacher') || value.startsWith('/pages/parent') ? studentHome : value;
};

const onSendCode = async () => {
    if (smsCountdown.value > 0 || sendingCode.value) return;
    const mobile = phone.value.trim();
    if (!isValidPhone(mobile)) {
        uni.showToast({ title: '请输入正确的手机号', icon: 'none' });
        return;
    }

    sendingCode.value = true;
    try {
        await sendParentLoginCode(mobile);
        uni.showToast({ title: '验证码已发送', icon: 'none' });
        startSmsCountdown();
    } catch (e: any) {
        uni.showToast({ title: e?.message || '发送失败', icon: 'none' });
    } finally {
        sendingCode.value = false;
    }
};

const onParentAuthorize = async () => {
    if (submitting.value) return;
    submitting.value = true;
    uni.showLoading({ title: '授权中...', mask: true });

    try {
        const loginRes = await new Promise<UniApp.LoginRes>((resolve, reject) => {
            uni.login({
                provider: 'weixin',
                success: (res) => resolve(res),
                fail: (err) => reject(err),
            });
        });

        const code = loginRes?.code || '';
        if (!code) {
            uni.hideLoading();
            uni.showToast({ title: '获取微信 code 失败', icon: 'none' });
            return;
        }

        const res = await parentMpLogin(code);
        const data = res?.data || {};
        const accessToken = data.accessToken;
        cacheWxOpenid(data.wxUser?.openid);

        if (accessToken) {
            await userStore.parentMpLoginSuccess(accessToken);
            setCache('role', 'parent');
            uni.hideLoading();
            uni.showToast({ title: '登录成功', icon: 'success' });
            setTimeout(() => navigateAfterLogin(), 800);
            return;
        }

        const openid = data.wxUser?.openid || '';
        if (!openid) {
            uni.hideLoading();
            uni.showToast({ title: '获取微信 openid 失败', icon: 'none' });
            return;
        }
        parentWxOpenid.value = openid;
        cacheWxOpenid(openid);
        parentStage.value = 'bind';
        if (data.phone) {
            phone.value = data.phone;
        }
        uni.hideLoading();
        uni.showToast({ title: '请先绑定手机号', icon: 'none' });
    } catch (e: any) {
        uni.hideLoading();
        uni.showToast({ title: e?.message || '授权失败', icon: 'none' });
    } finally {
        submitting.value = false;
    }
};

const navigateAfterLogin = () => {
    const targetUrl = getLoginTargetUrl();
    if (
        targetUrl === '/pages/index/index'
        || targetUrl === '/pages/teacher/index/index'
        || targetUrl === '/pages/parent/home/index'
    ) {
        uni.reLaunch({ url: targetUrl });
    } else {
        uni.redirectTo({ url: targetUrl });
    }
};

const onLogin = async () => {
    if (submitting.value) return;

    if (isParentLogin.value) {
        if (parentStage.value === 'authorize') {
            await onParentAuthorize();
            return;
        }

        const mobile = phone.value.trim();
        const code = smsCode.value.trim();
        if (!isValidPhone(mobile)) {
            uni.showToast({ title: '请输入正确的手机号', icon: 'none' });
            return;
        }
        if (!code) {
            uni.showToast({ title: '请输入验证码', icon: 'none' });
            return;
        }
        if (!parentWxOpenid.value) {
            uni.showToast({ title: '请先完成微信授权', icon: 'none' });
            parentStage.value = 'authorize';
            return;
        }

        submitting.value = true;
        uni.showLoading({ title: '登录中...', mask: true });
        try {
            await userStore.parentLogin({
                phone: mobile,
                verifyCode: code,
                openid: parentWxOpenid.value,
            });
            setCache('role', 'parent');
            uni.hideLoading();
            uni.showToast({ title: '登录成功', icon: 'success' });
            setTimeout(() => navigateAfterLogin(), 800);
        } catch (e: any) {
            uni.hideLoading();
            uni.showToast({ title: e?.message || '登录失败', icon: 'none' });
        } finally {
            submitting.value = false;
        }
        return;
    }

    if (!account.value.trim()) {
        uni.showToast({ title: '请输入账号', icon: 'none' });
        return;
    }
    if (!password.value) {
        uni.showToast({ title: '请输入密码', icon: 'none' });
        return;
    }

    submitting.value = true;
    uni.showLoading({ title: '登录中...', mask: true });

    try {
        const data: any = {
            account: account.value.trim(),
            password: password.value,
        };
        if (role.value === 'teacher') {
            data.clientType = 'MANAGE';
        }
        await userStore.accountLogin(data);
        setCache('role', role.value);

        uni.hideLoading();
        uni.showToast({ title: '登录成功', icon: 'success' });

        setTimeout(async () => {
            if (role.value === 'teacher') {
                try {
                    await teacherStore.getLoginUser();
                } catch (e) {
                    console.warn('teacher.getLoginUser err', e);
                }
            }
            navigateAfterLogin();
        }, 800);
    } catch (e: any) {
        uni.hideLoading();
        uni.showToast({ title: e?.message || '登录失败', icon: 'none' });
    } finally {
        submitting.value = false;
    }
};
</script>

<style lang="scss" scoped>
.login {
    min-height: 100vh;
    background: linear-gradient(180deg, #eef2ff 0%, #c7d2fe 100%);
    box-sizing: border-box;
    position: relative;
    overflow: hidden;
    padding: 0 56rpx 80rpx;
}

/* 背景装饰 */
.bg-blob {
    position: absolute;
    border-radius: 50%;
    filter: blur(40rpx);
    pointer-events: none;
    z-index: 0;
}

.blob-a {
    top: -120rpx;
    right: -120rpx;
    width: 400rpx;
    height: 400rpx;
    background: radial-gradient(circle, rgba(129, 140, 248, 0.7), transparent 70%);
}

.blob-b {
    top: 280rpx;
    left: -160rpx;
    width: 360rpx;
    height: 360rpx;
    background: radial-gradient(circle, rgba(34, 197, 94, 0.4), transparent 70%);
}

.blob-c {
    bottom: -80rpx;
    right: -80rpx;
    width: 380rpx;
    height: 380rpx;
    background: radial-gradient(circle, rgba(254, 215, 170, 0.5), transparent 70%);
}

/* 主体 */
.content {
    position: relative;
    z-index: 2;
    padding-top: 80rpx;
}

/* 品牌 */
.brand {
    text-align: center;
    margin-bottom: 60rpx;
}

.brand-logo {
    position: relative;
    width: 160rpx;
    height: 160rpx;
    margin: 0 auto 28rpx;
}

.brand-logo-glow {
    position: absolute;
    inset: -16rpx;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.9), transparent 70%);
    filter: blur(8rpx);
}

.brand-logo-img {
    position: relative;
    z-index: 1;
    width: 100%;
    height: 100%;
    border-radius: 48rpx;
    background: #ffffff;
    box-shadow:
        0 12rpx 32rpx rgba(99, 102, 241, 0.3),
        inset 0 -6rpx 0 rgba(0, 0, 0, 0.06);
}

.brand-name {
    font-size: 56rpx;
    font-weight: 800;
    color: #312e81;
    letter-spacing: 2rpx;

    .brand-name-ai {
        margin-left: 8rpx;
        background: linear-gradient(135deg, #4f46e5 0%, #22c55e 100%);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
    }
}

.brand-slogan {
    font-size: 24rpx;
    color: #6366f1;
    margin-top: 12rpx;
}

/* 角色切换 */
.role-switch {
    position: relative;
    height: 88rpx;
    margin-bottom: 40rpx;
    background: rgba(255, 255, 255, 0.7);
    border-radius: 999rpx;
    padding: 8rpx;
    display: flex;
    box-shadow: inset 0 4rpx 8rpx rgba(99, 102, 241, 0.12);
}

.role-switch-bg {
    position: absolute;
    top: 8rpx;
    left: 8rpx;
    width: calc(33.333% - 8rpx);
    height: calc(100% - 16rpx);
    background: linear-gradient(180deg, #818cf8 0%, #4f46e5 100%);
    border-radius: 999rpx;
    transition: transform 280ms cubic-bezier(0.4, 0, 0.2, 1);
    box-shadow:
        0 6rpx 14rpx rgba(79, 70, 229, 0.35),
        inset 0 -4rpx 0 rgba(0, 0, 0, 0.12);

    &.teacher {
        transform: translateX(100%);
        background: linear-gradient(180deg, #4ade80 0%, #16a34a 100%);
        box-shadow:
            0 6rpx 14rpx rgba(22, 163, 74, 0.35),
            inset 0 -4rpx 0 rgba(0, 0, 0, 0.12);
    }

    &.parent {
        transform: translateX(200%);
        background: linear-gradient(180deg, #22d3ee 0%, #0891b2 100%);
        box-shadow:
            0 6rpx 14rpx rgba(8, 145, 178, 0.35),
            inset 0 -4rpx 0 rgba(0, 0, 0, 0.12);
    }
}

.role-tab {
    position: relative;
    z-index: 1;
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10rpx;
    font-size: 28rpx;
    font-weight: 600;
    color: #94a3b8;
    transition: color 200ms ease;

    &.active {
        color: #ffffff;
    }
}

/* 表单 */
.form {
    display: flex;
    flex-direction: column;
    gap: 24rpx;
}

.form-item {
    display: flex;
    align-items: center;
    height: 104rpx;
    padding: 0 28rpx;
    background: #ffffff;
    border-radius: 28rpx;
    gap: 16rpx;
    transition: box-shadow 200ms ease, transform 150ms ease;
    box-shadow:
        0 8rpx 20rpx rgba(99, 102, 241, 0.1),
        inset 0 -4rpx 0 rgba(199, 210, 254, 0.5);

    &.focus {
        box-shadow:
            0 0 0 4rpx rgba(129, 140, 248, 0.4),
            0 8rpx 24rpx rgba(99, 102, 241, 0.18),
            inset 0 -4rpx 0 rgba(199, 210, 254, 0.5);
    }
}

.form-icon {
    width: 44rpx;
    height: 44rpx;
    flex-shrink: 0;

    svg {
        width: 100%;
        height: 100%;
    }
}

.form-input {
    flex: 1;
    height: 100%;
    font-size: 30rpx;
    color: #312e81;
    font-weight: 500;
}

.form-placeholder {
    color: #94a3b8;
    font-size: 28rpx;
}

.sms-btn {
    flex-shrink: 0;
    min-width: 168rpx;
    height: 64rpx;
    padding: 0 20rpx;
    border-radius: 18rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #0891b2;
    background: #ecfeff;
    font-size: 24rpx;
    font-weight: 700;

    &.disabled {
        color: #94a3b8;
        background: #f1f5f9;
    }
}

.form-eye {
    width: 56rpx;
    height: 56rpx;
    border-radius: 16rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;

    svg {
        width: 36rpx;
        height: 36rpx;
    }

    &:active {
        background: #eef2ff;
    }
}

/* 协议 */
.agreement {
    margin-top: 32rpx;
    text-align: center;
    font-size: 22rpx;
    color: #94a3b8;

    .link {
        color: #4f46e5;
        padding: 0 6rpx;
    }
}

/* 登录按钮 */
.btn-login {
    margin-top: 24rpx;
    height: 104rpx;
    border-radius: 999rpx;
    background: linear-gradient(180deg, #818cf8 0%, #4f46e5 100%);
    color: #ffffff;
    font-size: 32rpx;
    font-weight: 700;
    letter-spacing: 8rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow:
        0 12rpx 28rpx rgba(79, 70, 229, 0.4),
        inset 0 -6rpx 0 rgba(0, 0, 0, 0.15),
        inset 0 4rpx 0 rgba(255, 255, 255, 0.2);
    transition: transform 150ms ease, box-shadow 150ms ease;

    &:active {
        transform: translateY(4rpx);
        box-shadow:
            0 4rpx 12rpx rgba(79, 70, 229, 0.4),
            inset 0 -3rpx 0 rgba(0, 0, 0, 0.15),
            inset 0 4rpx 0 rgba(255, 255, 255, 0.2);
    }

    &.loading {
        opacity: 0.85;
    }

    &.parent {
        background: linear-gradient(180deg, #22d3ee 0%, #0891b2 100%);
        box-shadow:
            0 12rpx 28rpx rgba(8, 145, 178, 0.4),
            inset 0 -6rpx 0 rgba(0, 0, 0, 0.15),
            inset 0 4rpx 0 rgba(255, 255, 255, 0.2);

        &:active {
            box-shadow:
                0 4rpx 12rpx rgba(8, 145, 178, 0.4),
                inset 0 -3rpx 0 rgba(0, 0, 0, 0.15),
                inset 0 4rpx 0 rgba(255, 255, 255, 0.2);
        }
    }
}

.btn-wx {
    background: linear-gradient(180deg, #22c55e 0%, #16a34a 100%);
    box-shadow:
        0 12rpx 28rpx rgba(22, 163, 74, 0.4),
        inset 0 -6rpx 0 rgba(0, 0, 0, 0.15),
        inset 0 4rpx 0 rgba(255, 255, 255, 0.2);

    &:active {
        box-shadow:
            0 4rpx 12rpx rgba(22, 163, 74, 0.4),
            inset 0 -3rpx 0 rgba(0, 0, 0, 0.15),
            inset 0 4rpx 0 rgba(255, 255, 255, 0.2);
    }
}

.btn-loader {
    display: flex;
    gap: 12rpx;

    &-dot {
        width: 16rpx;
        height: 16rpx;
        border-radius: 50%;
        background: #ffffff;
        animation: bounce 1.4s infinite ease-in-out both;

        &:nth-child(1) { animation-delay: -0.32s; }
        &:nth-child(2) { animation-delay: -0.16s; }
    }
}

@keyframes bounce {
    0%, 80%, 100% { transform: scale(0.5); }
    40% { transform: scale(1); }
}

.hint {
    margin-top: 32rpx;
    text-align: center;
    color: #94a3b8;
    font-size: 22rpx;
}
</style>
