Code HTML
Code HTML
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AI MedDiagnostics - Ultimate Health Diagnostic Web App</title>
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?
family=Inter:wght@400;500;700&display=swap" rel="stylesheet" />
<!-- Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet" />
<style>
/* Reset */
*, *::before, *::after {
margin: 0; padding: 0; box-sizing: border-box;
}
html {
font-size: 16px;
font-family: 'Inter', sans-serif;
background: linear-gradient(135deg, #d6e9f7, #f9fbfd);
color: #2e3a59;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body, #app {
min-height: 100vh;
display: flex;
flex-direction: column;
}
a {
color: #007aff;
text-decoration: none;
}
a:hover, a:focus {
text-decoration: underline;
outline:none;
}
button {
font-family: 'Inter', sans-serif;
}
/* Utility */
.sr-only {
position: absolute !important;
width: 1px !important;
height: 1px !important;
padding: 0 !important;
margin: -1px !important;
overflow: hidden !important;
clip: rect(0,0,0,0) !important;
white-space: nowrap !important;
border: 0 !important;
}
/* Container */
.container {
max-width: 960px;
margin: 0 auto;
padding: 0 24px 48px;
flex-grow: 1;
display: flex;
flex-direction: column;
}
/* Header */
header {
position: sticky;
top: 0;
z-index: 10000;
background: rgba(255 255 255 / 0.85);
backdrop-filter: saturate(180%) blur(14px);
box-shadow: 0 2px 10px rgb(0 0 0 / 0.05);
user-select: none;
}
.header-container {
max-width: 960px;
margin: 0 auto;
padding: 14px 24px;
display: flex;
align-items: center;
justify-content: space-between;
}
.logo {
font-weight: 700;
font-size: 1.6rem;
color: #007aff;
user-select: text;
letter-spacing: 0.02em;
}
nav {
display: flex;
gap: 24px;
}
nav a {
font-weight: 600;
font-size: 1rem;
padding: 8px 14px;
border-radius: 14px;
color: #007aff;
display: flex;
align-items: center;
gap: 6px;
transition: background-color 0.3s ease, color 0.3s ease;
user-select: none;
}
nav a.active,
nav a:hover,
nav a:focus {
background: #007aff;
color: white;
outline-offset: 2px;
outline: 2px solid #005bb5;
}
nav a .material-icons {
font-size: 20px;
}
/* Main content */
main {
flex-grow: 1;
width: 100%;
}
/* Footer */
footer {
background: rgba(255 255 255 / 0.9);
text-align: center;
font-size: 0.875rem;
padding: 16px 24px;
color: #555d73;
user-select: none;
border-top: 1px solid #e0e6f2;
}
/* Pages */
.page {
display: none;
animation: fadeIn 0.4s ease forwards;
outline: none;
}
.page.active {
display: block;
}
@keyframes fadeIn {
from {opacity: 0}
to {opacity: 1}
}
/* Home Page */
#home .hero-section {
text-align: center;
margin-top: 72px;
max-width: 650px;
margin-left: auto;
margin-right: auto;
}
#home h1 {
font-weight: 900;
font-size: 3.3rem;
margin-bottom: 12px;
color: #0047cc;
line-height: 1.1;
letter-spacing: 0.01em;
}
#home p {
font-size: 1.15rem;
color: #515a7d;
line-height: 1.6;
margin-bottom: 36px;
}
#start-checker-btn {
background: linear-gradient(135deg, #007aff 0%, #00c6ff 100%);
color: white;
border: none;
padding: 18px 48px;
font-size: 1.15rem;
font-weight: 700;
border-radius: 24px;
box-shadow: 0 12px 28px rgba(0,122,255,0.42);
cursor: pointer;
user-select: none;
transition: all 0.3s ease;
}
#start-checker-btn:hover,
#start-checker-btn:focus {
box-shadow: 0 20px 40px rgba(0,198,255,0.6);
transform: translateY(-3px);
outline: none;
}
/* Symptom Checker Page */
#symptom-checker {
margin-top: 48px;
max-width: 650px;
margin-left: auto;
margin-right: auto;
}
#symptom-checker h2 {
font-size: 2.2rem;
font-weight: 700;
margin-bottom: 24px;
color: #1a2a6c;
}
form {
display: flex;
flex-direction: column;
gap: 16px;
}
label {
font-weight: 600;
font-size: 1rem;
color: #374172;
}
input[type="text"] {
padding: 14px 18px;
font-size: 1rem;
border-radius: 20px;
border: 1.5px solid #b1b7d1;
transition: border-color 0.3s ease;
outline-offset: 3px;
outline-color: #007aff;
}
input[type="text"]:focus {
border-color: #007aff;
outline: none;
}
#get-diagnosis-btn {
background: linear-gradient(135deg, #007aff, #00c6ff);
border: none;
color: white;
padding: 16px 40px;
font-weight: 700;
font-size: 1.1rem;
border-radius: 24px;
cursor: pointer;
box-shadow: 0 10px 24px rgba(0,122,255,0.45);
align-self: flex-start;
user-select: none;
transition: all 0.3s ease;
}
#get-diagnosis-btn:hover,
#get-diagnosis-btn:focus {
box-shadow: 0 18px 38px rgba(0,198,255,0.65);
transform: translateY(-3px);
outline: none;
}
/* Diagnosis Result Panel */
#diagnosis-result {
margin-top: 40px;
background: rgba(255 255 255 / 0.7);
border-radius: 24px;
box-shadow: 0 6px 28px rgba(0 122 255 / 0.22);
padding: 28px 36px;
user-select: text;
opacity: 0;
transform: translateY(60px);
pointer-events: none;
transition: opacity 0.5s ease, transform 0.5s ease;
}
#diagnosis-result.visible {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}
#diagnosis-result h3 {
font-size: 1.8rem;
font-weight: 700;
color: #007aff;
margin-bottom: 18px;
user-select: text;
}
#diagnosis-result p {
font-size: 1.15rem;
margin-bottom: 12px;
color: #4a5e95;
line-height: 1.5;
user-select: text;
}
#diagnosis-result p strong {
color: #0047cc;
}
/* Health Assistant Page */
#health-assistant {
margin-top: 48px;
max-width: 650px;
margin-left: auto;
margin-right: auto;
display: flex;
flex-direction: column;
height: calc(90vh);
}
#health-assistant h2 {
font-size: 2.2rem;
font-weight: 700;
margin-bottom: 20px;
color: #1a2a6c;
}
#assistant-chat {
flex-grow: 1;
background: white;
border-radius: 24px;
box-shadow: 0 12px 38px rgba(0 122 255 / 0.3);
display: flex;
flex-direction: column;
padding: 20px 24px;
user-select: none;
}
#assistant-messages {
flex-grow: 1;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 14px;
user-select: text;
}
.msg-bubble {
max-width: 82%;
padding: 14px 20px;
border-radius: 24px;
font-size: 1rem;
line-height: 1.3;
word-break: break-word;
white-space: pre-wrap;
user-select: text;
}
.msg-user {
background: #007aff;
color: white;
align-self: flex-end;
border-bottom-right-radius: 6px;
box-shadow: 0 8px 14px rgb(0 122 255 / 0.45);
animation: slideInRight 0.25s ease forwards;
}
.msg-bot {
background: #f1f6ff;
color: #2c3a59;
align-self: flex-start;
border-bottom-left-radius: 6px;
animation: slideInLeft 0.25s ease forwards;
}
@keyframes slideInRight {
from {opacity: 0; transform: translateX(60px);}
to {opacity: 1; transform: translateX(0);}
}
@keyframes slideInLeft {
from {opacity: 0; transform: translateX(-60px);}
to {opacity: 1; transform: translateX(0);}
}
#assistant-input-area {
margin-top: 16px;
display: flex;
gap: 16px;
}
#assistant-input {
flex-grow: 1;
padding: 14px 18px;
font-size: 1rem;
border-radius: 24px;
border: 1.5px solid #b1b7d1;
outline-offset: 3px;
outline-color: #007aff;
min-height: 44px;
resize: none;
font-family: 'Inter', sans-serif;
}
#assistant-input:focus {
border-color: #007aff;
outline: none;
}
#assistant-send-btn {
background: linear-gradient(135deg, #007aff 0%, #00c6ff 100%);
border: none;
border-radius: 24px;
color: white;
padding: 0 24px;
font-weight: 700;
font-size: 1.1rem;
cursor: pointer;
box-shadow: 0 10px 28px rgba(0,122,255,0.42);
transition: box-shadow 0.3s ease, transform 0.3s ease;
}
#assistant-send-btn:hover,
#assistant-send-btn:focus {
box-shadow: 0 18px 38px rgba(0,198,255,0.65);
transform: translateY(-2px);
outline: none;
}
/* Typing indicator for assistant */
#assistant-typing-indicator {
display: flex;
gap: 10px;
margin-top: 12px;
align-items: center;
user-select: none;
}
.typing-dot {
width: 10px;
height: 10px;
background: #007aff;
border-radius: 50%;
animation: typingBounce 1.4s infinite ease-in-out;
}
.typing-dot:nth-child(2) {
animation-delay: 0.2s;
}
.typing-dot:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes typingBounce {
0%, 80%, 100% {transform: translateY(0);}
40% {transform: translateY(-10px);}
}
/* Scrollbar */
::-webkit-scrollbar {
width: 10px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #a2a7bb;
border-radius: 8px;
}
/* Responsive */
@media (max-width: 600px) {
nav {
gap: 12px;
}
nav a {
font-size: 0.95rem;
padding: 6px 12px;
border-radius: 16px;
}
#home h1 {
font-size: 2.5rem;
}
#symptom-checker, #health-assistant {
margin-top: 32px;
max-width: 90vw;
}
#assistant-input-area {
gap: 12px;
}
.tracker-inputs {
flex-direction: column;
}
.tracker-inputs label,
.tracker-inputs input[type="number"],
.tracker-inputs input[type="date"] {
flex-grow: unset;
width: 100%;
}
.tab-buttons {
gap: 8px;
}
.tab-button {
flex: 1 1 auto;
font-size: 0.95rem;
}
}
</style>
</head>
<body>
<header role="banner" aria-label="Main Navigation">
<div class="header-container">
<a href="#home" class="logo" aria-label="AI MedDiagnostics Home - Made by
Shreyansh Saraswati">AI MedDiagnostics</a>
<nav role="navigation" aria-label="Primary navigation">
<a href="#home" class="nav-link active" id="nav-home" tabindex="0" aria-
current="page" role="link">
<span class="material-icons" aria-hidden="true">home</span> Home
</a>
<a href="#symptom-checker" class="nav-link" id="nav-symptom-checker"
tabindex="0" role="link">
<span class="material-icons" aria-hidden="true">healing</span> Symptom
Checker
</a>
<a href="#health-assistant" class="nav-link" id="nav-health-assistant"
tabindex="0" role="link">
<span class="material-icons" aria-hidden="true">smart_toy</span> Health
Assistant
</a>
</nav>
</div>
</header>
</div>
</section>
</main>
<footer role="contentinfo">
Made with care by <strong>Shreyansh Saraswati</strong> © 2024 AI MedDiagnostics
</footer>
<script>
(() => {
/* Utility for localStorage persistence */
function saveToStorage(key, data) {
localStorage.setItem(key, JSON.stringify(data));
}
function loadFromStorage(key) {
const json = localStorage.getItem(key);
if(!json) return null;
try {
return JSON.parse(json);
} catch {
return null;
}
}
/* SPA Navigation */
const pages = {
home: document.getElementById('home'),
symptomChecker: document.getElementById('symptom-checker'),
healthAssistant: document.getElementById('health-assistant'),
};
const navLinks = {
home: document.getElementById('nav-home'),
symptomChecker: document.getElementById('nav-symptom-checker'),
healthAssistant: document.getElementById('nav-health-assistant'),
};
function switchPage(target) {
Object.entries(pages).forEach(([key, el]) => {
if (key === target) {
el.classList.add('active');
el.setAttribute('aria-hidden', 'false');
navLinks[key].classList.add('active');
navLinks[key].setAttribute('aria-current', 'page');
el.focus();
} else {
el.classList.remove('active');
el.setAttribute('aria-hidden', 'true');
navLinks[key].classList.remove('active');
navLinks[key].removeAttribute('aria-current');
}
});
}
navLinks.home.addEventListener('click', e => { e.preventDefault();
switchPage('home'); });
navLinks.symptomChecker.addEventListener('click', e => { e.preventDefault();
switchPage('symptomChecker'); });
navLinks.healthAssistant.addEventListener('click', e => { e.preventDefault();
switchPage('healthAssistant'); });
document.getElementById('start-checker-btn').addEventListener('click', () =>
{ switchPage('symptomChecker'); document.getElementById('symptom-
input').focus(); });
const diagnosisDB = [
{name: "Common Cold", symptoms: ['cough', 'sneezing', 'runny nose', 'sore
throat'], explanation: "A viral infection affecting your nose and throat.",
recommendation: "Rest, stay hydrated, and use over-the-counter cold remedies if
necessary.", keywords: ['cough', 'sneezing', 'runny nose', 'sore throat'],
confidenceBase: 80},
{name: "Influenza (Flu)", symptoms: ['fever', 'muscle pain', 'chills',
'fatigue'], explanation: "A contagious respiratory illness caused by influenza
viruses.", recommendation: "Rest, drink fluids, and consult a doctor if symptoms
worsen or persist more than a few days.", keywords: ['fever', 'muscle pain',
'chills', 'fatigue'], confidenceBase: 85},
{name: "Tonsillitis", symptoms: ['sore throat', 'fever', 'difficulty
swallowing'], explanation: "Inflammation of the tonsils, typically due to viral or
bacterial infection.", recommendation: "Warm liquids, rest, and see a doctor if
symptoms worsen.", keywords: ['sore throat', 'fever', 'difficulty swallowing'],
confidenceBase: 87},
{name: "Food Poisoning", symptoms: ['nausea', 'vomiting', 'stomach ache',
'diarrhea'], explanation: "Illness caused by eating contaminated food or drinks.",
recommendation: "Stay hydrated, rest, and seek medical attention if symptoms are
severe or persist.", keywords: ['nausea', 'vomiting', 'stomach ache', 'diarrhea'],
confidenceBase: 90},
{name: "Migraine", symptoms: ['headache', 'nausea', 'sensitivity to light',
'pulsating pain'], explanation: "A neurological condition causing intense
headaches.", recommendation: "Rest in a quiet dark room and consider pain-relief
medications; consult a neurologist if frequent.", keywords: ['headache', 'nausea',
'sensitivity to light', 'pulsating pain'], confidenceBase: 75},
{name: "Anxiety", symptoms: ['restlessness', 'fatigue', 'difficulty
concentrating', 'irritability'], explanation: "A mental health disorder causing
excessive worry.", recommendation: "Practice relaxation techniques and consult a
mental health professional if persistent.", keywords: ['restlessness', 'fatigue',
'difficulty concentrating', 'irritability'], confidenceBase: 70},
];
function diagnoseSymptoms(input) {
const userSymptoms = input.toLowerCase()
.split(',')
.map(s => s.trim())
.filter(Boolean);
assistantForm.addEventListener('submit', e => {
e.preventDefault();
let userInput = assistantInput.value.trim();
if(!userInput) return;
assistantInput.value = '';
addMessage(userInput, 'user');
showTyping();
setTimeout(() => {
hideTyping();
let reply = generateAssistantReply(userInput);
addMessage(reply, 'bot');
}, 1200);
});
bmiForm.addEventListener('submit', e => {
e.preventDefault();
const height = parseFloat(bmiHeightInput.value);
const weight = parseFloat(bmiWeightInput.value);
function renderReminders(){
if(reminders.length === 0){
remindersList.innerHTML = "<p>No reminders added yet.</p>";
return;
}
remindersList.innerHTML = '';
reminders.forEach((r,i)=>{
const div = document.createElement('div');
div.className = 'tracker-log-item';
div.textContent = `${r.medName} - ${r.medDose || 'No dosage info'} at $
{r.time}`;
const btn = document.createElement('button');
btn.textContent = 'Delete';
btn.type = 'button';
btn.style.marginLeft = '12px';
btn.style.color = '#ff4d4d';
btn.style.background = 'none';
btn.style.border = 'none';
btn.style.cursor = 'pointer';
btn.style.fontWeight = '700';
btn.title = 'Delete reminder';
btn.addEventListener('click', () => {
reminders.splice(i, 1);
saveToStorage('medReminders', reminders);
renderReminders();
});
div.appendChild(btn);
remindersList.appendChild(div);
});
}
renderReminders();
reminderForm.addEventListener('submit', e => {
e.preventDefault();
const medName = medNameInput.value.trim();
const medDose = medDoseInput.value.trim();
const time = reminderTimeInput.value;
if(!medName){
alert('Please enter medication name.');
medNameInput.focus();
return;
}
if(!time){
alert('Please select reminder time.');
reminderTimeInput.focus();
return;
}
function renderHealthLogs(){
if(healthLogs.length === 0){
trackerLogs.innerHTML = "<p>No health logs added yet.</p>";
return;
}
trackerLogs.innerHTML = '';
healthLogs.slice().reverse().forEach(log=>{
const div = document.createElement('div');
div.className = 'tracker-log-item';
const dateStr = new Date(log.date).toLocaleDateString();
div.innerHTML = `<strong>${dateStr}</strong> - Temp: ${log.bodyTemp || 'N/A'}
°C, BP: ${log.systolic || 'N/A'}/${log.diastolic || 'N/A'} mmHg<br/>Notes: $
{log.notes || 'None'}`;
trackerLogs.appendChild(div);
});
}
renderHealthLogs();
trackerForm.addEventListener('submit', e => {
e.preventDefault();
const dateVal = trackDateInput.value;
if(!dateVal){
alert('Please select a date.');
trackDateInput.focus();
return;
}
const bodyTemp = bodyTempInput.value ? parseFloat(bodyTempInput.value) : null;
if(bodyTemp !== null && (bodyTemp < 30 || bodyTemp > 45)){
alert('Please enter a realistic body temperature between 30 and 45 °C.');
bodyTempInput.focus();
return;
}
const systolic = systolicInput.value ? parseInt(systolicInput.value) : null;
const diastolic = diastolicInput.value ? parseInt(diastolicInput.value) : null;
if((systolic !== null && (systolic < 50 || systolic > 250)) || (diastolic !==
null && (diastolic < 30 || diastolic > 150))){
alert('Please enter realistic blood pressure values.');
return;
}
const notes = trackerNotesInput.value.trim();
function renderNotes(){
if(personalNotes.length === 0){
notesList.innerHTML = "<p>No notes added yet.</p>";
return;
}
notesList.innerHTML = '';
personalNotes.slice().reverse().forEach(note=>{
const div = document.createElement('div');
div.className = 'tracker-log-item';
div.style.paddingBottom = '8px';
const dateStr = new Date(note.created).toLocaleString();
div.innerHTML = `<strong>${note.title}</strong> <small style="color:#555;
font-size: 0.8rem;">(${dateStr})</small><br/>${note.content}`;
notesList.appendChild(div);
});
}
renderNotes();
notesForm.addEventListener('submit', e => {
e.preventDefault();
const title = noteTitleInput.value.trim();
const content = noteContentInput.value.trim();
if(!title){
alert('Please enter a title for your note.');
noteTitleInput.focus();
return;
}
if(!content){
alert('Please enter some content for your note.');
noteContentInput.focus();
return;
}
noteTitleInput.value = '';
noteContentInput.value = '';
});
})();
</script>
</body>
</html>