<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <!-- Google Fonts (loaded as a proper <link> with crossorigin so
         PostHog session replay can read the stylesheet rules during
         playback — CSS @import would block this and cause replays
         to render with missing fonts/layout). -->
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      rel="stylesheet"
      crossorigin="anonymous"
      href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Instrument+Sans:wght@400;500;600;700&family=Space+Grotesk:wght@400;500;600;700&family=Sora:wght@300;400;500;600;700;800&display=swap"
    />
    
    <!-- Google tag (GA4 + Google Ads) -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-SPTVN46DMQ"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      window.gtag = window.gtag || gtag;
      gtag('js', new Date());
      gtag('config', 'G-SPTVN46DMQ');
      gtag('config', 'AW-17284351723');
    </script>

    <!-- Meta Pixel Code -->
    <script>
      !function (f, b, e, v, n, t, s) {
        if (f.fbq) return; n = f.fbq = function () {
          n.callMethod ?
          n.callMethod.apply(n, arguments) : n.queue.push(arguments)
        };
        if (!f._fbq) f._fbq = n; n.push = n; n.loaded = !0; n.version = '2.0';
        n.queue = []; t = b.createElement(e); t.async = !0;
        t.src = v; s = b.getElementsByTagName(e)[0];
        s.parentNode.insertBefore(t, s)
      }(window, document, 'script',
        'https://connect.facebook.net/en_US/fbevents.js');
      window.__META_PIXEL_ID__ = '1432026157948896';
      window.__META_ADV_MATCHING__ = window.__META_ADV_MATCHING__ || {};
      fbq('init', window.__META_PIXEL_ID__, window.__META_ADV_MATCHING__);
      fbq('track', 'PageView');
    </script>
    <!-- End Meta Pixel Code -->
    <!-- TikTok Pixel Code Start -->
    <script>
      !function (w, d, t) {
        w.TiktokAnalyticsObject = t; var ttq = w[t] = w[t] || []; ttq.methods = ["page", "track", "identify", "instances", "debug", "on", "off", "once", "ready", "alias", "group", "enableCookie", "disableCookie", "holdConsent", "revokeConsent", "grantConsent"], ttq.setAndDefer = function (t, e) { t[e] = function () { t.push([e].concat(Array.prototype.slice.call(arguments, 0))) } }; for (var i = 0; i < ttq.methods.length; i++)ttq.setAndDefer(ttq, ttq.methods[i]); ttq.instance = function (t) {
          for (
            var e = ttq._i[t] || [], n = 0; n < ttq.methods.length; n++)ttq.setAndDefer(e, ttq.methods[n]); return e
        }, ttq.load = function (e, n) {
          var r = "https://analytics.tiktok.com/i18n/pixel/events.js", o = n && n.partner; ttq._i = ttq._i || {}, ttq._i[e] = [], ttq._i[e]._u = r, ttq._t = ttq._t || {}, ttq._t[e] = +new Date, ttq._o = ttq._o || {}, ttq._o[e] = n || {}; n = document.createElement("script")
            ; n.type = "text/javascript", n.async = !0, n.src = r + "?sdkid=" + e + "&lib=" + t; e = document.getElementsByTagName("script")[0]; e.parentNode.insertBefore(n, e)
        };


        ttq.load('D2DK6AJC77U0CGBH0VNG');
        var rrTikTokPageSent = false;
        var rrTikTokIdentityTtlMs = 180 * 24 * 60 * 60 * 1000;
        var rrTikTokPageIdentity = {};

        function rrSendTikTokPage() {
          if (rrTikTokPageSent) return;
          rrTikTokPageSent = true;
          ttq.page();
        }

        function rrNormalizeTikTokEmail(email) {
          return typeof email === 'string' && email.trim()
            ? email.trim().toLowerCase()
            : undefined;
        }

        function rrNormalizeTikTokPhone(phone) {
          if (typeof phone !== 'string' && typeof phone !== 'number') return undefined;
          var raw = String(phone).trim();
          if (!raw) return undefined;
          var digits = raw.replace(/\D/g, '');
          if (digits.length === 10) return '+1' + digits;
          if (digits.length === 11 && digits.indexOf('1') === 0) return '+' + digits;
          if (raw.indexOf('+') === 0 && digits.length >= 8) return '+' + digits;
          return undefined;
        }

        function rrPersistTikTokIdentity(payload) {
          try {
            if (!window.localStorage || !payload || Object.keys(payload).length === 0) return;
            window.localStorage.setItem('rr_tiktok_identity', JSON.stringify({
              expiresAt: Date.now() + rrTikTokIdentityTtlMs,
              data: payload
            }));
          } catch {
            /* Ignore storage failures. */
          }
        }

        function rrIdentifyTikTok(payload) {
          if (!payload || Object.keys(payload).length === 0) return;
          rrTikTokPageIdentity = Object.assign(rrTikTokPageIdentity, payload);
          window.__TIKTOK_ADV_MATCHING__ = rrTikTokPageIdentity;
          rrPersistTikTokIdentity(rrTikTokPageIdentity);
          ttq.identify(rrTikTokPageIdentity);
        }

        function rrGetKnownSubscriptionIdFromUrl() {
          try {
            var params = new URLSearchParams(window.location.search);
            var token = params.get('token') || params.get('subId');
            if (!token) {
              var upgradeMatch = window.location.pathname.match(/^\/u\/([0-9a-f-]{36})/i);
              token = upgradeMatch && upgradeMatch[1];
            }
            return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(token || '')
              ? token
              : null;
          } catch {
            return null;
          }
        }

        async function rrHydrateTikTokIdentityFromUrl() {
          var token = rrGetKnownSubscriptionIdFromUrl();
          if (!token || !window.fetch) return;

          var controller = window.AbortController ? new AbortController() : null;
          var timeout = controller ? window.setTimeout(function () { controller.abort(); }, 700) : null;
          try {
            var response = await fetch('/api/preferences/by-token/' + encodeURIComponent(token), {
              credentials: 'include',
              signal: controller ? controller.signal : undefined
            });
            if (!response.ok) return;
            var body = await response.json();
            var data = body && (body.data || body);
            var subscription = data && (data.subscription || data);
            if (!subscription) return;

            var payload = {};
            var email = rrNormalizeTikTokEmail(subscription.email);
            var phone = rrNormalizeTikTokPhone(subscription.phone_number);
            if (email) payload.email = email;
            if (phone) payload.phone_number = phone;
            if (subscription.id) payload.external_id = subscription.id;
            rrIdentifyTikTok(payload);
          } catch {
            /* Keep PageView flowing if identity hydration fails. */
          } finally {
            if (timeout) window.clearTimeout(timeout);
          }
        }

        try {
          var rrTikTokUrlParams = new URLSearchParams(window.location.search);
          var rrTikTokClickId = rrTikTokUrlParams.get('ttclid');
          if (window.localStorage) {
            if (rrTikTokClickId) {
              window.localStorage.setItem('rr_ttclid', rrTikTokClickId);
            }
            var rrTikTokExternalId = window.localStorage.getItem('rr_tiktok_external_id');
            if (!rrTikTokExternalId) {
              rrTikTokExternalId = window.crypto && window.crypto.randomUUID
                ? 'rr_' + window.crypto.randomUUID()
                : 'rr_' + Date.now() + '_' + Math.random().toString(36).slice(2);
              window.localStorage.setItem('rr_tiktok_external_id', rrTikTokExternalId);
            }
            rrTikTokPageIdentity.external_id = rrTikTokExternalId;
          }
          var rrTikTokIdentityRaw = window.localStorage && window.localStorage.getItem('rr_tiktok_identity');
          if (rrTikTokIdentityRaw) {
            var rrTikTokIdentity = JSON.parse(rrTikTokIdentityRaw);
            if (rrTikTokIdentity && rrTikTokIdentity.expiresAt > Date.now() && rrTikTokIdentity.data) {
              rrTikTokPageIdentity = Object.assign(rrTikTokPageIdentity, rrTikTokIdentity.data);
            } else if (window.localStorage) {
              window.localStorage.removeItem('rr_tiktok_identity');
            }
          }
          rrIdentifyTikTok(rrTikTokPageIdentity);
        } catch {
          /* Ignore malformed stored identity. */
        }

        if (rrGetKnownSubscriptionIdFromUrl()) {
          Promise.race([
            rrHydrateTikTokIdentityFromUrl(),
            new Promise(function (resolve) { window.setTimeout(resolve, 800); })
          ]).finally(rrSendTikTokPage);
        } else {
          rrSendTikTokPage();
        }
      }(window, document, 'ttq');
    </script>
    <!-- TikTok Pixel Code End -->
    <!-- Favicon -->
    <link rel="icon" type="image/x-icon" href="/favicon.ico" sizes="16x16 32x32 48x48 64x64 128x128 256x256" />
    <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16" />
    <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32" />
    <link rel="icon" type="image/png" href="/favicon-48x48.png" sizes="48x48" />
    <link rel="icon" type="image/png" href="/favicon-64x64.png" sizes="64x64" />
    <link rel="icon" type="image/png" href="/favicon-128x128.png" sizes="128x128" />
    <link rel="icon" type="image/png" href="/favicon-256x256.png" sizes="256x256" />
    <link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3b82f6" />
    <meta name="msapplication-TileColor" content="#3b82f6" />
    <meta name="theme-color" content="#3b82f6" />
    
    <!-- Preconnect to Stripe for faster checkout -->
    <link rel="preconnect" href="https://checkout.stripe.com" />
    <link rel="dns-prefetch" href="https://checkout.stripe.com" />

    <!-- Base Meta Tags -->
    <title>RentReboot - Find Your Next Home in NYC</title>
    <meta name="description" content="Get instant alerts when affordable apartments become available in NYC. Be first in line for your dream apartment with real-time notifications." />
    <link rel="canonical" href="https://rentreboot.com/" />

    <!-- Open Graph -->
    <meta property="og:title" content="RentReboot - Find Your Next Home in NYC" />
    <meta property="og:description" content="Get instant alerts when affordable apartments become available in NYC. Be first in line for your dream apartment with real-time notifications." />
    <meta property="og:type" content="website" />
    <meta property="og:url" content="https://rentreboot.com/" />
    <meta property="og:image" content="https://rentreboot.com/images/social/homepage-og.jpg" />
    <meta property="og:image:width" content="1200" />
    <meta property="og:image:height" content="630" />
    <meta property="og:image:alt" content="RentReboot homepage preview showing NYC apartment alerts and neighborhood rent data tools" />
    <meta property="og:site_name" content="RentReboot" />

    <!-- Twitter Card -->
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:site" content="@rentreboot" />
    <meta name="twitter:creator" content="@rentreboot" />
    <meta name="twitter:title" content="RentReboot - Find Your Next Home in NYC" />
    <meta name="twitter:description" content="Get instant alerts when affordable apartments become available in NYC. Be first in line for your dream apartment with real-time notifications." />
    <meta name="twitter:image" content="https://rentreboot.com/images/social/homepage-og.jpg" />
    <meta name="twitter:image:alt" content="RentReboot homepage preview showing NYC apartment alerts and neighborhood rent data tools" />
    <meta name="twitter:url" content="https://rentreboot.com/" />

    <meta name="keywords" content="rent stabilized, NYC apartments, affordable housing, apartment alerts, New York City rentals, apartment hunting, real estate alerts" />
    <meta name="author" content="RentReboot" />
    <meta name="robots" content="index, follow" />
    <script type="application/ld+json" data-cfasync="false">
      {
        "@context": "https://schema.org",
        "@graph": [
          {
            "@type": "Organization",
            "@id": "https://rentreboot.com/#organization",
            "name": "RentReboot",
            "url": "https://rentreboot.com",
            "logo": "https://rentreboot.com/favicon.ico",
            "description": "Get instant alerts when affordable apartments become available in NYC. Be first in line for your dream apartment with real-time notifications.",
            "image": "https://rentreboot.com/images/social/homepage-og.jpg"
          },
          {
            "@type": "WebSite",
            "@id": "https://rentreboot.com/#website",
            "name": "RentReboot",
            "url": "https://rentreboot.com",
            "description": "Get instant alerts when affordable apartments become available in NYC. Be first in line for your dream apartment with real-time notifications.",
            "publisher": {
              "@id": "https://rentreboot.com/#organization"
            },
            "inLanguage": "en-US"
          }
        ]
      }
    </script>

    
    <meta name="mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />


    <script type="module" crossorigin src="/assets/index-Dw99OWed.js" data-cfasync="false"></script>
    <link rel="modulepreload" crossorigin href="/assets/react-vendor-Cx6VpA1G.js">
    <link rel="stylesheet" crossorigin href="/assets/index-Bfoml0WT.css">
  </head>
  <body>
    <!-- Meta Pixel noscript fallback -->
    <noscript><img height="1" width="1" style="display:none"
        src="https://www.facebook.com/tr?id=1432026157948896&ev=PageView&noscript=1" /></noscript>
    
    <div id="root"></div>
    <!-- data-cfasync="false" opts this entry out of Cloudflare Rocket Loader.
         Rocket Loader rewrites <script type="module" data-cfasync="false"> to a custom deferred type
         and re-injects it, which breaks ES module execution in strict WebViews
         (Instagram / Facebook in-app browser → "There was a problem loading
         this website"). Leave this attribute in place unless Rocket Loader is
         turned off at the Cloudflare level. -->
  </body>
</html>
