Spaces:
Sleeping
Sleeping
| <html lang="en" dir="ltr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"> | |
| <meta name="description" content="Arjun 2.O Advanced Artificial Intelligence System engineered by Abhay Kumar."> | |
| <meta name="theme-color" content="#FF9933"> | |
| <title>Arjun 2.O - Professional Advanced AI</title> | |
| <!-- ========================================================================================= | |
| 1. EXTERNAL RESOURCES & LIBRARIES (बाहरी स्रोत और लाइब्रेरीज़) | |
| ========================================================================================= --> | |
| <!-- Preconnect for Performance --> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <!-- Professional Typography: Inter (Sans), Geist Mono (Code), Instrument Serif (Display) --> | |
| <link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Inter:wght@300;400;500;600;700;800;900&family=Geist+Mono:wght@400;500;600;700&display=swap" rel="stylesheet"> | |
| <!-- Syntax Highlighting Theme (Atom One Dark for Professional Coding Workspace) --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/atom-one-dark.min.css"> | |
| <!-- Core External Scripts for Data Extraction and Rendering --> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.6.0/mammoth.browser.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/12.0.1/marked.min.js"></script> | |
| <!-- ========================================================================================= | |
| 2. MASSIVE CSS ARCHITECTURE (विस्तृत स्टाइलिंग और एनीमेशन) | |
| ========================================================================================= --> | |
| <style> | |
| /* --------------------------------------------------------------------------------------- | |
| A. CSS VARIABLES & DESIGN TOKENS | |
| --------------------------------------------------------------------------------------- */ | |
| :root { | |
| /* Branding: Professional Tiranga Theme */ | |
| --brand-saffron: #FF9933; | |
| --brand-saffron-light: rgba(255, 153, 51, 0.12); | |
| --brand-saffron-hover: #e68a2e; | |
| --brand-saffron-active: #cc7a29; | |
| --brand-white: #FFFFFF; | |
| --brand-white-glass: rgba(255, 255, 255, 0.85); | |
| --brand-green: #138808; | |
| --brand-green-light: rgba(19, 136, 8, 0.12); | |
| --brand-green-hover: #0f6e06; | |
| --brand-green-active: #0c5905; | |
| /* Core UI Colors */ | |
| --bg-primary: #ffffff; | |
| --bg-secondary: #f8f9fa; | |
| --bg-tertiary: #f1f3f5; | |
| --bg-glass: rgba(255, 255, 255, 0.75); | |
| --bg-overlay: rgba(0, 0, 0, 0.4); | |
| /* Text Hierarchy */ | |
| --text-primary: #111827; | |
| --text-secondary: #4b5563; | |
| --text-tertiary: #9ca3af; | |
| --text-inverse: #ffffff; | |
| /* Border & Dividers */ | |
| --border-light: rgba(0, 0, 0, 0.08); | |
| --border-medium: rgba(0, 0, 0, 0.15); | |
| --border-focus: rgba(255, 153, 51, 0.35); | |
| /* Depth & Elevation (Shadows) */ | |
| --shadow-xs: 0 1px 2px rgba(0,0,0,0.04); | |
| --shadow-sm: 0 1px 3px rgba(0,0,0,0.05), 0 1px 2px rgba(0,0,0,0.03); | |
| --shadow-md: 0 4px 6px -1px rgba(0,0,0,0.05), 0 2px 4px -1px rgba(0,0,0,0.03); | |
| --shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.05), 0 4px 6px -2px rgba(0,0,0,0.025); | |
| --shadow-xl: 0 20px 25px -5px rgba(0,0,0,0.05), 0 10px 10px -5px rgba(0,0,0,0.02); | |
| --shadow-glow-saffron: 0 0 15px rgba(255, 153, 51, 0.4); | |
| --shadow-glow-green: 0 0 15px rgba(19, 136, 8, 0.4); | |
| /* Typography Scale */ | |
| --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; | |
| --font-mono: 'Geist Mono', Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; | |
| --font-serif: 'Instrument Serif', Georgia, Cambria, "Times New Roman", Times, serif; | |
| --text-xs: 0.75rem; | |
| --text-sm: 0.875rem; | |
| --text-base: 1rem; | |
| --text-lg: 1.125rem; | |
| --text-xl: 1.25rem; | |
| --text-2xl: 1.5rem; | |
| --text-3xl: 1.875rem; | |
| --text-4xl: 2.25rem; | |
| /* Border Radii */ | |
| --radius-xs: 4px; | |
| --radius-sm: 8px; | |
| --radius-md: 12px; | |
| --radius-lg: 16px; | |
| --radius-xl: 24px; | |
| --radius-2xl: 32px; | |
| --radius-full: 9999px; | |
| /* Transitions & Easing */ | |
| --ease-fast: 0.15s cubic-bezier(0.4, 0, 0.2, 1); | |
| --ease-smooth: 0.3s cubic-bezier(0.4, 0, 0.2, 1); | |
| --ease-spring: 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); | |
| --ease-bounce: 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55); | |
| /* Z-Index Hierarchy */ | |
| --z-bg: -1; | |
| --z-base: 1; | |
| --z-overlay: 10; | |
| --z-dropdown: 50; | |
| --z-sidebar: 100; | |
| --z-modal: 5000; | |
| --z-toast: 9000; | |
| --z-live-mode: 9999; | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| B. RESET & GLOBAL BASE | |
| --------------------------------------------------------------------------------------- */ | |
| *, *::before, *::after { | |
| box-sizing: border-box; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| html { | |
| font-size: 16px; | |
| -webkit-text-size-adjust: 100%; | |
| } | |
| body { | |
| height: 100dvh; | |
| width: 100vw; | |
| overflow: hidden; | |
| background-color: var(--bg-primary); | |
| color: var(--text-primary); | |
| font-family: var(--font-sans); | |
| line-height: 1.5; | |
| -webkit-font-smoothing: antialiased; | |
| -moz-osx-font-smoothing: grayscale; | |
| } | |
| button, input, textarea, select { | |
| font-family: inherit; | |
| color: inherit; | |
| } | |
| a { | |
| color: inherit; | |
| text-decoration: none; | |
| } | |
| img { | |
| max-width: 100%; | |
| height: auto; | |
| display: block; | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| C. AMBIENT BACKGROUND EFFECTS | |
| --------------------------------------------------------------------------------------- */ | |
| .ambient-environment { | |
| position: fixed; | |
| top: 0; left: 0; right: 0; bottom: 0; | |
| z-index: var(--z-bg); | |
| overflow: hidden; | |
| pointer-events: none; | |
| background: linear-gradient(135deg, var(--brand-saffron-light) 0%, #ffffff 50%, var(--brand-green-light) 100%); | |
| } | |
| .ambient-orb { | |
| position: absolute; | |
| border-radius: 50%; | |
| filter: blur(120px); | |
| opacity: 0.45; | |
| animation: orbFloat 35s ease-in-out infinite alternate; | |
| will-change: transform; | |
| } | |
| .orb-top-left { | |
| width: 650px; | |
| height: 650px; | |
| background: radial-gradient(circle, rgba(255,153,51,0.25) 0%, transparent 70%); | |
| top: -200px; | |
| left: -150px; | |
| } | |
| .orb-bottom-right { | |
| width: 550px; | |
| height: 550px; | |
| background: radial-gradient(circle, rgba(19,136,8,0.2) 0%, transparent 70%); | |
| bottom: -150px; | |
| right: -100px; | |
| animation-delay: -15s; | |
| animation-duration: 40s; | |
| } | |
| @keyframes orbFloat { | |
| 0% { transform: translate(0, 0) scale(1); } | |
| 33% { transform: translate(60px, 80px) scale(1.1); } | |
| 66% { transform: translate(-40px, 50px) scale(0.95); } | |
| 100% { transform: translate(70px, -30px) scale(1.05); } | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| D. TOAST NOTIFICATION SYSTEM | |
| --------------------------------------------------------------------------------------- */ | |
| .toast-wrapper { | |
| position: absolute; | |
| top: 24px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| z-index: var(--z-toast); | |
| display: flex; | |
| flex-direction: column; | |
| gap: 12px; | |
| pointer-events: none; | |
| } | |
| .toast-notification { | |
| background: var(--text-primary); | |
| color: var(--text-inverse); | |
| padding: 14px 28px; | |
| border-radius: var(--radius-full); | |
| font-size: var(--text-sm); | |
| font-weight: 600; | |
| box-shadow: var(--shadow-lg); | |
| animation: toastSlideIn var(--ease-spring) forwards, toastFadeOut 0.4s 2.6s forwards; | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .toast-notification svg { | |
| width: 18px; | |
| height: 18px; | |
| stroke-width: 2.5; | |
| } | |
| @keyframes toastSlideIn { | |
| from { opacity: 0; transform: translateY(-30px) scale(0.9); } | |
| to { opacity: 1; transform: translateY(0) scale(1); } | |
| } | |
| @keyframes toastFadeOut { | |
| from { opacity: 1; transform: translateY(0); } | |
| to { opacity: 0; transform: translateY(-20px); } | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| E. INITIAL WELCOME OVERLAY | |
| --------------------------------------------------------------------------------------- */ | |
| .startup-overlay { | |
| position: fixed; | |
| inset: 0; | |
| background: var(--brand-white-glass); | |
| backdrop-filter: blur(25px); | |
| -webkit-backdrop-filter: blur(25px); | |
| z-index: calc(var(--z-toast) + 100); | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| text-align: center; | |
| padding: 24px; | |
| transition: opacity var(--ease-smooth), visibility var(--ease-smooth); | |
| } | |
| .startup-overlay.hidden { | |
| opacity: 0; | |
| visibility: hidden; | |
| pointer-events: none; | |
| } | |
| .startup-logo-container { | |
| position: relative; | |
| margin-bottom: 32px; | |
| animation: popIn var(--ease-spring) 0.2s both; | |
| } | |
| .startup-logo-container img { | |
| width: 140px; | |
| height: 140px; | |
| border-radius: var(--radius-xl); | |
| object-fit: cover; | |
| box-shadow: var(--shadow-xl); | |
| border: 3px solid var(--bg-primary); | |
| position: relative; | |
| z-index: 2; | |
| } | |
| .startup-logo-glow { | |
| position: absolute; | |
| inset: -15px; | |
| background: linear-gradient(135deg, var(--brand-saffron), var(--brand-green)); | |
| filter: blur(25px); | |
| opacity: 0.4; | |
| border-radius: var(--radius-full); | |
| z-index: 1; | |
| animation: pulseGlow 3s infinite alternate; | |
| } | |
| @keyframes pulseGlow { | |
| from { opacity: 0.3; transform: scale(0.95); } | |
| to { opacity: 0.6; transform: scale(1.05); } | |
| } | |
| @keyframes popIn { | |
| from { opacity: 0; transform: scale(0.8); } | |
| to { opacity: 1; transform: scale(1); } | |
| } | |
| .startup-title { | |
| font-family: var(--font-sans); | |
| font-size: var(--text-4xl); | |
| font-weight: 900; | |
| color: var(--text-primary); | |
| letter-spacing: -1.5px; | |
| margin-bottom: 16px; | |
| animation: slideUp var(--ease-smooth) 0.3s both; | |
| } | |
| .startup-desc { | |
| font-size: var(--text-lg); | |
| color: var(--text-secondary); | |
| line-height: 1.6; | |
| max-width: 500px; | |
| margin-bottom: 40px; | |
| animation: slideUp var(--ease-smooth) 0.4s both; | |
| } | |
| .btn-startup-launch { | |
| padding: 18px 48px; | |
| background: var(--text-primary); | |
| color: var(--text-inverse); | |
| border: none; | |
| border-radius: var(--radius-xl); | |
| font-size: var(--text-lg); | |
| font-weight: 700; | |
| cursor: pointer; | |
| transition: var(--ease-spring); | |
| box-shadow: 0 10px 25px rgba(0,0,0,0.15); | |
| animation: slideUp var(--ease-smooth) 0.5s both; | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| } | |
| .btn-startup-launch:hover { | |
| background: #000000; | |
| transform: translateY(-4px) scale(1.02); | |
| box-shadow: 0 15px 35px rgba(0,0,0,0.25); | |
| } | |
| @keyframes slideUp { | |
| from { opacity: 0; transform: translateY(20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| F. CORE APPLICATION LAYOUT | |
| --------------------------------------------------------------------------------------- */ | |
| .app-root { | |
| position: relative; | |
| z-index: var(--z-base); | |
| display: flex; | |
| height: 100dvh; | |
| width: 100vw; | |
| overflow: hidden; | |
| background: var(--bg-glass); | |
| backdrop-filter: blur(30px); | |
| -webkit-backdrop-filter: blur(30px); | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| G. SIDEBAR NAVIGATION | |
| --------------------------------------------------------------------------------------- */ | |
| .sidebar-container { | |
| width: 320px; | |
| display: flex; | |
| flex-direction: column; | |
| background: rgba(248, 249, 250, 0.85); | |
| border-right: 1px solid var(--border-light); | |
| flex-shrink: 0; | |
| z-index: var(--z-sidebar); | |
| transition: transform var(--ease-smooth); | |
| backdrop-filter: blur(15px); | |
| } | |
| .sidebar-header { | |
| padding: 28px 24px; | |
| border-bottom: 1px solid var(--border-light); | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| .brand-identity { | |
| display: flex; | |
| align-items: center; | |
| gap: 14px; | |
| text-decoration: none; | |
| } | |
| .brand-identity img { | |
| width: 52px; | |
| height: 52px; | |
| border-radius: var(--radius-md); | |
| object-fit: cover; | |
| box-shadow: var(--shadow-sm); | |
| border: 2px solid var(--bg-primary); | |
| transition: transform var(--ease-spring); | |
| } | |
| .brand-identity:hover img { | |
| transform: scale(1.08) rotate(-3deg); | |
| } | |
| .brand-typography { | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .brand-name { | |
| font-family: var(--font-sans); | |
| font-weight: 900; | |
| font-size: 20px; | |
| color: var(--text-primary); | |
| letter-spacing: -0.5px; | |
| line-height: 1.1; | |
| } | |
| .brand-edition { | |
| font-size: 11px; | |
| font-weight: 800; | |
| letter-spacing: 1.5px; | |
| text-transform: uppercase; | |
| background: linear-gradient(90deg, var(--brand-saffron), var(--brand-green)); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| margin-top: 4px; | |
| } | |
| .btn-mobile-close { | |
| display: none; | |
| background: rgba(0,0,0,0.05); | |
| border: none; | |
| width: 36px; | |
| height: 36px; | |
| border-radius: 50%; | |
| color: var(--text-primary); | |
| cursor: pointer; | |
| align-items: center; | |
| justify-content: center; | |
| transition: var(--ease-fast); | |
| } | |
| .btn-mobile-close:hover { | |
| background: rgba(239, 68, 68, 0.15); | |
| color: #ef4444; | |
| } | |
| /* Sidebar Content & Scrollbar */ | |
| .sidebar-body { | |
| flex: 1; | |
| overflow-y: auto; | |
| padding: 24px; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 28px; | |
| } | |
| .sidebar-body::-webkit-scrollbar { width: 5px; } | |
| .sidebar-body::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.1); border-radius: 10px; } | |
| .sidebar-body::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.2); } | |
| /* Authentication UI Widget */ | |
| .auth-widget { | |
| background: var(--bg-primary); | |
| border: 1px solid var(--border-light); | |
| border-radius: var(--radius-lg); | |
| padding: 20px; | |
| box-shadow: var(--shadow-sm); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .btn-secure-connect { | |
| width: 100%; | |
| padding: 14px; | |
| background: var(--text-primary); | |
| color: var(--text-inverse); | |
| border: none; | |
| border-radius: var(--radius-md); | |
| font-size: var(--text-sm); | |
| font-weight: 700; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 10px; | |
| transition: var(--ease-fast); | |
| } | |
| .btn-secure-connect:hover { | |
| background: #000000; | |
| transform: translateY(-2px); | |
| box-shadow: var(--shadow-md); | |
| } | |
| .user-profile-display { | |
| display: none; | |
| align-items: center; | |
| gap: 14px; | |
| } | |
| .avatar-badge { | |
| width: 44px; | |
| height: 44px; | |
| border-radius: var(--radius-full); | |
| background: linear-gradient(135deg, var(--brand-saffron), var(--brand-green)); | |
| color: var(--brand-white); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-weight: 800; | |
| font-size: 18px; | |
| box-shadow: var(--shadow-sm); | |
| border: 2px solid var(--bg-primary); | |
| } | |
| .user-details { | |
| flex: 1; | |
| overflow: hidden; | |
| } | |
| .user-email-id { | |
| font-size: 14px; | |
| font-weight: 700; | |
| color: var(--text-primary); | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| .user-clearance-level { | |
| font-size: 11px; | |
| color: var(--brand-green); | |
| font-weight: 600; | |
| margin-top: 2px; | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| } | |
| .user-clearance-level::before { | |
| content: ''; | |
| display: block; | |
| width: 6px; | |
| height: 6px; | |
| border-radius: 50%; | |
| background: var(--brand-green); | |
| } | |
| .btn-system-logout { | |
| background: rgba(239, 68, 68, 0.1); | |
| color: #ef4444; | |
| border: none; | |
| width: 36px; | |
| height: 36px; | |
| border-radius: var(--radius-md); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| transition: var(--ease-fast); | |
| } | |
| .btn-system-logout:hover { | |
| background: #ef4444; | |
| color: #ffffff; | |
| } | |
| /* Branding Box at Bottom */ | |
| .developer-credit-box { | |
| background: var(--bg-primary); | |
| border: 1px solid var(--border-light); | |
| border-radius: var(--radius-lg); | |
| padding: 28px 20px; | |
| text-align: center; | |
| box-shadow: var(--shadow-sm); | |
| margin-top: auto; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .developer-credit-box::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; left: 0; right: 0; height: 4px; | |
| background: linear-gradient(90deg, var(--brand-saffron), var(--brand-white), var(--brand-green)); | |
| } | |
| .developer-credit-box img { | |
| width: 72px; | |
| height: 72px; | |
| border-radius: var(--radius-lg); | |
| object-fit: cover; | |
| margin-bottom: 16px; | |
| box-shadow: var(--shadow-md); | |
| border: 1px solid var(--border-light); | |
| } | |
| .dev-box-title { | |
| font-size: 18px; | |
| font-weight: 800; | |
| color: var(--text-primary); | |
| margin-bottom: 6px; | |
| } | |
| .dev-box-subtitle { | |
| font-size: 11px; | |
| font-weight: 800; | |
| color: var(--text-tertiary); | |
| letter-spacing: 1px; | |
| text-transform: uppercase; | |
| } | |
| /* Clear Memory Button */ | |
| .btn-erase-memory { | |
| width: 100%; | |
| padding: 16px; | |
| border-radius: var(--radius-md); | |
| background: var(--bg-primary); | |
| border: 1px solid var(--border-light); | |
| color: var(--text-secondary); | |
| font-size: var(--text-sm); | |
| font-weight: 700; | |
| cursor: pointer; | |
| transition: var(--ease-fast); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 10px; | |
| } | |
| .btn-erase-memory:hover { | |
| background: #fee2e2; | |
| color: #ef4444; | |
| border-color: #fca5a5; | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| H. MAIN CHAT INTERFACE | |
| --------------------------------------------------------------------------------------- */ | |
| .main-chat-wrapper { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| position: relative; | |
| min-width: 320px; | |
| transition: width var(--ease-smooth); | |
| background: transparent; | |
| } | |
| /* Chat Header */ | |
| .chat-top-bar { | |
| padding: 18px 32px; | |
| border-bottom: 1px solid var(--border-light); | |
| background: rgba(255, 255, 255, 0.85); | |
| backdrop-filter: blur(15px); | |
| -webkit-backdrop-filter: blur(15px); | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| z-index: var(--z-overlay); | |
| } | |
| .top-bar-left { | |
| display: flex; | |
| align-items: center; | |
| gap: 16px; | |
| } | |
| .btn-hamburger { | |
| display: none; | |
| background: var(--bg-primary); | |
| border: 1px solid var(--border-light); | |
| cursor: pointer; | |
| color: var(--text-primary); | |
| width: 40px; | |
| height: 40px; | |
| border-radius: var(--radius-sm); | |
| align-items: center; | |
| justify-content: center; | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .system-status-pill { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| font-size: var(--text-sm); | |
| font-weight: 700; | |
| color: var(--text-primary); | |
| padding: 8px 18px; | |
| background: var(--bg-secondary); | |
| border-radius: var(--radius-full); | |
| border: 1px solid var(--border-light); | |
| box-shadow: inset 0 1px 2px rgba(255,255,255,0.5); | |
| } | |
| .pulse-dot { | |
| width: 10px; | |
| height: 10px; | |
| border-radius: 50%; | |
| background: var(--brand-green); | |
| box-shadow: 0 0 0 3px rgba(19, 136, 8, 0.2); | |
| animation: statusPulse 2s infinite; | |
| } | |
| @keyframes statusPulse { | |
| 0% { box-shadow: 0 0 0 0 rgba(19,136,8,0.4); } | |
| 70% { box-shadow: 0 0 0 6px rgba(19,136,8,0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(19,136,8,0); } | |
| } | |
| /* LIVE MODE TOGGLE BUTTON */ | |
| .btn-activate-live { | |
| background: linear-gradient(135deg, #ef4444 0%, #b91c1c 100%); | |
| color: white; | |
| border: none; | |
| padding: 10px 20px; | |
| border-radius: var(--radius-full); | |
| font-size: 14px; | |
| font-weight: 800; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| cursor: pointer; | |
| box-shadow: 0 4px 15px rgba(239, 68, 68, 0.35); | |
| transition: var(--ease-spring); | |
| letter-spacing: 0.5px; | |
| } | |
| .btn-activate-live:hover { | |
| transform: translateY(-2px) scale(1.02); | |
| box-shadow: 0 8px 25px rgba(239, 68, 68, 0.45); | |
| } | |
| .btn-activate-live svg { | |
| width: 18px; | |
| height: 18px; | |
| animation: liveBlink 1.5s infinite; | |
| } | |
| @keyframes liveBlink { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0.4; } | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| I. CONVERSATION SCROLL AREA & WELCOME | |
| --------------------------------------------------------------------------------------- */ | |
| .chat-scroll-area { | |
| flex: 1; | |
| overflow-y: auto; | |
| padding: 40px 10%; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 36px; | |
| scroll-behavior: smooth; | |
| position: relative; | |
| } | |
| .chat-scroll-area::-webkit-scrollbar { width: 6px; } | |
| .chat-scroll-area::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 10px; } | |
| /* Internal Welcome Hero */ | |
| .chat-hero-section { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| text-align: center; | |
| padding: 60px 20px; | |
| margin: auto; | |
| animation: slideUpFade 0.7s var(--ease-spring) both; | |
| max-width: 750px; | |
| } | |
| .hero-avatar-wrapper { | |
| position: relative; | |
| margin-bottom: 36px; | |
| } | |
| .hero-avatar-wrapper img { | |
| width: 100px; | |
| height: 100px; | |
| border-radius: var(--radius-xl); | |
| object-fit: cover; | |
| box-shadow: var(--shadow-xl); | |
| border: 3px solid var(--bg-primary); | |
| position: relative; | |
| z-index: 2; | |
| } | |
| .hero-avatar-glow { | |
| position: absolute; | |
| inset: -12px; | |
| background: linear-gradient(135deg, var(--brand-saffron), var(--brand-green)); | |
| filter: blur(25px); | |
| opacity: 0.35; | |
| border-radius: 40px; | |
| z-index: 1; | |
| } | |
| .hero-greeting { | |
| font-size: 42px; | |
| font-weight: 900; | |
| letter-spacing: -1.5px; | |
| margin-bottom: 18px; | |
| color: var(--text-primary); | |
| } | |
| .hero-description { | |
| font-size: 17px; | |
| color: var(--text-secondary); | |
| line-height: 1.6; | |
| margin-bottom: 40px; | |
| font-weight: 400; | |
| } | |
| .guest-warning-badge { | |
| font-size: 13px; | |
| font-weight: 700; | |
| color: #ef4444; | |
| background: #fee2e2; | |
| padding: 8px 16px; | |
| border-radius: var(--radius-full); | |
| margin-bottom: 32px; | |
| display: none; | |
| align-items: center; | |
| gap: 8px; | |
| border: 1px solid #fca5a5; | |
| } | |
| /* Action Suggestions Grid */ | |
| .prompt-suggestions-grid { | |
| display: grid; | |
| grid-template-columns: repeat(2, 1fr); | |
| gap: 20px; | |
| width: 100%; | |
| } | |
| .prompt-card { | |
| background: rgba(255, 255, 255, 0.7); | |
| backdrop-filter: blur(15px); | |
| border: 1px solid var(--border-light); | |
| border-radius: var(--radius-lg); | |
| padding: 24px; | |
| cursor: pointer; | |
| text-align: left; | |
| transition: var(--ease-smooth); | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .prompt-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: var(--shadow-lg); | |
| border-color: var(--brand-saffron); | |
| background: rgba(255, 255, 255, 0.95); | |
| } | |
| .prompt-icon { | |
| font-size: 28px; | |
| margin-bottom: 14px; | |
| display: inline-block; | |
| } | |
| .prompt-title { | |
| font-size: 15px; | |
| font-weight: 800; | |
| color: var(--text-primary); | |
| margin-bottom: 8px; | |
| } | |
| .prompt-desc { | |
| font-size: 13px; | |
| color: var(--text-secondary); | |
| line-height: 1.5; | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| J. CHAT MESSAGE BUBBLES & ATTACHMENT PREVIEWS | |
| --------------------------------------------------------------------------------------- */ | |
| .chat-message-row { | |
| display: flex; | |
| gap: 20px; | |
| max-width: 88%; | |
| animation: messagePopIn 0.5s var(--ease-spring) both; | |
| } | |
| @keyframes messagePopIn { | |
| from { opacity: 0; transform: translateY(25px) scale(0.97); } | |
| to { opacity: 1; transform: none; } | |
| } | |
| .chat-message-row.user-msg { | |
| flex-direction: row-reverse; | |
| align-self: flex-end; | |
| } | |
| .chat-message-row.bot-msg { | |
| align-self: flex-start; | |
| } | |
| .msg-avatar { | |
| width: 42px; | |
| height: 42px; | |
| border-radius: var(--radius-sm); | |
| flex-shrink: 0; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 15px; | |
| font-weight: 800; | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .user-msg .msg-avatar { | |
| background: var(--text-primary); | |
| color: var(--brand-white); | |
| } | |
| .bot-msg .msg-avatar { | |
| background: var(--bg-primary); | |
| border: 1px solid var(--border-light); | |
| padding: 3px; | |
| } | |
| .bot-msg .msg-avatar img { | |
| width: 100%; | |
| height: 100%; | |
| border-radius: 6px; | |
| object-fit: cover; | |
| } | |
| .msg-content-column { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| max-width: 100%; | |
| min-width: 0; /* Prevents flex blowout */ | |
| } | |
| .user-msg .msg-content-column { | |
| align-items: flex-end; | |
| } | |
| /* NEW: In-Message File Preview Cards */ | |
| .chat-in-bubble-img { | |
| max-width: 300px; | |
| max-height: 300px; | |
| border-radius: var(--radius-md); | |
| object-fit: cover; | |
| border: 2px solid rgba(255,255,255,0.2); | |
| box-shadow: var(--shadow-md); | |
| margin-bottom: 8px; | |
| } | |
| .chat-file-card { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| background: rgba(255,255,255,0.15); | |
| border: 1px solid rgba(255,255,255,0.3); | |
| padding: 12px 16px; | |
| border-radius: var(--radius-md); | |
| margin-bottom: 8px; | |
| backdrop-filter: blur(5px); | |
| max-width: 350px; | |
| } | |
| .chat-file-card .icon { | |
| font-size: 24px; | |
| background: rgba(0,0,0,0.1); | |
| width: 40px; height: 40px; | |
| display: flex; align-items: center; justify-content: center; | |
| border-radius: var(--radius-sm); | |
| } | |
| .chat-file-card .name { | |
| font-size: 13px; | |
| font-weight: 600; | |
| color: var(--brand-white); | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| .chat-bubble { | |
| padding: 18px 24px; | |
| font-size: 15px; | |
| line-height: 1.6; | |
| position: relative; | |
| word-wrap: break-word; | |
| overflow-wrap: anywhere; | |
| } | |
| .user-msg .chat-bubble { | |
| background: var(--text-primary); | |
| color: var(--text-inverse); | |
| border-radius: 24px 24px 6px 24px; | |
| box-shadow: var(--shadow-md); | |
| } | |
| .bot-msg .chat-bubble { | |
| background: var(--bg-primary); | |
| color: var(--text-primary); | |
| border: 1px solid var(--border-light); | |
| border-radius: 6px 24px 24px 24px; | |
| box-shadow: var(--shadow-sm); | |
| width: 100%; | |
| } | |
| /* Bot Action Buttons (TTS & Copy) */ | |
| .bot-actions-row { | |
| display: flex; | |
| gap: 10px; | |
| margin-top: 8px; | |
| padding-left: 14px; | |
| opacity: 0; | |
| transition: opacity var(--ease-smooth); | |
| flex-wrap: wrap; | |
| } | |
| .bot-msg:hover .bot-actions-row { opacity: 1; } | |
| .btn-bot-action { | |
| background: var(--bg-secondary); | |
| border: 1px solid var(--border-light); | |
| color: var(--text-secondary); | |
| font-size: 12px; | |
| font-weight: 700; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| padding: 8px 16px; | |
| border-radius: var(--radius-full); | |
| transition: var(--ease-fast); | |
| } | |
| .btn-bot-action:hover { | |
| background: var(--bg-primary); | |
| color: var(--text-primary); | |
| transform: translateY(-2px); | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .btn-bot-action.action-tts { | |
| color: var(--brand-green-hover); | |
| border-color: rgba(19, 136, 8, 0.25); | |
| background: var(--brand-green-light); | |
| } | |
| .btn-bot-action.action-tts:hover { | |
| background: rgba(19, 136, 8, 0.2); | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| K. MARKDOWN & CODE RENDERING STYLES | |
| --------------------------------------------------------------------------------------- */ | |
| .chat-bubble p { margin-bottom: 16px; } | |
| .chat-bubble p:last-child { margin-bottom: 0; } | |
| .chat-bubble strong { font-weight: 800; color: inherit; } | |
| .chat-bubble code { | |
| font-family: var(--font-mono); | |
| background: rgba(0,0,0,0.06); | |
| padding: 4px 8px; | |
| border-radius: 6px; | |
| font-size: 0.85em; | |
| color: #d946ef; | |
| font-weight: 600; | |
| } | |
| .user-msg .chat-bubble code { | |
| background: rgba(255,255,255,0.2); | |
| color: var(--brand-white); | |
| } | |
| .chat-bubble img { | |
| max-width: 100%; | |
| border-radius: var(--radius-md); | |
| margin: 16px 0; | |
| box-shadow: var(--shadow-lg); | |
| border: 1px solid var(--border-light); | |
| display: block; | |
| } | |
| .chat-bubble pre { | |
| background: #282c34; | |
| color: #abb2bf; | |
| padding: 20px; | |
| border-radius: var(--radius-md); | |
| overflow-x: auto; | |
| margin: 20px 0; | |
| font-family: var(--font-mono); | |
| font-size: 14px; | |
| line-height: 1.6; | |
| border: 1px solid #181a1f; | |
| } | |
| .chat-bubble pre code { | |
| background: transparent; | |
| color: inherit; | |
| padding: 0; | |
| font-weight: 400; | |
| } | |
| /* Streaming "Generating Code..." Component */ | |
| .streaming-code-container { | |
| background: #1e1e2e; | |
| border-radius: var(--radius-md); | |
| border: 1px solid #313244; | |
| overflow: hidden; | |
| margin: 20px 0; | |
| box-shadow: var(--shadow-lg); | |
| } | |
| .streaming-code-header { | |
| background: #11111b; | |
| padding: 12px 20px; | |
| font-size: 12px; | |
| font-weight: 700; | |
| color: #a6adc8; | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| border-bottom: 1px solid #313244; | |
| font-family: var(--font-mono); | |
| text-transform: uppercase; | |
| letter-spacing: 1.5px; | |
| } | |
| .loading-ring { | |
| width: 16px; | |
| height: 16px; | |
| border: 2px solid rgba(255,255,255,0.1); | |
| border-top-color: var(--brand-saffron); | |
| border-radius: 50%; | |
| animation: ringSpin 1s cubic-bezier(0.68, -0.55, 0.265, 1.55) infinite; | |
| } | |
| @keyframes ringSpin { to { transform: rotate(360deg); } } | |
| .streaming-code-container pre { | |
| margin: 0; | |
| background: transparent; | |
| border: none; | |
| border-radius: 0; | |
| } | |
| /* Final Workspace Execute Card */ | |
| .workspace-execute-card { | |
| background: var(--bg-secondary); | |
| border: 1px solid var(--border-light); | |
| border-radius: var(--radius-md); | |
| padding: 20px; | |
| margin: 20px 0; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| box-shadow: var(--shadow-sm); | |
| transition: var(--ease-smooth); | |
| } | |
| .workspace-execute-card:hover { | |
| border-color: var(--border-medium); | |
| box-shadow: var(--shadow-md); | |
| } | |
| .ws-card-left { | |
| display: flex; | |
| align-items: center; | |
| gap: 16px; | |
| } | |
| .ws-card-icon-box { | |
| width: 54px; | |
| height: 54px; | |
| border-radius: var(--radius-sm); | |
| background: var(--bg-primary); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 26px; | |
| box-shadow: var(--shadow-sm); | |
| border: 1px solid var(--border-light); | |
| color: var(--text-primary); | |
| } | |
| .ws-card-details h4 { | |
| font-size: 16px; | |
| font-weight: 800; | |
| margin-bottom: 4px; | |
| color: var(--text-primary); | |
| } | |
| .ws-card-details p { | |
| font-size: 12px; | |
| color: var(--text-secondary); | |
| font-family: var(--font-mono); | |
| text-transform: uppercase; | |
| letter-spacing: 0.5px; | |
| font-weight: 600; | |
| } | |
| .btn-launch-workspace { | |
| padding: 12px 24px; | |
| background: var(--text-primary); | |
| color: var(--brand-white); | |
| border: none; | |
| border-radius: var(--radius-sm); | |
| font-size: 14px; | |
| font-weight: 700; | |
| cursor: pointer; | |
| transition: var(--ease-spring); | |
| } | |
| .btn-launch-workspace:hover { | |
| transform: scale(1.05); | |
| background: var(--brand-saffron); | |
| box-shadow: 0 6px 15px rgba(255,153,51,0.35); | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| L. INPUT AREA & CONTROLS (BOTTOM BAR) | |
| --------------------------------------------------------------------------------------- */ | |
| .input-dock { | |
| flex-shrink: 0; | |
| padding: 0 40px 32px; | |
| background: transparent; | |
| position: relative; | |
| z-index: 20; | |
| } | |
| .input-master-container { | |
| display: flex; | |
| flex-direction: column; | |
| background: var(--bg-glass); | |
| backdrop-filter: blur(30px); | |
| -webkit-backdrop-filter: blur(30px); | |
| border: 1px solid var(--border-light); | |
| border-radius: var(--radius-2xl); | |
| box-shadow: var(--shadow-xl); | |
| transition: var(--ease-smooth); | |
| } | |
| .input-master-container:focus-within { | |
| border-color: var(--brand-saffron); | |
| box-shadow: 0 20px 40px -5px rgba(255,153,51,0.15), 0 0 0 4px var(--brand-saffron-light); | |
| } | |
| /* Uploaded File Preview Strip */ | |
| .upload-preview-bar { | |
| display: none; | |
| padding: 20px 28px 0; | |
| align-items: center; | |
| gap: 16px; | |
| } | |
| .upload-preview-bar.visible { | |
| display: flex; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| .upload-thumb { | |
| width: 52px; | |
| height: 52px; | |
| object-fit: cover; | |
| border-radius: var(--radius-sm); | |
| border: 1px solid var(--border-light); | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| background: var(--bg-tertiary); | |
| font-size: 24px; | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .upload-meta { | |
| flex: 1; | |
| } | |
| .upload-filename { | |
| font-size: 14px; | |
| font-weight: 700; | |
| color: var(--text-primary); | |
| max-width: 250px; | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| .upload-status-text { | |
| font-size: 12px; | |
| color: var(--brand-green); | |
| font-weight: 600; | |
| margin-top: 2px; | |
| } | |
| .btn-discard-upload { | |
| background: rgba(239, 68, 68, 0.1); | |
| border: none; | |
| width: 32px; | |
| height: 32px; | |
| border-radius: 50%; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: #ef4444; | |
| transition: var(--ease-fast); | |
| } | |
| .btn-discard-upload:hover { | |
| background: #ef4444; | |
| color: #fff; | |
| } | |
| /* Input Tools Row */ | |
| .input-tools-row { | |
| display: flex; | |
| align-items: flex-end; | |
| gap: 12px; | |
| padding: 14px 20px 14px 24px; | |
| } | |
| .main-textarea { | |
| flex: 1; | |
| border: none; | |
| outline: none; | |
| background: transparent; | |
| font-family: var(--font-sans); | |
| font-size: 16px; | |
| color: var(--text-primary); | |
| line-height: 1.5; | |
| resize: none; | |
| max-height: 200px; | |
| min-height: 24px; | |
| padding: 12px 0; | |
| margin: 0 8px; | |
| font-weight: 500; | |
| } | |
| .main-textarea::placeholder { | |
| color: var(--text-tertiary); | |
| font-weight: 400; | |
| } | |
| /* Attachment Dropdown Menu (Gemini Style) */ | |
| .attachment-module { | |
| position: relative; | |
| } | |
| .btn-tool-icon { | |
| width: 44px; | |
| height: 44px; | |
| border-radius: var(--radius-md); | |
| background: transparent; | |
| border: none; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| color: var(--text-secondary); | |
| transition: var(--ease-fast); | |
| position: relative; | |
| } | |
| .btn-tool-icon:hover { | |
| background: var(--bg-tertiary); | |
| color: var(--text-primary); | |
| } | |
| .btn-tool-icon svg { | |
| width: 24px; | |
| height: 24px; | |
| stroke-width: 2; | |
| } | |
| .attachment-dropdown { | |
| position: absolute; | |
| bottom: 60px; | |
| left: 0; | |
| background: rgba(255,255,255,0.95); | |
| backdrop-filter: blur(25px); | |
| -webkit-backdrop-filter: blur(25px); | |
| border: 1px solid var(--border-light); | |
| border-radius: var(--radius-lg); | |
| padding: 10px; | |
| box-shadow: var(--shadow-xl); | |
| display: none; | |
| flex-direction: column; | |
| gap: 6px; | |
| z-index: var(--z-dropdown); | |
| min-width: 220px; | |
| transform: translateY(15px) scale(0.95); | |
| opacity: 0; | |
| transition: all var(--ease-fast); | |
| transform-origin: bottom left; | |
| } | |
| .attachment-dropdown.visible { | |
| display: flex; | |
| transform: translateY(0) scale(1); | |
| opacity: 1; | |
| } | |
| .dropdown-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 14px; | |
| padding: 14px 18px; | |
| border-radius: var(--radius-sm); | |
| cursor: pointer; | |
| font-size: 15px; | |
| font-weight: 600; | |
| color: var(--text-primary); | |
| transition: var(--ease-fast); | |
| } | |
| .dropdown-item:hover { | |
| background: var(--bg-tertiary); | |
| color: var(--brand-saffron-hover); | |
| } | |
| .dropdown-item span.emoji-icon { | |
| font-size: 20px; | |
| } | |
| .stealth-input { | |
| display: none; | |
| } | |
| /* Smart Language Toggle & Mic */ | |
| .language-toggle-chip { | |
| font-size: 13px; | |
| font-weight: 800; | |
| color: var(--text-secondary); | |
| border: 2px solid var(--border-light); | |
| background: var(--bg-primary); | |
| border-radius: 10px; | |
| padding: 6px 10px; | |
| cursor: pointer; | |
| transition: var(--ease-smooth); | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| user-select: none; | |
| } | |
| .language-toggle-chip:hover { | |
| background: var(--brand-saffron-light); | |
| color: var(--brand-saffron-dark); | |
| border-color: var(--brand-saffron); | |
| } | |
| .language-toggle-chip.hindi-active { | |
| background: var(--brand-green-light); | |
| color: var(--brand-green-dark); | |
| border-color: var(--brand-green); | |
| } | |
| .btn-mic-tool.active-listening { | |
| color: #ffffff; | |
| background: #ef4444; | |
| animation: recordPulse 1.5s infinite; | |
| border-radius: var(--radius-full); | |
| } | |
| @keyframes recordPulse { | |
| 0% { box-shadow: 0 0 0 0 rgba(239,68,68,0.5); } | |
| 70% { box-shadow: 0 0 0 12px rgba(239,68,68,0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(239,68,68,0); } | |
| } | |
| /* Primary Send Button */ | |
| .btn-master-send { | |
| width: 48px; | |
| height: 48px; | |
| border-radius: 16px; | |
| border: none; | |
| background: linear-gradient(135deg, var(--brand-saffron) 0%, var(--brand-green) 100%); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| transition: var(--ease-spring); | |
| box-shadow: 0 6px 20px rgba(19, 136, 8, 0.25); | |
| } | |
| .btn-master-send svg { | |
| width: 20px; | |
| height: 20px; | |
| fill: white; | |
| transition: transform 0.2s; | |
| } | |
| .btn-master-send:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 10px 25px rgba(255, 153, 51, 0.4); | |
| } | |
| .btn-master-send:hover svg { | |
| transform: translate(2px, -2px); | |
| } | |
| .btn-master-send:disabled { | |
| opacity: 0.4; | |
| cursor: not-allowed; | |
| filter: grayscale(100%); | |
| transform: none; | |
| box-shadow: none; | |
| } | |
| .bottom-branding-text { | |
| text-align: center; | |
| font-size: 12px; | |
| color: var(--text-tertiary); | |
| margin-top: 16px; | |
| font-weight: 600; | |
| letter-spacing: 0.5px; | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| M. LIVE MODE FULLSCREEN OVERLAY | |
| --------------------------------------------------------------------------------------- */ | |
| .live-mode-viewport { | |
| position: fixed; | |
| inset: 0; | |
| background: rgba(255, 255, 255, 0.98); | |
| z-index: var(--z-live-mode); | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| opacity: 0; | |
| pointer-events: none; | |
| transition: opacity var(--ease-smooth); | |
| } | |
| .live-mode-viewport.active { | |
| opacity: 1; | |
| pointer-events: auto; | |
| } | |
| .btn-close-live { | |
| position: absolute; | |
| top: 40px; | |
| right: 40px; | |
| background: rgba(0,0,0,0.04); | |
| border: none; | |
| width: 56px; | |
| height: 56px; | |
| border-radius: 50%; | |
| font-size: 24px; | |
| cursor: pointer; | |
| transition: var(--ease-spring); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: var(--text-secondary); | |
| } | |
| .btn-close-live:hover { | |
| background: rgba(239, 68, 68, 0.15); | |
| color: #ef4444; | |
| transform: rotate(90deg); | |
| } | |
| .pulsing-orb-wrapper { | |
| position: relative; | |
| width: 250px; | |
| height: 250px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| margin-bottom: 50px; | |
| } | |
| .energy-core { | |
| width: 120px; | |
| height: 120px; | |
| border-radius: 50%; | |
| background: linear-gradient(135deg, var(--brand-saffron), var(--brand-green)); | |
| box-shadow: 0 0 50px rgba(19, 136, 8, 0.5); | |
| position: relative; | |
| z-index: 2; | |
| transition: transform 0.15s ease-out; | |
| } | |
| .energy-ring { | |
| position: absolute; | |
| inset: 0; | |
| border: 3px solid var(--brand-saffron); | |
| border-radius: 50%; | |
| opacity: 0; | |
| animation: energyRipple 2.5s cubic-bezier(0.4, 0, 0.2, 1) infinite; | |
| } | |
| .energy-ring:nth-child(2) { animation-delay: 0.8s; border-color: var(--brand-green); } | |
| .energy-ring:nth-child(3) { animation-delay: 1.6s; border-color: var(--text-primary); } | |
| @keyframes energyRipple { | |
| 0% { transform: scale(0.4); opacity: 1; border-width: 6px; } | |
| 100% { transform: scale(1.6); opacity: 0; border-width: 1px; } | |
| } | |
| .live-feedback-status { | |
| font-size: 28px; | |
| font-weight: 900; | |
| color: var(--text-primary); | |
| margin-bottom: 16px; | |
| font-family: var(--font-sans); | |
| letter-spacing: -0.5px; | |
| } | |
| .live-feedback-text { | |
| font-size: 18px; | |
| color: var(--text-secondary); | |
| max-width: 700px; | |
| text-align: center; | |
| line-height: 1.6; | |
| min-height: 60px; | |
| font-weight: 500; | |
| } | |
| .live-control-deck { | |
| display: flex; | |
| gap: 24px; | |
| margin-top: 50px; | |
| } | |
| .btn-live-deck { | |
| width: 76px; | |
| height: 76px; | |
| border-radius: 50%; | |
| border: none; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| box-shadow: var(--shadow-lg); | |
| transition: var(--ease-spring); | |
| } | |
| .btn-live-deck.mic-control { | |
| background: var(--bg-primary); | |
| border: 3px solid var(--border-light); | |
| color: var(--text-primary); | |
| } | |
| .btn-live-deck.mic-control:hover { | |
| transform: translateY(-6px); | |
| border-color: var(--brand-saffron); | |
| color: var(--brand-saffron); | |
| box-shadow: var(--shadow-xl); | |
| } | |
| .btn-live-deck.mic-control.is-recording { | |
| background: #ef4444; | |
| color: white; | |
| border-color: #ef4444; | |
| animation: pulseMicLive 1.2s infinite; | |
| } | |
| @keyframes pulseMicLive { | |
| 0% { box-shadow: 0 0 0 0 rgba(239,68,68,0.6); } | |
| 70% { box-shadow: 0 0 0 20px rgba(239,68,68,0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(239,68,68,0); } | |
| } | |
| .btn-live-deck svg { | |
| width: 32px; | |
| height: 32px; | |
| } | |
| /* Scroll Button */ | |
| .btn-scroll-trigger { | |
| position: absolute; | |
| bottom: 150px; | |
| left: 50%; | |
| width: 48px; | |
| height: 48px; | |
| border-radius: 50%; | |
| background: var(--bg-glass); | |
| backdrop-filter: blur(15px); | |
| border: 1px solid var(--border-light); | |
| box-shadow: var(--shadow-lg); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| color: var(--text-secondary); | |
| opacity: 0; | |
| pointer-events: none; | |
| transform: translateX(-50%) translateY(20px); | |
| transition: var(--ease-smooth); | |
| z-index: 20; | |
| } | |
| .btn-scroll-trigger.visible { | |
| opacity: 1; | |
| pointer-events: auto; | |
| transform: translateX(-50%) translateY(0); | |
| } | |
| .btn-scroll-trigger:hover { | |
| background: var(--bg-primary); | |
| color: var(--text-primary); | |
| transform: translateX(-50%) translateY(-5px); | |
| box-shadow: var(--shadow-xl); | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| N. WORKSPACE (CODE EXECUTION PANEL) | |
| --------------------------------------------------------------------------------------- */ | |
| .code-workspace-panel { | |
| width: 0; | |
| background: var(--bg-primary); | |
| border-left: 1px solid var(--border-light); | |
| display: flex; | |
| flex-direction: column; | |
| transition: width var(--ease-smooth); | |
| overflow: hidden; | |
| box-shadow: -15px 0 40px rgba(0,0,0,0.04); | |
| z-index: 25; | |
| } | |
| .code-workspace-panel.expanded { | |
| width: 55%; | |
| } | |
| .workspace-header-bar { | |
| padding: 20px 28px; | |
| border-bottom: 1px solid var(--border-light); | |
| background: var(--bg-primary); | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| flex-shrink: 0; | |
| } | |
| .workspace-title-group { | |
| font-size: 16px; | |
| font-weight: 800; | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| color: var(--text-primary); | |
| } | |
| .workspace-tools { | |
| display: flex; | |
| gap: 12px; | |
| } | |
| .btn-workspace-tool { | |
| padding: 10px 18px; | |
| border-radius: var(--radius-sm); | |
| background: var(--bg-secondary); | |
| border: 1px solid var(--border-light); | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| color: var(--text-primary); | |
| transition: var(--ease-fast); | |
| font-size: 14px; | |
| font-weight: 700; | |
| } | |
| .btn-workspace-tool:hover { | |
| background: var(--bg-tertiary); | |
| border-color: var(--border-medium); | |
| } | |
| .btn-workspace-tool.close { | |
| padding: 10px; | |
| } | |
| .btn-workspace-tool.close:hover { | |
| color: #ef4444; | |
| background: #fee2e2; | |
| border-color: #fca5a5; | |
| } | |
| .workspace-editor-surface { | |
| flex: 1; | |
| overflow-y: auto; | |
| background: var(--bg-secondary); | |
| padding: 30px; | |
| } | |
| .workspace-editor-surface pre { | |
| margin: 0; | |
| padding: 28px; | |
| background: #282c34; /* Atom One Dark BG */ | |
| border: 1px solid var(--border-light); | |
| border-radius: var(--radius-lg); | |
| font-family: var(--font-mono); | |
| font-size: 15px; | |
| line-height: 1.6; | |
| overflow-x: auto; | |
| box-shadow: var(--shadow-lg); | |
| color: #abb2bf; | |
| } | |
| /* --------------------------------------------------------------------------------------- | |
| O. AUTHENTICATION MODAL (SECURE GATEWAY) | |
| --------------------------------------------------------------------------------------- */ | |
| .secure-modal-backdrop { | |
| position: fixed; | |
| inset: 0; | |
| background: rgba(0,0,0,0.5); | |
| backdrop-filter: blur(10px); | |
| -webkit-backdrop-filter: blur(10px); | |
| z-index: var(--z-modal); | |
| display: none; | |
| justify-content: center; | |
| align-items: center; | |
| animation: fadeIn 0.3s ease; | |
| } | |
| .secure-modal-surface { | |
| background: var(--bg-primary); | |
| padding: 44px; | |
| border-radius: var(--radius-xl); | |
| width: 90%; | |
| max-width: 460px; | |
| box-shadow: var(--shadow-xl); | |
| position: relative; | |
| border: 1px solid rgba(255,255,255,0.4); | |
| } | |
| .btn-modal-dismiss { | |
| position: absolute; | |
| top: 24px; | |
| right: 24px; | |
| background: var(--bg-secondary); | |
| border: none; | |
| width: 36px; | |
| height: 36px; | |
| border-radius: 50%; | |
| font-size: 18px; | |
| color: var(--text-secondary); | |
| cursor: pointer; | |
| transition: 0.2s; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .btn-modal-dismiss:hover { | |
| background: #fee2e2; | |
| color: #ef4444; | |
| } | |
| .modal-brand-header { | |
| text-align: center; | |
| margin-bottom: 36px; | |
| font-family: var(--font-sans); | |
| font-size: 28px; | |
| font-weight: 900; | |
| color: var(--text-primary); | |
| letter-spacing: -0.5px; | |
| } | |
| .auth-tab-switch { | |
| display: flex; | |
| background: var(--bg-secondary); | |
| padding: 6px; | |
| border-radius: var(--radius-md); | |
| margin-bottom: 28px; | |
| } | |
| .auth-tab-item { | |
| flex: 1; | |
| padding: 14px; | |
| text-align: center; | |
| border-radius: var(--radius-sm); | |
| font-size: 15px; | |
| font-weight: 800; | |
| color: var(--text-secondary); | |
| cursor: pointer; | |
| transition: var(--ease-fast); | |
| } | |
| .auth-tab-item.active { | |
| background: var(--bg-primary); | |
| color: var(--text-primary); | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .auth-form-view { | |
| display: none; | |
| flex-direction: column; | |
| animation: slideIn 0.3s ease; | |
| } | |
| .auth-form-view.active { | |
| display: flex; | |
| } | |
| .auth-input-element { | |
| width: 100%; | |
| padding: 18px; | |
| border: 2px solid var(--border-light); | |
| border-radius: var(--radius-md); | |
| font-size: 16px; | |
| outline: none; | |
| background: var(--bg-secondary); | |
| transition: var(--ease-fast); | |
| font-family: var(--font-sans); | |
| margin-bottom: 20px; | |
| font-weight: 500; | |
| } | |
| .auth-input-element:focus { | |
| border-color: var(--brand-saffron); | |
| background: var(--bg-primary); | |
| box-shadow: 0 0 0 4px var(--brand-saffron-light); | |
| } | |
| .btn-auth-execute { | |
| width: 100%; | |
| padding: 18px; | |
| background: var(--text-primary); | |
| color: var(--brand-white); | |
| border: none; | |
| border-radius: var(--radius-md); | |
| font-size: 16px; | |
| font-weight: 800; | |
| cursor: pointer; | |
| transition: var(--ease-fast); | |
| margin-top: 10px; | |
| } | |
| .btn-auth-execute:hover { | |
| background: #000000; | |
| transform: translateY(-2px); | |
| box-shadow: var(--shadow-md); | |
| } | |
| .btn-auth-return { | |
| width: 100%; | |
| padding: 14px; | |
| background: transparent; | |
| color: var(--text-tertiary); | |
| border: none; | |
| font-size: 15px; | |
| font-weight: 700; | |
| cursor: pointer; | |
| margin-top: 10px; | |
| transition: 0.2s; | |
| } | |
| .btn-auth-return:hover { | |
| color: var(--text-primary); | |
| } | |
| /* Core Animations */ | |
| @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } | |
| @keyframes slideIn { from { opacity: 0; transform: translateX(25px); } to { opacity: 1; transform: none; } } | |
| /* Blinking Cursor for Typing */ | |
| .typing-cursor { | |
| display: inline-block; | |
| width: 10px; | |
| height: 18px; | |
| background: var(--brand-saffron); | |
| margin-left: 4px; | |
| animation: cursorBlink 1s step-end infinite; | |
| vertical-align: middle; | |
| } | |
| @keyframes cursorBlink { 50% { opacity: 0; } } | |
| /* Loading Dots */ | |
| .loading-dots-container { | |
| display: flex; | |
| align-items: center; | |
| gap: 6px; | |
| padding: 6px; | |
| } | |
| .loading-dot { | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 50%; | |
| background: var(--text-tertiary); | |
| opacity: 0.4; | |
| animation: dotBounce 1.4s infinite ease-in-out both; | |
| } | |
| .loading-dot:nth-child(1) { animation-delay: -0.32s; } | |
| .loading-dot:nth-child(2) { animation-delay: -0.16s; } | |
| @keyframes dotBounce { 0%, 80%, 100% { transform: scale(0); } 40% { transform: scale(1); } } | |
| /* --------------------------------------------------------------------------------------- | |
| P. RESPONSIVE MEDIA QUERIES | |
| --------------------------------------------------------------------------------------- */ | |
| @media (max-width: 1024px) { | |
| .code-workspace-panel.expanded { width: 100%; position: absolute; top: 0; left: 0; height: 100%; z-index: 2000; } | |
| } | |
| @media (max-width: 900px) { | |
| .sidebar-container { position: absolute; left: -320px; z-index: 1000; height: 100%; box-shadow: var(--shadow-float); } | |
| .sidebar-container.active { left: 0; } | |
| .btn-hamburger { display: flex; } | |
| .btn-mobile-close { display: flex; } | |
| .chat-scroll-area { padding: 24px 15px; } | |
| .input-dock { padding: 10px 15px 20px; } | |
| .chat-message-row { max-width: 95%; } | |
| .btn-scroll-trigger { bottom: 130px; } | |
| .hero-greeting { font-size: 32px; } | |
| .prompt-suggestions-grid { grid-template-columns: 1fr; } | |
| .input-tools-row { flex-wrap: wrap; } | |
| .main-textarea { min-width: 100%; order: -1; margin-bottom: 10px; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- ========================================================================================= | |
| DOM ELEMENT 1: GLOBAL NOTIFICATIONS | |
| ========================================================================================= --> | |
| <div id="toast-container" class="toast-wrapper"></div> | |
| <!-- ========================================================================================= | |
| DOM ELEMENT 2: INITIAL STARTUP OVERLAY | |
| ========================================================================================= --> | |
| <div class="startup-overlay" id="welcomeOverlay"> | |
| <div class="startup-logo-container"> | |
| <div class="startup-logo-glow"></div> | |
| <img src="https://i.ibb.co/0y2sdbq6/PT-20260523-133251-0000.png" alt="Arjun Core Identity"> | |
| </div> | |
| <h1 class="startup-title">Welcome to Arjun 2.O</h1> | |
| <p class="startup-desc">Professional Enterprise Edition. Experience secure workspace logic generation, high-fidelity visual rendering, and zero-latency live conversational mode.</p> | |
| <button class="btn-startup-launch" onclick="ApplicationCore.launchSystem()"> | |
| Initialize System | |
| <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg> | |
| </button> | |
| </div> | |
| <!-- ========================================================================================= | |
| DOM ELEMENT 3: LIVE MODE FULLSCREEN OVERLAY | |
| ========================================================================================= --> | |
| <div class="live-mode-viewport" id="liveOverlay"> | |
| <button class="btn-close-live" onclick="LiveModeController.terminate()" title="Exit Live Mode"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg> | |
| </button> | |
| <div class="pulsing-orb-wrapper"> | |
| <div class="energy-ring"></div> | |
| <div class="energy-ring"></div> | |
| <div class="energy-ring"></div> | |
| <div class="energy-core" id="liveOrb"></div> | |
| </div> | |
| <div class="live-feedback-status" id="liveStatusText">Initializing Audio Stream...</div> | |
| <div class="live-feedback-text" id="liveTranscriptText">Speak directly to Arjun. Natural language processing active.</div> | |
| <div class="live-control-deck"> | |
| <button class="btn-live-deck mic-control" id="liveMicBtn" onclick="VoiceEngine.toggleLive()"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><line x1="12" x2="12" y1="19" y2="22"></line></svg> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- ========================================================================================= | |
| DOM ELEMENT 4: AMBIENT BACKGROUND | |
| ========================================================================================= --> | |
| <div class="ambient-environment"> | |
| <div class="ambient-orb orb-top-left"></div> | |
| <div class="ambient-orb orb-bottom-right"></div> | |
| </div> | |
| <!-- ========================================================================================= | |
| DOM ELEMENT 5: MASTER APPLICATION CONTAINER | |
| ========================================================================================= --> | |
| <div class="app-root"> | |
| <!-- ------------------------------------------------------------------------------------- | |
| A. NAVIGATION SIDEBAR | |
| ------------------------------------------------------------------------------------- --> | |
| <aside class="sidebar-container" id="sidebar"> | |
| <div class="sidebar-header"> | |
| <a href="#" class="brand-identity"> | |
| <img src="https://i.ibb.co/0y2sdbq6/PT-20260523-133251-0000.png" alt="Arjun Logo"> | |
| <div class="brand-typography"> | |
| <span class="brand-name">ARJUN 2.O</span> | |
| <span class="brand-edition">Professional</span> | |
| </div> | |
| </a> | |
| <button class="btn-mobile-close" onclick="UIManager.toggleSidebar()"> | |
| <svg viewBox="0 0 24 24" width="20" height="20" stroke="currentColor" stroke-width="2.5" fill="none"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg> | |
| </button> | |
| </div> | |
| <div class="sidebar-body"> | |
| <!-- Authentication Widget --> | |
| <div class="auth-widget"> | |
| <button id="loginPromptBtn" class="btn-secure-connect" onclick="AuthManager.openModal()"> | |
| <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg> | |
| Secure Login | |
| </button> | |
| <div id="userProfile" class="user-profile-display"> | |
| <div class="avatar-badge" id="uAvatar">U</div> | |
| <div class="user-details"> | |
| <div class="user-email-id" id="uEmail">user@network.com</div> | |
| <div class="user-clearance-level">Verified Clearance</div> | |
| </div> | |
| <button class="btn-system-logout" onclick="AuthManager.logout()" title="Terminate Session"> | |
| <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Branding & Developer Info --> | |
| <div class="developer-credit-box"> | |
| <img src="https://i.ibb.co/0y2sdbq6/PT-20260523-133251-0000.png" alt="Arjun Core Image"> | |
| <h3 class="dev-box-title">Arjun Intelligence</h3> | |
| <p class="dev-box-subtitle">ENGINEERED BY ABHAY KUMAR</p> | |
| </div> | |
| <!-- Clear Memory Context --> | |
| <button class="btn-erase-memory" onclick="ChatEngine.clearMemory()"> | |
| <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg> | |
| Wipe Memory Context | |
| </button> | |
| </div> | |
| </aside> | |
| <!-- ------------------------------------------------------------------------------------- | |
| B. MAIN CHAT ENGINE INTERFACE | |
| ------------------------------------------------------------------------------------- --> | |
| <main class="main-chat-wrapper"> | |
| <!-- Top Status Bar --> | |
| <header class="chat-top-bar"> | |
| <div class="top-bar-left"> | |
| <button class="btn-hamburger" onclick="UIManager.toggleSidebar()"> | |
| <svg viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2.5" fill="none"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg> | |
| </button> | |
| <div class="system-status-pill"> | |
| <div class="pulse-dot"></div> | |
| System Online | |
| </div> | |
| </div> | |
| <!-- LIVE MODE ACTIVATOR --> | |
| <button class="btn-activate-live" onclick="LiveModeController.initialize()"> | |
| <svg viewBox="0 0 24 24" stroke="currentColor" stroke-width="2.5" fill="none"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="4" fill="currentColor"></circle></svg> | |
| LIVE MODE | |
| </button> | |
| </header> | |
| <!-- Scrollable Conversation Area --> | |
| <div class="chat-scroll-area" id="msgs" onscroll="UIManager.checkScrollState()"> | |
| <!-- Internal Welcome / Empty State --> | |
| <div class="chat-hero-section" id="welcomeState"> | |
| <div class="hero-avatar-wrapper"> | |
| <div class="hero-avatar-glow"></div> | |
| <img src="https://i.ibb.co/0y2sdbq6/PT-20260523-133251-0000.png" alt="Arjun Logo Large"> | |
| </div> | |
| <h2 class="hero-greeting">How can I assist you today?</h2> | |
| <p class="hero-description">Experience next-generation reasoning, seamless multi-file analysis, and secure workspace code generation engineered by Abhay Kumar.</p> | |
| <div id="guestBadge" class="guest-warning-badge"> | |
| ⚠️ Guest Mode Active: <span id="guestCountDisplay">0</span>/3 Queries Used. Please login. | |
| </div> | |
| <div class="prompt-suggestions-grid"> | |
| <div class="prompt-card" onclick="ChatEngine.sendExample('Write a secure python script for a modern Flask backend server.')"> | |
| <span class="prompt-icon">💻</span> | |
| <div class="prompt-title">Generate Production Code</div> | |
| <div class="prompt-desc">Create secure, workspace-ready architecture instantly.</div> | |
| </div> | |
| <div class="prompt-card" onclick="ChatEngine.sendExample('Create a hyper-realistic 8k image of a futuristic Indian smart city.')"> | |
| <span class="prompt-icon">🎨</span> | |
| <div class="prompt-title">Render Stunning Visions</div> | |
| <div class="prompt-desc">Utilize advanced AI to paint your imagination.</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Dynamic Chat Bubbles will be appended here --> | |
| </div> | |
| <!-- Floating Scroll Down Button --> | |
| <button class="btn-scroll-trigger" id="scrollTriggerBtn" onclick="UIManager.forceScrollDown()"> | |
| <svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"></polyline></svg> | |
| </button> | |
| <!-- Bottom Input Dock --> | |
| <div class="input-dock"> | |
| <div class="input-master-container"> | |
| <!-- File Preview Component --> | |
| <div class="upload-preview-bar" id="filePreviewBar"> | |
| <img class="upload-thumb" id="previewImgThumb" src="" style="display:none;"> | |
| <div class="upload-thumb" id="previewDocIcon" style="display:none;">📄</div> | |
| <div class="upload-meta"> | |
| <div class="upload-filename" id="previewFileName">document.pdf</div> | |
| <div class="upload-status-text">File ready to analyze</div> | |
| </div> | |
| <button class="btn-discard-upload" onclick="FileProcessor.discardFile()"> | |
| <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg> | |
| </button> | |
| </div> | |
| <!-- Main Tool & Input Row --> | |
| <div class="input-tools-row"> | |
| <!-- Attachment Dropdown Module --> | |
| <div class="attachment-module"> | |
| <button class="btn-tool-icon" onclick="UIManager.toggleAttachMenu()" title="Attach File"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" 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"></path></svg> | |
| </button> | |
| <div class="attachment-dropdown" id="attachDropdownMenu"> | |
| <div class="dropdown-item" onclick="FileProcessor.triggerFileSelector('image')"> | |
| <span class="emoji-icon">🖼️</span> High-Res Image | |
| </div> | |
| <div class="dropdown-item" onclick="FileProcessor.triggerFileSelector('video')"> | |
| <span class="emoji-icon">🎥</span> Video Media | |
| </div> | |
| <div class="dropdown-item" onclick="FileProcessor.triggerFileSelector('audio')"> | |
| <span class="emoji-icon">🎵</span> Audio Track | |
| </div> | |
| <div class="dropdown-item" onclick="FileProcessor.triggerFileSelector('document')"> | |
| <span class="emoji-icon">📄</span> Document / Code | |
| </div> | |
| </div> | |
| <!-- Hidden File Inputs --> | |
| <input type="file" id="sys-inp-image" class="stealth-input" accept="image/*" onchange="FileProcessor.processFile(this, 'image')"> | |
| <input type="file" id="sys-inp-video" class="stealth-input" accept="video/*" onchange="FileProcessor.processFile(this, 'video')"> | |
| <input type="file" id="sys-inp-audio" class="stealth-input" accept="audio/*" onchange="FileProcessor.processFile(this, 'audio')"> | |
| <input type="file" id="sys-inp-document" class="stealth-input" accept=".pdf,.doc,.docx,.txt,.md,.csv,.json,.py,.js,.html,.css,.cpp,.c,.java" onchange="FileProcessor.processFile(this, 'document')"> | |
| </div> | |
| <!-- Smart Language Toggle Button --> | |
| <button class="language-toggle-chip" id="smartLangToggle" onclick="VoiceEngine.switchLanguage()" title="Switch Voice Engine Language"> | |
| 🌐 <span id="langDisplayBadge">EN</span> | |
| </button> | |
| <!-- Voice Dictation Button --> | |
| <button class="btn-tool-icon btn-mic-tool" id="masterVoiceBtn" onclick="VoiceEngine.toggleDictation()" title="Voice Dictation"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><line x1="12" x2="12" y1="19" y2="22"></line></svg> | |
| </button> | |
| <!-- Expanding Text Area --> | |
| <textarea class="main-textarea" id="mainChatInput" placeholder="Message Arjun Intelligence..." rows="1" onkeydown="ChatEngine.handleKeyboard(event)" oninput="UIManager.autoGrowTextArea(this)"></textarea> | |
| <!-- Master Send Button --> | |
| <button class="btn-master-send" id="masterSendBtn" onclick="ChatEngine.initiateDispatch()"> | |
| <svg viewBox="0 0 24 24"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bottom-branding-text">Secured by Arjun Core Architecture • Developed by Abhay Kumar</div> | |
| </div> | |
| </main> | |
| <!-- ------------------------------------------------------------------------------------- | |
| C. WORKSPACE CODE EDITOR PANEL | |
| ------------------------------------------------------------------------------------- --> | |
| <aside class="code-workspace-panel" id="workspacePanel"> | |
| <div class="workspace-header-bar"> | |
| <div class="workspace-title-group"> | |
| <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg> | |
| <span id="workspaceTitleBadge">Workspace</span> | |
| </div> | |
| <div class="workspace-tools"> | |
| <button class="btn-workspace-tool" onclick="WorkspaceEngine.executeCopy(this)"> | |
| <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg> | |
| Copy Source | |
| </button> | |
| <button class="btn-workspace-tool close" onclick="WorkspaceEngine.closePanel()" title="Close Editor"> | |
| <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="workspace-editor-surface"> | |
| <pre><code id="workspaceCodeBlock" class="hljs"></code></pre> | |
| </div> | |
| </aside> | |
| </div> | |
| <!-- ========================================================================================= | |
| DOM ELEMENT 6: SECURE AUTHENTICATION MODAL | |
| ========================================================================================= --> | |
| <div class="secure-modal-backdrop" id="secureAuthModal"> | |
| <div class="secure-modal-surface"> | |
| <button class="btn-modal-dismiss" onclick="AuthManager.closeModal()"> | |
| <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg> | |
| </button> | |
| <div class="modal-brand-header">Arjun Network</div> | |
| <div class="auth-tab-switch"> | |
| <div class="auth-tab-item active" id="btn-tab-login" onclick="AuthManager.switchTab('login')">Connect</div> | |
| <div class="auth-tab-item" id="btn-tab-register" onclick="AuthManager.switchTab('register')">Enroll</div> | |
| </div> | |
| <!-- Login Flow --> | |
| <div id="auth-flow-login"> | |
| <div class="auth-form-view active" id="auth-log-phase-1"> | |
| <input type="email" class="auth-input-element" id="authLogEmail" placeholder="Authorized Email Address"> | |
| <button class="btn-auth-execute" id="btn-fire-log-otp" onclick="AuthManager.process('login_send_otp')">Generate OTP</button> | |
| </div> | |
| <div class="auth-form-view" id="auth-log-phase-2"> | |
| <input type="number" class="auth-input-element" id="authLogOTP" placeholder="Validation Code (OTP)"> | |
| <button class="btn-auth-execute" id="btn-fire-log-verify" onclick="AuthManager.process('login_verify')">Authenticate</button> | |
| <button class="btn-auth-return" onclick="AuthManager.switchPhase('auth-log-phase-2', 'auth-log-phase-1')">← Go Back</button> | |
| </div> | |
| </div> | |
| <!-- Register Flow --> | |
| <div id="auth-flow-register" style="display:none;"> | |
| <div class="auth-form-view active" id="auth-reg-phase-1"> | |
| <input type="text" class="auth-input-element" id="authRegName" placeholder="Full Legal Name"> | |
| <input type="email" class="auth-input-element" id="authRegEmail" placeholder="Email Address"> | |
| <button class="btn-auth-execute" id="btn-fire-reg-otp" onclick="AuthManager.process('register_send_otp')">Verify Identity</button> | |
| </div> | |
| <div class="auth-form-view" id="auth-reg-phase-2"> | |
| <input type="number" class="auth-input-element" id="authRegOTP" placeholder="Identity Token (OTP)"> | |
| <button class="btn-auth-execute" id="btn-fire-reg-verify" onclick="AuthManager.process('register_verify')">Initialize Account</button> | |
| <button class="btn-auth-return" onclick="AuthManager.switchPhase('auth-reg-phase-2', 'auth-reg-phase-1')">← Go Back</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- ========================================================================================= | |
| 7. ENTERPRISE JAVASCRIPT LOGIC (पूर्ण आर्किटेक्चर) | |
| ========================================================================================= --> | |
| <script> | |
| /** | |
| * System Configuration & State Management | |
| */ | |
| const Config = { | |
| GAS_URL: "https://script.google.com/macros/s/AKfycbzTsXGoVh97JjtFAAG825GF4WUZqf7FDB3Zbxyf0nrLXt_1HjJSSqA829UcdoamRPvg0A/exec", | |
| LOGO_URL: "https://i.ibb.co/0y2sdbq6/PT-20260523-133251-0000.png", | |
| PDF_WORKER: 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js' | |
| }; | |
| // Initialize PDF worker | |
| pdfjsLib.GlobalWorkerOptions.workerSrc = Config.PDF_WORKER; | |
| // Global Application State | |
| const AppState = { | |
| currentUser: localStorage.getItem('arjun_user') || null, | |
| guestCount: parseInt(localStorage.getItem('arjun_guest') || '0', 10), | |
| history: [], | |
| pendingAttachment: null, | |
| isProcessing: false, | |
| isUserScrolling: false, | |
| generatedCodeBlocks: [], | |
| currentWorkspaceId: null, | |
| isStreamingActive: false, | |
| isLiveModeEngaged: false | |
| }; | |
| /** | |
| * Utility Classes & Functions | |
| */ | |
| const Utils = { | |
| showToast: (message) => { | |
| const container = document.getElementById('toast-container'); | |
| const toast = document.createElement('div'); | |
| toast.className = 'toast-notification'; | |
| // Success SVG Icon inline | |
| toast.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><polyline points="20 6 9 17 4 12"></polyline></svg> ${message}`; | |
| container.appendChild(toast); | |
| setTimeout(() => toast.remove(), 3000); | |
| }, | |
| escapeHTML: (str) => { | |
| return str.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); | |
| }, | |
| // Robust Fallback Copy Mechanism (100% Reliability) | |
| executeFallbackCopy: (text, btnElement) => { | |
| const textArea = document.createElement("textarea"); | |
| textArea.value = text; | |
| textArea.style.top = "0"; | |
| textArea.style.left = "0"; | |
| textArea.style.position = "fixed"; | |
| document.body.appendChild(textArea); | |
| textArea.focus(); | |
| textArea.select(); | |
| try { | |
| const successful = document.execCommand('copy'); | |
| if (successful) { | |
| const originalHTML = btnElement.innerHTML; | |
| btnElement.innerHTML = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"></polyline></svg> Success`; | |
| setTimeout(() => { btnElement.innerHTML = originalHTML; }, 2500); | |
| } else { | |
| Utils.showToast("Clipboard access denied."); | |
| } | |
| } catch (err) { | |
| Utils.showToast("System error copying text."); | |
| } | |
| document.body.removeChild(textArea); | |
| }, | |
| copyToClipboard: (btnElement, textToCopy) => { | |
| if (!navigator.clipboard) { | |
| Utils.executeFallbackCopy(textToCopy, btnElement); | |
| return; | |
| } | |
| navigator.clipboard.writeText(textToCopy).then(() => { | |
| const originalHTML = btnElement.innerHTML; | |
| btnElement.innerHTML = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="20 6 9 17 4 12"></polyline></svg> Success`; | |
| setTimeout(() => { btnElement.innerHTML = originalHTML; }, 2500); | |
| }).catch((err) => { | |
| console.warn('Modern API failed, utilizing fallback...', err); | |
| Utils.executeFallbackCopy(textToCopy, btnElement); | |
| }); | |
| } | |
| }; | |
| /** | |
| * Authentication Manager (Google Apps Script Integration) | |
| */ | |
| const AuthManager = { | |
| initUI: () => { | |
| const promptBtn = document.getElementById('loginPromptBtn'); | |
| const profileCard = document.getElementById('userProfile'); | |
| const guestBadge = document.getElementById('guestBadge'); | |
| if (AppState.currentUser) { | |
| promptBtn.style.display = 'none'; | |
| profileCard.style.display = 'flex'; | |
| document.getElementById('uEmail').innerText = AppState.currentUser; | |
| document.getElementById('uAvatar').innerText = AppState.currentUser.charAt(0).toUpperCase(); | |
| if(guestBadge) guestBadge.style.display = 'none'; | |
| } else { | |
| promptBtn.style.display = 'flex'; | |
| profileCard.style.display = 'none'; | |
| if(guestBadge) { | |
| guestBadge.style.display = 'inline-flex'; | |
| document.getElementById('guestCountDisplay').innerText = AppState.guestCount; | |
| } | |
| } | |
| }, | |
| openModal: () => document.getElementById('secureAuthModal').style.display = 'flex', | |
| closeModal: () => document.getElementById('secureAuthModal').style.display = 'none', | |
| switchTab: (tabName) => { | |
| document.querySelectorAll('.auth-tab-item').forEach(el => el.classList.remove('active')); | |
| document.getElementById(`btn-tab-${tabName}`).classList.add('active'); | |
| document.getElementById('auth-flow-login').style.display = tabName === 'login' ? 'block' : 'none'; | |
| document.getElementById('auth-flow-register').style.display = tabName === 'register' ? 'block' : 'none'; | |
| }, | |
| switchPhase: (currentId, nextId) => { | |
| document.getElementById(currentId).classList.remove('active'); | |
| document.getElementById(nextId).classList.add('active'); | |
| }, | |
| process: async (actionType) => { | |
| const payload = { action: actionType }; | |
| let buttonId = ''; | |
| if (actionType === 'register_send_otp') { | |
| payload.name = document.getElementById('authRegName').value.trim(); | |
| payload.email = document.getElementById('authRegEmail').value.trim(); | |
| payload.phone = "0000000000"; payload.organization = "Arjun Base"; | |
| if (!payload.email || !payload.name) return Utils.showToast("Identification details required."); | |
| buttonId = 'btn-fire-reg-otp'; | |
| } | |
| else if (actionType === 'login_send_otp') { | |
| payload.email = document.getElementById('authLogEmail').value.trim(); | |
| if (!payload.email) return Utils.showToast("Email required for validation."); | |
| buttonId = 'btn-fire-log-otp'; | |
| } | |
| else if (actionType === 'register_verify' || actionType === 'login_verify') { | |
| payload.email = document.getElementById(actionType === 'register_verify' ? 'authRegEmail' : 'authLogEmail').value.trim(); | |
| payload.otp = document.getElementById(actionType === 'register_verify' ? 'authRegOTP' : 'authLogOTP').value.trim(); | |
| if (!payload.otp) return Utils.showToast("Security token required."); | |
| buttonId = actionType === 'register_verify' ? 'btn-fire-reg-verify' : 'btn-fire-log-verify'; | |
| } | |
| const triggerBtn = document.getElementById(buttonId); | |
| const originalText = triggerBtn.innerHTML; | |
| triggerBtn.disabled = true; | |
| triggerBtn.innerText = 'Establishing Connection...'; | |
| try { | |
| const response = await fetch(Config.GAS_URL, { method: 'POST', body: JSON.stringify(payload) }); | |
| const result = await response.json(); | |
| if (result.status === 'success') { | |
| Utils.showToast(result.message); | |
| if (actionType === 'register_send_otp') AuthManager.switchPhase('auth-reg-phase-1', 'auth-reg-phase-2'); | |
| else if (actionType === 'login_send_otp') AuthManager.switchPhase('auth-log-phase-1', 'auth-log-phase-2'); | |
| else if (actionType === 'register_verify' || actionType === 'login_verify') { | |
| AppState.currentUser = payload.email; | |
| localStorage.setItem('arjun_user', AppState.currentUser); | |
| AuthManager.closeModal(); | |
| AuthManager.initUI(); | |
| ChatEngine.syncHistoryFromCloud(); | |
| } | |
| } else { | |
| Utils.showToast(result.message); | |
| } | |
| } catch (error) { | |
| Utils.showToast("Encrypted gateway error. Check network."); | |
| } | |
| triggerBtn.disabled = false; | |
| triggerBtn.innerHTML = originalText; | |
| }, | |
| logout: () => { | |
| localStorage.removeItem('arjun_user'); | |
| location.reload(); | |
| } | |
| }; | |
| /** | |
| * UI & DOM Management | |
| */ | |
| const UIManager = { | |
| toggleSidebar: () => { | |
| document.getElementById('sidebar').classList.toggle('active'); | |
| }, | |
| checkScrollState: () => { | |
| const msgArea = document.getElementById('msgs'); | |
| const isAtBottom = Math.abs((msgArea.scrollHeight - msgArea.scrollTop) - msgArea.clientHeight) < 80; | |
| AppState.isUserScrolling = !isAtBottom; | |
| const scrollBtn = document.getElementById('scrollTriggerBtn'); | |
| if (AppState.isUserScrolling) scrollBtn.classList.add('visible'); | |
| else scrollBtn.classList.remove('visible'); | |
| }, | |
| forceScrollDown: () => { | |
| const msgArea = document.getElementById('msgs'); | |
| msgArea.scrollTo({ top: msgArea.scrollHeight, behavior: 'smooth' }); | |
| AppState.isUserScrolling = false; | |
| document.getElementById('scrollTriggerBtn').classList.remove('visible'); | |
| }, | |
| autoScroll: () => { | |
| if (!AppState.isUserScrolling) { | |
| const msgArea = document.getElementById('msgs'); | |
| msgArea.scrollTop = msgArea.scrollHeight; | |
| } | |
| }, | |
| autoGrowTextArea: (element) => { | |
| element.style.height = 'auto'; | |
| element.style.height = Math.min(element.scrollHeight, 200) + 'px'; | |
| }, | |
| toggleAttachMenu: () => { | |
| document.getElementById('attachDropdownMenu').classList.toggle('visible'); | |
| } | |
| }; | |
| // Close dropdown when clicking outside | |
| document.addEventListener('click', (event) => { | |
| const wrapper = document.querySelector('.attachment-module'); | |
| if (!wrapper.contains(event.target)) { | |
| document.getElementById('attachDropdownMenu').classList.remove('visible'); | |
| } | |
| }); | |
| /** | |
| * Voice & Speech Engine (Smart Bilingual Toggle) | |
| */ | |
| const VoiceEngine = { | |
| recognition: null, | |
| currentLanguage: 'en-IN', | |
| init: () => { | |
| const SR = window.SpeechRecognition || window.webkitSpeechRecognition; | |
| if (!SR) return; | |
| VoiceEngine.recognition = new SR(); | |
| VoiceEngine.recognition.continuous = false; | |
| VoiceEngine.recognition.interimResults = false; | |
| VoiceEngine.recognition.lang = VoiceEngine.currentLanguage; | |
| VoiceEngine.recognition.onstart = () => { | |
| document.getElementById('masterVoiceBtn').classList.add('active-listening'); | |
| if (AppState.isLiveModeEngaged) { | |
| document.getElementById('liveMicBtn').classList.add('is-recording'); | |
| document.getElementById('liveStatusText').innerText = "Analyzing Input..."; | |
| document.getElementById('liveOrb').style.transform = "scale(1.25)"; | |
| } | |
| }; | |
| VoiceEngine.recognition.onresult = (event) => { | |
| let transcript = ''; | |
| for (let i = event.resultIndex; i < event.results.length; ++i) { | |
| transcript += event.results[i][0].transcript; | |
| } | |
| transcript = transcript.trim(); | |
| if (transcript.length > 0) { | |
| transcript = transcript.charAt(0).toUpperCase() + transcript.slice(1); | |
| if (!/[.!?।]$/.test(transcript)) transcript += '.'; | |
| transcript += ' '; | |
| } | |
| if (AppState.isLiveModeEngaged) { | |
| document.getElementById('liveTranscriptText').innerText = `"${transcript}"`; | |
| document.getElementById('liveStatusText').innerText = "Synthesizing Response..."; | |
| document.getElementById('mainChatInput').value = transcript; | |
| ChatEngine.initiateDispatch(); | |
| } else { | |
| const inputField = document.getElementById('mainChatInput'); | |
| inputField.value = (inputField.value + ' ' + transcript).trim(); | |
| UIManager.autoGrowTextArea(inputField); | |
| } | |
| }; | |
| VoiceEngine.recognition.onend = () => { | |
| document.getElementById('masterVoiceBtn').classList.remove('active-listening'); | |
| if (AppState.isLiveModeEngaged && !AppState.isProcessing) { | |
| document.getElementById('liveMicBtn').classList.remove('is-recording'); | |
| document.getElementById('liveStatusText').innerText = "Tap mic to interact"; | |
| document.getElementById('liveOrb').style.transform = "scale(1)"; | |
| } | |
| }; | |
| VoiceEngine.recognition.onerror = (event) => { | |
| Utils.showToast("Voice module error: " + event.error); | |
| document.getElementById('masterVoiceBtn').classList.remove('active-listening'); | |
| if (AppState.isLiveModeEngaged) { | |
| document.getElementById('liveMicBtn').classList.remove('is-recording'); | |
| document.getElementById('liveStatusText').innerText = "Audio Failure. Retry."; | |
| } | |
| }; | |
| }, | |
| switchLanguage: () => { | |
| const btn = document.getElementById('smartLangToggle'); | |
| const badge = document.getElementById('langDisplayBadge'); | |
| if (VoiceEngine.currentLanguage === 'en-IN') { | |
| VoiceEngine.currentLanguage = 'hi-IN'; | |
| badge.innerText = 'हि'; | |
| btn.classList.add('hindi-active'); | |
| Utils.showToast("Acoustic Protocol: Pure Hindi (देवनागरी)"); | |
| } else { | |
| VoiceEngine.currentLanguage = 'en-IN'; | |
| badge.innerText = 'EN'; | |
| btn.classList.remove('hindi-active'); | |
| Utils.showToast("Acoustic Protocol: English / Hybrid"); | |
| } | |
| if (VoiceEngine.recognition) { | |
| VoiceEngine.recognition.lang = VoiceEngine.currentLanguage; | |
| } | |
| }, | |
| toggleDictation: () => { | |
| if (!VoiceEngine.recognition) return Utils.showToast("Hardware dictation unsupported."); | |
| try { VoiceEngine.recognition.start(); } catch (e) { VoiceEngine.recognition.stop(); } | |
| }, | |
| toggleLive: () => { | |
| if (!VoiceEngine.recognition) return Utils.showToast("Hardware dictation unsupported."); | |
| try { VoiceEngine.recognition.start(); } catch (e) { VoiceEngine.recognition.stop(); } | |
| }, | |
| // Calling Backend TTS | |
| executeTTS: async (text) => { | |
| const cleanText = text.replace(/[*_~`#]/g, '').replace(/<[^>]*>?/gm, ''); | |
| Utils.showToast("🔊 Linking with Neural Voice Matrix..."); | |
| try { | |
| const response = await fetch('/api/tts', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ text: cleanText }) | |
| }); | |
| if (!response.ok) throw new Error("Backend Synthesis Fault"); | |
| const blob = await response.blob(); | |
| const audioUrl = URL.createObjectURL(blob); | |
| const audio = new Audio(audioUrl); | |
| audio.play(); | |
| } catch (error) { | |
| Utils.showToast("Neural link failed. Verify backend integrity."); | |
| } | |
| } | |
| }; | |
| VoiceEngine.init(); | |
| /** | |
| * Live Mode Controller | |
| */ | |
| const LiveModeController = { | |
| initialize: () => { | |
| AppState.isLiveModeEngaged = true; | |
| document.getElementById('liveOverlay').classList.add('active'); | |
| if (VoiceEngine.recognition) { | |
| setTimeout(() => { | |
| try { VoiceEngine.recognition.start(); } catch(e){} | |
| }, 600); | |
| } | |
| }, | |
| terminate: () => { | |
| AppState.isLiveModeEngaged = false; | |
| document.getElementById('liveOverlay').classList.remove('active'); | |
| if (VoiceEngine.recognition) { | |
| try { VoiceEngine.recognition.stop(); } catch(e){} | |
| } | |
| } | |
| }; | |
| /** | |
| * File & Attachment Processor | |
| */ | |
| const FileProcessor = { | |
| triggerFileSelector: (type) => { | |
| document.getElementById('attachDropdownMenu').classList.remove('visible'); | |
| document.getElementById('sys-inp-' + type).click(); | |
| }, | |
| processFile: async (inputElement, typeContext) => { | |
| const file = inputElement.files[0]; | |
| if (!file) return; | |
| const fName = file.name.toLowerCase(); | |
| const mime = file.type; | |
| // Strict validation | |
| if (typeContext === 'image' && !mime.startsWith('image/')) { Utils.showToast("Format Rejected: Visual media required."); inputElement.value=''; return; } | |
| if (typeContext === 'video' && !mime.startsWith('video/')) { Utils.showToast("Format Rejected: Video media required."); inputElement.value=''; return; } | |
| if (typeContext === 'audio' && !mime.startsWith('audio/')) { Utils.showToast("Format Rejected: Audio media required."); inputElement.value=''; return; } | |
| // Non-technical Toast Update | |
| Utils.showToast("Uploading your file, please wait..."); | |
| // Prepare UI preview | |
| const thumbImg = document.getElementById('previewImgThumb'); | |
| const docIcon = document.getElementById('previewDocIcon'); | |
| thumbImg.style.display = 'none'; | |
| docIcon.style.display = 'none'; | |
| document.getElementById('previewFileName').innerText = file.name; | |
| document.getElementById('filePreviewBar').classList.add('visible'); | |
| const fileReader = new FileReader(); | |
| if (typeContext === 'image') { | |
| fileReader.onload = (e) => { | |
| AppState.pendingAttachment = { type: 'image', data: e.target.result.split(',')[1], name: file.name }; | |
| thumbImg.src = e.target.result; | |
| thumbImg.style.display = 'flex'; | |
| }; | |
| fileReader.readAsDataURL(file); | |
| } | |
| else if (typeContext === 'video' || typeContext === 'audio') { | |
| fileReader.onload = (e) => { | |
| AppState.pendingAttachment = { type: typeContext, data: e.target.result.split(',')[1], name: file.name }; | |
| docIcon.innerText = typeContext === 'video' ? '🎥' : '🎵'; | |
| docIcon.style.display = 'flex'; | |
| }; | |
| fileReader.readAsDataURL(file); | |
| } | |
| else if (typeContext === 'document') { | |
| docIcon.innerText = '📄'; | |
| docIcon.style.display = 'flex'; | |
| if (fName.endsWith('.pdf')) { | |
| fileReader.onload = async function() { | |
| try { | |
| const typedArray = new Uint8Array(this.result); | |
| const pdfDoc = await pdfjsLib.getDocument(typedArray).promise; | |
| let extractedText = ""; | |
| for (let i = 1; i <= pdfDoc.numPages; i++) { | |
| const page = await pdfDoc.getPage(i); | |
| const content = await page.getTextContent(); | |
| extractedText += content.items.map(s => s.str).join(' ') + "\n"; | |
| } | |
| AppState.pendingAttachment = { type: 'text', data: extractedText.trim() || "No readable text found.", name: file.name }; | |
| Utils.showToast("Your PDF is ready!"); | |
| } catch (e) { | |
| Utils.showToast("PDF parsing encountered an error."); | |
| FileProcessor.discardFile(); | |
| } | |
| }; | |
| fileReader.readAsArrayBuffer(file); | |
| } | |
| else if (fName.endsWith('.docx') || fName.endsWith('.doc')) { | |
| fileReader.onload = async function() { | |
| try { | |
| const buffer = this.result; | |
| const resultData = await mammoth.extractRawText({ arrayBuffer: buffer }); | |
| AppState.pendingAttachment = { type: 'text', data: resultData.value.trim() || "No readable text found.", name: file.name }; | |
| Utils.showToast("Your Word document is ready!"); | |
| } catch(e) { | |
| Utils.showToast("Document parsing encountered an error."); | |
| FileProcessor.discardFile(); | |
| } | |
| }; | |
| fileReader.readAsArrayBuffer(file); | |
| } | |
| else { | |
| // Standard Text/Code parsing | |
| fileReader.onload = (e) => { | |
| AppState.pendingAttachment = { type: 'text', data: e.target.result, name: file.name }; | |
| Utils.showToast("Your file is ready!"); | |
| }; | |
| fileReader.readAsText(file); | |
| } | |
| } | |
| // Reset input for sequential identical uploads | |
| inputElement.value = ''; | |
| }, | |
| discardFile: () => { | |
| AppState.pendingAttachment = null; | |
| document.getElementById('filePreviewBar').classList.remove('visible'); | |
| } | |
| }; | |
| /** | |
| * Workspace Code Engine | |
| */ | |
| const WorkspaceEngine = { | |
| launch: (codeBlockId) => { | |
| AppState.currentWorkspaceId = codeBlockId; | |
| const codeData = AppState.generatedCodeBlocks[codeBlockId]; | |
| document.getElementById('wsTitleText').innerText = codeData.lang ? `Generated ${codeData.lang.toUpperCase()}` : "Compiled Code"; | |
| const blockDisplay = document.getElementById('workspaceCodeBlock'); | |
| blockDisplay.className = `hljs language-${codeData.lang || 'plaintext'}`; | |
| blockDisplay.textContent = codeData.code; | |
| hljs.highlightElement(blockDisplay); | |
| document.getElementById('workspacePanel').classList.add('expanded'); | |
| if (window.innerWidth <= 1024) { | |
| document.getElementById('sidebar').classList.remove('active'); | |
| } | |
| }, | |
| closePanel: () => { | |
| document.getElementById('workspacePanel').classList.remove('expanded'); | |
| }, | |
| executeCopy: (btnElement) => { | |
| if (AppState.currentWorkspaceId !== null) { | |
| const srcCode = AppState.generatedCodeBlocks[AppState.currentWorkspaceId].code; | |
| Utils.copyToClipboard(btnElement, srcCode); | |
| } | |
| } | |
| }; | |
| // Customize Marked.js Renderer for Streaming UI & Workspace Cards | |
| const MD_Renderer = new marked.Renderer(); | |
| MD_Renderer.code = function(token) { | |
| const rawCode = typeof token === 'string' ? token : (token.text || ''); | |
| const langClass = typeof token === 'string' ? arguments[1] : (token.lang || ''); | |
| // Render beautiful loading box during stream | |
| if (AppState.isStreamingActive) { | |
| return ` | |
| <div class="streaming-code-container"> | |
| <div class="streaming-code-header"> | |
| <div class="loading-ring"></div> | |
| Generating Architecture... | |
| </div> | |
| <pre><code class="language-${langClass}">${Utils.escapeHTML(rawCode)}</code></pre> | |
| </div>`; | |
| } | |
| // Once stream ends, render functional Workspace button | |
| const internalId = AppState.generatedCodeBlocks.length; | |
| AppState.generatedCodeBlocks.push({ code: rawCode, lang: langClass }); | |
| return ` | |
| <div class="workspace-execute-card"> | |
| <div class="ws-card-left"> | |
| <div class="ws-card-icon-box"> | |
| <svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg> | |
| </div> | |
| <div class="ws-card-details"> | |
| <h4>Code Module Compiled</h4> | |
| <p>${langClass || 'Syntax Detected'}</p> | |
| </div> | |
| </div> | |
| <button class="btn-launch-workspace" onclick="WorkspaceEngine.launch(${internalId})">Open Workspace</button> | |
| </div>`; | |
| }; | |
| marked.use({ renderer: MD_Renderer }); | |
| /** | |
| * Core Chat Processing Engine | |
| */ | |
| const ChatEngine = { | |
| handleKeyboard: (e) => { | |
| if (e.key === 'Enter' && !e.shiftKey) { | |
| e.preventDefault(); | |
| ChatEngine.initiateDispatch(); | |
| } | |
| }, | |
| sendExample: (queryText) => { | |
| document.getElementById('mainChatInput').value = queryText; | |
| ChatEngine.initiateDispatch(); | |
| }, | |
| clearMemory: async () => { | |
| if (AppState.currentUser) { | |
| Utils.showToast("Purging neural link memory..."); | |
| await fetch(Config.GAS_URL, { | |
| method: 'POST', | |
| body: JSON.stringify({ action: "delete_history", email: AppState.currentUser }) | |
| }); | |
| } | |
| location.reload(); | |
| }, | |
| syncHistoryFromCloud: async () => { | |
| const messageZone = document.getElementById('msgs'); | |
| document.getElementById('welcomeState').style.display = 'none'; | |
| messageZone.innerHTML = '<div style="text-align:center; padding:80px; font-weight:800; color:var(--brand-saffron); font-size:18px;">Decrypting Historic Archives...</div>'; | |
| try { | |
| const response = await fetch(Config.GAS_URL, { | |
| method: 'POST', | |
| body: JSON.stringify({ action: "get_history", email: AppState.currentUser }) | |
| }); | |
| const resData = await response.json(); | |
| messageZone.innerHTML = ''; | |
| if (resData.status === 'success' && resData.historyJSON !== "[]") { | |
| AppState.history = JSON.parse(resData.historyJSON); | |
| AppState.history.forEach(msgObj => { | |
| if (msgObj.role === 'user') { | |
| ChatEngine.renderUserMessage(msgObj.content, msgObj.badge, msgObj.previewHTML); | |
| } else { | |
| AppState.isStreamingActive = false; | |
| ChatEngine.renderBotMessage(msgObj.content, true); | |
| } | |
| }); | |
| setTimeout(UIManager.forceScrollDown, 150); | |
| } else { | |
| document.getElementById('welcomeState').style.display = 'flex'; | |
| } | |
| } catch (err) { | |
| messageZone.innerHTML = ''; | |
| document.getElementById('welcomeState').style.display = 'flex'; | |
| } | |
| }, | |
| saveHistoryToCloud: () => { | |
| if (AppState.currentUser) { | |
| fetch(Config.GAS_URL, { | |
| method: 'POST', | |
| body: JSON.stringify({ action: "save_history", email: AppState.currentUser, historyJSON: JSON.stringify(AppState.history) }) | |
| }); | |
| } | |
| }, | |
| // Creates visually appealing preview HTML for within the chat bubble | |
| buildPreviewHTML: (attachmentObj) => { | |
| if (!attachmentObj) return ''; | |
| if (attachmentObj.type === 'image') { | |
| return `<img src="data:image/jpeg;base64,${attachmentObj.data}" class="chat-in-bubble-img" alt="Attached Image">`; | |
| } else if (attachmentObj.type === 'video') { | |
| return `<div class="chat-file-card"><span class="icon">🎥</span><span class="name">${attachmentObj.name}</span></div>`; | |
| } else if (attachmentObj.type === 'audio') { | |
| return `<div class="chat-file-card"><span class="icon">🎵</span><span class="name">${attachmentObj.name}</span></div>`; | |
| } else { | |
| return `<div class="chat-file-card"><span class="icon">📄</span><span class="name">${attachmentObj.name}</span></div>`; | |
| } | |
| }, | |
| renderUserMessage: (textContent, badgeText, previewHTMLString = '') => { | |
| let badgeNode = badgeText ? `<div class="file-badge">${Utils.escapeHTML(badgeText)}</div>` : ''; | |
| const bubbleBox = document.createElement('div'); | |
| bubbleBox.className = 'chat-message-row user-msg'; | |
| bubbleBox.innerHTML = ` | |
| <div class="msg-avatar">U</div> | |
| <div class="msg-content-column"> | |
| ${badgeNode} | |
| <div class="chat-bubble"> | |
| ${previewHTMLString} | |
| ${Utils.escapeHTML(textContent)} | |
| </div> | |
| </div>`; | |
| document.getElementById('msgs').appendChild(bubbleBox); | |
| }, | |
| renderBotMessage: (textContent, bypassStreamFormatting = false) => { | |
| const bubbleBox = document.createElement('div'); | |
| bubbleBox.className = 'chat-message-row bot-msg'; | |
| bubbleBox.innerHTML = ` | |
| <div class="msg-avatar"><img src="${Config.LOGO_URL}" alt="AI"></div> | |
| <div class="msg-content-column"> | |
| <div class="chat-bubble"></div> | |
| </div>`; | |
| document.getElementById('msgs').appendChild(bubbleBox); | |
| ChatEngine.updateBotBubble(bubbleBox, textContent, !bypassStreamFormatting); | |
| return bubbleBox; | |
| }, | |
| updateBotBubble: (bubbleDOM, rawMarkup, isCurrentlyStreaming) => { | |
| const contentTarget = bubbleDOM.querySelector('.chat-bubble'); | |
| // Strip out internal `<think>` reasoning logic so it is hidden | |
| const strippedMarkup = rawMarkup.replace(/<think>([\s\S]*?)(<\/think>|$)/gi, ''); | |
| let renderHTML = marked.parse(strippedMarkup.trim()); | |
| if (isCurrentlyStreaming) { | |
| renderHTML += `<div class="loading-dots-container"><div class="loading-dot"></div><div class="loading-dot"></div><div class="loading-dot"></div></div>`; | |
| } | |
| contentTarget.innerHTML = renderHTML; | |
| // Mount actionable buttons when complete | |
| let actionTray = bubbleDOM.querySelector('.bot-actions-row'); | |
| if (!isCurrentlyStreaming && !actionTray && strippedMarkup.trim().length > 0) { | |
| const safeRawCopy = strippedMarkup.replace(/"/g, '"').replace(/'/g, "\\'").replace(/\n/g, '\\n').replace(/\r/g, ''); | |
| const safeRawTTS = strippedMarkup.replace(/"/g, '"').replace(/'/g, "\\'").replace(/\n/g, ' '); | |
| const actionsHTML = ` | |
| <div class="bot-actions-row"> | |
| <button class="btn-bot-action" onclick="Utils.copyToClipboard(this, \`${safeRawCopy}\`)"> | |
| <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg> | |
| Copy Logic | |
| </button> | |
| <button class="btn-bot-action action-tts" onclick="VoiceEngine.executeTTS(\`${safeRawTTS}\`)"> | |
| <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"></path></svg> | |
| Neural Voice | |
| </button> | |
| </div>`; | |
| bubbleDOM.querySelector('.msg-content-column').insertAdjacentHTML('beforeend', actionsHTML); | |
| } | |
| }, | |
| initiateDispatch: async () => { | |
| if (AppState.isProcessing) return; | |
| const inputField = document.getElementById('mainChatInput'); | |
| const rawUserText = inputField.value.trim(); | |
| if (!rawUserText && !AppState.pendingAttachment) return; | |
| // Validate Guest Session Constraint | |
| if (!AppState.currentUser) { | |
| if (AppState.guestCount >= 3) { | |
| AuthManager.openModal(); | |
| return Utils.showToast("Unregistered query limit reached. Secure Login required."); | |
| } | |
| AppState.guestCount++; | |
| localStorage.setItem('arjun_guest', AppState.guestCount.toString()); | |
| document.getElementById('guestCountDisplay').innerText = AppState.guestCount; | |
| } | |
| // UI Cleanup prior to dispatch | |
| inputField.value = ''; | |
| inputField.style.height = 'auto'; | |
| document.getElementById('masterSendBtn').disabled = true; | |
| AppState.isProcessing = true; | |
| const wState = document.getElementById('welcomeState'); | |
| if (wState) wState.style.display = 'none'; | |
| let payloadStr = rawUserText; | |
| let payloadAttachments = []; | |
| let visualBadge = null; | |
| let previewHTMLForChat = ''; | |
| // Handle Pending Document/Media Logic | |
| if (AppState.pendingAttachment) { | |
| previewHTMLForChat = ChatEngine.buildPreviewHTML(AppState.pendingAttachment); | |
| if (AppState.pendingAttachment.type === 'text') { | |
| payloadStr = `[Document Analyzed: ${AppState.pendingAttachment.name}]\n\n---DATA BEGIN---\n${AppState.pendingAttachment.data}\n---DATA END---\n\nUser Prompt: ${rawUserText}`; | |
| visualBadge = '📄 File Appended'; | |
| } else { | |
| payloadAttachments.push({ | |
| type: AppState.pendingAttachment.type, | |
| data: AppState.pendingAttachment.data, | |
| name: AppState.pendingAttachment.name | |
| }); | |
| const icoMap = { 'video': '🎥 ', 'audio': '🎵 ', 'image': '🖼️ ' }; | |
| visualBadge = (icoMap[AppState.pendingAttachment.type] || '📎 ') + "Media Appended"; | |
| } | |
| // Render locally | |
| ChatEngine.renderUserMessage(rawUserText || '[Transmitting Media Context]', visualBadge, previewHTMLForChat); | |
| // Save to logical history | |
| AppState.history.push({ | |
| role: 'user', | |
| content: payloadStr, | |
| badge: visualBadge, | |
| previewHTML: previewHTMLForChat | |
| }); | |
| } else { | |
| ChatEngine.renderUserMessage(rawUserText, null, ''); | |
| AppState.history.push({ role: 'user', content: rawUserText }); | |
| } | |
| FileProcessor.discardFile(); | |
| ChatEngine.saveHistoryToCloud(); | |
| // Create Empty Bot Bubble for streaming | |
| const activeBotBubble = ChatEngine.renderBotMessage('', false); | |
| UIManager.forceScrollDown(); | |
| // 🎲 Dynamic Pollinations Generator | |
| const cryptographicSeed = Math.floor(Math.random() * 999999999); | |
| // 🧠 Advanced Cognitive System Instructions | |
| let cognitivePrompt = `You are Arjun 2.O, a sophisticated enterprise AI system architected by Abhay Kumar. | |
| LANGUAGE REGULATION: You possess strict bilingual fluency. You MUST analyze the user's language and respond seamlessly in BOTH English and Hindi. | |
| - If the prompt is purely English, output pure English. | |
| - If the prompt contains Hindi (Devanagari or Hinglish), respond in natural Hindi. | |
| - Adapt tone to be highly professional, intelligent, and authoritative. | |
| IMAGE SYNTHESIS OVERRIDE: | |
| When commanded to render, generate, or create an image/photograph, you MUST reply with a precise markdown image node targeting Pollinations AI. | |
| Formula:  | |
| Available Models: flux, flux-realism, flux-anime, flux-3d. | |
| CRITICAL: The seed parameter is mandatory to bypass cache mechanics. Always render this markdown node.`; | |
| if (AppState.isLiveModeEngaged) { | |
| cognitivePrompt += `\n\n[LIVE ACOUSTIC OVERRIDE]: You are currently engaged in a LIVE, REAL-TIME VOCAL INTERFACE. | |
| MANDATORY direct answers. Maximum brevity. Eliminate complex markdown, massive code blocks, or extended lists. Replicate human telephonic brevity perfectly.`; | |
| } | |
| // Sanitize payload for backend | |
| const secureHistory = AppState.history.slice(0, -1).map(h => ({ role: h.role, content: h.content })); | |
| const transmissionPayload = { | |
| message: payloadStr, | |
| attachments: payloadAttachments, | |
| system_prompt: cognitivePrompt, | |
| history: secureHistory, | |
| max_tokens: AppState.isLiveModeEngaged ? 120 : 4096, | |
| temperature: 0.75 | |
| }; | |
| // Network Transmission Logic | |
| try { | |
| const fetchOp = await fetch('/api/chat', { | |
| method: 'POST', | |
| headers: {'Content-Type': 'application/json'}, | |
| body: JSON.stringify(transmissionPayload) | |
| }); | |
| if (!fetchOp.ok) throw new Error("API Matrix Disconnected."); | |
| const networkReader = fetchOp.body.getReader(); | |
| const textDecoder = new TextDecoder(); | |
| let responseBuffer = ""; | |
| AppState.isStreamingActive = true; | |
| while (true) { | |
| const { done, value } = await networkReader.read(); | |
| if (done) break; | |
| const decodedChunk = textDecoder.decode(value, { stream: true }); | |
| const fragmentedLines = decodedChunk.split('\n'); | |
| for (let line of fragmentedLines) { | |
| if (line.startsWith('data: ')) { | |
| const parseableStr = line.substring(6); | |
| if (parseableStr.trim() === '[DONE]') continue; | |
| try { | |
| const jsonSegment = JSON.parse(parseableStr); | |
| if (jsonSegment.choices && jsonSegment.choices[0].delta.content) { | |
| responseBuffer += jsonSegment.choices[0].delta.content; | |
| ChatEngine.updateBotBubble(activeBotBubble, responseBuffer, true); | |
| UIManager.autoScroll(); | |
| } | |
| } catch (e) { /* Segment fragmentation caught silently */ } | |
| } | |
| } | |
| } | |
| AppState.isStreamingActive = false; | |
| ChatEngine.updateBotBubble(activeBotBubble, responseBuffer, false); | |
| AppState.history.push({ role: 'bot', content: responseBuffer }); | |
| ChatEngine.saveHistoryToCloud(); | |
| if (AppState.isLiveModeEngaged) { | |
| document.getElementById('liveStatusText').innerText = "Arjun Transmitting..."; | |
| await VoiceEngine.executeTTS(responseBuffer); | |
| document.getElementById('liveStatusText').innerText = "Tap mic to respond"; | |
| } | |
| } catch(error) { | |
| AppState.isStreamingActive = false; | |
| ChatEngine.updateBotBubble(activeBotBubble, `**System Error:** Communication array offline. Verification needed.`, false); | |
| if (AppState.isLiveModeEngaged) { | |
| document.getElementById('liveStatusText').innerText = "Neural Link Severed."; | |
| } | |
| } | |
| AppState.isProcessing = false; | |
| document.getElementById('masterSendBtn').disabled = false; | |
| UIManager.autoScroll(); | |
| } | |
| }; | |
| // Bootstrap Core | |
| window.ApplicationCore = { | |
| launchSystem: startArjunApp | |
| }; | |
| </script> | |
| </body> | |
| </html> |