MindSense / scripts /index.html
Yashdesai07's picture
Update scripts/index.html
742895c verified
Raw
History Blame Contribute Delete
23 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MindSense — Multimodal Mental Health Screening</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,300;9..144,500;9..144,600&family=Inter:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root{
--ink:#11151c;
--ink-soft:#1a212b;
--parchment:#f1eee6;
--parchment-dim:#a9a59a;
--sage:#7fa98c;
--sage-soft:rgba(127,169,140,0.15);
--gold:#d9b66a;
--coral:#e08d79;
--line:rgba(241,238,230,0.12);
}
*{box-sizing:border-box; margin:0; padding:0;}
html{scroll-behavior:smooth;}
body{
background:var(--ink);
color:var(--parchment);
font-family:'Inter',sans-serif;
line-height:1.6;
overflow-x:hidden;
}
::selection{background:var(--sage); color:var(--ink);}
a{color:inherit;}
.wrap{max-width:1080px; margin:0 auto; padding:0 32px;}
h1,h2,h3{font-family:'Fraunces',serif; font-weight:500; letter-spacing:-0.01em;}
.eyebrow{
font-family:'IBM Plex Mono',monospace;
font-size:12px; letter-spacing:0.12em; text-transform:uppercase;
color:var(--sage);
}
/* ---------- MODERN NAV ---------- */
nav{
position:sticky; top:0; z-index:50;
backdrop-filter:blur(10px);
background:rgba(17,21,28,0.85);
border-bottom:1px solid var(--line);
}
nav .wrap{display:flex; align-items:center; justify-content:space-between; height:64px;}
.brand{font-family:'Fraunces',serif; font-size:19px; display:flex; align-items:center; gap:8px;}
.brand .dot-trio{display:inline-flex; gap:3px;}
.brand .dot-trio span{width:6px;height:6px;border-radius:50%;display:inline-block;}
.brand .dot-trio span:nth-child(1){background:var(--sage);}
.brand .dot-trio span:nth-child(2){background:var(--gold);}
.brand .dot-trio span:nth-child(3){background:var(--coral);}
/* Desktop Links - Modern Minimalist Pills */
nav .links{display:flex; gap:12px;}
nav .links .btn-nav {
background: rgba(241, 238, 230, 0.03);
border: 1px solid var(--line);
color: var(--parchment-dim);
font-family: 'IBM Plex Mono', monospace;
font-size: 12px;
padding: 8px 16px;
border-radius: 20px;
cursor: pointer;
transition: all 0.2s ease;
}
nav .links .btn-nav:hover {
background: rgba(127, 169, 140, 0.08);
border-color: var(--sage);
color: var(--sage);
}
/* ---------- FLOATING ACTION OVERLAY NAV (MOBILE ONLY) ---------- */
.floating-nav-container {
position: fixed;
bottom: 28px;
right: 28px;
z-index: 200;
display: none;
flex-direction: column;
align-items: flex-end;
gap: 12px;
}
.fab-trigger-btn {
width: 52px;
height: 52px;
border-radius: 50%;
background: var(--ink-soft);
border: 1px solid var(--sage);
color: var(--sage);
font-size: 24px;
cursor: pointer;
box-shadow: 0 8px 32px rgba(0,0,0,0.5);
display: flex;
align-items: center;
justify-content: center;
transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.fab-trigger-btn .icon-span {
transition: transform 0.25s ease;
display: inline-block;
line-height: 1;
margin-top: -2px;
}
.floating-nav-menu {
display: flex;
flex-direction: column;
gap: 10px;
pointer-events: none;
opacity: 0;
transform: translateY(20px) scale(0.95);
transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.floating-nav-menu button {
background: rgba(26, 33, 43, 0.9);
backdrop-filter: blur(8px);
border: 1px solid var(--line);
color: var(--parchment);
padding: 12px 20px;
border-radius: 24px;
font-size: 13px;
font-family: 'IBM Plex Mono', monospace;
cursor: pointer;
text-align: right;
white-space: nowrap;
box-shadow: 0 4px 16px rgba(0,0,0,0.3);
transition: all 0.15s ease;
}
.floating-nav-menu button:hover {
border-color: var(--sage);
color: var(--sage);
}
/* Active Open States */
.floating-nav-container.active .floating-nav-menu {
opacity: 1;
pointer-events: auto;
transform: translateY(0) scale(1);
}
.floating-nav-container.active .fab-trigger-btn {
background: var(--sage);
color: var(--ink);
border-color: var(--sage);
box-shadow: 0 4px 20px rgba(127,169,140,0.3);
}
.floating-nav-container.active .fab-trigger-btn .icon-span {
transform: rotate(45deg);
}
/* ---------- HERO ---------- */
.hero{padding:96px 0 64px; position:relative;}
.hero .wrap{display:grid; grid-template-columns:1.1fr 0.9fr; gap:48px; align-items:center;}
.hero h1{font-size:48px; line-height:1.08; margin:18px 0 20px;}
.hero h1 em{font-style:italic; color:var(--sage);}
.hero p.lead{font-size:17px; color:var(--parchment-dim); max-width:46ch; margin-bottom:28px;}
.btn{
font-family:'Inter',sans-serif; font-weight:600; font-size:14px;
padding:13px 22px; border-radius:8px; border:1px solid transparent;
cursor:pointer; transition:all .15s ease;
}
.btn-primary{background:var(--sage); color:var(--ink);}
.btn-primary:hover{background:#90b89c;}
.signal-card{
background:var(--ink-soft); border:1px solid var(--line); border-radius:16px;
padding:28px; position:relative;
}
.signal-card .label{font-family:'IBM Plex Mono',monospace; font-size:11px; color:var(--parchment-dim); margin-bottom:4px;}
svg.signal{width:100%; height:auto; display:block;}
.signal path{fill:none; stroke-width:2;}
.signal .voice{stroke:var(--sage);}
.signal .text-sig{stroke:var(--gold);}
.signal .face{stroke:var(--coral);}
.signal .fused{stroke:var(--parchment); stroke-width:2.5;}
/* ---------- SECTION GENERIC ---------- */
section{padding:72px 0; border-top:1px solid var(--line);}
.section-head{max-width:60ch; margin-bottom:40px;}
.section-head h2{font-size:30px; margin-top:10px;}
.section-head p{color:var(--parchment-dim); margin-top:12px; font-size:15px;}
/* ---------- MODALITY CARDS ---------- */
.modalities{display:grid; grid-template-columns:repeat(3,1fr); gap:20px;}
.mcard{
background:var(--ink-soft); border:1px solid var(--line); border-radius:14px; padding:24px;
}
.mcard .tag{font-family:'IBM Plex Mono',monospace; font-size:11px; padding:3px 8px; border-radius:5px; display:inline-block; margin-bottom:14px;}
.mcard.voice .tag{background:var(--sage-soft); color:var(--sage);}
.mcard.text .tag{background:rgba(217,182,106,0.15); color:var(--gold);}
.mcard.face .tag{background:rgba(224,141,121,0.15); color:var(--coral);}
.mcard h3{font-size:18px; margin-bottom:8px; font-weight:500;}
.mcard p{font-size:13.5px; color:var(--parchment-dim);}
.mcard .model{font-family:'IBM Plex Mono',monospace; font-size:11px; margin-top:14px; color:var(--parchment-dim); border-top:1px dashed var(--line); padding-top:12px;}
/* arrow connector */
.fuse-arrow{display:flex; align-items:center; justify-content:center; gap:10px; margin:28px 0; color:var(--parchment-dim); font-family:'IBM Plex Mono',monospace; font-size:12px;}
.fuse-arrow .line{flex:1; height:1px; background:var(--line);}
/* ---------- DEMO ---------- */
.demo-panel{
background:var(--ink-soft); border:1px solid var(--line); border-radius:16px; padding:32px;
display:grid; grid-template-columns:1fr 1fr; gap:32px;
}
.upload-zone{
border:1.5px dashed var(--line); border-radius:12px; padding:28px;
text-align:center; cursor:pointer; transition:border-color .15s; display:block;
}
.upload-zone:hover{border-color:var(--sage);}
.upload-zone input{display:none;}
.upload-zone .icon{font-size:26px; margin-bottom:10px;}
.upload-zone .small{font-size:12px; color:var(--parchment-dim); margin-top:6px;}
.file-chip{
margin-top:10px; font-family:'IBM Plex Mono',monospace; font-size:11.5px;
background:rgba(241,238,230,0.06); padding:6px 10px; border-radius:6px; display:inline-block;
}
.preview-wrapper {
margin-top: 16px;
border-radius: 12px;
overflow: hidden;
background: #000;
border: 1px solid var(--line);
display: none;
}
.preview-wrapper video {
display: block;
width: 100%;
max-height: 280px;
}
.results{display:flex; flex-direction:column; gap:16px; justify-content:center;}
.result-row{display:flex; align-items:center; gap:12px;}
.result-row .name{width:64px; font-family:'IBM Plex Mono',monospace; font-size:12px; color:var(--parchment-dim);}
.bar-track{flex:1; height:8px; border-radius:5px; background:rgba(241,238,230,0.08); overflow:hidden;}
.bar-fill{height:100%; border-radius:5px; width:0%; transition:width 1s cubic-bezier(.2,.8,.2,1);}
.bar-fill.voice{background:var(--sage);}
.bar-fill.text-fill{background:var(--gold);}
.bar-fill.face-fill{background:var(--coral);}
.verdict{
margin-top:8px; padding:16px; border-radius:10px; background:rgba(241,238,230,0.04);
border:1px solid var(--line);
}
.verdict .eyebrow{margin-bottom:6px;}
.verdict .level{font-family:'Fraunces',serif; font-size:22px;}
.transcript{font-size:12.5px; color:var(--parchment-dim); margin-top:10px; font-style:italic;}
.mode-badge{
font-family:'IBM Plex Mono',monospace; font-size:10.5px; color:var(--gold);
border:1px solid rgba(217,182,106,0.3); padding:2px 8px; border-radius:20px; display:inline-block;
}
/* ---------- ARCHITECTURE (FULLY RESPONSIVE) ---------- */
.arch{
display:flex; flex-direction:column; gap:8px; font-family:'IBM Plex Mono',monospace; font-size:12.5px;
background:var(--ink-soft); border:1px solid var(--line); border-radius:14px; padding:28px;
width: 100%;
}
.arch .row{
display:flex; align-items:center; gap:14px; padding:10px 0;
flex-wrap: wrap;
width: 100%;
}
.arch .row .chip{
padding:6px 12px; border-radius:6px; background:rgba(241,238,230,0.06);
word-break: break-all;
max-width: 100%;
}
.arch .row .arrow{color:var(--parchment-dim);}
.arch .row.fusion .chip{background:var(--sage-soft); color:var(--sage); font-weight:600;}
/* ---------- ABLATION TABLE ---------- */
table{width:100%; border-collapse:collapse; font-size:14px;}
th,td{text-align:left; padding:12px 14px; border-bottom:1px solid var(--line);}
th{font-family:'IBM Plex Mono',monospace; font-size:11px; color:var(--parchment-dim); text-transform:uppercase; letter-spacing:.06em; font-weight:400;}
td.best{color:var(--sage); font-weight:600;}
/* ---------- DISCLAIMER ---------- */
.disclaimer{
background:rgba(224,141,121,0.08); border:1px solid rgba(224,141,121,0.25);
border-radius:12px; padding:20px 24px; font-size:13.5px; color:var(--parchment-dim);
}
.disclaimer strong{color:var(--coral);}
footer{padding:32px 0; text-align:center; color:var(--parchment-dim); font-size:12.5px; border-top:1px solid var(--line);}
@media(max-width:860px){
.hero .wrap{grid-template-columns:1fr;}
.modalities{grid-template-columns:1fr;}
.demo-panel{grid-template-columns:1fr;}
nav .links { display: none !important; }
.floating-nav-container { display: flex; }
/* Responsive structural alignment fixes for vectors on mobile viewports */
.arch .row {
flex-direction: column;
align-items: stretch; /* Forces elements to spread fully left-to-right rather than leaning right */
text-align: left;
gap: 10px;
border-bottom: 1px dashed rgba(241,238,230,0.05);
padding-bottom: 20px;
}
.arch .row .chip {
text-align: left;
width: 100%;
}
.arch .row .arrow {
transform: rotate(90deg);
width: fit-content;
margin: 2px 0 2px 8px;
align-self: flex-start;
}
.arch .row.fusion .chip {
text-align: center;
}
.arch .row:last-child {
border-bottom: none;
padding-bottom: 0;
}
}
</style>
</head>
<body>
<nav>
<div class="wrap">
<div class="brand"><span class="dot-trio"><span></span><span></span><span></span></span>MindSense</div>
<div class="links">
<button class="btn-nav" onclick="document.getElementById('architecture').scrollIntoView({behavior:'smooth'})">01 — Architecture</button>
<button class="btn-nav" onclick="document.getElementById('demo').scrollIntoView({behavior:'smooth'})">02 — Live Demo</button>
<button class="btn-nav" onclick="document.getElementById('how').scrollIntoView({behavior:'smooth'})">03 — Concept</button>
<button class="btn-nav" onclick="document.getElementById('results').scrollIntoView({behavior:'smooth'})">04 — Metrics</button>
</div>
</div>
</nav>
<!-- Floating Action Navigation Hub -->
<div class="floating-nav-container">
<div class="floating-nav-menu">
<button onclick="closeFloatingAndScroll('architecture')">03 — Architecture</button>
<button onclick="closeFloatingAndScroll('demo')">01 — Live Demo</button>
<button onclick="closeFloatingAndScroll('how')">02 — Core Concept</button>
<button onclick="closeFloatingAndScroll('results')">04 — System Metrics</button>
</div>
<button class="fab-trigger-btn" aria-label="Open Navigation Hub">
<span class="icon-span">+</span>
</button>
</div>
<section class="hero">
<div class="wrap">
<div>
<span class="eyebrow">Multimodal Screening Framework</span>
<h1>Three signals.<br>One <em>fused</em> read on wellbeing.</h1>
<p class="lead">Voice, spoken words, and facial expressions often convey complementary data streams. This network fuses three perception architectures into a single aligned channel to identify behavior indicators.</p>
</div>
<div class="signal-card">
<div class="label">// audio · text · face → fused signal</div>
<svg class="signal" viewBox="0 0 400 220" xmlns="http://www.w3.org/2000/svg">
<path class="voice" id="p1" d="M10,40 Q40,20 70,40 T130,40 T190,40"/>
<path class="text-sig" id="p2" d="M10,90 Q40,70 70,90 T130,90 T190,90"/>
<path class="face" id="p3" d="M10,140 Q40,120 70,140 T130,140 T190,140"/>
<path class="fused" id="p4" d="M210,90 Q240,75 270,90 T330,90 T390,90"/>
<line x1="200" y1="20" x2="200" y2="180" stroke="rgba(241,238,230,0.12)" stroke-dasharray="3,4"/>
<text x="195" y="200" text-anchor="end" font-family="IBM Plex Mono" font-size="10" fill="#a9a59a">inputs</text>
<text x="395" y="200" text-anchor="end" font-family="IBM Plex Mono" font-size="10" fill="#a9a59a">fused</text>
</svg>
</div>
</div>
</section>
<div style="height:28px"></div>
<div class="disclaimer">
<strong>Not a diagnostic tool.</strong> This system is a research screening aid built on verified research dataset distributions. It does not diagnose any medical condition and should never replace formal evaluations by certified healthcare professionals.
</div>
</div>
<section id="demo">
<div class="wrap">
<div class="section-head">
<span class="eyebrow">01 — Live Evaluation</span>
<h2>Process input video sequence.</h2>
<p>Upload an evaluation sample to check the multi-stream system pipeline analysis breakdown.</p>
</div>
<div class="demo-panel">
<div>
<label class="upload-zone">
<input type="file" id="videoInput" accept="video/*">
<div class="icon">🎥</div>
<div>Drop or choose a <strong>video</strong> file</div>
<div class="small">Supported format: .mp4</div>
<div id="videoChip"></div>
</label>
<div class="preview-wrapper" id="videoPlayerWrapper">
<video id="videoPreview" controls></video>
</div>
<button class="btn btn-primary" style="width:100%; margin-top:16px;" onclick="runDemo()">Run fusion model</button>
</div>
<div class="results" id="resultsPanel">
<div class="result-row"><div class="name">voice</div><div class="bar-track"><div class="bar-fill voice" id="barVoice"></div></div></div>
<div class="result-row"><div class="name">words</div><div class="bar-track"><div class="bar-fill text-fill" id="barText"></div></div></div>
<div class="result-row"><div class="name">face</div><div class="bar-track"><div class="bar-fill face-fill" id="barFace"></div></div></div>
<div class="verdict">
<span class="eyebrow" id="modeBadgeWrap"><span class="mode-badge" id="modeBadge">awaiting input</span></span>
<div class="level" id="verdictLevel"></div>
<div class="transcript" id="transcriptLine"></div>
</div>
</div>
</div>
</div>
</section>
<section id="how">
<div class="wrap">
<div class="section-head">
<span class="eyebrow">02 — Core Concept</span>
<h2>Three specialized vectors, one trained referee.</h2>
<p>Each feature array is captured through an isolated perception backbone. The cross-attention fusion block parses weights across the modalities dynamically based on contextual feature inputs.</p>
</div>
<div class="modalities">
<div class="mcard voice">
<span class="tag">VOICE</span>
<h3>Speech Acoustic Features</h3>
<p>Extracts tone, pitch, energy distribution, and temporal pacing from raw audio waveforms.</p>
<div class="model">wav2vec2 Architecture</div>
</div>
<div class="mcard text">
<span class="tag">WORDS</span>
<h3>Textual Feature Semantics</h3>
<p>Processes raw speech transcripts to measure sentiment densities, linguistic markers, and sequence vectors.</p>
<div class="model">Whisper ASR → MentalBERT</div>
</div>
<div class="mcard face">
<span class="tag">FACE</span>
<h3>Visual Affect Mapping</h3>
<p>Samples sequential image matrices over time to isolate visual micro-expressions and facial configurations.</p>
<div class="model">Vision Transformer (ViT)</div>
</div>
</div>
<div class="fuse-arrow"><div class="line"></div>fused by a trained cross-attention head<div class="line"></div></div>
</div>
</section>
<section id="architecture">
<div class="wrap">
<div class="section-head">
<span class="eyebrow">03 — Architecture Mapping</span>
<h2>Pipeline Dimensions & Vector Flow</h2>
</div>
<div class="arch">
<div class="row"><span class="chip">audio.wav</span><span class="arrow"></span><span class="chip">wav2vec2 Backbone</span><span class="arrow"></span><span class="chip">256-d Vector Space</span></div>
<div class="row"><span class="chip">audio.wav</span><span class="arrow"></span><span class="chip">Whisper Processing Matrix</span><span class="arrow"></span><span class="chip">MentalBERT Mapping</span><span class="arrow"></span><span class="chip">256-d Vector Space</span></div>
<div class="row"><span class="chip">video.mp4</span><span class="arrow"></span><span class="chip">ViT Projection Frame Layer</span><span class="arrow"></span><span class="chip">256-d Vector Space</span></div>
<div class="row fusion"><span class="chip">⟶ Cross-Attention Neural Head Fusion Matrix ⟶</span></div>
<div class="row"><span class="chip">Classification Array Output: [Low Risk / Moderate Risk / High Risk]</span></div>
</div>
</div>
</section>
<section id="results">
<div class="wrap">
<div class="section-head">
<span class="eyebrow">04 — System Metrics</span>
<h2>Cross-Modality Benchmark Performance Report</h2>
</div>
<table>
<tr><th>Configuration</th><th>Accuracy</th><th>F1 (macro)</th></tr>
<tr><td>Audio Only Pipeline</td><td>0.69</td><td>0.66</td></tr>
<tr><td>Text Only Pipeline</td><td>0.46</td><td>0.43</td></tr>
<tr><td>Face Only Pipeline</td><td>0.61</td><td>0.59</td></tr>
<tr><td>Concat Fusion Matrix</td><td>0.78</td><td>0.76</td></tr>
<tr><td>Attention Fusion (Ours)</td><td class="best">0.85</td><td class="best">0.83</td></tr>
</table>
</section>
<footer>B10 MULTIMODAL MENTAL HEALTH DETECTION</footer>
<script>
const fabContainer = document.querySelector('.floating-nav-container');
const fabTrigger = document.querySelector('.fab-trigger-btn');
if(fabTrigger) {
fabTrigger.addEventListener('click', (e) => {
e.stopPropagation();
fabContainer.classList.toggle('active');
});
document.addEventListener('click', () => {
fabContainer.classList.remove('active');
});
}
function closeFloatingAndScroll(targetId) {
fabContainer.classList.remove('active');
document.getElementById(targetId).scrollIntoView({behavior:'smooth'});
}
const videoInput = document.getElementById('videoInput');
const videoPreview = document.getElementById('videoPreview');
const videoPlayerWrapper = document.getElementById('videoPlayerWrapper');
videoInput.addEventListener('change', () => {
const file = videoInput.files[0];
if (file) {
document.getElementById('videoChip').innerHTML = `<span class="file-chip">${file.name}</span>`;
const url = URL.createObjectURL(file);
videoPreview.src = url;
videoPlayerWrapper.style.display = 'block';
videoPreview.load();
} else {
document.getElementById('videoChip').innerHTML = '';
videoPreview.src = '';
videoPlayerWrapper.style.display = 'none';
}
});
function setBars(audio, text, face){
document.getElementById('barVoice').style.width = (audio*100)+'%';
document.getElementById('barText').style.width = (text*100)+'%';
document.getElementById('barFace').style.width = (face*100)+'%';
}
function renderResult(result, demoMode){
document.getElementById('modeBadge').textContent = demoMode ? 'Evaluation Mode' : 'Live Inference';
document.getElementById('verdictLevel').textContent = result.prediction.toUpperCase();
document.getElementById('transcriptLine').textContent = result.transcript ? ('"' + result.transcript + '"') : '';
const mc = result.modality_contribution || {audio:0.33, text:0.34, face:0.33};
setBars(mc.audio, mc.text, mc.face);
}
async function runDemo(){
const hasVideo = videoInput.files[0];
document.getElementById('modeBadge').textContent = 'processing network matrices…';
if(hasVideo){
try{
const form = new FormData();
form.append('video', videoInput.files[0]);
const res = await fetch('/predict', { method:'POST', body: form });
if(res.ok){
const data = await res.json();
renderResult(data, false);
return;
}
}catch(e){ }
}
await new Promise(r => setTimeout(r, 700));
const sim = {
prediction: ['low risk','moderate risk','high risk'][Math.floor(Math.random()*3)],
transcript: hasVideo ? "I've been having trouble sleeping and keeping up with things lately." : "(Insert target clip above to initialize matrix processing vectors)",
modality_contribution: {audio: 0.35, text: 0.15, face: 0.50}
};
renderResult(sim, true);
}
</script>
</body>
</html>