<!DOCTYPE html>
<html lang="en" data-theme="dark">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" sizes="any" />
    <link rel="icon" href="/icon.svg" type="image/svg+xml" />
    <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
    <link rel="manifest" href="/manifest.webmanifest" />
    <meta name="description" content="Take Control of Your Subscriptions with SubPilot" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
    <meta name="theme-color" content="#09081B" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="default" />
    <meta name="apple-mobile-web-app-title" content="Subpilot" />

    <meta name="mobile-web-app-capable" content="yes" />
    <meta name="msapplication-TileColor" content="#09081B" />

    <link rel="dns-prefetch" href="https://fonts.googleapis.com" />
    <link rel="dns-prefetch" href="https://fonts.gstatic.com" />
    <link rel="dns-prefetch" href="https://api.subpilot.net/" />
    <!-- The transcriber the voice arm's browser talks to directly. Warmed here because the socket
         cannot be: its token is single-use and spent on connect, so there is nothing to open early
         — only DNS and TLS to have done already. Measured on the stand, the handshake was taking
         836ms in front of the first byte of audio, and every one of those milliseconds is one the
         user waits to see their own words. -->
    <link rel="dns-prefetch" href="https://api.elevenlabs.io" />




    <title>Subpilot</title>
    <style>
      :root {
        --w-mobile: 768px;
        --h-footer: 4rem;
        --h-header: 3rem;
      }

      #root {
        max-width: var(--w-mobile, 768px);
        margin: 0 auto;
        padding: 0;
        display: flex;
        flex-direction: column;
        width: 100%;
      }

      /* Desktop layout (SPLT-2286). The sidebar needs the full viewport, so the mobile column cap is
         released here and re-applied one level down by each layout's content wrapper. That way
         preserving today's 768px column is the default and widening is the explicit act — a screen
         nobody has touched cannot accidentally stretch. */
      @media (min-width: 80rem) {
        #root {
          max-width: none;
          /* Gives the auth funnel the free space its centred column measures against (FR-022b).
             Inert everywhere else: #root is a top-aligned flex column, so the extra height simply
             collects at the bottom unless a child asks for it with auto margins, and the authorized
             layouts are already full height. */
          min-height: 100dvh;
        }

        /* ...but only for a tree that actually asked for the width. Releasing the cap
           unconditionally made stretching the default and re-applying it the opt-in, which is the
           reverse of the intent above: five of the seven layouts re-apply nothing, so the upsells,
           web-to-app, the product-subscription funnel and /public/* all lost their 768px column.

           Keying the release off the composition markers themselves keeps the mobile column as the
           DEFAULT — a screen nobody has adapted cannot stretch, and a layout added later inherits
           the safe behaviour instead of silently regressing.

             .shell-content  the authorized shell, which needs the viewport for its sidebar
             .content-*      a screen that has declared a desktop composition (the auth funnel)

           Webview is unaffected: it is served from webview.html with its own #webview-root, which
           has never carried this cap.
           for upsell + web2app pages*/
        #root:not(:has(.shell-content, .content-wide, .content-article, .content-form, .content-full)) {
          max-width: var(--w-mobile, 768px);
        }
      }

      html {
        font-size: 16px;
        scroll-behavior: smooth;
        -webkit-text-size-adjust: 100%;
        -ms-text-size-adjust: 100%;
      }

      body {
        font-family: "Inter", Arial, Helvetica, sans-serif;
        color: var(--text-primary, #2A5779);
        line-height: 1.5;
        background-color: var(--background-primary, #ffffff);
        margin: 0;
        padding: 0;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-rendering: optimizeLegibility;
      }

      #launcher-frame {
        display: none !important;
      }

      @media (prefers-reduced-motion: reduce) {
        html {
          scroll-behavior: auto;
        }
      }

      @media print {
        body {
          background: white !important;
          color: black !important;
        }
      }

      @media (prefers-color-scheme: dark) {
        :root {
          color-scheme: dark;
        }
      }

      @media (prefers-color-scheme: light) {
        :root {
          color-scheme: light;
        }
      }
    </style>

    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link rel="preconnect" href="https://api.elevenlabs.io" crossorigin />
    <link
      rel="preload"
      as="style"
      href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
      onload="this.onload=null;this.rel='stylesheet'"
    />

    <!--
      Consent is signalled at runtime from src/shared/lib/consent/channels.ts via Clarity's
      `consentv2` API, not by blocking this tag. The `data-cookiecategory` attribute that used to sit
      here was read by nothing — no consent-management platform is installed — so it described a gate
      that did not exist. Removed rather than left to be trusted (spec 039 FR-031).
    -->
    <script class="clarity-init" type="text/javascript" defer>
      (function(c,l,a,r,i,t,y){
        c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
        t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
        y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
      })(window, document, "clarity", "script", "t5gwflt7r4");
    </script>

    <noscript>
      <link
        rel="stylesheet"
        href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
      />
    </noscript>
    <script type="module" crossorigin src="/assets/main-CfbpfjCe.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt"></script>
    <link rel="modulepreload" crossorigin href="/assets/js/vendor/i18n.oADmEJZs.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt">
    <link rel="modulepreload" crossorigin href="/assets/js/vendor/libs.CNLrD2J2.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt">
    <link rel="modulepreload" crossorigin href="/assets/js/vendor/lodash.B0ZtDLEZ.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt">
    <link rel="modulepreload" crossorigin href="/assets/js/vendor/amplitude.CHs0cTnd.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt">
    <link rel="modulepreload" crossorigin href="/assets/js/vendor/analytics.BlB1sbZu.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt">
    <link rel="modulepreload" crossorigin href="/assets/js/vendor/grafana.BbtOFuMi.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt">
    <link rel="modulepreload" crossorigin href="/assets/js/vendor/icons.Dl93GQkp.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt">
    <link rel="modulepreload" crossorigin href="/assets/js/sentry.4PkpippY.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt">
    <link rel="modulepreload" crossorigin href="/assets/js/Card.CtmBK7v_.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt">
    <link rel="modulepreload" crossorigin href="/assets/js/Skeleton.By-fk38w.js?dpl=dpl_5rajeFVkGWrX4JynwNdErhBNHsZt">
    <link rel="stylesheet" crossorigin href="/assets/css/vendor/libs-Dg2VPHGHO6.css">
    <link rel="stylesheet" crossorigin href="/assets/css/sentry-fBDDb23SUm.css">
    <link rel="stylesheet" crossorigin href="/assets/css/Card-q7rSlEp196.css">
    <link rel="stylesheet" crossorigin href="/assets/css/Skeleton-Cmo4gY6ncR.css">
    <link rel="stylesheet" crossorigin href="/assets/css/main-D6yLZEik8H.css">
  </head>
  <body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>
  </body>
</html>
