<!doctype html>
<html lang="en">
  <head>
    <!-- Google tag (gtag.js) -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-D811YBLE05"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', 'G-D811YBLE05');
    </script>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <link rel="icon" href="/favicon.png" type="image/png" />
    
    <!-- PWA Meta Tags -->
    <meta name="theme-color" content="#406E71" />
    <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" />
    <meta name="apple-mobile-web-app-title" content="LevelUp" />
    <link rel="apple-touch-icon" href="/pwa-192x192.png" />
    
    <title>LevelUp — The Agent Operating System for Real Estate</title>
    <meta name="description" content="Coaching, marketing, CRM, lead sites, social studio & 40+ tools — everything real estate agents need to grow, in one members-only portal." />
    <meta name="author" content="LevelUp" />

    <meta property="og:title" content="LevelUp — The Agent Operating System" />
    <meta property="og:description" content="Coaching, marketing, CRM, lead sites, social studio & 40+ tools — everything agents need to grow." />
    <meta property="og:type" content="website" />
    <meta property="og:url" content="https://dashboard.relevelup.com/" />
    <meta property="og:image" content="https://relzejiswnotikjgvjhz.supabase.co/storage/v1/object/public/email-assets/home-og.png" />
    <meta property="og:image:width" content="1200" />
    <meta property="og:image:height" content="630" />

    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:site" content="@levelup" />
    <meta name="twitter:title" content="LevelUp — The Agent Operating System" />
    <meta name="twitter:description" content="Coaching, marketing, CRM, lead sites, social studio & 40+ tools — everything agents need to grow." />
    <meta name="twitter:image" content="https://relzejiswnotikjgvjhz.supabase.co/storage/v1/object/public/email-assets/home-og.png" />

    <!-- Libre Baskerville for serif headings -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&family=Playfair+Display:ital,wght@0,400;0,600;0,700;0,800;1,400&family=Instrument+Serif:ital@0;1&family=DM+Serif+Display:ital@0;1&family=Fira+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400&family=Work+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet">

    <!-- OpenAI Pixel -->
    <script>!function(w,d,s,u){if(w.oaiq)return;var q=function(){q.q.push(arguments)};q.q=[];w.oaiq=q;var j=d.createElement(s);j.async=1;j.src=u;var f=d.getElementsByTagName(s)[0];f.parentNode.insertBefore(j,f)}(window,document,"script","https://bzrcdn.openai.com/sdk/oaiq.min.js");oaiq("init",{pixelId:"HA4BJGmTw5vz43iY55ZnYK",debug:true});</script>

    <!--
      Agent-owned websites (custom domains and *.thelocalmove.com) must never carry the
      LevelUp marketing description or social tags: the page then has two competing
      descriptions and crawlers can pick the wrong one. Each agent page sets its own
      tags at runtime, so strip the LevelUp defaults on those hosts before paint.
    -->
    <script>
      (function () {
        try {
          var host = window.location.hostname.replace(/^www\./, '').toLowerCase();
          var isLevelUpHost =
            host === 'localhost' ||
            host === '127.0.0.1' ||
            host.endsWith('relevelup.com') ||
            host.endsWith('lovable.app') ||
            host.endsWith('lovableproject.com') ||
            host.endsWith('lovable.dev') ||
            host.endsWith('vercel.app');
          if (isLevelUpHost) return;
          var sel = [
            'meta[name="description"]',
            'meta[name="author"]',
            'meta[property^="og:"]',
            'meta[name^="twitter:"]',
          ].join(',');
          document.querySelectorAll(sel).forEach(function (el) { el.remove(); });
        } catch (e) { /* never block page load */ }
      })();
    </script>
    <script type="module" crossorigin src="/assets/index-D7Vor1Tn.js"></script>
    <link rel="stylesheet" crossorigin href="/assets/index-3o5uSdVv.css">
  </head>

  <body>
    <div id="root"></div>

    <!-- 
      CRITICAL: Strip Canva OAuth ?code= from URL BEFORE the Supabase client initializes.
      The Supabase client's detectSessionInUrl=true will mistake Canva's ?code= for a
      Supabase auth code and sign the user out. This script runs synchronously before
      any module scripts, so it fires before supabase-js is ever loaded.
    -->
    <script>
      (function() {
        try {
          var params = new URLSearchParams(window.location.search);
          var code = params.get('code');
          var state = params.get('state');
          var storedState = localStorage.getItem('canva_oauth_state');

          // If this looks like a Canva callback (state matches what we stored), 
          // handle it here and clean the URL immediately.
          if (code && state && storedState && state === storedState) {
            // This is a Canva OAuth callback — strip the URL immediately so Supabase never sees ?code=
            var cleanUrl = window.location.pathname;
            window.history.replaceState({}, document.title, cleanUrl);

            // Now do the token exchange using the stored verifier and session token
            var sessionKey = Object.keys(localStorage).find(function(k) {
              return k.startsWith('sb-') && k.endsWith('-auth-token');
            });
            var token = null;
            if (sessionKey) {
              try { token = JSON.parse(localStorage.getItem(sessionKey) || '{}').access_token; } catch(e) {}
            }

            if (token) {
              var supabaseUrl = 'https://relzejiswnotikjgvjhz.supabase.co';
              var supabaseAnonKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InJlbHplamlzd25vdGlramd2amh6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjE5NTAzNDQsImV4cCI6MjA3NzUyNjM0NH0.dzIkIr_oFSbFE3oWS0ktIr83iKHHkZxt40Gc7SpC_mM';

              // Fire and forget — the page will load normally, and a toast will show on success
              fetch(supabaseUrl + '/functions/v1/canva-oauth', {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json',
                  'Authorization': 'Bearer ' + token,
                  'apikey': supabaseAnonKey,
                },
                body: JSON.stringify({ action: 'exchange_code', code: code, state: state }),
              }).then(function(res) {
                return res.json();
              }).then(function(data) {
                localStorage.removeItem('canva_code_verifier');
                localStorage.removeItem('canva_oauth_state');
                if (data && data.success) {
                  localStorage.setItem('canva_oauth_result', 'success');
                } else {
                  localStorage.setItem('canva_oauth_result', 'error:' + (data && data.error || 'Unknown error'));
                }
              }).catch(function(err) {
                localStorage.setItem('canva_oauth_result', 'error:' + (err && err.message || 'Network error'));
              });
            } else {
              localStorage.removeItem('canva_code_verifier');
              localStorage.removeItem('canva_oauth_state');
            }
          }
        } catch(e) {
          // Never block page load
          console.warn('Canva pre-init handler error:', e);
        }
      })();
    </script>

    <script>
      // Only load chat widget if NOT on listings subdomain and NOT on public video share pages.
      // Video share pages should be distraction-free and the widget can cover the reply form on mobile.
      // Also suppress on agent-owned lead-site custom domains (keep in sync with src/lib/leadSiteDomains.ts).
      var host = window.location.hostname.replace(/^www\./, '').toLowerCase();
      var isListings = host.startsWith('listings.');
      var isCardsSubdomain = host.startsWith('cards.');
      var isPresentations = host.startsWith('presentations.');
      var isGuestbook = host.startsWith('guestbook.');
      var isClients = host.startsWith('clients.');
      var isCardStudio = host.startsWith('cardstudio.');
      var isBooking = host.startsWith('booking.');
      var isContacts = host.startsWith('contacts.');
      var isCommercial = host.startsWith('commercial.');
      var isVideoShare = window.location.pathname.startsWith('/share/video');
      var isAgentCard = window.location.pathname.startsWith('/card/');
      var isPublicBookingPath = window.location.pathname === '/book' || window.location.pathname.startsWith('/book/');
      var isMobileCommand = window.location.pathname.startsWith('/m');
      var isLiveEvent = window.location.pathname.startsWith('/live/');
      var isPublicReview = window.location.pathname.startsWith('/review/') || window.location.pathname.startsWith('/reviews/');
      var isBuyerMatch = window.location.pathname.startsWith('/buyer-match/');
      var isPublicListing = window.location.pathname.startsWith('/public/listing') || window.location.pathname.startsWith('/listing/');
      var isLocalMove = host.indexOf('thelocalmove.com') !== -1;
      var isBestBrokerage = host.indexOf('bestbrokerage.') !== -1;
      // Any host that is not a LevelUp app host is an agent-owned custom domain
      // serving a public lead site. Keep in sync with src/lib/leadSiteDomains.ts.
      var isKnownAppHost = (function () {
        if (host === 'localhost' || host.indexOf('.localhost') === host.length - 10) return true;
        if (/^\d{1,3}(\.\d{1,3}){3}$/.test(host)) return true;
        if (/(^|\.)(lovable\.app|lovableproject\.com|lovable\.dev|vercel\.app)$/.test(host)) return true;
        if (host === 'relevelup.com' || /\.relevelup\.com$/.test(host)) return true;
        if (host === 'thelocalmove.com' || /\.thelocalmove\.com$/.test(host)) return true;
        return false;
      })();
      var isLeadSiteCustomDomain = !isKnownAppHost;

      if (!isListings && !isCommercial && !isCardsSubdomain && !isPresentations && !isGuestbook && !isClients && !isCardStudio && !isBooking && !isContacts && !isVideoShare && !isAgentCard && !isPublicBookingPath && !isLocalMove && !isBestBrokerage && !isMobileCommand && !isLiveEvent && !isPublicReview && !isBuyerMatch && !isPublicListing && !isLeadSiteCustomDomain) {
        var chatScript = document.createElement('script');
        chatScript.src = 'https://widgets.leadconnectorhq.com/loader.js';
        chatScript.setAttribute('data-resources-url', 'https://widgets.leadconnectorhq.com/chat-widget/loader.js');
        chatScript.setAttribute('data-widget-id', '6986204c7cd1e673fb852ee0');
        document.body.appendChild(chatScript);
      }
    </script>
  </body>
</html>
