228 lines
8.8 KiB
Vue
228 lines
8.8 KiB
Vue
<script setup lang="ts">
|
||
import { Head, Link } from '@inertiajs/vue3';
|
||
import LoginForm from '@/components/auth/LoginForm.vue';
|
||
import UserLayout from '@/layouts/user/userlayout.vue';
|
||
|
||
defineProps<{
|
||
status?: string;
|
||
canResetPassword: boolean;
|
||
canRegister: boolean;
|
||
}>();
|
||
</script>
|
||
|
||
<template>
|
||
<UserLayout>
|
||
<Head title="Login" />
|
||
|
||
<div class="lp-wrap">
|
||
<!-- Ambient background -->
|
||
<div class="lp-bg">
|
||
<div class="orb orb-a"></div>
|
||
<div class="orb orb-b"></div>
|
||
<div class="orb orb-c"></div>
|
||
<div class="grid-overlay"></div>
|
||
</div>
|
||
|
||
<div class="lp-card">
|
||
<!-- Glowing top bar -->
|
||
<div class="card-glow-bar"></div>
|
||
|
||
<!-- Brand / Logo area -->
|
||
<div class="lp-brand">
|
||
<div class="brand-diamond">
|
||
<span class="diamond-icon">♦</span>
|
||
</div>
|
||
<h1 class="brand-title">WELCOME <span class="brand-accent">BACK</span></h1>
|
||
<p class="brand-sub">Sign in to continue playing</p>
|
||
</div>
|
||
|
||
<!-- Divider -->
|
||
<div class="lp-divider">
|
||
<span class="divider-dot"></span>
|
||
<span class="divider-line"></span>
|
||
<span class="divider-text">Your Account</span>
|
||
<span class="divider-line"></span>
|
||
<span class="divider-dot"></span>
|
||
</div>
|
||
|
||
<!-- Form -->
|
||
<LoginForm :status="status">
|
||
<template #forgot-password>
|
||
<Link v-if="canResetPassword" href="/forgot-password" class="forgot-link">
|
||
Forgot password?
|
||
</Link>
|
||
</template>
|
||
</LoginForm>
|
||
|
||
<!-- Footer -->
|
||
<div class="lp-footer" v-if="canRegister">
|
||
<span class="footer-text">New here?</span>
|
||
<button
|
||
class="reg-link"
|
||
@click="() => window.dispatchEvent(new Event('require-register'))"
|
||
>
|
||
Create account
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Trust badges -->
|
||
<div class="trust-row">
|
||
<div class="trust-badge"><span class="trust-icon">🔒</span> SSL Encrypted</div>
|
||
<div class="trust-badge"><span class="trust-icon">⚡</span> Instant Access</div>
|
||
<div class="trust-badge"><span class="trust-icon">🛡️</span> Secure</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</UserLayout>
|
||
</template>
|
||
|
||
<style scoped>
|
||
/* ── Wrapper ─────────────────────────────────────────────── */
|
||
.lp-wrap {
|
||
min-height: calc(100vh - 80px);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 40px 20px;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* ── Ambient background ──────────────────────────────────── */
|
||
.lp-bg { position: absolute; inset: 0; pointer-events: none; }
|
||
|
||
.orb {
|
||
position: absolute;
|
||
border-radius: 50%;
|
||
filter: blur(90px);
|
||
animation: orb-float 12s ease-in-out infinite;
|
||
}
|
||
.orb-a { width: 360px; height: 360px; background: var(--primary, #df006a); opacity: .18; top: -80px; left: -80px; }
|
||
.orb-b { width: 440px; height: 440px; background: #7c3aed; opacity: .12; bottom: -120px; right: -100px; animation-delay: -5s; }
|
||
.orb-c { width: 220px; height: 220px; background: #06b6d4; opacity: .10; top: 40%; left: 60%; animation-delay: -9s; }
|
||
|
||
@keyframes orb-float {
|
||
0%, 100% { transform: translate(0, 0) scale(1); }
|
||
33% { transform: translate(20px, 30px) scale(1.05); }
|
||
66% { transform: translate(-15px, -20px) scale(.97); }
|
||
}
|
||
|
||
.grid-overlay {
|
||
position: absolute; inset: 0;
|
||
background-image:
|
||
linear-gradient(rgba(255,255,255,.025) 1px, transparent 1px),
|
||
linear-gradient(90deg, rgba(255,255,255,.025) 1px, transparent 1px);
|
||
background-size: 40px 40px;
|
||
mask-image: radial-gradient(ellipse 80% 80% at 50% 50%, black 30%, transparent 100%);
|
||
}
|
||
|
||
/* ── Card ────────────────────────────────────────────────── */
|
||
.lp-card {
|
||
width: 100%;
|
||
max-width: 440px;
|
||
background: rgba(8, 8, 12, 0.85);
|
||
backdrop-filter: blur(24px);
|
||
border: 1px solid rgba(255,255,255,.08);
|
||
border-radius: 28px;
|
||
padding: 0 0 28px;
|
||
position: relative;
|
||
z-index: 10;
|
||
box-shadow:
|
||
0 0 0 1px rgba(255,255,255,.04),
|
||
0 25px 60px rgba(0,0,0,.6),
|
||
0 0 80px rgba(223,0,106,.06);
|
||
animation: card-in .7s cubic-bezier(.16,1,.3,1) both;
|
||
}
|
||
@keyframes card-in {
|
||
from { opacity: 0; transform: translateY(32px) scale(.96); }
|
||
to { opacity: 1; transform: translateY(0) scale(1); }
|
||
}
|
||
|
||
/* ── Top glow bar ────────────────────────────────────────── */
|
||
.card-glow-bar {
|
||
height: 3px;
|
||
border-radius: 28px 28px 0 0;
|
||
background: linear-gradient(90deg, transparent, var(--primary, #df006a) 30%, #a855f7 70%, transparent);
|
||
margin-bottom: 32px;
|
||
}
|
||
|
||
/* ── Brand ───────────────────────────────────────────────── */
|
||
.lp-brand { text-align: center; padding: 0 32px 8px; }
|
||
|
||
.brand-diamond {
|
||
width: 60px; height: 60px;
|
||
background: rgba(223,0,106,.1);
|
||
border: 1px solid rgba(223,0,106,.25);
|
||
border-radius: 16px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
margin: 0 auto 18px;
|
||
box-shadow: 0 0 30px rgba(223,0,106,.15);
|
||
}
|
||
.diamond-icon { font-size: 28px; color: var(--primary, #df006a); filter: drop-shadow(0 0 8px var(--primary, #df006a)); }
|
||
|
||
.brand-title {
|
||
font-size: 1.9rem;
|
||
font-weight: 900;
|
||
color: #fff;
|
||
letter-spacing: 3px;
|
||
margin: 0 0 6px;
|
||
line-height: 1.1;
|
||
}
|
||
.brand-accent {
|
||
color: var(--primary, #df006a);
|
||
text-shadow: 0 0 24px rgba(223,0,106,.5);
|
||
}
|
||
.brand-sub { color: #555; font-size: .8rem; letter-spacing: 1.5px; text-transform: uppercase; margin: 0; }
|
||
|
||
/* ── Divider ─────────────────────────────────────────────── */
|
||
.lp-divider {
|
||
display: flex; align-items: center; gap: 10px;
|
||
padding: 20px 32px 24px;
|
||
}
|
||
.divider-line { flex: 1; height: 1px; background: rgba(255,255,255,.06); }
|
||
.divider-dot { width: 4px; height: 4px; border-radius: 50%; background: rgba(223,0,106,.4); }
|
||
.divider-text { font-size: 10px; color: #444; letter-spacing: 2px; text-transform: uppercase; white-space: nowrap; }
|
||
|
||
/* ── Form wrapper ────────────────────────────────────────── */
|
||
:deep(.login-form-content) { padding: 0 32px; }
|
||
|
||
/* ── Footer ──────────────────────────────────────────────── */
|
||
.lp-footer {
|
||
display: flex; align-items: center; justify-content: center; gap: 10px;
|
||
padding: 24px 32px 8px;
|
||
border-top: 1px solid rgba(255,255,255,.05);
|
||
margin-top: 24px;
|
||
}
|
||
.footer-text { color: #555; font-size: .82rem; }
|
||
.reg-link {
|
||
display: flex; align-items: center; gap: 5px;
|
||
background: none; border: none; cursor: pointer;
|
||
color: var(--primary, #df006a); font-size: .82rem; font-weight: 700;
|
||
letter-spacing: .5px; transition: .2s; padding: 0;
|
||
}
|
||
.reg-link:hover { gap: 8px; filter: brightness(1.2); }
|
||
|
||
/* ── Trust badges ────────────────────────────────────────── */
|
||
.trust-row {
|
||
display: flex; align-items: center; justify-content: center; gap: 12px;
|
||
padding: 16px 32px 0;
|
||
flex-wrap: wrap;
|
||
}
|
||
.trust-badge {
|
||
display: flex; align-items: center; gap: 5px;
|
||
font-size: 10px; color: #444; letter-spacing: .5px;
|
||
}
|
||
.trust-icon { font-size: 11px; }
|
||
|
||
/* ── Forgot link (rendered inside LoginForm slot) ────────── */
|
||
:deep(.forgot-link) {
|
||
font-size: .75rem;
|
||
color: #555;
|
||
text-decoration: none;
|
||
transition: .2s;
|
||
letter-spacing: .3px;
|
||
}
|
||
:deep(.forgot-link:hover) { color: var(--primary, #df006a); }
|
||
</style>
|