StemGraph_AI / static /index.html
Krishna111111's picture
round-robin removed; static models; fix; ux changes..
bc7a752
Raw
History Blame Contribute Delete
56.2 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<meta name="screen-orientation" content="portrait">
<meta name="x5-orientation" content="portrait">
<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">
<title>STEM Copilot</title>
<meta name="description" content="AI-powered NCERT tutor for Class XI and XII Physics, Chemistry, and Mathematics.">
<meta name="theme-color" content="#0a0a0a">
<link rel="icon" type="image/png" href="/assets/bot.png">
<link rel="manifest" href="/manifest.json">
<link rel="apple-touch-icon" href="/assets/stem_black.png">
<!-- Preconnect for faster font/CDN loading -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css">
<link rel="stylesheet" href="/static/style.css">
<!-- Google Identity Services: loaded dynamically by initGoogleAuth() in app.js -->
</head>
<body>
<!-- ==================== LOGIN SCREEN ==================== -->
<div class="login-screen" id="loginScreen">
<div class="login-top-actions">
<button class="login-theme-btn" id="loginThemeBtn" title="Toggle dark / light mode">
<svg class="icon-sun" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5" />
<line x1="12" y1="1" x2="12" y2="3" />
<line x1="12" y1="21" x2="12" y2="23" />
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
<line x1="1" y1="12" x2="3" y2="12" />
<line x1="21" y1="12" x2="23" y2="12" />
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
</svg>
<svg class="icon-moon" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
</svg>
</button>
</div>
<div class="login-card">
<img src="/assets/stembotix.png" alt="STEM Copilot" class="login-logo-stembotix">
<h1 class="login-title">Welcome to STEM Copilot</h1>
<p class="login-subtitle">Your personal NCERT tutor for Physics, Chemistry &amp; Mathematics</p>
<div id="gsi-hidden-btn" style="position:fixed;top:-9999px;left:-9999px;opacity:0;pointer-events:none;">
</div>
<div class="google-btn-wrap">
<button id="customGoogleBtn" class="gsi-custom-btn" onclick="triggerGoogleSignIn()">
<svg width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
<path fill="#2231D4"
d="M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.875 2.684-6.615z" />
<path fill="#34A853"
d="M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z" />
<path fill="#FBBC05"
d="M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z" />
<path fill="#EA4335"
d="M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 6.29C4.672 4.163 6.656 3.58 9 3.58z" />
</svg>
<span>Sign in with Google</span>
</button>
</div>
<p class="login-footer">By signing in, you agree to our <a href="https://www.stembotix.com/terms-policy" target="_blank" rel="noopener" class="terms-link">Terms of Service</a>.</p>
</div>
</div>
<!-- ==================== BYOK SCREEN ==================== -->
<div class="byok-screen" id="byokScreen" style="display:none;">
<div class="byok-card">
<h2>One Last Step</h2>
<p class="byok-desc">
STEM Copilot uses your own OpenRouter API key to power the tutor.
It's free — takes 30 seconds to set up.
</p>
<ol class="byok-steps">
<li>Go to <a href="https://openrouter.ai/workspaces/default/keys" target="_blank"
rel="noopener">openrouter.ai/keys</a></li>
<li>Create a new key (free)</li>
<li>Paste it below</li>
</ol>
<input type="text" id="byokInput" class="settings-input" placeholder="Paste your OpenRouter API key here"
autocomplete="off" spellcheck="false">
<div class="byok-optional">
<p class="byok-optional-label">Tavily API key <span class="byok-optional-badge">Optional</span></p>
<p class="byok-optional-desc">Add it to unlock live web search. Skip it and web search stays disabled.</p>
<input type="text" id="byokTavilyInput" class="settings-input" placeholder="Paste your Tavily API key (optional)"
autocomplete="off" spellcheck="false">
<p class="byok-optional-hint">Get a free Tavily key at
<a href="https://app.tavily.com/home" target="_blank" rel="noopener">app.tavily.com</a>
</p>
</div>
<button class="byok-submit-btn" id="byokSubmitBtn">Start Learning</button>
<p class="byok-note">Your keys are stored securely and never shared.</p>
</div>
</div>
<!-- ==================== PWA INSTALL BANNER ==================== -->
<div class="install-banner" id="installBanner" style="display:none;">
<img src="/assets/bot.png" alt="" class="install-banner-icon">
<div class="install-banner-text">
<strong>STEM Copilot</strong>
<span>Install as app for faster access</span>
</div>
<button class="install-banner-btn" id="installBtn">Install</button>
<button class="install-banner-dismiss" id="installDismiss">&times;</button>
</div>
<!-- ==================== MOBILE TOP NAV BAR ==================== -->
<div class="mobile-topbar" id="mobileTopbar">
<button class="topbar-profile-btn" id="topbarProfileBtn" title="Account">
<img id="topbarAvatar" class="topbar-avatar" src="/assets/bot.png" alt="">
</button>
<img src="/assets/stembotix.png" alt="STEM Copilot" class="topbar-logo">
<div class="topbar-actions">
<button class="topbar-icon-btn" id="topbarHistoryBtn" title="Chat history">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10" />
<polyline points="12 6 12 12 16 14" />
</svg>
</button>
<button class="topbar-icon-btn" id="topbarNewChatBtn" title="New chat">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M12 5v14M5 12h14" />
</svg>
</button>
</div>
</div>
<!-- ==================== MOBILE ACCOUNT OVERLAY ==================== -->
<div class="fullscreen-overlay" id="accountOverlay">
<div class="overlay-header">
<h2>Account</h2>
<button class="overlay-close-btn" id="accountOverlayClose">&times;</button>
</div>
<div class="overlay-body">
<div class="overlay-user-info" id="overlayUserInfo">
<img id="overlayUserAvatar" class="overlay-avatar" src="/assets/bot.png" alt="">
<div class="overlay-user-details">
<span class="overlay-user-name" id="overlayUserName">Student</span>
<span class="overlay-user-email" id="overlayUserEmail"></span>
</div>
</div>
<div class="overlay-menu">
<button class="overlay-menu-item" id="overlaySettingsBtn">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="3" />
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.6 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" />
</svg>
Settings
</button>
<button class="overlay-menu-item overlay-menu-logout" id="overlayLogoutBtn">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
<polyline points="16 17 21 12 16 7" />
<line x1="21" y1="12" x2="9" y2="12" />
</svg>
Log out
</button>
</div>
</div>
</div>
<!-- ==================== MOBILE HISTORY OVERLAY ==================== -->
<div class="fullscreen-overlay" id="historyOverlay">
<div class="overlay-header">
<h2>Chat History</h2>
<button class="overlay-close-btn" id="historyOverlayClose">&times;</button>
</div>
<div class="overlay-body">
<div class="overlay-history-list" id="overlayHistoryList"></div>
<div class="overlay-empty-state" id="overlayHistoryEmpty">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="opacity:0.3">
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
</svg>
<p>No conversations yet</p>
</div>
</div>
</div>
<!-- Mobile sidebar overlay (kept for edge-swipe on mobile) -->
<div class="sidebar-overlay" id="sidebarOverlay"></div>
<!-- ==================== MAIN APP ==================== -->
<div class="app-container" id="appContainer" style="display:none;">
<!-- Sidebar (full — desktop only) -->
<aside class="sidebar collapsed" id="sidebar">
<div class="sidebar-top">
<div class="sidebar-logo-row">
<img src="/assets/stembotix.png" alt="STEMbotix" class="sidebar-logo">
</div>
<button class="new-chat-btn" id="newChatBtn">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M12 5v14M5 12h14" />
</svg>
New Chat
</button>
<div class="chat-history" id="chatHistoryList"></div>
</div>
<div class="sidebar-bottom">
<div class="user-profile-btn" id="userProfileBtn">
<img id="userAvatar" class="user-avatar" src="" alt="">
<span id="userDisplayName" class="user-name">Student</span>
</div>
<!-- User menu popup -->
<div class="user-menu" id="userMenu">
<div class="user-menu-item" id="openSettingsBtn">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<circle cx="12" cy="12" r="3" />
<path
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.6 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" />
</svg>
Settings
</div>
<div class="user-menu-item user-menu-logout" id="logoutBtn">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
<polyline points="16 17 21 12 16 7" />
<line x1="21" y1="12" x2="9" y2="12" />
</svg>
Log out
</div>
</div>
</div>
</aside>
<!-- Sidebar rail (collapsed, desktop only) -->
<aside class="sidebar-rail" id="sidebarRail">
<div class="rail-top">
<button class="rail-icon-btn" id="railExpandBtn" title="Open sidebar">
<img src="/assets/stem_transparent.png" alt="S" class="rail-logo">
</button>
<button class="rail-icon-btn" id="railNewChatBtn" title="New chat">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M12 5v14M5 12h14" />
</svg>
</button>
</div>
<div class="rail-bottom">
<button class="rail-icon-btn" id="railProfileBtn" title="Profile">
<img id="railAvatar" class="rail-avatar" src="" alt="">
</button>
</div>
</aside>
<!-- Main -->
<main class="main-chat">
<!-- Desktop header -->
<header class="main-header" id="mainHeader">
<button class="toggle-sidebar-btn" id="toggleSidebarBtn" title="Toggle Sidebar">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
<line x1="9" y1="3" x2="9" y2="21" />
</svg>
</button>
</header>
<div class="chat-container" id="chatContainer">
<!-- Hero / Welcome screen -->
<div class="hero-welcome" id="welcomeScreen">
<img src="/assets/bot.png" alt="STEM Copilot" class="hero-bot-icon">
<h1 class="hero-title" id="heroTitle">What should we study today?</h1>
<div class="hero-input-wrap">
<!-- Image / Doc preview in hero -->
<div class="hero-image-preview" id="heroImagePreview">
<div class="hero-image-preview-thumb" id="heroImagePreviewThumb"></div>
<span class="image-preview-name" id="heroImagePreviewName"></span>
<button class="hero-image-preview-remove" id="heroImagePreviewRemove">&times;</button>
</div>
<!-- Tool progress bar (hero) -->
<div class="tool-progress-bar" id="heroToolProgressBar">
<div class="tool-progress-label" id="heroToolProgressLabel">Searching...</div>
<div class="tool-progress-track"><div class="tool-progress-fill" id="heroToolProgressFill"></div></div>
</div>
<div class="hero-input-box" id="heroInputBox">
<!-- + Attach menu (Hero) -->
<div class="attach-wrap" id="heroAttachWrap">
<button class="attach-plus-btn" id="heroAttachPlusBtn" title="Attach or search">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
</svg>
</button>
<div class="attach-menu" id="heroAttachMenu">
<button class="attach-menu-item" id="heroWebSearchToggle" data-active="false">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
<span class="attach-menu-label">Web Search</span>
<span class="attach-info" tabindex="0" role="button" aria-label="About web search" data-tip="Search the live web for current info and topics beyond Physics, Chemistry &amp; Maths. Requires a Tavily API key.">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
</span>
</button>
<button class="attach-menu-item" id="heroYtSearchToggle" data-active="false">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
<span class="attach-menu-label">YouTube Video</span>
<span class="attach-info" tabindex="0" role="button" aria-label="About YouTube search" data-tip="Paste a YouTube link and I'll use the video's transcript to answer your questions about it.">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
</span>
</button>
<button class="attach-menu-item" id="heroAttachFileBtn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>
<span class="attach-menu-label">Add Photos/Files</span>
</button>
</div>
</div>
<!-- Hidden file inputs -->
<input type="file" id="heroImageInput" accept="image/*" style="display:none;">
<input type="file" id="heroDocInput" accept=".pdf,.doc,.docx,.txt,.md,.py,.js,.ts,.csv" style="display:none;">
<textarea id="heroInput" placeholder="Ask STEM Copilot..." rows="1"></textarea>
<!-- Teaching style selector (scrollable) -->
<div class="style-selector-wrap" id="heroStyleSelectorWrap">
<button class="style-selector-btn" id="heroStyleSelectorBtn" title="Teaching style">
<span id="heroStyleSelectorLabel">Vidyut</span>
<svg viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9" /></svg>
</button>
<div class="style-dropdown" id="heroStyleDropdown">
<div class="style-option active" data-persona="vidyut">
<div class="style-option-name">Guru</div>
<div class="style-option-desc">Calm, clear, step-by-step master teacher. Makes hard concepts obvious.</div>
</div>
<div class="style-option" data-persona="nerd">
<div class="style-option-name">Nerd</div>
<div class="style-option-desc">Deep, rigorous, first-principles. Goes beyond the textbook.</div>
</div>
<div class="style-option" data-persona="noob">
<div class="style-option-name">Beginner</div>
<div class="style-option-desc">Patient, step-by-step. Explains like you're seeing it for the first time.</div>
</div>
<div class="style-option" data-persona="thoughtful">
<div class="style-option-name">Thoughtful</div>
<div class="style-option-desc">Connects science to the real world. Every formula has a story.</div>
</div>
<div class="style-option" data-persona="panic">
<div class="style-option-name">Panic</div>
<div class="style-option-desc">Exam tomorrow? Concise bullets, key formulas, no fluff.</div>
</div>
</div>
</div>
<!-- Adaptive action button: mic when empty, send when text present -->
<button class="adaptive-action-btn" id="heroAdaptiveBtn" title="Voice input">
<svg class="icon-mic" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" /><path d="M19 10v2a7 7 0 0 1-14 0v-2" /><line x1="12" y1="19" x2="12" y2="23" /><line x1="8" y1="23" x2="16" y2="23" /></svg>
<svg class="icon-send" viewBox="0 0 24 24"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"></path></svg>
</button>
</div>
</div>
<!-- Hero pills REMOVED per todo item 3 -->
</div>
</div>
<!-- Bottom input (hidden during hero, shown during chat) -->
<div class="input-container" id="bottomInputContainer" style="display:none;">
<!-- Tool progress bar (shown while web/yt tool is running) -->
<div class="tool-progress-bar" id="toolProgressBar" style="display:none;">
<div class="tool-progress-label" id="toolProgressLabel">Searching...</div>
<div class="tool-progress-track"><div class="tool-progress-fill" id="toolProgressFill"></div></div>
</div>
<!-- Image/Doc preview -->
<div class="image-preview-bar" id="imagePreviewBar" style="display:none;">
<div class="image-preview-thumb" id="imagePreviewThumb"></div>
<span class="image-preview-name" id="imagePreviewName"></span>
<button class="image-preview-remove" id="imagePreviewRemove">&times;</button>
</div>
<div class="input-box" id="inputBox">
<!-- + Attach menu -->
<div class="attach-wrap" id="attachWrap">
<button class="attach-plus-btn" id="attachPlusBtn" title="Attach or search">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
</svg>
</button>
<div class="attach-menu" id="attachMenu">
<button class="attach-menu-item" id="webSearchToggle" data-active="false">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
<span class="attach-menu-label">Web Search</span>
<span class="attach-info" tabindex="0" role="button" aria-label="About web search" data-tip="Search the live web for current info and topics beyond Physics, Chemistry &amp; Maths. Requires a Tavily API key.">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
</span>
</button>
<button class="attach-menu-item" id="ytSearchToggle" data-active="false">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg>
<span class="attach-menu-label">YouTube Video</span>
<span class="attach-info" tabindex="0" role="button" aria-label="About YouTube search" data-tip="Paste a YouTube link and I'll use the video's transcript to answer your questions about it.">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
</span>
</button>
<button class="attach-menu-item" id="attachFileBtn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>
<span class="attach-menu-label">Add Photos/Files</span>
</button>
</div>
</div>
<!-- Hidden file inputs -->
<input type="file" id="imageInput" accept="image/*" style="display:none;">
<input type="file" id="docInput" accept=".pdf,.doc,.docx,.txt,.md,.py,.js,.ts,.csv" style="display:none;">
<textarea id="userInput" placeholder="Ask STEM Copilot..." rows="1"></textarea>
<!-- Teaching style selector -->
<div class="style-selector-wrap" id="styleSelectorWrap">
<button class="style-selector-btn" id="styleSelectorBtn" title="Teaching style">
<span id="styleSelectorLabel">Guru</span>
<svg viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9" /></svg>
</button>
<div class="style-dropdown" id="styleDropdown">
<div class="style-option active" data-persona="vidyut">
<div class="style-option-name">Guru</div>
<div class="style-option-desc">Calm, clear, step-by-step master teacher. Makes hard concepts obvious.</div>
</div>
<div class="style-option" data-persona="nerd">
<div class="style-option-name">Nerd</div>
<div class="style-option-desc">Deep, rigorous, first-principles. Goes beyond the textbook.</div>
</div>
<div class="style-option" data-persona="noob">
<div class="style-option-name">Beginner</div>
<div class="style-option-desc">Patient, step-by-step. Explains like you're seeing it for the first time.</div>
</div>
<div class="style-option" data-persona="thoughtful">
<div class="style-option-name">Thoughtful</div>
<div class="style-option-desc">Connects science to the real world. Every formula has a story.</div>
</div>
<div class="style-option" data-persona="panic">
<div class="style-option-name">Panic</div>
<div class="style-option-desc">Exam tomorrow? Concise bullets, key formulas, no fluff.</div>
</div>
</div>
</div>
<!-- Adaptive action button + stop -->
<button class="adaptive-action-btn" id="adaptiveBtn" title="Voice input">
<svg class="icon-mic" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" /><path d="M19 10v2a7 7 0 0 1-14 0v-2" /><line x1="12" y1="19" x2="12" y2="23" /><line x1="8" y1="23" x2="16" y2="23" /></svg>
<svg class="icon-send" viewBox="0 0 24 24"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"></path></svg>
</button>
<button class="stop-btn" id="stopBtn" title="Stop generating">
<svg viewBox="0 0 24 24" fill="currentColor">
<rect x="7" y="7" width="10" height="10" rx="1" />
</svg>
</button>
</div>
<div class="disclaimer-text">
STEM Copilot is AI and can make mistakes.
</div>
</div>
</main>
</div>
<!-- ==================== SETTINGS MODAL ==================== -->
<div class="modal-overlay" id="settingsOverlay">
<div class="settings-modal" id="settingsModal">
<div class="modal-header">
<h2>Settings</h2>
<button class="modal-close" id="settingsCloseBtn">&times;</button>
</div>
<div class="modal-body settings-layout">
<!-- Vertical Tab Navigation -->
<div class="settings-nav">
<button class="settings-nav-btn active" data-tab="general">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<circle cx="12" cy="12" r="3" />
<path
d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.6 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.6a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" />
</svg>
<span>General</span>
</button>
<button class="settings-nav-btn" data-tab="apikeys">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<path
d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4" />
</svg>
<span>API Keys</span>
</button>
<button class="settings-nav-btn" data-tab="personalization">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
<circle cx="12" cy="7" r="4" />
</svg>
<span>Profile</span>
</button>
<button class="settings-nav-btn" data-tab="feedback">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2">
<path
d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" />
</svg>
<span>Feedback</span>
</button>
</div><!-- /settings-nav -->
<!-- Settings Content Panel -->
<div class="settings-panel">
<!-- General Tab -->
<div class="tab-content active" id="tab-general">
<h3 class="settings-section-title">Language</h3>
<select class="settings-select" id="languageSelect" style="display:none;">
<option value="auto">Auto-detect</option>
<option value="english">English</option>
<option value="hinglish">Hinglish</option>
<option value="hindi">Hindi</option>
<option value="gujarati">Gujarati</option>
<option value="marathi">Marathi</option>
<option value="french">French</option>
</select>
<div class="custom-select-wrap" id="languageSelectWrap">
<button type="button" class="custom-select-btn" id="languageSelectBtn">
<span>Auto-detect</span>
<svg viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9" /></svg>
</button>
<div class="custom-select-list" id="languageSelectList">
<div class="custom-select-option active" data-value="auto">Auto-detect</div>
<div class="custom-select-option" data-value="english">English</div>
<div class="custom-select-option" data-value="hinglish">Hinglish</div>
<div class="custom-select-option" data-value="hindi">Hindi</div>
<div class="custom-select-option" data-value="gujarati">Gujarati</div>
<div class="custom-select-option" data-value="marathi">Marathi</div>
<div class="custom-select-option" data-value="french">French</div>
</div>
</div>
<h3 class="settings-section-title">Theme</h3>
<div class="theme-option-group">
<button class="theme-option-btn" data-theme-val="dark" id="themeDarkBtn">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
</svg>
Dark
</button>
<button class="theme-option-btn" data-theme-val="light" id="themeLightBtn">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="5" />
<line x1="12" y1="1" x2="12" y2="3" />
<line x1="12" y1="21" x2="12" y2="23" />
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
<line x1="1" y1="12" x2="3" y2="12" />
<line x1="21" y1="12" x2="23" y2="12" />
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
</svg>
Light
</button>
</div>
</div>
<!-- API Keys Tab -->
<div class="tab-content" id="tab-apikeys">
<div class="apikey-group">
<h3 class="settings-section-title">OpenRouter API Key</h3>
<p class="settings-hint">
Powers the tutor. Get your free key at
<a href="https://openrouter.ai/workspaces/default/keys" target="_blank"
rel="noopener">openrouter.ai/keys</a>
</p>
<input type="password" class="settings-input" id="settingsApiKeyInput" placeholder="sk-or-..."
autocomplete="off" spellcheck="false">
<button class="settings-save-btn" id="saveApiKeyBtn">Save Key</button>
</div>
<div class="apikey-group">
<h3 class="settings-section-title">Tavily API Key <span class="settings-optional-badge">Optional</span></h3>
<p class="settings-hint">
Enables live web search. Get a free key at
<a href="https://app.tavily.com/home" target="_blank" rel="noopener">app.tavily.com</a>
</p>
<input type="password" class="settings-input" id="settingsTavilyKeyInput" placeholder="tvly-..."
autocomplete="off" spellcheck="false">
<button class="settings-save-btn" id="saveTavilyKeyBtn">Save Key</button>
</div>
</div>
<!-- Profile Tab -->
<div class="tab-content" id="tab-personalization">
<h3 class="settings-section-title">Your Name</h3>
<input type="text" class="settings-input" id="usernameInput"
placeholder="What should I call you?" maxlength="30" autocomplete="off">
<h3 class="settings-section-title" style="margin-top:20px;">About You</h3>
<textarea class="settings-textarea" id="profileInput"
placeholder="e.g. I'm in Class XII, preparing for JEE. Physics and Maths scare me. I'm good at Chemistry."
rows="4"></textarea>
<button class="settings-save-btn" id="saveProfileBtn">Save Profile</button>
</div>
<!-- Feedback Tab -->
<div class="tab-content" id="tab-feedback">
<!-- Overall rating -->
<h3 class="settings-section-title">Rate Your Experience</h3>
<div class="fb-stars" id="fbStars">
<span class="fb-star" data-val="1">
<svg viewBox="0 0 24 24" fill="currentColor"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
</span>
<span class="fb-star" data-val="2">
<svg viewBox="0 0 24 24" fill="currentColor"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
</span>
<span class="fb-star" data-val="3">
<svg viewBox="0 0 24 24" fill="currentColor"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
</span>
<span class="fb-star" data-val="4">
<svg viewBox="0 0 24 24" fill="currentColor"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
</span>
<span class="fb-star" data-val="5">
<svg viewBox="0 0 24 24" fill="currentColor"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
</span>
</div>
<input type="hidden" id="fbOverall" value="0">
<!-- Sub-ratings row -->
<div class="fb-subratings">
<div class="fb-subrating-group">
<span class="fb-subrating-label">Ease of Use</span>
<div class="fb-emojis" id="fbEaseEmojis" data-field="fbEase">
<!-- Poor: frown face -->
<span class="fb-emoji" data-val="1" title="Poor">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M16 16s-1.5-2-4-2-4 2-4 2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
</span>
<!-- Fair: neutral/meh face -->
<span class="fb-emoji" data-val="2" title="Fair">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="8" y1="15" x2="16" y2="15"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
</span>
<!-- Good: smile face -->
<span class="fb-emoji" data-val="3" title="Good">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M8 13s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
</span>
<!-- Excellent: big smile / star-eyes -->
<span class="fb-emoji" data-val="4" title="Excellent">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M8 13s1.5 3 4 3 4-3 4-3"/><path d="M9 9l.5.5-.5.5-.5-.5z" fill="currentColor"/><path d="M15 9l.5.5-.5.5-.5-.5z" fill="currentColor"/></svg>
</span>
</div>
<input type="hidden" id="fbEase" value="0">
</div>
<div class="fb-subrating-group">
<span class="fb-subrating-label">Response Quality</span>
<div class="fb-emojis" id="fbQualityEmojis" data-field="fbQuality">
<span class="fb-emoji" data-val="1" title="Poor">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M16 16s-1.5-2-4-2-4 2-4 2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
</span>
<span class="fb-emoji" data-val="2" title="Fair">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="8" y1="15" x2="16" y2="15"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
</span>
<span class="fb-emoji" data-val="3" title="Good">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M8 13s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
</span>
<span class="fb-emoji" data-val="4" title="Excellent">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M8 13s1.5 3 4 3 4-3 4-3"/><path d="M9 9l.5.5-.5.5-.5-.5z" fill="currentColor"/><path d="M15 9l.5.5-.5.5-.5-.5z" fill="currentColor"/></svg>
</span>
</div>
<input type="hidden" id="fbQuality" value="0">
</div>
</div>
<!-- Category -->
<h3 class="settings-section-title" style="margin-top:18px;">Category</h3>
<div class="fb-categories">
<button type="button" class="fb-cat-btn active" data-val="bug">
<svg class="fb-cat-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 2l1.88 1.88"/><path d="M14.12 3.88L16 2"/><path d="M9 7.13v-1a3.003 3.003 0 1 1 6 0v1"/><path d="M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6z"/><path d="M12 20v-9"/><path d="M6.53 9C4.6 8.8 3 7.1 3 5"/><path d="M6 13H2"/><path d="M3 21c0-2.1 1.7-3.9 3.8-4"/><path d="M20.97 5c0 2.1-1.6 3.8-3.5 4"/><path d="M22 13h-4"/><path d="M17.2 17c2.1.1 3.8 1.9 3.8 4"/></svg>
Bug Report
</button>
<button type="button" class="fb-cat-btn" data-val="feature">
<svg class="fb-cat-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="2" x2="12" y2="6"/><line x1="12" y1="18" x2="12" y2="22"/><line x1="4.93" y1="4.93" x2="7.76" y2="7.76"/><line x1="16.24" y1="16.24" x2="19.07" y2="19.07"/><line x1="2" y1="12" x2="6" y2="12"/><line x1="18" y1="12" x2="22" y2="12"/><line x1="4.93" y1="19.07" x2="7.76" y2="16.24"/><line x1="16.24" y1="7.76" x2="19.07" y2="4.93"/></svg>
Feature
</button>
<button type="button" class="fb-cat-btn" data-val="iam">
<svg class="fb-cat-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
IAM Policy
</button>
<button type="button" class="fb-cat-btn" data-val="documentation">
<svg class="fb-cat-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
Docs
</button>
<button type="button" class="fb-cat-btn" data-val="other">
<svg class="fb-cat-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
Other
</button>
</div>
<input type="hidden" id="fbCategory" value="bug">
<!-- Message -->
<h3 class="settings-section-title" style="margin-top:18px;">Message <span style="color:var(--brand);font-size:11px;margin-left:4px;">required</span></h3>
<textarea class="settings-textarea" id="feedbackMessage" rows="4"
placeholder="Describe the issue, feature idea, or your thoughts..."></textarea>
<!-- Image attachments -->
<h3 class="settings-section-title" style="margin-top:14px;">Attach Screenshots <span style="color:var(--text-muted);font-size:11px;font-weight:400;margin-left:4px;">up to 5</span></h3>
<div class="fb-attach-area" id="fbAttachArea">
<input type="file" id="fbImageInput" accept="image/*" multiple style="display:none;">
<div class="fb-attach-chips" id="fbAttachChips"></div>
<button type="button" class="fb-attach-btn" id="fbAttachBtn">
<svg viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
Add images
</button>
</div>
<!-- Submit -->
<button class="settings-save-btn" id="submitFeedbackBtn" style="width:100%;margin-top:18px;">
Send Feedback
</button>
<!-- Cooldown bar -->
<div class="fb-cooldown-wrap" id="fbCooldownWrap" style="display:none;">
<div class="fb-cooldown-bar" id="fbCooldownBar"></div>
<span class="fb-cooldown-label" id="fbCooldownLabel">Please wait 60s before sending again</span>
</div>
</div>
</div><!-- /settings-panel -->
</div><!-- /settings-layout -->
</div><!-- /settings-modal -->
</div><!-- /settingsOverlay -->
<!-- ==================== PWA CONFIRM MODAL ==================== -->
<div class="pwa-modal-overlay" id="pwaConfirmOverlay">
<div class="pwa-modal">
<p class="pwa-modal-message" id="pwaConfirmMessage">Are you sure?</p>
<div class="pwa-modal-actions">
<button class="pwa-modal-btn pwa-modal-cancel" id="pwaConfirmCancel">No</button>
<button class="pwa-modal-btn pwa-modal-ok" id="pwaConfirmOk">Yes</button>
</div>
</div>
</div>
<!-- ==================== PWA PROMPT MODAL ==================== -->
<div class="pwa-modal-overlay" id="pwaPromptOverlay">
<div class="pwa-modal">
<p class="pwa-modal-message" id="pwaPromptMessage">Enter value:</p>
<input type="text" class="pwa-modal-input" id="pwaPromptInput" autocomplete="off" spellcheck="false">
<div class="pwa-modal-actions">
<button class="pwa-modal-btn pwa-modal-cancel" id="pwaPromptCancel">Cancel</button>
<button class="pwa-modal-btn pwa-modal-ok" id="pwaPromptOk">Save</button>
</div>
</div>
</div>
<!-- Dependencies -->
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/mhchem.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script defer src="/static/app.js"></script>
</body>
</html>