Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Jain Sage AI | Interactive Interface</title> | |
| <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=Outfit:wght@300;400;600;700&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --primary: #FF9F1C; | |
| /* Saffron/Gold */ | |
| --secondary: #2EC4B6; | |
| /* Teal/Turquoise */ | |
| --dark: #0F172A; | |
| --darker: #020617; | |
| --light: #F8FAFC; | |
| --glass: rgba(255, 255, 255, 0.05); | |
| --glass-border: rgba(255, 255, 255, 0.1); | |
| } | |
| * { | |
| box-sizing: border-box; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| body { | |
| font-family: 'Outfit', sans-serif; | |
| background-color: var(--darker); | |
| color: var(--light); | |
| min-height: 100vh; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| background: radial-gradient(circle at top right, #1e293b, var(--darker)); | |
| overflow-x: hidden; | |
| } | |
| .container { | |
| width: 100%; | |
| max-width: 900px; | |
| padding: 2rem; | |
| position: relative; | |
| z-index: 10; | |
| } | |
| /* Ambient Background blobs */ | |
| .blob { | |
| position: absolute; | |
| width: 400px; | |
| height: 400px; | |
| background: var(--primary); | |
| filter: blur(150px); | |
| opacity: 0.2; | |
| border-radius: 50%; | |
| z-index: -1; | |
| animation: float 10s infinite alternate; | |
| } | |
| .blob-2 { | |
| background: var(--secondary); | |
| top: 10%; | |
| right: 10%; | |
| animation-delay: -5s; | |
| } | |
| @keyframes float { | |
| 0% { | |
| transform: translate(0, 0); | |
| } | |
| 100% { | |
| transform: translate(20px, 40px); | |
| } | |
| } | |
| header { | |
| text-align: center; | |
| margin-bottom: 3rem; | |
| } | |
| h1 { | |
| font-size: 3.5rem; | |
| font-weight: 700; | |
| background: linear-gradient(135deg, #fff 0%, var(--primary) 100%); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| margin-bottom: 0.5rem; | |
| letter-spacing: -1px; | |
| } | |
| .subtitle { | |
| color: #94A3B8; | |
| font-size: 1.1rem; | |
| } | |
| .chat-card { | |
| background: var(--glass); | |
| backdrop-filter: blur(16px); | |
| border: 1px solid var(--glass-border); | |
| border-radius: 24px; | |
| padding: 2rem; | |
| box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); | |
| } | |
| .api-config { | |
| margin-bottom: 1.5rem; | |
| display: flex; | |
| gap: 1rem; | |
| align-items: center; | |
| background: rgba(0, 0, 0, 0.2); | |
| padding: 1rem; | |
| border-radius: 12px; | |
| } | |
| .input-group { | |
| flex: 1; | |
| } | |
| label { | |
| display: block; | |
| margin-bottom: 0.5rem; | |
| font-size: 0.85rem; | |
| color: var(--secondary); | |
| font-weight: 600; | |
| text-transform: uppercase; | |
| letter-spacing: 0.5px; | |
| } | |
| input[type="text"], | |
| textarea { | |
| width: 100%; | |
| background: rgba(15, 23, 42, 0.6); | |
| border: 1px solid var(--glass-border); | |
| color: white; | |
| padding: 1rem; | |
| border-radius: 12px; | |
| font-family: inherit; | |
| font-size: 1rem; | |
| transition: all 0.3s ease; | |
| } | |
| input[type="text"]:focus, | |
| textarea:focus { | |
| outline: none; | |
| border-color: var(--primary); | |
| box-shadow: 0 0 0 2px rgba(255, 159, 28, 0.2); | |
| } | |
| .chat-box { | |
| min-height: 200px; | |
| max-height: 500px; | |
| overflow-y: auto; | |
| margin-bottom: 1.5rem; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1rem; | |
| } | |
| .message { | |
| padding: 1rem 1.5rem; | |
| border-radius: 16px; | |
| max-width: 80%; | |
| line-height: 1.6; | |
| animation: slideIn 0.3s ease-out; | |
| } | |
| @keyframes slideIn { | |
| from { | |
| opacity: 0; | |
| transform: translateY(10px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| .message.user { | |
| align-self: flex-end; | |
| background: rgba(46, 196, 182, 0.15); | |
| border: 1px solid rgba(46, 196, 182, 0.3); | |
| color: #d1fae5; | |
| border-bottom-right-radius: 4px; | |
| } | |
| .message.bot { | |
| align-self: flex-start; | |
| background: rgba(255, 255, 255, 0.05); | |
| border: 1px solid var(--glass-border); | |
| color: #e2e8f0; | |
| border-bottom-left-radius: 4px; | |
| } | |
| .controls { | |
| display: flex; | |
| gap: 1rem; | |
| } | |
| button { | |
| background: var(--primary); | |
| color: var(--darker); | |
| border: none; | |
| padding: 1rem 2rem; | |
| border-radius: 12px; | |
| font-weight: 700; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| } | |
| button:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 20px -5px rgba(255, 159, 28, 0.4); | |
| } | |
| button:disabled { | |
| background: #64748b; | |
| cursor: not-allowed; | |
| transform: none; | |
| } | |
| .spinner { | |
| width: 20px; | |
| height: 20px; | |
| border: 3px solid rgba(0, 0, 0, 0.3); | |
| border-radius: 50%; | |
| border-top-color: var(--darker); | |
| animation: spin 1s linear infinite; | |
| display: none; | |
| } | |
| @keyframes spin { | |
| to { | |
| transform: rotate(360deg); | |
| } | |
| } | |
| /* Formatting for bot responses */ | |
| .message.bot strong { | |
| color: var(--primary); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="blob"></div> | |
| <div class="blob blob-2"></div> | |
| <div class="container"> | |
| <header> | |
| <h1>Jain Sage AI</h1> | |
| <p class="subtitle">Deep Wisdom from Anekant Syadvad & The Tirthankaras</p> | |
| </header> | |
| <div class="chat-card"> | |
| <div class="api-config"> | |
| <div class="input-group"> | |
| <label for="apiUrl">API Endpoint URL</label> | |
| <input type="text" id="apiUrl" value="https://deploymentcode.onrender.com/chat" | |
| placeholder="http://localhost:10000/chat"> | |
| </div> | |
| <div style="font-size: 0.8rem; color: #64748b; max-width: 300px;"> | |
| Replace with your Render URL after deployment. | |
| </div> | |
| </div> | |
| <div class="chat-box" id="chatBox"> | |
| <div class="message bot"> | |
| Namaste. I am an AI scholar of Jain Philosophy. Ask me about Anekantavada, Karma, or the path to | |
| Moksha. | |
| </div> | |
| </div> | |
| <div class="controls"> | |
| <input type="text" id="queryInput" placeholder="Ask a question..." | |
| onkeydown="if(event.key==='Enter') sendMessage()"> | |
| <button onclick="sendMessage()" id="sendBtn"> | |
| <span>Ask</span> | |
| <div class="spinner" id="spinner"></div> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| async function sendMessage() { | |
| const input = document.getElementById('queryInput'); | |
| const chatBox = document.getElementById('chatBox'); | |
| const btn = document.getElementById('sendBtn'); | |
| const spinner = document.getElementById('spinner'); | |
| const apiUrl = document.getElementById('apiUrl').value; | |
| const query = input.value.trim(); | |
| if (!query) return; | |
| // Add User Message | |
| addMessage(query, 'user'); | |
| input.value = ''; | |
| // Loading State | |
| btn.disabled = true; | |
| spinner.style.display = 'block'; | |
| try { | |
| const response = await fetch(apiUrl, { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ query: query }) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`API Error: ${response.statusText}`); | |
| } | |
| const data = await response.json(); | |
| addMessage(formatResponse(data.answer), 'bot'); | |
| } catch (error) { | |
| addMessage(`⚠️ Error: ${error.message}. Please check if the API URL is correct and the server is running.`, 'bot'); | |
| } finally { | |
| btn.disabled = false; | |
| spinner.style.display = 'none'; | |
| chatBox.scrollTop = chatBox.scrollHeight; | |
| } | |
| } | |
| function addMessage(text, type) { | |
| const chatBox = document.getElementById('chatBox'); | |
| const div = document.createElement('div'); | |
| div.className = `message ${type}`; | |
| div.innerHTML = text.replace(/\n/g, '<br>'); | |
| chatBox.appendChild(div); | |
| chatBox.scrollTop = chatBox.scrollHeight; | |
| } | |
| function formatResponse(text) { | |
| // Simple markdown-like formatting for bold text | |
| return text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>'); | |
| } | |
| </script> | |
| </body> | |
| </html> |