PageSourceSearch

https://vanillasquad.com/assets/themes/apex/js/auth-enhancer.js?v1.2.13?v=20260707-social-off

js vanillasquad.com collected 2026-10-05 03:40:57 UTC 33,480 bytes, 945 lines download raw bytes

1// Auth Enhancer - Apex Theme
2// Enhances authentication pages (login, register, password reset, 2fa, verify)
3// with a beautiful centered card design and improved styling
4
5(function () {
6    "use strict";
7
8    // Translation helper - reads from window.APEX_LANG.auth
9    function _lang(key, fallback) {
10        var T = (window.APEX_LANG && window.APEX_LANG.auth) || {};
11        return T[key] !== undefined ? T[key] : fallback;
12    }
13
14    // Execute immediately, don't wait for DOMContentLoaded
15    function initAuthEnhancer() {
16        // Only run on authentication pages
17        const path = window.location.pathname.replace(/\/+$/, "");
18        const authFormSelector =
19            'form[action*="/user/login"], form[action*="/user/register"], form[action*="/user/password"], form[action*="/two-factor"], form[action*="/email/verify"]';
20        const hasAuthForm = !!document.querySelector(authFormSelector);
21        const isAuthPage =
22            path.includes("user/login") ||
23            path.includes("user/register") ||
24            path.includes("user/password") ||
25            path.includes("two-factor") ||
26            path.includes("email/verify") ||
27            hasAuthForm;
28
29        if (!isAuthPage) {
30            console.log("[Auth Enhancer] Not an auth page, skipping");
31            return;
32        }
33
34        console.log("[Auth Enhancer] Auth page detected:", path);
35
36        // Inject styles immediately
37        injectStyles();
38
39        // Wait for DOM to be ready
40        if (document.readyState === "loading") {
41            document.addEventListener("DOMContentLoaded", transformPage);
42        } else {
43            transformPage();
44        }
45
46        // Re-run once the DOM has fully settled to re-assert the layout/title
47        setTimeout(transformPage, 180);
48        setTimeout(transformPage, 450);
49    }
50
51    function injectStyles() {
52        if (document.getElementById("auth-enhancer-styles")) return;
53
54        const style = document.createElement("style");
55        style.id = "auth-enhancer-styles";
56        style.textContent = `
57      /* ============================================
58         AUTH ENHANCER - Beautiful Login/Register Cards
59         ============================================ */
60
61      /* Hide profile component zone and sidebar on auth pages */
62      .page-content.auth-enhanced .apex-editable-zone[data-zone-id="global.profile"],
63      .page-content.auth-enhanced .apex-editable-zone[data-zone-id="home.sidebar-left"],
64      .page-content.auth-enhanced .col-md-7-5,
65      .page-content.auth-enhanced .col-md-4-5 {
66        display: none !important;
67      }
68
69      /* Hide all h1 titles outside the card - more specific selectors */
70      .page-content.auth-enhanced > .row > .col-md-7-5 h1,
71      .page-content.auth-enhanced > .row > [class*="col-"] > h1,
72      .page-content.auth-enhanced .col-md-9 > h1,
73      .page-content.auth-enhanced .col-lg-6 > h1,
74      .page-content.auth-enhanced h1.no-remove,
75      .page-content.auth-enhanced h1:not(.auth-title) {
76        display: none !important;
77      }
78      
79        /* Forced title wrapper that we ensure stays visible */
80        .auth-forced-title {
81          display: block !important;
82          visibility: visible !important;
83          padding: 0 1rem 1.25rem;
84          width: 100%;
85          max-width: 520px;
86          margin: 0 auto;
87          text-align: center;
88          position: relative;
89          z-index: 3;
90        }
91      
92        .auth-forced-title h1 {
93          display: block !important;
94          visibility: visible !important;
95          margin: 0;
96          font-family: var(--font-heading, 'Lexend'), sans-serif;
97          font-weight: 800;
98          font-size: 1.65rem;
99          color: var(--color2, #fff);
100          text-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
101        }
102      
103        .auth-forced-title p {
104          display: block !important;
105          visibility: visible !important;
106          margin: 0.35rem 0 0;
107          color: rgba(var(--color2-rgb, 255, 255, 255), 0.65);
108          font-size: 0.9rem;
109        }
110
111      /* Override page-content layout for auth pages */
112      .page-content.auth-enhanced {
113        display: flex !important;
114        align-items: center !important;
115        justify-content: center !important;
116        min-height: calc(100vh - 120px) !important;
117        padding: 2rem 1rem !important;
118      }
119
120      .page-content.auth-enhanced > .row {
121        display: flex !important;
122        justify-content: center !important;
123        width: 100% !important;
124        max-width: 100% !important;
125        margin: 0 !important;
126      }
127
128      /* Override column widths for auth pages */
129      .page-content.auth-enhanced > .row > .col-md-9,
130      .page-content.auth-enhanced > .row > .col-lg-6,
131      .page-content.auth-enhanced > .row > [class*="col-md-9"],
132      .page-content.auth-enhanced > .row > [class*="col-lg-6"],
133      .page-content.auth-enhanced .auth-column {
134        flex: 0 0 auto !important;
135        width: 100% !important;
136        max-width: 500px !important;
137        padding: 0 1rem !important;
138      }
139
140      /* Remove unused auth-page-wrapper styles */
141
142      /* Auth Card Container */
143      .auth-card-wrapper {
144        width: 100%;
145      }
146
147      /* Auth Card Styling */
148      .auth-enhanced-card {
149        position: relative;
150        background: linear-gradient(145deg, 
151          rgba(var(--color3-rgb, 30, 30, 45), 0.95) 0%, 
152          rgba(var(--color4-rgb, 20, 20, 35), 0.98) 100%) !important;
153        border-radius: 20px !important;
154        box-shadow: 
155          0 25px 50px rgba(0, 0, 0, 0.4),
156          0 0 0 1px rgba(255, 255, 255, 0.08),
157          inset 0 1px 0 rgba(255, 255, 255, 0.1) !important;
158        overflow: hidden;
159        backdrop-filter: blur(20px);
160        -webkit-backdrop-filter: blur(20px);
161        border: none !important;
162      }
163
164      /* Gradient accent top border */
165      .auth-enhanced-card::before {
166        content: '';
167        position: absolute;
168        top: 0;
169        left: 0;
170        right: 0;
171        height: 4px;
172        background: linear-gradient(90deg, 
173          var(--color5, #7c4dfd) 0%, 
174          var(--color6, #a855f7) 50%,
175          var(--color5, #7c4dfd) 100%);
176        background-size: 200% 100%;
177        animation: auth-gradient-shift 4s ease-in-out infinite;
178        border-radius: 20px 20px 0 0;
179        z-index: 2;
180      }
181
182      @keyframes auth-gradient-shift {
183        0%, 100% { background-position: 0% 50%; }
184        50% { background-position: 100% 50%; }
185      }
186
187      /* Decorative glow effect */
188      .auth-enhanced-card::after {
189        content: '';
190        position: absolute;
191        top: -50%;
192        right: -50%;
193        width: 100%;
194        height: 100%;
195        background: radial-gradient(
196          circle at center,
197          rgba(var(--color5-rgb, 124, 77, 253), 0.08) 0%,
198          transparent 60%
199        );
200        pointer-events: none;
201        z-index: 0;
202      }
203
204      /* Card Header with Title */
205      .auth-card-header {
206        position: relative;
207        z-index: 1;
208        padding: 1.75rem 1.75rem 0 1.75rem;
209        text-align: center;
210      }
211
212      .auth-card-header .auth-icon {
213        width: 56px;
214        height: 56px;
215        background: linear-gradient(135deg, 
216          var(--color5, #7c4dfd) 0%, 
217          var(--color6, #a855f7) 100%);
218        border-radius: 50%;
219        display: flex;
220        align-items: center;
221        justify-content: center;
222        margin: 0 auto 1rem;
223        box-shadow: 
224          0 10px 30px rgba(var(--color5-rgb, 124, 77, 253), 0.35),
225          0 0 0 4px rgba(255, 255, 255, 0.1);
226        animation: auth-icon-pulse 3s ease-in-out infinite;
227      }
228
229      @keyframes auth-icon-pulse {
230        0%, 100% { 
231          transform: scale(1);
232          box-shadow: 
233            0 10px 30px rgba(var(--color5-rgb, 124, 77, 253), 0.35),
234            0 0 0 4px rgba(255, 255, 255, 0.1);
235        }
236        50% { 
237          transform: scale(1.02);
238          box-shadow: 
239            0 15px 40px rgba(var(--color5-rgb, 124, 77, 253), 0.45),
240            0 0 0 6px rgba(255, 255, 255, 0.12);
241        }
242      }
243
244      .auth-card-header .auth-icon i {
245        font-size: 1.5rem;
246        color: white;
247      }
248
249      .auth-card-header .auth-title {
250        font-family: var(--font-heading, 'Lexend'), sans-serif;
251        font-weight: 700;
252        font-size: 1.5rem;
253        color: var(--color2, #fff);
254        margin-bottom: 0.35rem;
255        text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
256        display: block !important;
257      }
258
259      .auth-card-header .auth-subtitle {
260        color: rgba(var(--color2-rgb, 255, 255, 255), 0.6);
261        font-size: 0.85rem;
262        margin-bottom: 0;
263      }
264
265      /* Card Body */
266      .auth-enhanced-card .card-body {
267        position: relative;
268        z-index: 1;
269        padding: 2.15rem 2.25rem 2.4rem !important;
270      }
271
272      /* Form Styling */
273      .auth-enhanced-card .form-label {
274        font-weight: 600;
275        font-size: 0.9rem;
276        color: var(--color2, #fff);
277        margin-bottom: 0.5rem;
278        text-transform: uppercase;
279        letter-spacing: 0.5px;
280        opacity: 0.9;
281      }
282
283      .auth-enhanced-card .form-control {
284        background: rgba(255, 255, 255, 0.05) !important;
285        border: 2px solid rgba(255, 255, 255, 0.1) !important;
286        border-radius: 12px !important;
287        padding: 0.85rem 1.1rem !important;
288        color: var(--color2, #fff) !important;
289        font-size: 1rem;
290        transition: all 0.3s ease;
291      }
292
293      .auth-enhanced-card .form-control::placeholder {
294        color: rgba(255, 255, 255, 0.35);
295      }
296
297      .auth-enhanced-card .form-control:focus {
298        background: rgba(255, 255, 255, 0.08) !important;
299        border-color: var(--color5, #7c4dfd) !important;
300        box-shadow: 
301          0 0 0 4px rgba(var(--color5-rgb, 124, 77, 253), 0.15),
302          0 4px 20px rgba(var(--color5-rgb, 124, 77, 253), 0.2) !important;
303        outline: none;
304      }
305
306      .auth-enhanced-card .form-control.is-invalid {
307        border-color: #dc3545 !important;
308        box-shadow: 0 0 0 4px rgba(220, 53, 69, 0.15) !important;
309      }
310
311      /* Checkbox styling */
312      .auth-enhanced-card .form-check-input {
313        width: 1.25rem;
314        height: 1.25rem;
315        border-radius: 6px;
316        background-color: rgba(255, 255, 255, 0.05);
317        border: 2px solid rgba(255, 255, 255, 0.2);
318        transition: all 0.2s ease;
319        margin-top: 0.15rem;
320      }
321
322      .auth-enhanced-card .form-check-input:checked {
323        background-color: var(--color5, #7c4dfd);
324        border-color: var(--color5, #7c4dfd);
325        background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e");
326        background-position: center;
327        background-size: contain;
328        background-repeat: no-repeat;
329      }
330
331      .auth-enhanced-card .form-check-label {
332        font-size: 0.95rem;
333        color: rgba(255, 255, 255, 0.85);
334        margin-left: 0.5rem;
335      }
336        color: rgba(var(--color2-rgb, 255, 255, 255), 0.8);
337        font-size: 0.95rem;
338      }
339
340      /* Links styling */
341      .auth-enhanced-card a {
342        color: var(--color5, #7c4dfd);
343        font-weight: 600;
344        transition: all 0.2s ease;
345      }
346
347      .auth-enhanced-card a:hover {
348        color: var(--color6, #a855f7);
349        text-decoration: none;
350      }
351
352      /* Button styling */
353      .auth-enhanced-card .btn-primary {
354        background: linear-gradient(135deg, 
355          var(--color5, #7c4dfd) 0%, 
356          var(--color6, #a855f7) 100%) !important;
357        border: none !important;
358        border-radius: 12px !important;
359        padding: 0.9rem 2rem !important;
360        font-weight: 700;
361        font-size: 1rem;
362        text-transform: uppercase;
363        letter-spacing: 1px;
364        transition: all 0.3s ease;
365        box-shadow: 
366          0 8px 25px rgba(var(--color5-rgb, 124, 77, 253), 0.35),
367          inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
368        position: relative;
369        overflow: hidden;
370      }
371
372      .auth-enhanced-card .btn-primary::before {
373        content: '';
374        position: absolute;
375        top: 0;
376        left: -100%;
377        width: 100%;
378        height: 100%;
379        background: linear-gradient(
380          90deg,
381          transparent,
382          rgba(255, 255, 255, 0.2),
383          transparent
384        );
385        transition: left 0.5s ease;
386      }
387
388      .auth-enhanced-card .btn-primary:hover {
389        transform: translateY(-3px);
390        box-shadow: 
391          0 12px 35px rgba(var(--color5-rgb, 124, 77, 253), 0.45),
392          inset 0 1px 0 rgba(255, 255, 255, 0.25) !important;
393      }
394
395      .auth-enhanced-card .btn-primary:hover::before {
396        left: 100%;
397      }
398
399      .auth-enhanced-card .btn-primary:active {
400        transform: translateY(-1px);
401      }
402
403      /* Social login buttons */
404      .auth-enhanced-card .btn-secondary,
405      .auth-enhanced-card .btn-outline-secondary {
406        background: rgba(255, 255, 255, 0.05);
407        border: 2px solid rgba(255, 255, 255, 0.15);
408        border-radius: 12px;
409        color: var(--color2, #fff);
410        transition: all 0.3s ease;
411      }
412
413      .auth-enhanced-card .btn-secondary:hover,
414      .auth-enhanced-card .btn-outline-secondary:hover {
415        background: rgba(255, 255, 255, 0.1);
416        border-color: rgba(255, 255, 255, 0.25);
417        transform: translateY(-2px);
418      }
419
420      /* Divider styling */
421      .auth-enhanced-card hr {
422        border-color: rgba(255, 255, 255, 0.1);
423        margin: 1.5rem 0;
424      }
425
426      /* Invalid feedback */
427      .auth-enhanced-card .invalid-feedback {
428        font-size: 0.85rem;
429        margin-top: 0.5rem;
430      }
431
432      /* Register link at bottom */
433      .auth-card-footer {
434        position: relative;
435        z-index: 1;
436        text-align: center;
437        padding: 0 1.75rem 1.5rem;
438        color: rgba(var(--color2-rgb, 255, 255, 255), 0.6);
439        font-size: 0.875rem;
440      }
441
442      .auth-card-footer a {
443        color: var(--color5, #7c4dfd);
444        font-weight: 600;
445      }
446
447      /* Captcha section styling */
448      .auth-enhanced-card .g-recaptcha,
449      .auth-enhanced-card [data-captcha],
450      .auth-enhanced-card .h-captcha {
451        display: flex;
452        justify-content: center;
453        margin: 1rem 0;
454      }
455
456      /* Mobile Responsive */
457      @media (max-width: 576px) {
458        .page-content.auth-enhanced {
459          padding: 1rem 0 !important;
460        }
461
462        .page-content.auth-enhanced .auth-column {
463          padding: 0 !important;
464        }
465
466        .auth-page-wrapper {
467          max-width: 100%;
468          padding: 0 0.5rem;
469        }
470
471        .auth-card-header {
472          padding: 2rem 1.5rem 0 1.5rem;
473        }
474
475        .auth-card-header .auth-icon {
476          width: 60px;
477          height: 60px;
478        }
479
480        .auth-card-header .auth-icon i {
481          font-size: 1.5rem;
482        }
483
484        .auth-card-header .auth-title {
485          font-size: 1.5rem;
486        }
487
488        .auth-enhanced-card .card-body {
489          padding: 1.5rem !important;
490        }
491
492        .auth-card-footer {
493          padding: 0 1.5rem 1.5rem;
494        }
495
496        .auth-enhanced-card .btn-primary {
497          padding: 0.8rem 1.5rem !important;
498          font-size: 0.95rem;
499        }
500      }
501
502      .auth-provider-btn,
503      .auth-discord-btn {
504        display: flex;
505        align-items: center;
506        justify-content: center;
507        gap: 0.75rem;
508        width: 100%;
509        padding: 0.95rem 1.25rem;
510        border: none !important;
511        border-radius: 12px !important;
512        font-weight: 800;
513        font-size: 0.95rem;
514        text-transform: uppercase;
515        letter-spacing: 0.5px;
516        text-decoration: none !important;
517        transition: all 0.3s ease;
518      }
519
520      .auth-provider-grid {
521        display: grid;
522        grid-template-columns: 1fr;
523        gap: 0.75rem;
524        margin-bottom: 0.75rem;
525      }
526
527      .auth-provider-btn {
528        color: white !important;
529        box-shadow: 0 8px 25px rgba(0, 0, 0, 0.18);
530      }
531
532      .auth-provider-google {
533        background: #fff !important;
534        color: #3c4043 !important;
535        border: 1.5px solid #e0e0e0 !important;
536        box-shadow: 0 2px 8px rgba(60,64,67,0.08);
537        font-weight: 600;
538      }
539      .auth-provider-google .auth-provider-icon {
540        background: transparent;
541      }
542      .auth-provider-google:hover {
543        box-shadow: 0 4px 16px rgba(60,64,67,0.12);
544        filter: none;
545      }
546
547      .auth-provider-yandex {
548        background: linear-gradient(135deg, #fc3f1d 0%, #ef2a0f 100%) !important;
549        box-shadow: 0 8px 25px rgba(252, 63, 29, 0.35);
550      }
551
552      .auth-provider-btn:hover {
553        transform: translateY(-2px);
554        filter: brightness(1.05);
555      }
556
557      .auth-provider-google:hover {
558        box-shadow: 0 12px 35px rgba(66, 133, 244, 0.45);
559      }
560
561      .auth-provider-yandex:hover {
562        box-shadow: 0 12px 35px rgba(252, 63, 29, 0.45);
563      }
564
565      .auth-provider-icon {
566        display: inline-flex;
567        align-items: center;
568        justify-content: center;
569        width: 26px;
570        height: 26px;
571        border-radius: 0;
572        flex: 0 0 26px;
573        font-weight: 800;
574        line-height: 1;
575        background: transparent;
576        border: none;
577        box-shadow: none;
578      }
579
580      .auth-provider-icon svg {
581        display: block;
582        width: 100%;
583        height: 100%;
584      }
585
586      .auth-discord-btn {
587        background: #5865F2 !important;
588        color: white !important;
589        box-shadow: 0 8px 25px rgba(88, 101, 242, 0.35);
590        margin-bottom: 1rem;
591      }
592
593      .auth-discord-btn:hover {
594        background: #4752C4 !important;
595        transform: translateY(-2px);
596        box-shadow: 0 12px 35px rgba(88, 101, 242, 0.45);
597      }
598
599      .auth-discord-btn svg {
600        width: 22px;
601        height: 22px;
602      }
603
604      .auth-divider {
605        display: flex;
606        align-items: center;
607        margin: 1.25rem 0;
608        color: rgba(var(--color2-rgb, 255, 255, 255), 0.5);
609        font-size: 0.85rem;
610        text-transform: uppercase;
611        letter-spacing: 1px;
612      }
613
614      .auth-divider::before,
615      .auth-divider::after {
616        content: '';
617        flex: 1;
618        height: 1px;
619        background: rgba(255, 255, 255, 0.15);
620      }
621
622      .auth-divider::before {
623        margin-right: 1rem;
624      }
625
626      .auth-divider::after {
627        margin-left: 1rem;
628      }
629
630      /* Animation on load */
631      @keyframes auth-card-appear {
632        0% {
633          opacity: 0;
634          transform: translateY(30px) scale(0.95);
635        }
636        100% {
637          opacity: 1;
638          transform: translateY(0) scale(1);
639        }
640      }
641
642      .auth-enhanced-card {
643        animation: auth-card-appear 0.6s cubic-bezier(0.22, 1, 0.36, 1) forwards;
644      }
645
646      /* Floating particles background effect */
647      .auth-particles {
648        position: fixed;
649        top: 0;
650        left: 0;
651        width: 100%;
652        height: 100%;
653        pointer-events: none;
654        z-index: 0;
655        overflow: hidden;
656      }
657
658      .auth-particle {
659        position: absolute;
660        width: 6px;
661        height: 6px;
662        background: var(--color5, #7c4dfd);
663        border-radius: 50%;
664        opacity: 0.3;
665        animation: auth-particle-float 15s infinite;
666      }
667
668      @keyframes auth-particle-float {
669        0%, 100% {
670          transform: translateY(100vh) rotate(0deg);
671          opacity: 0;
672        }
673        10% {
674          opacity: 0.3;
675        }
676        90% {
677          opacity: 0.3;
678        }
679        100% {
680          transform: translateY(-100vh) rotate(720deg);
681          opacity: 0;
682        }
683      }
684    `;
685        document.head.appendChild(style);
686        console.log("[Auth Enhancer] Styles injected");
687    }
688
689    function removeDisabledSocialAuth(root) {
690        var selectors = [];
691        var authConfig = window.APEX_AUTH_CONFIG || {};
692
693        if (!authConfig.googleAuthEnabled) {
694            selectors.push(
695                '.auth-provider-google, a[href*="/google-auth"], a[href*="google-auth"]'
696            );
697        }
698
699        if (!authConfig.discordAuthEnabled) {
700            selectors.push(
701                '.auth-discord-btn, a[href*="/discord-auth"], a[href*="discord-auth"], a[href*="/discord"]'
702            );
703        }
704
705        if (selectors.length === 0) {
706            return;
707        }
708
709        (root || document).querySelectorAll(selectors.join(", ")).forEac
709h(function (element) {
710            element.remove();
711        });
712    }
713
714    function transformPage() {
715        console.log("[Auth Enhancer] Transforming page...");
716        removeDisabledSocialAuth(document);
717
718        // Add class to page-content for auth styling
719        const pageContent = document.querySelector(".page-content");
720        if (pageContent) {
721            pageContent.classList.add("auth-enhanced");
722            console.log("[Auth Enhancer] Added auth-enhanced class");
723        }
724
725        // Find the card element - look for the one containing the auth form
726        const authFormSelectors = [
727            'form[action*="/user/login"]',
728            'form[action*="/user/register"]',
729            'form[action*="/user/password"]',
730            'form[action*="/two-factor"]',
731            'form[action*="/email/verify"]',
732            "form#captcha-form",
733        ];
734
735        let card = null;
736        for (const selector of authFormSelectors) {
737            const form = document.querySelector(selector);
738            if (form) {
739                card = form.closest(".card");
740                if (card) break;
741            }
742        }
743
744        // Fallback: looking for card in main layout columns
745        if (!card) {
746            card = document.querySelector(".col-md-9 .card, .col-lg-6 .card");
747        }
748
749        // Fallback: exclude known widgets if picking generic card
750        if (!card) {
751            const allCards = document.querySelectorAll(".card");
752            for (const c of allCards) {
753                if (
754                    !c.closest(".apex-editable-zone") &&
755                    !c.id.includes("component")
756                ) {
757                    card = c;
758                    break;
759                }
760            }
761        }
762
763        if (!card) {
764            console.warn("[Auth Enhancer] No auth card found");
765            return;
766        }
767
768        console.log("[Auth Enhancer] Card found");
769
770        // Hide ALL h1 elements that are not our auth-title
771        document.querySelectorAll("h1").forEach((h1) => {
772            if (!h1.classList.contains("auth-title")) {
773                h1.style.cssText =
774                    "display: none !important; visibility: hidden !important;";
775            }
776        });
777
778        // Determine title based on URL
779        const path = window.location.pathname;
780        let titleText = _lang("login_title", "Login");
781        let iconClass = "bi-box-arrow-in-right";
782        let subtitle = _lang("login_subtitle", "Log in to access your account");
783
784        if (path.includes("user/register")) {
785            titleText = _lang("register_title", "Register");
786            iconClass = "bi-person-plus";
787            subtitle = _lang(
788                "register_subtitle",
789                "Create your account to get started",
790            );
791        } else if (path.includes("user/password")) {
792            titleText = _lang("password_title", "Password");
793            iconClass = "bi-key";
794            subtitle = _lang("password_subtitle", "Reset your password");
795        } else if (path.includes("two-factor")) {
796            titleText = _lang("2fa_title", "2FA Verification");
797            iconClass = "bi-shield-lock";
798            subtitle = _lang("2fa_subtitle", "Two-factor verification");
799        } else if (path.includes("verify")) {
800            titleText = _lang("verify_title", "Verification");
801            iconClass = "bi-envelope-check";
802            subtitle = _lang("verify_subtitle", "Verify your email address");
803        }
804
805        // Add enhanced class to card
806        card.classList.add("auth-enhanced-card");
807        removeDisabledSocialAuth(card);
808
809        /* Forced title removed as per user request */
810
811        // Only add header if not already present
812        if (!card.querySelector(".auth-card-header")) {
813            const cardHeader = document.createElement("div");
814            cardHeader.className = "auth-card-header";
815            cardHeader.innerHTML = `
816        <div class="auth-icon">
817          <i class="bi ${iconClass}"></i>
818        </div>
819        <h1 class="auth-title" style="display: block !important; visibility: visible !important;">${titleText}</h1>
820        <p class="auth-subtitle">${subtitle}</p>
821      `;
822            card.insertBefore(cardHeader, card.firstChild);
823            console.log("[Auth Enhancer] Header added with title:", titleText);
824        }
825
826        // Add social auth buttons on login/register pages
827        var authConfig = window.APEX_AUTH_CONFIG || {};
828        if (
829            (path.includes("user/login") || path.includes("user/register")) &&
830            !card.querySelector(".auth-social-section")
831        ) {
832            var cardBody = card.querySelector(".card-body");
833            if (cardBody) {
834                var providerButtons = [];
835
836                // Render the installed OAuth entry points directly. Some
837                // Azuriom auth plugins are not exposed through the theme's
838                // plugin manager, which previously hid valid buttons.
839                var googleAuthUrl = authConfig.googleAuthUrl || "/google-auth";
840                var yandexAuthUrl = authConfig.yandexAuthUrl || "/yandex-auth";
841
842                if (authConfig.googleAuthEnabled && googleAuthUrl) {
843                    providerButtons.push(
844                        '<a href="' +
845                            googleAuthUrl +
846                            '" class="auth-provider-btn auth-provider-google">' +
847                            '<span class="auth-provider-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 10v4.2h5.8c-.2 1.1-1.1 2.4-2.4 3.3l-.1.1 3.1 3.1c1.8-1.7 2.8-4.2 2.8-7.1 0-.7-.1-1.4-.3-2.1H12z" fill="#4285F4"/><path d="M5.2 14.4A6.9 6.9 0 0 1 5 12c0-1 .2-2 .6-2.9l.1-.2L2.5 5.8A11.9 11.9 0 0 0 1 12c0 1.9.4 3.6 1.2 5.2l3-2.8z" fill="#EA4335"/><path d="M12 22c2.9 0 5.4-.9 7.2-2.6l-3.4-2.9c-.9.6-2.1.9-3.8.9-2.9 0-5.4-1.9-6.2-4.6l-3 2.9A11.9 11.9 0 0 0 12 22z" fill="#34A853"/><path d="M18.2 4.4A11.7 11.7 0 0 0 12 1a11.9 11.9 0 0 0-10.8 6.8l3.1 2.4c.8-2.7 3.3-4.6 6.2-4.6 1.4 0 2.6.4 3.6 1.1l2.9-2.9z" fill="#FBBC05"/></svg></span>' +
848                            _lang("google_login_button", "Войти через Google") +
849                            "</a>",
850                    );
851                }
852
853                if (yandexAuthUrl) {
854                    providerButtons.push(
855                        '<a href="' +
856                            yandexAuthUrl +
857                            '" class="auth-provider-btn auth-provider-yandex">' +
858                            '<span class="auth-provider-icon"><svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2"><path d="M455.999 6h-400C28.388 6 6 28.387 6 56v399.999c0 27.612 22.388 50 50 50h400c27.612 0 50-22.388 50-50v-400c0-27.612-22.388-50-50-50z" fill="#fc3f1d" fill-rule="nonzero"/><path d="M283.718 362.624v53.781h-55.062v-90.687L124.75 99.75h57.456l80.95 176.78c15.606 33.782 20.562 45.52 20.562 86.094zM387.249 99.75l-67.55 153.093h-55.981L331.262 99.75h55.987z" fill="#fff" fill-rule="nonzero"/></svg></span>' +
859                            _lang("yandex_login_button", "Войти через Яндекс") +
860                            "</a>",
861                    );
862                }
863
864                if (providerButtons.length > 0 || authConfig.discordAuthEnabled) {
865                    var socialSection = document.createElement("div");
866                    socialSection.className = "auth-social-section";
867                    socialSection.innerHTML =
868                        (providerButtons.length > 0
869                            ? '<div class="auth-provider-grid">' +
870                              providerButtons.join("") +
871                              "</div>"
872                            : "") +
873                        (authConfig.discordAuthEnabled
874                            ? '<a href="' +
875                              authConfig.discordAuthUrl +
876                              '" class="auth-discord-btn">' +
877                              '<svg viewBox="0 0 24 24" fill="white"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 
8771.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/></svg>' +
878                              _lang("discord_login_button", "Войти через Discord") +
879                              "</a>"
880                            : "") +
881                        '<div class="auth-divider">' +
882                        _lang("or", "or") +
883                        "</div>";
884                    cardBody.insertBefore(socialSection, cardBody.firstChild);
885                    removeDisabledSocialAuth(socialSection);
886                }
887            }
888        }
889
890        // Add footer links (register link only if route exists)
891        if (!card.querySelector(".auth-card-footer")) {
892            if (path.includes("user/login") && authConfig.registerRouteExists) {
893                const footer = document.createElement("div");
894                footer.className = "auth-card-footer";
895                footer.innerHTML =
896                    "<span>" +
897                    _lang("no_account", "Don't have an account?") +
898                    '</span> <a href="/user/register">' +
899                    _lang("sign_up", "Sign up") +
900                    "</a>";
901                card.appendChild(footer);
902            } else if (path.includes("user/register")) {
903                const footer = document.createElement("div");
904                footer.className = "auth-card-footer";
905                footer.innerHTML =
906                    "<span>" +
907                    _lang("already_account", "Already have an account?") +
908                    '</span> <a href="/user/login">' +
909                    _lang("sign_in", "Log in") +
910                    "</a>";
911                card.appendChild(footer);
912            }
913        }
914
915        // Mark column for CSS
916        const col = card.closest('[class*="col-"]');
917        if (col) {
918            col.classList.add("auth-column");
919        }
920
921        // Add particles
922        if (!document.querySelector(".auth-particles")) {
923            const particles = document.createElement("div");
924            particles.className = "auth-particles";
925            for (let i = 0; i < 15; i++) {
926                const p = document.createElement("div");
927                p.className = "auth-particle";
928                p.style.left = `${Math.random() * 100}%`;
929                p.style.animationDelay = `${Math.random() * 15}s`;
930                p.style.animationDuration = `${15 + Math.random() * 10}s`;
931                const size = 4 + Math.random() * 4;
932                p.style.width = `${size}px`;
933                p.style.height = `${size}px`;
934                particles.appendChild(p);
935            }
936            document.body.appendChild(particles);
937        }
938
939        console.log("[Auth Enhancer] Transformation complete");
940    }
941
942    // Initialize
943    initAuthEnhancer();
944})();
945

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.