File size: 4,392 Bytes
6bf9e00
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
// Neon Cyber Login Form
class NeonCyberLoginForm extends FormUtils.LoginFormBase {
    constructor() {
        super({
            submitButtonSelector: '.neon-button',
            formGroupSelector: '.cyber-field',
            cardSelector: '.cyber-terminal',
            hideOnSuccess: ['.matrix-social', '.matrix-signup', '.cyber-divider'],
            validators: {
                email: (v) => {
                    if (!v) return { isValid: false, message: '[ ERROR: EMAIL_REQUIRED ]' };
                    if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)) return { isValid: false, message: '[ ERROR: INVALID_FORMAT ]' };
                    return { isValid: true };
                },
                password: (v) => {
                    if (!v) return { isValid: false, message: '[ ERROR: ACCESS_CODE_REQUIRED ]' };
                    if (v.length < 6) return { isValid: false, message: '[ ERROR: CODE_TOO_SHORT ]' };
                    return { isValid: true };
                },
            },
        });
    }

    decorate() {
        if (!document.getElementById('neon-cyber-keyframes')) {
            const style = document.createElement('style');
            style.id = 'neon-cyber-keyframes';
            style.textContent = `
                @keyframes textGlitch {
                    0%, 100% { transform: translate(0); }
                    20% { transform: translate(-2px, 1px); }
                    40% { transform: translate(2px, -1px); }
                    60% { transform: translate(-1px, 2px); }
                    80% { transform: translate(1px, -2px); }
                }
            `;
            document.head.appendChild(style);
        }

        // Cyber-scan effect on field focus
        [this.form.querySelector('#email'), this.form.querySelector('#password')].forEach(input => {
            if (!input) return;
            input.setAttribute('placeholder', ' ');
            input.addEventListener('focus', () => {
                const scanner = input.closest('.cyber-field')?.querySelector('.cyber-scanner');
                if (scanner) scanner.style.opacity = '1';
            });
            input.addEventListener('blur', () => {
                const scanner = input.closest('.cyber-field')?.querySelector('.cyber-scanner');
                if (scanner) scanner.style.opacity = '0.3';
            });
        });

        // Random title glitch using requestAnimationFrame
        const titleGlitch = document.querySelector('.title-glitch');
        if (titleGlitch) {
            let last = 0;
            const tick = (now) => {
                if (!document.body.contains(titleGlitch)) return;
                if (now - last > 2000) {
                    last = now;
                    if (Math.random() < 0.1) {
                        titleGlitch.style.transform = `translate(${Math.random() * 4 - 2}px, ${Math.random() * 4 - 2}px)`;
                        titleGlitch.style.filter = `hue-rotate(${Math.random() * 360}deg)`;
                        setTimeout(() => {
                            titleGlitch.style.transform = '';
                            titleGlitch.style.filter = '';
                        }, 100);
                    }
                }
                requestAnimationFrame(tick);
            };
            requestAnimationFrame(tick);
        }
    }

    onSuccess() {
        this.form.style.transition = 'all 0.3s ease';
        this.form.style.transform = 'scale(0.9)';
        this.form.style.opacity = '0';
        this.form.style.filter = 'blur(2px)';

        setTimeout(() => {
            this.form.style.display = 'none';
            this.hideOnSuccess.forEach(sel => {
                const el = document.querySelector(sel);
                if (el) el.style.display = 'none';
            });
            this.successMessage?.classList.add('show');
            setTimeout(() => {
                const successTitle = document.querySelector('.success-title');
                if (successTitle) {
                    successTitle.style.animation = 'textGlitch 0.5s ease-in-out';
                    successTitle.addEventListener('animationend', () => {
                        successTitle.style.animation = '';
                    }, { once: true });
                }
            }, 1500);
        }, 300);
    }
}

document.addEventListener('DOMContentLoaded', () => new NeonCyberLoginForm());