PageSourceSearch

https://docaccess.com/app/login

html docaccess.com collected 2026-10-02 03:40:13 UTC 29,647 bytes, 654 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5    <meta charset="UTF-8">
6    <meta name="viewport" content="width=device-width, initial-scale=1.0">
7    <title>Login - DocAccess - Revolutionary Document Accessibility</title>
8    
8<script src="/static/homepage.js"></script>
8
9    <link rel="stylesheet" href="/static/style.css">
10    <link rel="preconnect" href="https://fonts.googleapis.com">
11    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
12    <link
13        href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,800;0,900;1,100;1,300;1,400;1,700;1,800;1,900&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap"
14        rel="stylesheet">
15    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
16    <style>
17        .password-toggle {
18            background: none;
19            border: none;
20            cursor: pointer;
21            padding: 4px 10px;
22            color: #666;
23            right: 0;
24            top: 0;
25            bottom: 0;
26        }
27
28        .password-toggle:hover {
29            color: #333;
30        }
31
32        .password-toggle:focus {
33            outline: 2px solid #007bff;
34            outline-offset: 2px;
35            border-radius: 4px;
36        }
37
38        .alert-danger {
39            color: #721c24;
40            background-color: #f8d7da;
41            border: 1px solid #f5c6cb;
42            padding: 12px;
43            margin-bottom: 16px;
44            border-radius: 4px;
45        }
46
47        .form-group {
48            margin-bottom: 1rem;
49        }
50
51        .form-control {
52            width: 100%;
53            padding: 8px 12px;
54            border: 1px solid #ced4da;
55            border-radius: 4px;
56        }
57
58        .form-control:focus {
59            outline: 2px solid #007bff;
60            outline-offset: 2px;
61            border-color: #007bff;
62        }
63
64        .btn-gradient:focus {
65            outline: 2px solid #007bff;
66            outline-offset: 2px;
67        }
68
69        .btn-link {
70            display: inline-block;
71            margin-left: 1rem;
72            color: #007bff;
73            text-decoration: none;
74        }
75
76        .btn-link:hover {
77            text-decoration: underline;
78        }
79
80        .btn-link:focus {
81            outline: 2px solid #007bff;
82            outline-offset: 2px;
83            border-radius: 4px;
84        }
85
86        .sr-only {
87            position: absolute;
88            width: 1px;
89            height: 1px;
90            padding: 0;
91            margin: -1px;
92            overflow: hidden;
93            clip: rect(0, 0, 0, 0);
94            white-space: nowrap;
95            border: 0;
96        }
97
98        /* SSO Login Buttons */
99        .sso-login-section {
100            margin-top: 30px;
101            padding: 20px 0;
102            border-top: 1px solid #ccc;
103        }
104
105        .sso-login-buttons {
106            display: flex;
107            flex-direction: column;
108            gap: 12px;
109            margin-top: 15px;
110        }
111
112        .sso-login-button {
113            display: flex;
114            align-items: center;
115            justify-content: center;
116            padding: 5px 20px;
117            border: 1px solid #ddd;
118            border-radius: 4px;
119            text-decoration: none;
120            font-weight: 500;
121            transition: all 0.2s ease;
122            width: 100%;
123            font-size: 16px;
124        }
125
126        .sso-login-button:hover {
127            text-decoration: none;
128            transform: translateY(-1px);
129            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
130        }
131
132        .sso-login-button.google {
133            background-color: #fff;
134            color: #333;
135            border-color: #dadce0;
136        }
137
138        .sso-login-button.google:hover {
139            background-color: #f8f9fa;
140            color: #333;
141        }
142
143        .sso-login-button.microsoft {
144            background-color: #0078d4;
145            color: white;
146            border-color: #0078d4;
147        }
148
149        .sso-login-button.microsoft:hover {
150            background-color: #106ebe;
151            color: white;
152        }
153
154        .sso-login-button.sso {
155            background-color: #178758;
156            color: #fff;
157            border-color: #178758;
158        }
159
160        .sso-login-button.sso:hover {
161            background-color: #136f48;
162            color: #fff;
163        }
164
165        .sso-icon {
166            margin-right: 10px;
167            width: 18px;
168            height: 18px;
169        }
170
171        /* "Works with your identity provider" trust strip below the SSO
172           buttons. Icons for the providers we natively support (Google,
173           Microsoft, Okta) plus name chips for common SAML/OIDC IdPs that
174           route through the same generic flow. */
175        .sso-supported {
176            margin-top: 18px;
177            text-align: center;
178        }
179
180        .sso-supported-label {
181            font-size: 12px;
182            color: #6b7280;
183            margin: 0 0 10px;
184            text-transform: uppercase;
185            letter-spacing: 0.04em;
186        }
187
188        .sso-supported-logos {
189            display: flex;
190            flex-wrap: wrap;
191            justify-content: center;
192            gap: 8px;
193        }
194
195        .sso-chip {
196            display: inline-flex;
197            align-items: center;
198            gap: 6px;
199            padding: 4px 10px;
200            border: 1px solid #e5e7eb;
201            border-radius: 9999px;
202            font-size: 12px;
203            font-weight: 500;
204            color: #374151;
205            background: #fff;
206            white-space: nowrap;
207        }
208
209        .sso-chip svg {
210            width: 14px;
211            height: 14px;
212            flex-shrink: 0;
213        }
214
215        .sso-supported-more {
216            font-size: 12px;
217            color: #9ca3af;
218            margin: 10px 0 0;
219        }
220
221        .alert-info {
222            color: #004085;
223            background-color: #cce5ff;
224            border: 1px solid #b8daff;
225            padding: 12px;
226            margin-bottom: 16px;
227            border-radius: 4px;
228        }
229    </style>
230    
230<script src="/static/common.js"></script>
vendor: 1 bytes, line 230
230
231<script>
232    (function () {
233        // Check for affiliate parameter in URL
234        const urlParams = new URLSearchParams(window.location.search);
235        const affiliateId = urlParams.get('affiliate');
236
237        if (affiliateId) {
238            // Store affiliate ID in cookie for 30 days
239            const maxAge = 30 * 24 * 60 * 60; // 30 days in seconds
240
241            // Build cookie string using max-age instead of expires
242            let cookieString = `docaccess_affiliate=${affiliateId}; max-age=${maxAge}; path=/`;
243
244            // Only set domain if we're on the production domain
245            const hostname = window.location.hostname;
246            if (hostname.includes('docaccess.com')) {
247                // For subdomain compatibility, use the root domain with a dot prefix
248                if (hostname === 'docaccess.com' || hostname === 'www.docaccess.com') {
249                    cookieString += `; domain=.docaccess.com`;
250                } else {
251                    // For other subdomains, use the specific hostname
252                    cookieString += `; domain=${hostname}`;
253                }
254            }
255            // For localhost or IP addresses, don't set domain at all
256
257            // Add Secure flag if on HTTPS
258            if (window.location.protocol === 'https:') {
259                cookieString += '; Secure';
260            }
261
262            // Always use SameSite=Lax for better compatibility
263            cookieString += '; SameSite=Lax';
264
265            // Set the cookie
266            document.cookie = cookieString;
267
268            console.log('Affiliate ID stored:', affiliateId);
269            console.log('Cookie string:', cookieString);
270            console.log('Current domain:', hostname);
271            console.log('Protocol:', window.location.protocol);
272
273            // Verify cookie was set
274            setTimeout(() => {
275                const storedValue = window.getAffiliateCookie();
276                if (storedValue) {
277                    console.log('Cookie verified - affiliate ID:', storedValue);
278                } else {
279                    console.warn('Cookie was not stored successfully');
280                }
281            }, 100);
282        }
283
284        // Helper function to read cookie (for other scripts to use)
285        window.getAffiliateCookie = function () {
286            // First try to get from cookie
287            const cookies = document.cookie.split(';');
288            for (let cookie of cookies) {
289                const [name, value] = cookie.trim().split('=');
290                if (name === 'docaccess_affiliate') {
291                    return value;
292                }
293            }
294
295            // Fallback to localStorage for development environments
296            if (typeof (Storage) !== "undefined") {
297                const localStorageValue = localStorage.getItem('docaccess_affiliate');
298                if (localStorageValue) {
299                    console.log('Using affiliate ID from localStorage:', localStorageValue);
300                    return localStorageValue;
301                }
302            }
303
304            return null;
305        };
306
307        // Also store in localStorage as a fallback (useful for development)
308        if (affiliateId && typeof (Storage) !== "undefined") {
309            localStorage.setItem('docaccess_affiliate', affiliateId);
310            console.log('Also stored affiliate ID in localStorage for fallback');
311        }
312    })();
313</script>
vendor: 1 bytes, line 313
313
314<script>
315    // UTM Parameter Tracking (always loaded — independent from affiliate capture)
316    (function () {
317        // Check for UTM parameters in URL
318        const urlParams = new URLSearchParams(window.location.search);
319        const utmParams = {};
320
321        // List of UTM parameters to capture
322        const utmKeys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
323
324        // Also capture custom tracking parameters
325        const customKeys = ['gclid', 'fbclid', 'ref'];
326
327        // Capture all UTM parameters
328        let hasUTM = false;
329        utmKeys.forEach(key => {
330            const value = urlParams.get(key);
331            if (value) {
332                utmParams[key] = value;
333                hasUTM = true;
334            }
335        });
336
337        // Capture custom parameters
338        customKeys.forEach(key => {
339            const value = urlParams.get(key);
340            if (value) {
341                utmParams[key] = value;
342            }
343        });
344
345        // If we have UTM parameters, store them
346        if (hasUTM || Object.keys(utmParams).length > 0) {
347            // Store in sessionStorage for immediate use
348            try {
349                sessionStorage.setItem('utm_params', JSON.stringify(utmParams));
350                console.log('UTM parameters captured in sessionStorage:', utmParams);
351            } catch (e) {
352                console.error('Error storing UTM parameters in sessionStorage:', e);
353            }
354
355            // Store in localStorage for persistence across sessions
356            try {
357                // Get existing stored UTMs to merge (first-touch attribution)
358                const existingUTMs = localStorage.getItem('docaccess_utm_params');
359                const existingData = existingUTMs ? JSON.parse(existingUTMs) : {};
360
361                // Store with timestamp using ISO string format
362                const currentISOString = new Date().toISOString();
363                const utmData = {
364                    ...utmParams,
365                    timestamp: currentISOString,
366                    first_touch: existingData.first_touch || utmParam
366s,
367                    first_touch_time: existingData.first_touch_time || currentISOString
368                };
369
370                localStorage.setItem('docaccess_utm_params', JSON.stringify(utmData));
371                console.log('UTM parameters stored in localStorage:', utmData);
372            } catch (e) {
373                console.error('Error storing UTM parameters in localStorage:', e);
374            }
375
376            // Store in cookie for server-side access (30 days)
377            const maxAge = 30 * 24 * 60 * 60; // 30 days in seconds
378
379            let cookieString = `docaccess_utm=${encodeURIComponent(JSON.stringify(utmParams))}; max-age=${maxAge}; path=/`;
380
381            // Root-domain cookie only on the production host — a preview or
382            // sandbox subdomain must not write attribution cookies that prod reads
383            const hostname = window.location.hostname;
384            if (hostname === 'docaccess.com' || hostname === 'www.docaccess.com') {
385                cookieString += `; domain=.docaccess.com`;
386            }
387
388            // Add security flags
389            if (window.location.protocol === 'https:') {
390                cookieString += '; Secure';
391            }
392            cookieString += '; SameSite=Lax';
393
394            document.cookie = cookieString;
395            console.log('UTM parameters stored in cookie');
396        }
397
398        // Helper function to get stored UTM parameters
399        window.getStoredUTMParams = function () {
400            // Try sessionStorage first (current session)
401            try {
402                const sessionUTMs = sessionStorage.getItem('utm_params');
403                if (sessionUTMs) {
404                    return JSON.parse(sessionUTMs);
405                }
406            } catch (e) { }
407
408            // Try localStorage (persistent)
409            try {
410                const localUTMs = localStorage.getItem('docaccess_utm_params');
411                if (localUTMs) {
412                    const data = JSON.parse(localUTMs);
413                    // Return just the UTM params, not the metadata
414                    const { timestamp, first_touch, first_touch_time, ...utms } = data;
415                    return utms;
416                }
417            } catch (e) { }
418
419            // Try cookie
420            const cookies = document.cookie.split(';');
421            for (let cookie of cookies) {
422                const [name, value] = cookie.trim().split('=');
423                if (name === 'docaccess_utm') {
424                    try {
425                        return JSON.parse(decodeURIComponent(value));
426                    } catch (e) { }
427                }
428            }
429
430            return {};
431        };
432
433        // Helper to get first-touch attribution data
434        window.getFirstTouchUTMs = function () {
435            try {
436                const localUTMs = localStorage.getItem('docaccess_utm_params');
437                if (localUTMs) {
438                    const data = JSON.parse(localUTMs);
439                    return {
440                        utms: data.first_touch || {},
441                        timestamp: data.first_touch_time || null
442                    };
443                }
444            } catch (e) { }
445            return { utms: {}, timestamp: null };
446        };
447    })();
448</script>
448
449</head>
450
451<body class="da" id="da">
452    <a href="#main-content" class="sr-only sr-only-focusable">Skip to main content</a>
453    <header class="flex items-center justify-between py-4 px-8 ">
454        <div class="logo-container flex items-center">
455            <a href="/"><img src="/static/doc-access-streamline.svg" alt="DocAccess Logo, powered by CivicPlus" class="h-10"><span class="beta-badge" style="display: none;">Beta</span></a>
456        </div>
457        <nav id="main-nav" class="hidden md:flex items-center font-medium docaccess-nav">
458            <ul class="flex items-center space-x-7 list-none m-0 p-0">
459                <li><a href="/">Home</a></li>
460                <li><a href="/blog">Blog</a></li>
461                <li><a href="/support">Support</a></li>
462                <li><a href="/pricing">Pricing</a></li>
463                <li><a href="/contact">Contact</a></li>
464                <li><a href="/app/" class="btn-action" aria-label="Sign in">Log In</a></li>
465                <li><a href="/start" class="btn-gradient">Get Your Free Accessibility Report</a></li>
466            </ul>
467        </nav>
468        <button id="mobile-menu-btn" class="hamburger md:hidden focus:outline-none z-20 relative w-8 h-8" aria-label="Mobile Menu">
469            <span></span>
470            <span></span>
471            <span></span>
472        </button>
473    </header>
474    <main id="main-content" class="w-full" role="main">
475        <section class="login-page start-hero py-16" aria-labelledby="page-title">
476            <div class="max-w-screen-lg mx-auto px-6hero-content">
477                <h1 id="page-title" class="text-3xl md:text-5xl font-bold mb-4 text-center">
478                    Login                </h1>
479                <div class="text-lg md:text-xl mb-16 text-center card">
480                    
481                                                        <form method="post" action="/app/login" id='login-form' aria-labelledby="login-title">
482                                                                                <h2 id="login-title" class="sr-only">Login Form</h2>
483                                        <div class="form-group">
484                                            <label for="email">Email</label>
485                                            <input type="email" class="form-control" id="email" name="email" required
486                                                aria-required="true" autocomplete="email">
487                                        </div>
488
489                                        <div class="form-group">
490                                            <label for="password">Password</label>
491                                            <div class="relative">
492                                                <input type="password" class="form-control pr-10" id="password" name="password" required
493                                                    aria-required="true" autocomplete="current-password"
494                                                    aria-describedby="login-password-toggle-desc">
495                                                <button type="button"
496                                                    class="password-toggle absolute right-3 top-1/2 transform -translate-y-1/2"
497                                                    id="toggle_password" aria-label="Show password" aria-pressed="false"
498                                                    aria-controls="password">
499                                                    <i class="fas fa-eye" aria-hidden="true"></i>
500                                                </button>
501                                                <span id="login-password-toggle-desc" class="sr-only">Toggle password visibility</span>
502                                            </div>
503                                        </div>
504
505                                        <button type="submit" class="btn-gradient form-submit-button">Login</button>
506                                        <a href="/app/forgot-password" class="btn-link">Forgot Password?</a>
507                                    </form>
508
509
510                                    <div class="sso-login-section ">
511                                                                                <div class="sso-login-buttons">
512                                                                                        <a href="https://accounts.google.com/o/oauth2/v2/auth?client_id=489961069422-5b8t3kektuloc3frco66bcgvnle9n1v2.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fdocaccess.com%2Fapp%2Flogin&response_type=code&scope=openid+email+profile&state=5bfecd6de33e754d32cbfc2fe26278cffe9c5cbeac693c71a785564c5c39b7e4&nonce=bd43697a9c21
512d838a0e17d2fa0f5aa6e" class="sso-login-button google">
513                                                <svg class="sso-icon" viewBox="0 0 24 24">
514                                                    <path fill="#4285f4"
515                                                        d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" />
516                                                    <path fill="#34a853"
517                                                        d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" />
518                                                    <path fill="#fbbc05"
519                                                        d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" />
520                                                    <path fill="#ea4335"
521                                                        d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" />
522                                                </svg>
523                                                Sign in with Google Workspace
524                                            </a>
525                                                                                        <a href="https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=894e292a-793e-4446-bdb9-8c2d5bf00349&redirect_uri=https%3A%2F%2Fdocaccess.com%2Fapp%2Flogin&response_type=code&scope=openid+profile+email+User.Read&state=74374971aca3d2b58246d74e79a08c49b35f7187f51568420c4542a676b9b012&nonce=8423b15c8f4768452f4e8ee36d681bb1"
526                                                class="sso-login-button microsoft">
527                                                <svg class="sso-icon" viewBox="0 0 24 24" fill="currentColor">
528                                                    <path
529                                                        d="M11.4 24H0V12.6h11.4V24zM24 24H12.6V12.6H24V24zM11.4 11.4H0V0h11.4v11.4zM24 11.4H12.6V0H24v11.4z" />
530                                                </svg>
531                                                Sign in with Microsoft
532                                            </a>
533                                            <a href="?sso=true" class="sso-login-button sso">
534                                                <svg class="sso-icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
535                                                    <path d="M12 2 4 6v6c0 5 3.5 9.4 8 10 4.5-.6 8-5 8-10V6l-8-4z"/>
536                                                </svg>
537                                                Sign in with Single Sign-On
538                                            </a>
539                                        </div>
540                                        <div class="sso-supported" role="note" aria-label="Supported single sign-on providers">
541                                            <p class="sso-supported-label">Works with your organization's identity provider</p>
542                                            <div class="sso-supported-logos">
543                                                <span class="sso-chip">
544                                                    <svg viewBox="0 0 24 24" aria-hidden="true">
545                                                        <path fill="#4285f4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" />
546                                                        <path fill="#34a853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" />
547                                                        <path fill="#fbbc05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" />
548                                                        <path fill="#ea4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" />
549                                                    </svg>
549Google Workspace</span>
550                                                <span class="sso-chip">
551                                                    <svg viewBox="0 0 24 24" aria-hidden="true">
552                                                        <defs>
553                                                            <linearGradient id="entraChipGrad" x1="2" y1="3" x2="20" y2="21" gradientUnits="userSpaceOnUse">
554                                                                <stop offset="0" stop-color="#32d4f5"/>
555                                                                <stop offset=".5" stop-color="#198ab3"/>
556                                                                <stop offset="1" stop-color="#114a8b"/>
557                                                            </linearGradient>
558                                                        </defs>
559                                                        <path fill="url(#entraChipGrad)" d="M12 2.5 3 19.5l1.9 1 7.1-13 4.2 7.7-3.9 2.1 1 1.9 6.6-3.6L12 2.5z"/>
560                                                    </svg>Microsoft Entra ID</span>
561                                                <span class="sso-chip">Okta</span>
562                                                <span class="sso-chip">OneLogin</span>
563                                                <span class="sso-chip">Ping Identity</span>
564                                                <span class="sso-chip">Auth0</span>
565                                            </div>
566                                            <p class="sso-supported-more">…and any other SAML or OIDC identity provider</p>
567                                        </div>
568                                    </div>
569                    
570                </div>
571            </div>
572        </section>
573    </main>
574    <footer class="docaccess-footer text-white w-full">
575        <div class="max-w-7xl mx-auto px-8 py-10 flex flex-col md:flex-row justify-between items-start md:items-center">
576            <!-- Logo and tagline -->
577            <div class="mb-8 md:mb-0">
578                <img src="/static/doc-access-streamline-reversed.svg" alt="DocAccess, powered by CivicPlus" class="h-12 mb-4">
579                <p class="text-sm">
580                    Your Same Documents - Transcribed, Searchable, Translated, &amp; Assisted. <span aria-hidden="true">👏</span>
581                </p>
582            </div>
583
584            <!-- Navigation -->
585            <nav class="grid grid-cols-2 gap-x-12 gap-y-2 h-full">
586                <ul class="list-none m-0 p-0 flex flex-col justify-between h-full">
587                    <li><a href="/app/login" class="block hover:underline" aria-label="Sign in">Log In</a></li>
588                    <li><a href="/support" class="block hover:underline">Support</a></li>
589                    <li><a href="/pricing" class="block hover:underline">Pricing</a></li>
590                </ul>
591                <ul class="list-none m-0 p-0 flex flex-col justify-between h-full">
592                    <li><a href="/start" class="inline-block btn-gradient text-center mt-2">Get Your Free Accessibility Report</a></li>
593                </ul>
594            </nav>
595        </div>
596
597        <!-- Bottom Footer -->
598        <div class="lower-footer text-sm py-4">
599            <div class="mx-auto px-8 flex flex-col md:flex-row justify-between items-center">
600                <p><a href="https://www.civicplus.com" target="_blank">© CivicPlus LLC</a>
601                    <span id="current-year"></span>
602                    
602<script>
603                        document.getElementById('current-year').textContent = new Date().getFullYear();
604                    </script>
604
605                </p>
606                <a href="/terms-of-use">Terms of Use</a>
607                <a href="/privacy-policy">Privacy Policy</a>
608                <a href="/terms-of-service">Customer Terms of Service</a>
609                <a href="/accessibility-statement">Accessibility Statement</a>
610            </div>
611        </div>
612    </footer>
613    
613<script>
614        document.addEventListener('DOMContentLoaded', function () {
615            function setupPasswordToggle(toggleId, inputId) {
616                const toggleButton = document.getElementById(toggleId);
617                const passwordInput = document.getElementById(inputId);
618
619                if (toggleButton && passwordInput) {
620                    toggleButton.addEventListener('click', function () {
621                        const type = passwordInput.type === 'password' ? 'text' : 'password';
622                        passwordInput.type = type;
623
624                        // Update ARIA attributes
625                        const isPressed = type === 'text';
626                        this.setAttribute('aria-pressed', isPressed);
627                        this.setAttribute('aria-label', isPressed ? 'Hide password' : 'Show password');
628
629                        // Update icon
630                        const icon = this.querySelector('i');
631                        icon.classList.toggle('fa-eye');
632                        icon.classList.toggle('fa-eye-slash');
633                    });
634
635                    // Add keyboard support
636                    toggleButton.addEventListener('keydown', function (e) {
637                        if (e.key === 'Enter' || e.key === ' ') {
638                            e.preventDefault();
639                            this.click();
640                        }
641                    });
642                }
643            }
644
645            // Setup toggles for both forms
646            setupPasswordToggle('toggle_password', 'password');
647            setupPasswordToggle('toggle_confirm_password', 'confirm_password');
648
649            // Auto-focus SSO section if owner account error is shown
650                    });
651    </script>
651
652</body>
653
654</html>

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.