PageSourceSearch

https://repsshield.com/login/

html repsshield.com collected 2026-10-02 01:59:50 UTC 43,218 bytes, 894 lines download raw bytes

1<!DOCTYPE html><html lang="en"><head>
2    <!-- Analytics will be loaded after DOM ready for better performance -->
3
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
6    
6<script type="text/javascript" async="" src="https://www.clarity.ms/tag/txssedjw3f?ref=gtm"></script>
6<script type="text/javascript" async="" src="https://www.googletagmanager.com/gtag/js?id=G-VXZQGNBXN9&amp;cx=c&amp;gtm=4e69u2"></script>
6<script async="" src="https://www.googletagmanager.com/gtm.js?id=GTM-TZZ5448V"></script>
6<script type="text/javascript" async="" src="//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js"></script>
6<script>
7      (function () {
8        var protocol = window.location && window.location.protocol;
9        var isNativeShell = protocol === "capacitor:" || protocol === "ionic:";
10
11        if (!isNativeShell) {
12          return;
13        }
14
15        document.documentElement.classList.add("native-capacitor-shell");
16
17        function clearNativeStartupRoot() {
18          var root = document.getElementById("root");
19          if (!root) {
20            return false;
21          }
22
23          var hasPrerenderedContent =
24            root.getAttribute("data-prerendered") === "true";
25          var hasStartupLoader = !!root.querySelector("#loading-indicator");
26
27          if (!hasPrerenderedContent && !hasStartupLoader) {
28            return false;
29          }
30
31          root.innerHTML = "";
32          root.removeAttribute("data-prerendered");
33          root.removeAttribute("style");
34          root.setAttribute("data-native-startup-cleared", "true");
35          return true;
36        }
37
38        if (!clearNativeStartupRoot()) {
39          var observer = new MutationObserver(function () {
40            if (clearNativeStartupRoot()) {
41              observer.disconnect();
42            }
43          });
44
45          observer.observe(document.documentElement, {
46            childList: true,
47            subtree: true,
48          });
49
50          document.addEventListener(
51            "DOMContentLoaded",
52            function () {
53              clearNativeStartupRoot();
54              observer.disconnect();
55            },
56            { once: true }
57          );
58        }
59      })();
60    </script>
60
61    <style>
62      html.native-capacitor-shell #root[data-prerendered="true"] {
63        visibility: hidden !important;
64        opacity: 0 !important;
65      }
66    </style>
67
68    <!-- Safari Compatibility Meta Tags -->
69    <meta name="format-detection" content="telephone=no">
70    <meta name="apple-mobile-web-app-capable" content="yes">
71    <meta name="apple-mobile-web-app-status-bar-style" content="default">
72    <meta name="apple-touch-fullscreen" content="yes">
73
74    <!-- Additional Safari iOS Support -->
75    <meta name="mobile-web-app-capable" content="yes">
76    <meta name="apple-mobile-web-app-title" content="REPSShield">
77    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
78    <!-- SEO Meta Tags -->
79    <meta name="description" content="Professional IRS REP tracking software to track REP hours and maintain IRS compliance. Comprehensive real estate professional time tracking with audit-ready reports for REP status qualification.">
80    <meta name="keywords" content="IRS REP tracking, track REP hours, IRS compliance tools, real estate professional, REP status, time tracking, material participation, audit compliance">
81    <meta name="author" content="REPSShield">
82    <meta name="robots" content="index, follow">
83
84    <!-- Open Graph Meta Tags -->
85    <meta property="og:title" content="IRS REP Tracking &amp; Compliance Tools | REPSShield">
86    <meta property="og:description" content="Track REP hours with professional IRS compliance tools. Secure time tracking software for real estate professionals seeking REP status qualification.">
87    <meta property="og:type" content="website">
88    <meta property="og:image" content="https://repsshield.com/repsshield-logo-main.png">
89    <meta property="og:url" content="">
90    <meta property="og:locale" content="en_US">
91    <meta property="og:site_name" content="REPSShield">
92
93    <!-- Twitter Card Meta Tags -->
94    <meta name="twitter:card" content="summary_large_image">
95    <meta name="twitter:title" content="IRS REP Tracking &amp; Compliance Tools | REPSShield">
96    <meta name="twitter:description" content="Professional software to track REP hours and maintain IRS compliance for real estate professionals.">
97    <meta name="twitter:image" content="https://repsshield.com/repsshield-logo-main.png">
98
99    <!-- Google Workspace Domain Verification -->
100    <meta name="google-site-verification" content="cqP-09PR0BaU2WIhFBeqgZVvytDSELFNgi81gP7DLYc">
101
102    <!-- Technical Meta Tags -->
103    <meta name="theme-color" content="#55b021">
104    <meta name="apple-mobile-web-app-capable" content="yes">
105    <meta name="apple-mobile-web-app-status-bar-style" content="default">
106    <meta name="apple-mobile-web-app-title" content="REPSShield">
107    <meta name="mobile-web-app-capable" content="yes">
108
109    <!-- SEO Technical Tags -->
110    <link rel="canonical" id="canonical-link" href="https://repsshield.com/login">
111    <meta name="referrer" content="no-referrer-when-downgrade">
112    <meta http-equiv="content-language" content="en-US">
113    <meta name="geo.region" content="US">
114    <meta name="geo.placename" content="United States">
115
116    <!-- Resource Links -->
117    <link rel="icon" type="image/x-icon" href="/favicon.ico">
118    <link rel="shortcut icon" href="/favicon.png">
119    <link rel="apple-touch-icon" href="/repsshield-logo-main.png">
120    <link rel="manifest" href="/manifest.json">
121    <link rel="sitemap" type="application/xml" href="/sitemap.xml">
122
123    <!-- LunchMoney Style System with performance optimization -->
124    <link rel="stylesheet" href="/style.css" media="all">
125
126    <!-- Performance: Preload critical CSS -->
127    <link rel="stylesheet" href="/style.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
128    <noscript><link rel="stylesheet" href="/style.css" /></noscript>
129
130    <title>
131      IRS REP Tracking &amp; Compliance Tools | Track REP Hours | REPSShield
132    </title>
133
134    <!-- Performance Optimization: Resource Hints -->
135    <link rel="preconnect" href="https://www.googletagmanager.com" crossorigin="">
136    <link rel="preconnect" href="https://fonts.googleapis.com" crossorigin="">
137    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
138    <link rel="dns-prefetch" href="//www.google-analytics.com">
139    <link rel="preconnect" href="https://cdn.amplitude.com" crossorigin="">
140
141    <!-- Deferred Google Tag Manager for better performance -->
142    
142<script>
143      // Defer GTM loading until after page load for better performance
144      window.addEventListener("load", function () {
145        (function (w, d, s, l, i) {
146          w[l] = w[l] || [];
147          w[l].push({
148            "gtm.start": new Date().getTime(),
149            event: "gtm.js",
150          });
151          var f = d.getElementsByTagName(s)[0],
152            j = d.createElement(s),
153            dl = l != "dataLayer" ? "&l=" + l : "";
154          j.async = true;
155          j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
156          f.parentNode.insertBefore(j, f);
157        })(window, document, "script", "dataLayer", "GTM-TZZ5448V");
158      });
159    </script>
159
160
161    <!-- Structured Data for SEO -->
162    
162<script type="application/ld+json">
163      {
164        "@context": "https://schema.org",
165        "@type": "SoftwareApplication",
166        "name": "REPSShield",
167        "applicationCategory": "BusinessApplication",
168        "description": "Professional IRS REP tracking software to track REP hours and maintain IRS compliance for real estate professionals",
169        "url": "https://repsshield.com",
170        "operatingSystem": "Web Browser",
171        "softwareVersion": "1.0",
172        "offers": {
173          "@type": "Offer",
174          "price": "5.00",
175          "priceCurrency": "USD",
176          "priceValidUntil": "2026-12-31"
177        },
178        "applicationSubCategory": "Time Tracking Software",
179        "featureList": [
180          "IRS REP tracking",
181          "Track REP hours",
182          "IRS compliance tools",
183          "Material participation tracking",
184          "Audit-ready reports",
185          "Real estate professional time tracking"
186        ],
187        "creator": {
188          "@type": "Organization",
189          "name": "REPSShield",
190          "url": "https://repsshield.com"
191        }
192      }
193    </script>
193
194    
vendor: 3,251 bytes, lines 194-270
194<script type="text/javascript">
195      (function (e, c) {
196        if (!c.__SV) {
197          var l, h;
198          window.mixpanel = c;
199          c._i = [];
200          c.init = function (q, r, f) {
201            function t(d, a) {
202              var g = a.split(".");
203              2 == g.length && ((d = d[g[0]]), (a = g[1]));
204              d[a] = function () {
205                d.push([a].concat(Array.prototype.slice.call(arguments, 0)));
206              };
207            }
208            var b = c;
209            "undefined" !== typeof f ? (b = c[f] = []) : (f = "mixpanel");
210            b.people = b.people || [];
211            b.toString = function (d) {
212              var a = "mixpanel";
213              "mixpanel" !== f && (a += "." + f);
214              d || (a += " (stub)");
215              return a;
216            };
217            b.people.toString = function () {
218              return b.toString(1) + ".people (stub)";
219            };
220            l =
221              "disable time_event track track_pageview track_links track_forms track_with_groups add_group set_group remove_group register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking start_batch_senders start_session_recording stop_session_recording people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user people.remove".split(
222                " "
223              );
224            for (h = 0; h < l.length; h++) t(b, l[h]);
225            var n = "set set_once union unset remove delete".split(" ");
226            b.get_group = function () {
227              function d(p) {
228                a[p] = function () {
229                  b.push([
230                    g,
231                    [p].concat(Array.prototype.slice.call(arguments, 0)),
232                  ]);
233                };
234              }
235              for (
236                var a = {},
237                  g = ["get_group"].concat(
238                    Array.prototype.slice.call(arguments, 0)
239                  ),
240                  m = 0;
241                m < n.length;
242                m++
243              )
244                d(n[m]);
245              return a;
246            };
247            c._i.push([q, r, f]);
248          };
249          c.__SV = 1.2;
250          var k = e.createElement("script");
251          k.type = "text/javascript";
252          k.async = !0;
253          k.src =
254            "undefined" !== typeof MIXPANEL_CUSTOM_LIB_URL
255              ? MIXPANEL_CUSTOM_LIB_URL
256              : "file:" === e.location.protocol &&
257                "//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)
258              ? "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js"
259              : "//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";
260          e = e.getElementsByTagName("script")[0];
261          e.parentNode.insertBefore(k, e);
262        }
263      })(document, window.mixpanel || []);
264      mixpanel.init("edfe0ecd8c675dbbc5d0103ee433f5e5", {
265        autocapture: true,
266        // Session recording consolidated into PostHog — Mixpanel keeps
267        // analytics/autocapture only, it no longer records sessions.
268        record_sessions_percent: 0,
269      });
270    </script>
270
271
272    <!-- Amplitude Analytics (session replay consolidated into PostHog:
273         the Session Replay plugin is no longer loaded or registered) -->
274    
274<script defer="" src="https://cdn.amplitude.com/libs/analytics-browser-2.11.1-min.js.gz"></script>
274
275    
275<script>
276      window.addEventListener("load", function () {
277      if (window.amplitude?.init) {
278        window.amplitude.init("c705623f4bce3f86b242ede807f4c23e", {
279          autocapture: { elementInteractions: true },
280        });
281      }
282      });
283    </script>
283
284    
284<script type="module" crossorigin="" src="/assets/index-DGo-vssZ.js"></script>
284
285    <link rel="modulepreload" crossorigin="" href="/assets/vendor-Qgthw7N1.js">
286    <link rel="stylesheet" crossorigin="" href="/assets/index-C2doZrJs.css">
287  <style id="immediate-overlay-kill">
288            vite-error-overlay,
289            [data-type="error"],
290            .error-overlay {
291              display: none !important;
292              visibility: hidden !important;
293              opacity: 0 !important;
294              pointer-events: none !important;
295              z-index: -999999 !important;
296            }
297            #root { display: block !important; visibility: visible !important; opacity: 1 !important; }
298            body { pointer-events: auto !important; visibility: visible !important; opacity: 1 !important; }
299          </style>
vendor: 67 bytes, line 299
299<script src="https://www.google.com/recaptcha/enterprise.js?render=
2996LdyvaorAAAAACV4Fsr2EadWDEICggtxuL2gjdI6
vendor: 29 bytes, line 299
299" async="" defer=""></script>
299<script defer="" data-domain="repsshield.com" data-api="https://plausible.io/api/event" src="https://plausible.io/js/script.file-downloads.hash.outbound-links.pageview-props.revenue.tagged-events.js"></script>
299</head>
300  <body class="wallpaper-bg">
301    <!-- Google Tag Manager (noscript) -->
vendor: 80 bytes, lines 301-303
301
302    <noscript><iframe
303        src="https://www.googletagmanager.com/ns.html?id=
303GTM-TZZ5448V
vendor: 126 bytes, lines 303-309
303"
304        height="0"
305        width="0"
306        style="display: none; visibility: hidden"
307      ></iframe
308    ></noscript>
309    
309<!-- End Google Tag Manager (noscript) -->
310
311    <!-- Debug: Ensure body and root are visible -->
312    <style>
313      body {
314        visibility: visible !important;
315        opacity: 1 !important;
316        display: block !important;
317        background-color: #f7f7f7;
318      }
319      #root {
320        visibility: visible !important;
321        opacity: 1 !important;
322        display: block !important;
323        min-height: 100vh;
324      }
325      .native-startup-shell {
326        min-height: 100vh;
327        display: flex;
328        align-items: center;
329        justify-content: center;
330        background: #f7f7f7;
331        color: #111827;
332        font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
333        padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
334      }
335      .native-startup-mascot-wrap {
336        position: relative;
337        display: inline-flex;
338        flex-direction: column;
339        align-items: center;
340        margin: 16px 0 24px;
341      }
342      .native-startup-mascot {
343        width: 96px;
344        height: 96px;
345        -o-object-fit: contain;
346           object-fit: contain;
347        animation: native-startup-bounce 1.4s ease-in-out infinite;
348      }
349      .native-startup-shadow {
350        width: 64px;
351        height: 12px;
352        margin-top: 8px;
353        border-radius: 999px;
354        background: rgba(0, 0, 0, 0.18);
355        filter: blur(2px);
356        animation: native-startup-shadow 1.4s ease-in-out infinite;
357      }
358      @keyframes native-startup-bounce {
359        0%, 100% { transform: translateY(0); }
360        50% { transform: translateY(-14px); }
361      }
362      @keyframes native-startup-shadow {
363        0%, 100% { transform: scale(1); opacity: 0.2; }
364        50% { transform: scale(0.72); opacity: 0.1; }
365      }
366    </style>
367
368    <div id="root" data-prerendered="true"><div class="min-h-screen flex flex-col" data-prerendered="true"><main class="flex-1"><div class="h-[100dvh] min-h-[100dvh] w-full flex items-center justify-center overflow-hidden px-4 py-3 sm:p-4" style="background: transparent; padding-top: max(0.75rem, env(safe-area-inset-top)); padding-bottom: max(0.75rem, env(safe-area-inset-bottom));"><div class="w-full max-w-md"><div class="rounded-xl bg-card text-card-foreground transition-all duration-200 w-full shadow-lg border border-gray-200" style="transform: scale(1); transform-origin: center top;"><div class="flex flex-col space-y-1.5 p-6 text-center pb-3 sm:pb-6"><div class="mascot-container login-mascot-container"><img src="/repsshield-logo-main.png" alt="REPSShield" class="bouncing-mascot login-mascot"><div class="mascot-shadow"></div></div><div class="tracking-tight text-2xl sm:text-3xl font-bold">Welcome Back!</div></div><div class="p-6 pt-0 space-y-3 sm:space-y-6"><div class="space-y-2 sm:space-y-3"><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-all duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 touch-manipulation active:scale-[0.97] active:opacity-90 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-12 px-4 py-2 sm:h-10 w-full"><svg class="w-4 h-4 mr-2" viewBox="0 0 24 24"><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"></path><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"></path><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"></path><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"></path></svg>Continue with Google</button><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-all duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 touch-manipulation active:scale-[0.97] active:opacity-90 border border-input bg-background hover:bg-accent hover:text-accent-foreground h-12 px-4 py-2 sm:h-10 w-full"><svg class="w-4 h-4 mr-2" viewBox="0 0 24 24">
368<path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z" fill="currentColor"></path></svg>Continue with Apple</button></div><div class="relative"><div class="absolute inset-0 flex items-center"><div data-orientation="horizontal" role="none" class="shrink-0 bg-border h-[1px] w-full"></div></div><div class="relative flex justify-center text-xs uppercase"><span class="bg-white px-2 text-gray-500">Or continue with email</span></div></div><form class="space-y-3 sm:space-y-4"><div class="space-y-2"><label class="text-base font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for=":r3:-form-item">Email</label><input type="email" class="flex w-full border border-input bg-background px-3 py-2 ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 h-12 sm:h-10 text-base sm:text-sm rounded-xl sm:rounded-md touch-manipulation" placeholder="[email protected]" autocomplete="email" name="email" id=":r3:-form-item" aria-describedby=":r3:-form-item-description" aria-invalid="false" value=""></div><div class="space-y-2"><label class="text-base font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" for=":r4:-form-item">Password</label><div class="relative" id=":r4:-form-item" aria-describedby=":r4:-form-item-description" aria-invalid="false"><input type="password" class="flex w-full border border-input bg-background px-3 py-2 ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 h-12 sm:h-10 text-base sm:text-sm rounded-xl sm:rounded-md touch-manipulation" placeholder="Enter your password" name="password" value=""><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm font-medium ring-offset-background transition-all duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 touch-manipulation active:scale-[0.97] active:opacity-90 hover:text-accent-foreground rounded-md sm:h-9 absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent" type="button"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-eye h-4 w-4"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"></path><circle cx="12" cy="12" r="3"></circle></svg></button></div></div><div class="text-right"><button type="button" class="text-sm text-[#44958c] hover:text-[#367068] underline">Forgot password?</button></div><div class="flex items-center justify-center space-x-2 py-1 sm:py-2"><div class="flex items-center space-x-2 text-gray-400"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-loader-circle w-4 h-4 animate-spin"><path d="M21 12a9 9 0 1 1-6.219-8.56"></path></svg><span class="text-sm">Loading security verification...</span></div></div><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-all duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0 touch-manipulation active:scale-[0.97] active:opacity-90 bg-primary text-primary-foreground hover:bg-primary/90 h-12 px-4 py-2 sm:h-10 w-full" t
368ype="submit">Sign In</button></form><div class="text-center"><button type="button" class="text-sm text-[#44958c] hover:text-[#367068] underline">Don't have an account? Sign up</button></div></div></div></div></div></main></div><div role="region" aria-label="Notifications (F8)" tabindex="-1" style="pointer-events: none;"><ol tabindex="-1" class="fixed top-0 z-[11000] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]"></ol></div></div>
369
370
371
372    <!-- Performance Optimized React Pre-Initialization -->
373    
373<script type="text/javascript" crossorigin="anonymous" src="https://us-assets.i.posthog.com/static/1.435.3/surveys.js"></script>
373<script type="text/javascript" crossorigin="anonymous" src="https://us-assets.i.posthog.com/array/phc_x5APwUeWZHhqtjerPtcWNqvv2PQN5EsWdYHsqXj9tgwx/config.js"></script>
373<script type="text/javascript" crossorigin="anonymous" src="https://us-assets.i.posthog.com/static/1.435.3/dead-clicks-autocapture.js"></script>
373<script type="text/javascript" crossorigin="anonymous" src="https://us-assets.i.posthog.com/static/1.435.3/posthog-recorder.js"></script>
373<script type="text/javascript" crossorigin="anonymous" src="https://us-assets.i.posthog.com/static/1.435.3/web-vitals-with-attribution.js"></script>
373<script defer="">
374      // Optimize: Defer execution until DOM is parsed
375      document.addEventListener("DOMContentLoaded", function () {
376        // Environment detection
377        const isDevUrl = !window.parent || window.parent === window;
378        const isPreview = window.parent && window.parent !== window;
379
380        
381
382        // Create React namespace with complete hooks implementation IMMEDIATELY
383        window.React = {
384          // Core hooks that the plugin tries to access
385          useState: function (initialState) {
386            
387            let state = initialState;
388            const setState = (newState) => {
389              state =
390                typeof newState === "function" ? newState(state) : newState;
391            };
392            return [state, setState];
393          },
394
395          useEffect: function (effect, deps) {
396            
397            try {
398              if (typeof effect === "function") {
399                const cleanup = effect();
400                if (typeof cleanup === "function") {
401                  setTimeout(cleanup, 0);
402                }
403              }
404            } catch (e) {
405              console.warn("IMMEDIATE: useEffect error handled safely:", e);
406            }
407          },
408
409          useRef: function (initialValue) {
410            
411            return { current: initialValue };
412          },
413
414          useContext: function (context) {
415            
416            return context?._currentValue || null;
417          },
418
419          useReducer: function (reducer, initialState) {
420            
421            let state = initialState;
422            const dispatch = (action) => {
423              try {
424                state = reducer(state, action);
425              } catch (e) {
426                console.warn("IMMEDIATE: useReducer error handled:", e);
427              }
428            };
429            return [state, dispatch];
430          },
431
432          useCallback: function (callback, deps) {
433            
434            return callback;
435          },
436
437          useMemo: function (factory, deps) {
438            
439            try {
440              return factory();
441            } catch (e) {
442              console.warn("IMMEDIATE: useMemo error handled:", e);
443              return null;
444            }
445          },
446
447          // Additional React properties that might be accessed
448          createElement: function (type, props, ...children) {
449            return {
450              type,
451              props: {
452                ...props,
453                children: children.length === 1 ? children[0] : children,
454              },
455              key: props?.key || null,
456              ref: props?.ref || null,
457            };
458          },
459
460          Component: class Component {
461            constructor(props) {
462              this.props = props;
463              this.state = {};
464            }
465            setState(partialState) {
466              this.state = { ...this.state, ...partialState };
467            }
468            render() {
469              return null;
470            }
471          },
472
473          Fragment: "React.Fragment",
474          version: "18.0.0",
475        };
476
477        // Ensure React hooks are NEVER null by overriding property access
478        const reactProxy = new Proxy(window.React, {
479          get(target, prop) {
480            if (target[prop]) {
481              return target[prop];
482            }
483
484            // If a hook is accessed that we haven't defined, provide a safe fallback
485            if (prop.startsWith("use")) {
486              
487              return function (...args) {
488                console.warn(
489                  `IMMEDIATE: Safe fallback ${prop} called with:`,
490                  args
491                );
492                return prop === "useState"
493                  ? [null, () => {}]
494                  : prop === "useRef"
495                  ? { current: null }
496                  : null;
497              };
498            }
499
500            return target[prop];
501          },
502        });
503
504        window.React = reactProxy;
505
506        // Enhanced global error suppression for plugin errors including wallet extensions
507        window.addEventListener(
508          "error",
509          function (event) {
510            const message = event.message || "";
511            const filename = event.filename || "";
512
513            // Suppress React hook null access errors
514            if (
515              message.includes("Cannot read properties of null") &&
516              (message.includes("useEffect") || message.includes("useState"))
517            ) {
518              console.log(
519                "IMMEDIATE: Prevented plugin null access error from displaying"
520              );
521              event.preventDefault();
522              event.stopPropagation();
523              return false;
524            }
525
526            // Suppress browser extension property redefinition errors
527            if (
528              message.includes("Cannot redefine property") &&
529              filename.includes("extension")
530            ) {
531              console.log(
532                "IMMEDIATE: Prevented browser extension error from displaying"
533              );
534              event.preventDefault();
535              event.stopPropagation();
536              return false;
537            }
538
539            // Suppress browser extension injection errors
540            if (
541              message.includes("TypeError") &&
542              filename.includes("extension")
543            ) {
544              console.log(
545                "IMMEDIATE: Prevented browser extension error from displaying"
546              );
547              event.preventDefault();
548              event.stopPropagation();
549              return false;
550            }
551          },
552          true
553        ); // Use capture phase to catch early
554
555        // Enhanced console.error suppression for plugin and wallet extension errors
556        const originalConsoleError = console.error;
557        console.error = function (...args) {
558          const message = args.join(" ");
559
560          // Suppress plugin runtime errors
561          if (
562            message.includes("[plugin:runtime-error-plugin]") &&
563            message.includes("Cannot read properties of null")
564          ) {
565            console.warn("IMMEDIATE: Suppressed plugin error message");
566            return;
567          }
568
569          // Suppress browser extension property errors
570          if (
571            message.includes("Cannot redefine property") &&
572            filename.includes("extension")
573          ) {
574            console.warn(
575              "IMMEDIATE: Suppressed browser extension error message"
576            );
577            return;
578          }
579
580          originalConsoleError.apply(console, args);
581        };
582
583        // Immediate overlay suppression
584        const suppressOverlaysImmediately = () => {
585          const overlays = document.querySelectorAll(
586            'vite-error-overlay, [data-type="error"], .error-overlay'
587          );
588          overlays.forEach((overlay) => {
589            if (
590              overlay.textContent &&
591              overlay.textContent.includes("runtime-error-plugin")
592            ) {
593              overlay.style.display = "none !important";
594              overlay.remove();
595            }
596          });
597
598          // Add permanent CSS suppression
599          if (!document.getElementById("immediate-overlay-kill")) {
600            const style = document.createElement("style");
601            style.id = "immediate-overlay-kill";
602            style.textContent = `
603            vite-error-overlay,
604            [data-type="error"],
605            .error-overlay {
606              display: none !important;
607              visibility: hidden !important;
608              opacity: 0 !important;
609              pointer-events: none !important;
610              z-index: -999999 !important;
611            }
612            #root { display: block !important; visibility: visible !important; opacity: 1 !important; }
613            body { pointer-events: auto !important; visibility: visible !important; opacity: 1 !important; }
614          `;
615            document.head.appendChild(style);
616          }
617        };
618
619        // Run immediately and continuously for first few seconds
620        suppressOverlaysImmediately();
621        const immediateInterval = setInterval(suppressOverlaysImmediately, 25);
622
623        // Early detection: Stop suppression as soon as React content appears
624        const earlyDetection = setInterval(() => {
625          const hasAppElements =
626            window.__APP_INITIALIZED__ ||
627            document.querySelector(
628              '.bg-background, .min-h-screen, #root > div, .text-center, .dashboard-container, [class*="card"], [class*="container"]'
629            ) ||
630            (document.querySelector("#root") &&
631              document.querySelector("#root").innerHTML.length > 100);
632          if (hasAppElements) {
633            console.log(
634              "IMMEDIATE: Early React app detection - stopping overlay suppression"
635            );
636            clearInterval(immediateInterval);
637            clearInterval(earlyDetection);
638          }
639        }, 200); // Check every 200ms for early detection
640
641        // Stop after React app loads or timeout (Safari gets special treatment)
642        const isSafari =
643          /Safari/.test(navigator.userAgent) &&
644          !/Chrome/.test(navigator.userAgent);
645        const timeoutDuration = isSafari ? 60000 : 45000; // Safari gets 60s, others get 45s
646
647        setTimeout(() => {
648          const hasAppElements =
649            window.__APP_INITIALIZED__ ||
650            document.querySelector(
651              '.bg-background, .min-h-screen, #root > div, .text-center, .dashboard-container, [class*="card"], [class*="container"]'
652            ) ||
653            (document.querySelector("#root") &&
654              document.querySelector("#root").innerHTML.length > 100);
655
656          console.log(
657            "IMMEDIATE: Timeout check - App elements found:",
658            hasAppElements
659          );
660          console.log(
661            "IMMEDIATE: Available elements:",
662            document.querySelector("#root")
663              ? document.querySelector("#root").innerHTML.length +
664                  " chars in root"
665              : "No root element"
666          );
667
668          if (hasAppElements) {
669            console.log(
670              "IMMEDIATE: React app loaded successfully, stopping overlay suppression"
671            );
672            clearInterval(immediateInterval);
673            clearInterval(earlyDetection);
674          } else {
675            console.log(
676              "IMMEDIATE: React app failed to load after " +
677                timeoutDuration / 1000 +
678                "s - applying fallback strategy"
679            );
680            clearInterval(immediateInterval);
681            clearInterval(earlyDetection);
682
683            // For mobile devices, especially Safari and post-OAuth, handle specially
684            const isMobile = /Mobi|Android|iPhone|iPad/i.test(
685              navigator.userAgent
686            );
687            const isAfterOAuth =
688              document.referrer.includes("/api/auth/") ||
689              window.location.search.includes("code=") ||
690              sessionStorage.getItem("oauth-in-progress") === "true" ||
691              sessionStorage.getItem("oauthFlowInitiated") === "true";
692
693            // Clear OAuth flags
694            sessionStorage.removeItem("oauth-in-progress");
695            sessionStorage.removeItem("oauthFlowInitiated");
696
697            // Safari NEVER goes to static page - always reloads or redirects to login
698            if (isSafari) {
699              console.log(
700                "IMMEDIATE: Safari detected - NEVER redirecting to static page"
701              );
702              console.log(
703                "IMMEDIATE: Safari fallback - redirecting to login page for fresh auth check"
704              );
705              window.location.href = "/login";
706            } else if (isMobile || isAfterOAuth) {
707              console.log(
708                "IMMEDIATE: Mobile/post-OAuth detected - reloading page instead of static redirect"
709              );
710              console.log(
711                "IMMEDIATE: isMobile:",
712                isMobile,
713                "isAfterOAuth:",
714                isAfterOAuth
715              );
716              window.location.reload();
717            } else {
718              console.log(
719                "IMMEDIATE: Desktop device - redirecting to login for auth check"
720              );
721              window.location.href = "/login";
722            }
723          }
724        }, timeoutDuration);
725
726        
727
728        // Fix canonical URL to reflect current page URL
729        // Always uses the production base and strips trailing slashes so
730        // /blog/slug and /blog/slug/ resolve to the same canonical URL.
731        const canonicalLink = document.getElementById("canonical-link");
732        if (canonicalLink) {
733          let currentPath = location.pathname;
734          if (currentPath.length > 1 && currentPath.endsWith("/")) {
735            currentPath = currentPath.slice(0, -1);
736          }
737          const correctUrl = `https://repsshield.com${currentPath}`;
738          canonicalLink.setAttribute("href", correctUrl);
739        }
740      }); // End DOMContentLoaded
741    </script>
741
742
743    <!-- Performance Monitoring and Optimization -->
744    
744<script>
745      // Critical Web Vitals monitoring
746      const observer = new PerformanceObserver((list) => {
747        for (const entry of list.getEntries()) {
748          if (entry.entryType === "measure") {
749            
750          }
751        }
752      });
753      observer.observe({ entryTypes: ["measure"] });
754
755      // Lazy load non-critical images
756      if ("IntersectionObserver" in window) {
757        const imageObserver = new IntersectionObserver((entries, observer) => {
758          entries.forEach((entry) => {
759            if (entry.isIntersecting) {
760              const img = entry.target;
761              img.src = img.dataset.src;
762              img.classList.remove("lazy");
763              imageObserver.unobserve(img);
764            }
765          });
766        });
767
768        document.addEventListener("DOMContentLoaded", () => {
769          document.querySelectorAll("img[data-src]").forEach((img) => {
770            imageObserver.observe(img);
771          });
772        });
773      }
774    </script>
774
775
776    <!-- Optimized Post-OAuth Analytics Loading -->
777    
777<script defer="">
778      // Performance-optimized analytics loading for post-OAuth scenarios
779      window.deferredAnalyticsLoad = function () {
780        
781
782        // Google Tag Manager - Load after dashboard render
783        (function (w, d, s, l, i) {
784          w[l] = w[l] || [];
785          w[l].push({
786            "gtm.start": new Date().getTime(),
787            event: "gtm.js",
788          });
789          var f = d.getElementsByTagName(s)[0],
790            j = d.createElement(s),
791            dl = l != "dataLayer" ? "&l=" + l : "";
792          j.async = true;
793          j.src = "https://www.googletagmanager.com/gtm.js?id=" + i + dl;
794          f.parentNode.insertBefore(j, f);
795        })(window, document, "script", "dataLayer", "GTM-TZZ5448V");
796
797        // Umami Analytics - Deferred to post-dashboard render using requestIdleCallback
798        function loadUmami() {
799          
800          var umamiScript = document.createElement("script");
801          umamiScript.defer = true;
802          umamiScript.src = "https://cloud.umami.is/script.js";
803          umamiScript.setAttribute(
804            "data-website-id",
805            "0473b837-662f-4cd9-ada3-b65b89dc1e73"
806          );
807          umamiScript.onload = function () {
808            
809          };
810          umamiScript.onerror = function () {
811            console.warn("[Analytics] Umami analytics failed to load");
812          };
813          document.head.appendChild(umamiScript);
814        }
815
816        // Use requestIdleCallback to load Umami when browser is idle (after dashboard render)
817        if (window.requestIdleCallback) {
818          window.requestIdleCallback(loadUmami, { timeout: 3000 });
819        } else {
820          setTimeout(loadUmami, 1500); // Fallback with 1.5s delay
821        }
822      };
823
824      // Global performance optimization for ALL pages
825      window.addEventListener("DOMContentLoaded", function () {
826        // For ALL pages (public and authenticated), defer analytics to improve performance
827        console.log(
828          "[Analytics] Page loaded - deferring analytics for optimal performance"
829        );
830
831        // Always use maximum delay for public pages performance
832        const isPublicPage =
833          ["/features", "/pricing", "/why-reps-shield", "/about"].includes(
834            window.location.pathname
835          ) || window.location.pathname.startsWith("/features/");
836
837        if (isPublicPage) {
838          console.log(
839            "[Analytics] Public page detected - maximum deferral for speed"
840          );
841          // For public marketing pages, defer analytics heavily to maximize page speed
842          if (window.requestIdleCallback) {
843            window.requestIdleCallback(window.deferredAnalyticsLoad, {
844              timeout: 5000,
845            });
846          } else {
847            setTimeout(window.deferredAnalyticsLoad, 2000); // 2s delay for public pages
848          }
849        } else if (
850          window.location.pathname === "/" ||
851          window.location.hash === "#/"
852        ) {
853          console.log(
854            "[Analytics] Dashboard detected - deferring analytics until after render"
855          );
856          // Wait for dashboard to be fully rendered before loading analytics
857          function waitForDashboard() {
858            if (
859              document.querySelector(
860                '[data-testid="dashboard-content"], .dashboard-container, .min-h-screen'
861              )
862            ) {
863              
864              window.deferredAnalyticsLoad();
865            } else {
866              setTimeout(waitForDashboard, 100);
867            }
868          }
869          setTimeout(waitForDashboard, 500); // Give dashboard time to start rendering
870        } else {
871          // For other pages, load analytics with moderate delay
872          if (window.requestIdleCallback) {
873            window.requestIdleCallback(window.deferredAnalyticsLoad, {
874              timeout: 3000,
875            });
876          } else {
877            setTimeout(window.deferredAnalyticsLoad, 1000);
878          }
879        }
880      });
881    </script>
881
882    <!-- This is a replit script which adds a banner on the top of the page when opened in development mode outside the replit environment -->
883    <!-- Commented out to prevent blue debug banner showing in production
884    
884<script type="text/javascript" src="https://replit.com/public/js/replit-dev-banner.js"></script>
884
885    -->
886
887    <!-- React App Entry Point - MUST be last to ensure all scripts are loaded first -->
888  
889
890
891<script type="text/javascript" id="" charset="">var script=document.createElement("script");script.defer=!0;script.dataset.domain="repsshield.com";script.dataset.api="https://plausible.io/api/event";script.src="https://plausible.io/js/script.file-downloads.hash.outbound-links.pageview-props.revenue.tagged-events.js";document.getElementsByTagName("head")[0].appendChild(script);</script>
891
892
893<script type="text/javascript" id="" charset="">window.plausible=window.plausible||function(){(window.plausible.q=window.plausible.q||[]).push(arguments)};</script>
893
894</body></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.