{"html_form": "\n\n<!-- ====== Modal Body Content ====== -->\n<div class=\"bb-modal bb-compact\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"bb-login-title\">\n  <header class=\"bb-modal__header has-text-centered\">\n    <div class=\"bb-brand\">\n      <img alt=\"Bravoboard\" class=\"bb-brand__logo\" src=\"https://d1e7moeca5rg6t.cloudfront.net/static/assets/img/favicons/Bravoboard_logo_2025v1.2.png\">\n      <h2 id=\"bb-login-title\" class=\"bb-brand__title\">Welcome to Bravoboard!</h2>\n    </div>\n\n    <p class=\"bb-secure\">\n      <span class=\"bb-secure__icon\" aria-hidden=\"true\">\u2705</span>\n      <span>Secure passwordless authentication</span>\n    </p>\n\n  </header>\n\n  <div class=\"bb-actions\">\n    <!-- Google -->\n    <a class=\"bb-btn bb-btn--provider\" href=\"/oauth/login/google-oauth2/\">\n      <span class=\"bb-btn__icon\" aria-hidden=\"true\">\n        <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" focusable=\"false\">\n          <path d=\"M23 12.253c0-.814-.064-1.633-.2-2.434H12.875v4.612H19.13c-.259 1.487-1.093 2.803-2.315 3.639v2.993h3.733C22.74 19.166 23 16.086 23 12.253Z\" fill=\"#4285F4\"/>\n          <path d=\"M12.878 24c3.124 0 5.758-1.06 7.678-2.891l-3.732-2.993c-1.039.731-2.38 1.144-3.942 1.144-3.022 0-5.584-2.108-6.503-4.943H2.527v3.085C4.494 21.13 8.499 24 12.878 24Z\" fill=\"#34A853\"/>\n          <path d=\"M6.379 14.317a7.78 7.78 0 0 1 0-4.586V6.646H2.532a11.24 11.24 0 0 0 0 10.708l3.847-3.037Z\" fill=\"#FBBC04\"/>\n          <path d=\"M12.878 4.784c1.651-.026 3.247.616 4.443 1.796l3.307-3.419C18.533 1.128 15.753.01 12.878.045c-4.38 0-8.385 2.553-10.351 6.602l3.847 3.085c.915-2.838 3.481-4.948 6.504-4.948Z\" fill=\"#EA4335\"/>\n        </svg>\n      </span>\n      <span>Continue with Google</span>\n    </a>\n\n    <!-- LinkedIn -->\n    <a class=\"bb-btn bb-btn--provider\" href=\"/oauth/login/linkedin-oauth2/\">\n      <span class=\"bb-btn__icon\" aria-hidden=\"true\">\n        <svg width=\"24\" height=\"24\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" focusable=\"false\">\n          <path fill=\"#0A66C2\" d=\"M12.225 12.225h-1.778V9.44c0-.664-.012-1.519-.925-1.519-.926 0-1.068.724-1.068 1.47v2.834H6.676V6.498h1.707v.783h.024c.348-.594.996-.95 1.684-.925 1.802 0 2.135 1.185 2.135 2.728v3.141zM4.67 5.715a1.037 1.037 0 1 1 0-2.063 1.037 1.037 0 0 1 0 2.063zm.889 6.51h-1.78V6.498h1.78v5.727zM13.11 2H2.885A.88.88 0 0 0 2 2.866v10.268a.88.88 0 0 0 .885.866h10.226a.882.882 0 0 0 .889-.866V2.865A.88.88 0 0 0 13.11 2z\"/>\n        </svg>\n      </span>\n      <span>Continue with LinkedIn</span>\n    </a>\n\n    <div class=\"bb-divider\" role=\"separator\" aria-label=\"or\">\n      <span>OR</span>\n    </div>\n\n    <p class=\"bb-microcopy\" aria-live=\"polite\">One secure link, and you\u2019re in.</p>\n    <!-- Email -->\n    <form class=\"bb-email\" novalidate>\n      <div class=\"bb-inputwrap\">\n        <span class=\"bb-inputwrap__lefticon\" aria-hidden=\"true\">\n          <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" role=\"img\" focusable=\"false\">\n            <path d=\"M3 6.75A1.75 1.75 0 0 1 4.75 5h14.5A1.75 1.75 0 0 1 21 6.75v10.5A1.75 1.75 0 0 1 19.25 19H4.75A1.75 1.75 0 0 1 3 17.25V6.75Z\" stroke=\"currentColor\" stroke-width=\"1.5\" opacity=\".85\"/>\n            <path d=\"M4 7l8 6 8-6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" opacity=\".85\"/>\n          </svg>\n        </span>\n        <input id=\"bb-email-input\" name=\"email\" class=\"input is-medium bb-input bb-input--pill\" type=\"email\" inputmode=\"email\" autocomplete=\"email\" placeholder=\"you@example.com\" required>\n        <span class=\"bb-inputwrap__status\" aria-hidden=\"true\"></span>\n      </div>\n\n      <div class=\"bb-feedback\" aria-live=\"polite\"></div>\n\n      <div class=\"bb-email__actions\">\n        <button type=\"submit\" class=\"button is-link bb-btn--primary js_send_link\" disabled>\n          <span class=\"btn-text\">Send link</span>\n          <span class=\"bb-btn__icon\" aria-hidden=\"true\">\n            <svg class=\"ml-1\" xmlns=\"http://www.w3.org/2000/svg\" width=\"18px\" height=\"18px\" viewBox=\"0 0 24 24\" fill=\"#fff\">\n                <path d=\"M7.39999 6.32003L15.89 3.49003C19.7 2.22003 21.77 4.30003 20.51 8.11003L17.68 16.6C15.78 22.31 12.66 22.31 10.76 16.6L9.91999 14.08L7.39999 13.24C1.68999 11.34 1.68999 8.23003 7.39999 6.32003Z\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n                <path d=\"M10.11 13.6501L13.69 10.0601\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n            </svg>\n          </span>\n        </button>\n      </div>\n    </form>\n  </div>\n\n  <!-- Tiny social-proof strip (no slider, no JS) -->\n  <div class=\"bb-socialproof\" aria-label=\"social proof\">\n    <span class=\"bb-stars\" aria-hidden=\"true\">\u2605\u2605\u2605\u2605\u2605</span>\n    <span class=\"bb-sp-text\">Loved by 1,000+ teams</span>\n    <span class=\"bb-dot\" aria-hidden=\"true\">\u2022</span>\n    <em class=\"bb-quote\">\u201cAffordable and fun features\u2026 an instant favorite.\u201d \u2014 James M.</em>\n  </div>\n\n  <footer class=\"bb-legal has-text-centered\">\n    <small>By continuing, you agree to the Bravoboard <a href=\"/terms/\">Terms of Service</a> and <a href=\"/privacy/\">Privacy Policy</a></small>\n  </footer>\n</div>\n\n<!-- ====== Styles (scoped) ====== -->\n<style>\n  :root { --bb-bg: rgba(20,22,45,.88); --bb-ring: #7BD3FF; --bb-fieldBorder: rgba(255,255,255,.6); --bb-fieldBG: rgba(255,255,255,.10); --bb-focus: rgba(193,167,255,.45); }\n\n  /* Base shell + soft radial glow */\n  .bb-modal{ width:min(100%,600px); margin:0 auto; padding:28px 24px 20px; border-radius:20px; background:transparent; color:#fff; position:relative; }\n  .bb-modal::before{\n    content:\"\"; position:absolute; inset:-24px; z-index:-1;\n    /*\n    background:\n      radial-gradient(1200px 600px at 50% -5%, rgba(123, 211, 255, 0.28), transparent 60%),\n      radial-gradient(900px 500px at 50% 105%, rgba(193, 167, 255, 0.24), transparent 60%);\n    filter: blur(2px);\n    */\n  }\n\n  /* Compact: keep vertical spacing, just narrow horizontally */\n  .bb-modal.bb-compact{ width:min(100%,520px); padding:28px 40px 24px; }\n\n  /* Brand/header */\n  .bb-brand{ display:inline-flex; align-items:center; gap:10px; margin-bottom:6px; }\n  .bb-brand__logo{ width:32px; height:32px; }\n  .bb-brand__title{ font: 900 1.55rem/1.1 Inter, system-ui, -apple-system, Segoe UI, Roboto, sans-serif; background:linear-gradient(135deg,#F7FF6E 10%,#6FD5FF 100%); -webkit-background-clip:text; -webkit-text-fill-color:transparent; margin:0; }\n  .bb-secure{ display:flex; justify-content:center; align-items:center; gap:.5rem; opacity:.9; font-weight:600; margin:8px 0 8px; }\n  .bb-microcopy{ opacity:.9; font-size:.98rem;}\n\n  /* Provider/action buttons */\n  .bb-actions{ display:flex; flex-direction:column; gap:12px; }\n  .bb-btn {\n    display:flex;\n    align-items:center;\n    justify-content:center;\n    gap:10px;\n    padding:12px 14px;\n    border-radius:10px;\n    border:1px solid rgba(0,0,0,.2);\n    background:#fff;\n    color:#111;\n    font-size:.95rem;\n    transition:transform .06s ease, box-shadow .2s ease, border-color .2s ease;\n  }\n  .bb-btn:hover { transform:translateY(-1px); box-shadow:0 4px 10px rgba(0,0,0,.18); }\n  .bb-btn:focus-visible{ outline:3px solid var(--bb-ring); outline-offset:2px; }\n  .bb-btn__icon{ width:20px; height:20px; display:inline-flex; }\n\n  /* Divider */\n  .bb-divider{ position:relative; text-align:center; margin:6px 0; color:#c8e5ff; opacity:.8; }\n  .bb-divider::before, .bb-divider::after{ content:\"\"; display:block; height:1px; background:linear-gradient(90deg,transparent,rgba(255,255,255,.4),transparent); }\n  .bb-divider span{ display:inline-block; margin:8px 0; font-weight:700; letter-spacing:.06em; }\n\n  /* Email field */\n  .bb-label{ display:block; font-size:.9rem; margin-bottom:6px; opacity:.9; }\n  .bb-inputwrap{ position:relative; }\n  .bb-inputwrap__lefticon{ position:absolute; left:12px; top:50%; transform:translateY(-50%); opacity:.85; color:#fff; pointer-events:none; }\n  .bb-inputwrap input.input{ padding-right:44px; padding-left:38px; }\n  .bb-inputwrap__status{ position:absolute; right:10px; top:50%; transform:translateY(-50%); width:22px; height:22px; display:none; }\n  .bb-inputwrap__status.is-ok{ display:block; background:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\"><circle cx=\"32\" cy=\"32\" r=\"30\" fill=\"%234bd37b\"/><path fill=\"%23fff\" d=\"M46 14L25 35.6l-7-7.2-7 7.2L25 50l28-28.8z\"/></svg>') center/cover no-repeat; }\n\n  /* Feedback */\n  .bb-feedback{ min-height:24px; font-size:.9rem; margin-top:6px; }\n  .bb-feedback--error{ color:#FFD08A; }\n  .bb-feedback--ok{ color:#B7FFBC; }\n\n  /* Email action buttons row */\n  .bb-email__actions { display:flex; justify-content:flex-end; margin-top:12px; }\n  .bb-btn--primary{ padding:8px 14px; min-height:40px; font-weight:600; }\n\n  /* Tiny social-proof strip */\n  .bb-socialproof{\n    display:flex; align-items:center; gap:.5rem;\n    margin:14px 0 8px;\n    font-size:.9rem; color:#E8F6FF; opacity:.9; flex-wrap:wrap; justify-content:center;\n    border:0.5px solid #777;\n    padding:10px;\n    border-radius:12px;\n    background:rgba(255,255,255,.08);\n    box-shadow:inset 0 1px 0 rgba(255,255,255,.08);\n  }\n  .bb-stars{ letter-spacing:.08em; filter: drop-shadow(0 0 6px rgba(255,255,255,.15)); }\n  .bb-sp-text{ font-weight:700; }\n  .bb-dot{ opacity:.6; }\n  .bb-quote{ opacity:.9; font-style:italic; }\n\n  /* Legal */\n  .bb-legal{ margin-top:8px; opacity:.8; }\n  .bb-legal a{ color:#fff; text-decoration:underline; text-underline-offset:2px; }\n\n  /* Pill input styling */\n  .bb-input{\n    appearance:none; width:100%; color:#fff;\n    background: var(--bb-fieldBG);\n    border:1.25px solid var(--bb-fieldBorder);\n    border-radius:16px;\n    padding:12px 44px 12px 14px;\n    font-size:.95rem; line-height:1.2;\n    backdrop-filter: blur(6px) saturate(120%);\n    box-shadow: inset 0 1px 0 rgba(255,255,255,.10), 0 6px 16px rgba(0,0,0,.16);\n    transition: border-color .2s ease, box-shadow .2s ease, background .2s ease;\n  }\n  .bb-input::placeholder{ color: rgba(255,255,255,.8); }\n  .bb-input:hover{ background: rgba(255,255,255,.12); }\n  .bb-input:focus{ outline:none; border-color:#C1A7FF; box-shadow:0 0 0 2px var(--bb-focus), 0 8px 22px rgba(0,0,0,.18), inset 0 1px 0 rgba(255,255,255,.18); }\n\n  @media (max-width:420px){\n    .bb-modal.bb-compact{ width:min(100%,94vw); padding:28px 18px 24px; }\n    .bb-modal.bb-compact .bb-btn{ max-width:100%; }\n    .bb-socialproof{ font-size:.88rem; }\n  }\n</style>\n\n<!-- ====== Behavior ====== -->\n<script>\n$(function () {\n  const $email = $('#bb-email-input');\n  const $send  = $('.js_send_link');\n  const $feed  = $('.bb-feedback');\n  const $status= $('.bb-inputwrap__status');\n  let debounceId = null;\n  let lastChecked = '';\n\n  // enable button only when native validity passes\n  $email.on('input', function () {\n    $send.prop('disabled', !this.validity.valid);\n    $status.removeClass('is-ok');\n    $feed.removeClass('bb-feedback--ok bb-feedback--error').text('');\n    scheduleCheck();\n  });\n\n  // Back button (if you wire one)\n  $('.js-back').on('click', () => {\n    $email.val('');\n    $send.prop('disabled', true);\n    $status.removeClass('is-ok');\n    $feed.removeClass('bb-feedback--ok bb-feedback--error').text('');\n    $email.trigger('focus');\n  });\n\n  function scheduleCheck() {\n    clearTimeout(debounceId);\n    const val = $email.val().trim();\n    if (!val || !/\\S+@\\S+\\.\\S+/.test(val)) return;\n    debounceId = setTimeout(() => checkEmail(val), 500);\n  }\n\n  function checkEmail(val) {\n    if (val === lastChecked) return;\n    lastChecked = val;\n\n    const csrftoken = Cookies.get('csrftoken');\n    $.ajax({\n      url: \"/api/email_check/\",\n      type: \"POST\",\n      dataType: \"json\",\n      data: JSON.stringify({ email: val }),\n      beforeSend: function(xhr, settings) {\n        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) xhr.setRequestHeader(\"X-CSRFToken\", csrftoken);\n        $feed.removeClass('bb-feedback--ok bb-feedback--error').text('Checking\u2026');\n      },\n      success: function(data) {\n        if (data.no_input) {\n          $feed.text('Enter email'); $send.prop('disabled', true);\n          return;\n        }\n        if (data.email_valid) {\n          $status.addClass('is-ok');\n          $feed.addClass('bb-feedback--ok')\n               .html(data.email_exists ? 'Account found \u2014 use your email link to log in.' : \"Looks good \u2014 we\u2019ll email you a secure login link.\");\n          $send.prop('disabled', false);\n        } else {\n          $feed.addClass('bb-feedback--error').text('Please enter a valid, non-disposable email');\n          $send.prop('disabled', true);\n        }\n      },\n      error: function() {\n        $feed.addClass('bb-feedback--error').text('Something went wrong. Please try again.');\n      }\n    });\n  }\n\n  // Send magic link\n  $('.bb-email').on('submit', function (e) {\n    e.preventDefault();\n    if ($send.prop('disabled')) return;\n\n    const email = $email.val().trim();\n    const csrftoken = Cookies.get('csrftoken');\n\n    $.ajax({\n      url: \"/sesame/auth/\",\n      type: \"POST\",\n      dataType: \"json\",\n      data: JSON.stringify({ email }),\n      beforeSend: function(xhr, settings) {\n        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) xhr.setRequestHeader(\"X-CSRFToken\", csrftoken);\n        $send.prop('disabled', true).addClass('is-loading');\n        $email.prop('disabled', true);\n      },\n      success: function() {\n        $feed.removeClass('bb-feedback--error').addClass('bb-feedback--ok')\n             .html('\u2705 Please check your inbox for a secure login link.');\n        setTimeout(() => {\n          $send.removeClass('is-loading').prop('disabled', false);\n          $send.find('.btn-text').text('Resend');\n          $email.prop('disabled', false).trigger('focus');\n        }, 30000);\n      },\n      error: function() {\n        $feed.addClass('bb-feedback--error').text('We couldn\u2019t send the email. Try again in a bit.');\n        $send.removeClass('is-loading').prop('disabled', false);\n        $email.prop('disabled', false).trigger('focus');\n      }\n    });\n  });\n\n  // ESC hook (wire to your modal close if needed)\n  $(document).on('keydown', function(e) {\n    if (e.key === 'Escape') {\n      // Example: $('.modal .modal-close, .modal-background').click();\n    }\n  });\n});\n</script>\n"}