"""SMTP-backed transactional email. Sends multipart/alternative: a plain-text body for accessibility / minimal clients and an HTML body for richer rendering. Designed for cross-client robustness: - Inline styles on every element (Outlook desktop ignores
Your {brand} sign-in code — {code} — expires in {ttl_minutes} minutes.
▰ {brand_upper}
 
Your sign-in code
 
{code}
 
This code expires in {ttl_minutes} minutes. If you didn’t request it, you can safely ignore this email — no changes will be made to any account.
 
 
Sent automatically by {brand} · do not reply
""" def _html_template_filled(code: str, ttl_minutes: int) -> str: """Substitute palette + content into the OTP HTML template.""" return _OTP_HTML_TEMPLATE.format( code=code, ttl_minutes=ttl_minutes, brand=branding.BRAND_NAME, brand_upper=branding.BRAND_NAME.upper(), FONT_MONO=branding.FONT_MONO, **{f"L_{k.replace('-', '_')}": v for k, v in branding.LIGHT.items()}, **{f"D_{k.replace('-', '_')}": v for k, v in branding.DARK.items()}, ) _OTP_TEXT_TEMPLATE = """\ {brand_upper} — sign in Your verification code: {code} This code expires in {ttl_minutes} minutes. If you didn't request it, you can safely ignore this email — no changes will be made to any account. — Sent automatically by {brand} · do not reply """ def render_otp_email(code: str, ttl_minutes: int) -> tuple[str, str, str]: """Returns (subject, text_body, html_body). Subject embeds the code so users can read it directly from the inbox list without opening the message — common practice for OTP emails (Notion, Substack). The lock-screen exposure tradeoff is minimal: anyone with phone access who could see the notification could also open the email.""" subject = f"{branding.BRAND_NAME} sign-in: {code}" text = _OTP_TEXT_TEMPLATE.format( code=code, ttl_minutes=ttl_minutes, brand=branding.BRAND_NAME, brand_upper=branding.BRAND_NAME.upper(), ) html = _html_template_filled(code=code, ttl_minutes=ttl_minutes) return subject, text, html async def send_otp(to: str, code: str, ttl_minutes: int) -> None: subject, text, html = render_otp_email(code, ttl_minutes) await send_email(to, subject, text, html_body=html)