BinKhoaLe1812 commited on
Commit
3a4efe4
·
verified ·
1 Parent(s): 791045d

Upload 6 files

Browse files
Files changed (6) hide show
  1. Dockerfile +14 -0
  2. assets/.DS_Store +0 -0
  3. assets/app.js +296 -0
  4. assets/logo.svg +8 -0
  5. assets/styles.css +1262 -0
  6. index.html +479 -0
Dockerfile ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Simple static server using Python for Hugging Face Spaces (Docker SDK)
2
+ FROM python:3.11-slim
3
+
4
+ ENV PYTHONDONTWRITEBYTECODE=1
5
+ ENV PYTHONUNBUFFERED=1
6
+ ENV PORT=7860
7
+
8
+ WORKDIR /app
9
+ COPY . /app
10
+
11
+ EXPOSE 7860
12
+
13
+ # Serve static files from /app at $PORT
14
+ CMD ["/bin/sh", "-lc", "python -m http.server ${PORT:-7860}"]
assets/.DS_Store ADDED
Binary file (6.15 kB). View file
 
assets/app.js ADDED
@@ -0,0 +1,296 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Enhanced theme toggle with smooth transitions
2
+ const toggle = document.getElementById('themeToggle');
3
+ const root = document.documentElement;
4
+ const saved = localStorage.getItem('theme') || 'dark';
5
+
6
+ // Apply saved theme
7
+ if (saved === 'light') {
8
+ document.documentElement.classList.remove('dark');
9
+ } else {
10
+ document.documentElement.classList.add('dark');
11
+ }
12
+
13
+ // Update theme toggle icon
14
+ const updateThemeIcon = () => {
15
+ const icon = toggle?.querySelector('i');
16
+ if (icon) {
17
+ icon.setAttribute('data-lucide', document.documentElement.classList.contains('dark') ? 'sun-medium' : 'moon');
18
+ if (window.lucide) {
19
+ lucide.createIcons();
20
+ }
21
+ }
22
+ };
23
+
24
+ // Initialize theme icon
25
+ updateThemeIcon();
26
+
27
+ toggle?.addEventListener('click', () => {
28
+ const isDark = document.documentElement.classList.toggle('dark');
29
+ localStorage.setItem('theme', isDark ? 'dark' : 'light');
30
+ updateThemeIcon();
31
+
32
+ // Add smooth transition effect
33
+ document.body.style.transition = 'background-color 0.3s ease, color 0.3s ease';
34
+ setTimeout(() => {
35
+ document.body.style.transition = '';
36
+ }, 300);
37
+ });
38
+
39
+ // Enhanced tabs logic with smooth transitions and ARIA support
40
+ document.querySelectorAll('.tab').forEach(btn => {
41
+ btn.addEventListener('click', () => {
42
+ // Remove active class and ARIA attributes from all tabs
43
+ document.querySelectorAll('.tab').forEach(b => {
44
+ b.classList.remove('active');
45
+ b.setAttribute('aria-selected', 'false');
46
+ });
47
+
48
+ // Add active class and ARIA attributes to clicked tab
49
+ btn.classList.add('active');
50
+ btn.setAttribute('aria-selected', 'true');
51
+
52
+ // Get target diagram
53
+ const target = btn.getAttribute('data-target');
54
+ const targetDiagram = document.querySelector(target);
55
+
56
+ if (targetDiagram) {
57
+ // Hide all diagrams completely and update ARIA
58
+ document.querySelectorAll('.diagram').forEach(d => {
59
+ d.style.opacity = '0';
60
+ d.style.transform = 'translateY(20px)';
61
+ d.style.display = 'none';
62
+ d.setAttribute('aria-hidden', 'true');
63
+ d.classList.remove('visible');
64
+ });
65
+
66
+ // Show target diagram with fade in and update ARIA
67
+ setTimeout(() => {
68
+ targetDiagram.style.display = 'block';
69
+ targetDiagram.classList.add('visible');
70
+ targetDiagram.style.opacity = '1';
71
+ targetDiagram.style.transform = 'translateY(0)';
72
+ targetDiagram.setAttribute('aria-hidden', 'false');
73
+ }, 150);
74
+ }
75
+ });
76
+ });
77
+
78
+ // Initialize first tab as active and show first diagram
79
+ document.addEventListener('DOMContentLoaded', () => {
80
+ // Hide all diagrams except the first one
81
+ document.querySelectorAll('.diagram').forEach((diagram, index) => {
82
+ if (index === 0) {
83
+ // First diagram should be visible
84
+ diagram.style.display = 'block';
85
+ diagram.style.opacity = '1';
86
+ diagram.style.transform = 'translateY(0)';
87
+ diagram.classList.add('visible');
88
+ diagram.setAttribute('aria-hidden', 'false');
89
+ } else {
90
+ // Other diagrams should be hidden
91
+ diagram.style.display = 'none';
92
+ diagram.style.opacity = '0';
93
+ diagram.style.transform = 'translateY(20px)';
94
+ diagram.classList.remove('visible');
95
+ diagram.setAttribute('aria-hidden', 'true');
96
+ }
97
+ });
98
+
99
+ // Ensure Mermaid diagrams are properly initialized
100
+ if (window.mermaid) {
101
+ mermaid.init(undefined, document.querySelectorAll('.mermaid'));
102
+ }
103
+ });
104
+
105
+ // Enhanced metric counters with better performance
106
+ const counters = document.querySelectorAll('.metric-value');
107
+ const easeOutCubic = t => 1 - Math.pow(1 - t, 3);
108
+ const easeOutQuart = t => 1 - Math.pow(1 - t, 4);
109
+
110
+ const animateCount = (el, to, duration = 1200) => {
111
+ const start = performance.now();
112
+ const from = 0;
113
+ const isLargeNumber = to > 1000;
114
+ const easing = isLargeNumber ? easeOutQuart : easeOutCubic;
115
+
116
+ // Ensure the element has proper positioning
117
+ el.style.position = 'relative';
118
+ el.style.zIndex = '2';
119
+ el.style.width = '100%';
120
+ el.style.textAlign = 'center';
121
+ el.style.display = 'block';
122
+
123
+ const step = (now) => {
124
+ const p = Math.min(1, (now - start) / duration);
125
+ const v = Math.floor(from + (to - from) * easing(p));
126
+
127
+ // Format number with appropriate separators
128
+ if (to >= 1000000) {
129
+ el.textContent = (v / 1000000).toFixed(1) + 'M';
130
+ } else if (to >= 1000) {
131
+ el.textContent = (v / 1000).toFixed(1) + 'K';
132
+ } else {
133
+ el.textContent = v.toLocaleString();
134
+ }
135
+
136
+ if (p < 1) {
137
+ requestAnimationFrame(step);
138
+ } else {
139
+ // Ensure final value is exact
140
+ if (to >= 1000000) {
141
+ el.textContent = (to / 1000000).toFixed(1) + 'M';
142
+ } else if (to >= 1000) {
143
+ el.textContent = (to / 1000).toFixed(1) + 'K';
144
+ } else {
145
+ el.textContent = to.toLocaleString();
146
+ }
147
+ }
148
+ };
149
+ requestAnimationFrame(step);
150
+ };
151
+
152
+ // Enhanced intersection observer with better performance
153
+ const observer = new IntersectionObserver(entries => {
154
+ entries.forEach(e => {
155
+ if (e.isIntersecting) {
156
+ const el = e.target;
157
+ const count = parseInt(el.dataset.count, 10) || 0;
158
+
159
+ // Add loading state
160
+ el.classList.add('loading');
161
+
162
+ // Animate with slight delay for better visual effect
163
+ setTimeout(() => {
164
+ animateCount(el, count);
165
+ el.classList.remove('loading');
166
+ }, 200);
167
+
168
+ observer.unobserve(el);
169
+ }
170
+ });
171
+ }, {
172
+ threshold: 0.3,
173
+ rootMargin: '0px 0px -50px 0px'
174
+ });
175
+
176
+ // Observe counters
177
+ counters.forEach(c => observer.observe(c));
178
+
179
+ // Enhanced VanillaTilt initialization with error handling
180
+ const initTilt = () => {
181
+ if (window.VanillaTilt) {
182
+ try {
183
+ document.querySelectorAll('[data-tilt]').forEach(el => {
184
+ VanillaTilt.init(el, {
185
+ max: 6,
186
+ speed: 400,
187
+ glare: true,
188
+ 'max-glare': 0.1,
189
+ scale: 1.02,
190
+ gyroscope: false
191
+ });
192
+ });
193
+ } catch (error) {
194
+ console.warn('VanillaTilt initialization failed:', error);
195
+ }
196
+ }
197
+ };
198
+
199
+ // Initialize tilt effects
200
+ initTilt();
201
+
202
+ // Smooth scrolling for navigation links
203
+ document.querySelectorAll('a[href^="#"]').forEach(link => {
204
+ link.addEventListener('click', (e) => {
205
+ e.preventDefault();
206
+ const targetId = link.getAttribute('href');
207
+ const targetElement = document.querySelector(targetId);
208
+
209
+ if (targetElement) {
210
+ const headerHeight = document.querySelector('header')?.offsetHeight || 0;
211
+ const targetPosition = targetElement.offsetTop - headerHeight - 20;
212
+
213
+ window.scrollTo({
214
+ top: targetPosition,
215
+ behavior: 'smooth'
216
+ });
217
+ }
218
+ });
219
+ });
220
+
221
+ // Enhanced error handling for external resources
222
+ const handleResourceError = (resource, fallback) => {
223
+ resource.addEventListener('error', () => {
224
+ console.warn(`Failed to load resource, using fallback`);
225
+ if (fallback) {
226
+ resource.src = fallback;
227
+ }
228
+ });
229
+ };
230
+
231
+ // Handle external script loading errors
232
+ window.addEventListener('error', (e) => {
233
+ if (e.target.tagName === 'SCRIPT' && e.target.src) {
234
+ console.warn(`Script failed to load: ${e.target.src}`);
235
+ }
236
+ });
237
+
238
+ // Performance monitoring
239
+ const logPerformance = () => {
240
+ if ('performance' in window) {
241
+ window.addEventListener('load', () => {
242
+ setTimeout(() => {
243
+ const perfData = performance.getEntriesByType('navigation')[0];
244
+ console.log(`Page load time: ${perfData.loadEventEnd - perfData.loadEventStart}ms`);
245
+ }, 0);
246
+ });
247
+ }
248
+ };
249
+
250
+ // Initialize performance monitoring
251
+ logPerformance();
252
+
253
+ // Add keyboard navigation support
254
+ document.addEventListener('keydown', (e) => {
255
+ // Tab navigation for architecture tabs
256
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
257
+ const activeTab = document.querySelector('.tab.active');
258
+ if (activeTab) {
259
+ const tabs = Array.from(document.querySelectorAll('.tab'));
260
+ const currentIndex = tabs.indexOf(activeTab);
261
+ let nextIndex;
262
+
263
+ if (e.key === 'ArrowLeft') {
264
+ nextIndex = currentIndex > 0 ? currentIndex - 1 : tabs.length - 1;
265
+ } else {
266
+ nextIndex = currentIndex < tabs.length - 1 ? currentIndex + 1 : 0;
267
+ }
268
+
269
+ tabs[nextIndex].click();
270
+ tabs[nextIndex].focus();
271
+ }
272
+ }
273
+ });
274
+
275
+ // Add loading states for dynamic content
276
+ const addLoadingState = (element, duration = 1000) => {
277
+ element.classList.add('loading');
278
+ setTimeout(() => {
279
+ element.classList.remove('loading');
280
+ }, duration);
281
+ };
282
+
283
+ // Initialize all interactive elements
284
+ document.addEventListener('DOMContentLoaded', () => {
285
+ // Add loading states to cards that might load content dynamically
286
+ document.querySelectorAll('.card').forEach(card => {
287
+ card.addEventListener('mouseenter', () => {
288
+ addLoadingState(card, 500);
289
+ });
290
+ });
291
+
292
+ // Initialize tooltips for chips
293
+ document.querySelectorAll('.chip').forEach(chip => {
294
+ chip.setAttribute('title', chip.textContent);
295
+ });
296
+ });
assets/logo.svg ADDED
assets/styles.css ADDED
@@ -0,0 +1,1262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Custom styles and utilities beyond Tailwind */
2
+ :root {
3
+ --ring: 0 0% 100%;
4
+ --shadow-glow: 0 0 20px rgba(99,102,241,0.3), 0 0 40px rgba(99,102,241,0.2);
5
+ }
6
+
7
+ /* Fallback styles in case Tailwind doesn't load */
8
+ body {
9
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
10
+ background-color: #0f172a;
11
+ color: #f1f5f9;
12
+ line-height: 1.6;
13
+ margin: 0;
14
+ padding: 0;
15
+ }
16
+
17
+ /* Global text justification */
18
+ p, li, div {
19
+ text-align: justify;
20
+ text-justify: inter-word;
21
+ }
22
+
23
+ /* Override for specific elements that should be left-aligned */
24
+ .btn-primary, .btn-secondary, .btn-ghost,
25
+ .tab, .chip, .metric-value, .metric-label {
26
+ text-align: left;
27
+ }
28
+
29
+ /* Ensure h2 headers in section headers are centered */
30
+ .section-header h2 {
31
+ text-align: center !important;
32
+ }
33
+
34
+ /* Add proper margins to main content */
35
+ .container {
36
+ margin-left: auto;
37
+ margin-right: auto;
38
+ padding-left: 2rem;
39
+ padding-right: 2rem;
40
+ }
41
+
42
+ @media (max-width: 768px) {
43
+ .container {
44
+ padding-left: 1rem;
45
+ padding-right: 1rem;
46
+ }
47
+ }
48
+
49
+ h1, h3, h5, h6 {
50
+ font-weight: 700;
51
+ line-height: 1.2;
52
+ margin: 0 0 1rem 0;
53
+ }
54
+
55
+ /* Ensure card titles have proper styling */
56
+ .card-title {
57
+ font-weight: 600 !important;
58
+ font-size: 1.125rem !important;
59
+ line-height: 1.4 !important;
60
+ margin-bottom: 0.75rem !important;
61
+ color: #f1f5f9 !important;
62
+ text-align: left !important;
63
+ }
64
+
65
+ h1 { font-size: 2.5rem; }
66
+ h3 { font-size: 1.5rem; }
67
+
68
+ /* Only apply basic h2 styles to non-section-header h2s */
69
+ h2:not(.section-header h2) {
70
+ font-size: 2rem;
71
+ font-weight: 700;
72
+ line-height: 1.2;
73
+ margin: 0 0 1rem 0;
74
+ }
75
+
76
+ /* Override any conflicting h2 styles for section headers */
77
+ .section-header h2 {
78
+ font-size: 3rem !important;
79
+ font-weight: 800 !important;
80
+ line-height: 1.2 !important;
81
+ margin: 0 0 1rem 0 !important;
82
+ text-align: center !important;
83
+ }
84
+
85
+ @media (min-width: 1024px) {
86
+ .section-header h2 {
87
+ font-size: 4rem !important;
88
+ }
89
+ }
90
+
91
+ section {
92
+ padding: 4rem 0;
93
+ }
94
+
95
+ .container {
96
+ max-width: 80rem;
97
+ margin: 0 auto;
98
+ padding: 0 1rem;
99
+ }
100
+
101
+ .grid {
102
+ display: grid;
103
+ gap: 1.5rem;
104
+ }
105
+
106
+ .grid.lg\\:grid-cols-2 {
107
+ grid-template-columns: 1fr;
108
+ }
109
+
110
+ @media (min-width: 1024px) {
111
+ .grid.lg\\:grid-cols-2 {
112
+ grid-template-columns: repeat(2, 1fr);
113
+ }
114
+ }
115
+
116
+ .grid.md\\:grid-cols-3 {
117
+ grid-template-columns: 1fr;
118
+ }
119
+
120
+ @media (min-width: 768px) {
121
+ .grid.md\\:grid-cols-3 {
122
+ grid-template-columns: repeat(3, 1fr);
123
+ }
124
+ }
125
+
126
+ .flex {
127
+ display: flex;
128
+ }
129
+
130
+ .items-center {
131
+ align-items: center;
132
+ }
133
+
134
+ .justify-between {
135
+ justify-content: space-between;
136
+ }
137
+
138
+ .gap-3 {
139
+ gap: 0.75rem;
140
+ }
141
+
142
+ .gap-6 {
143
+ gap: 1.5rem;
144
+ }
145
+
146
+ .gap-12 {
147
+ gap: 3rem;
148
+ }
149
+
150
+ .text-4xl {
151
+ font-size: 2.25rem;
152
+ }
153
+
154
+ .text-6xl {
155
+ font-size: 3.75rem;
156
+ }
157
+
158
+ .font-extrabold {
159
+ font-weight: 800;
160
+ }
161
+
162
+ .leading-tight {
163
+ line-height: 1.25;
164
+ }
165
+
166
+ .mt-5 {
167
+ margin-top: 1.25rem;
168
+ }
169
+
170
+ .mt-8 {
171
+ margin-top: 2rem;
172
+ }
173
+
174
+ .mt-6 {
175
+ margin-top: 1.5rem;
176
+ }
177
+
178
+ .text-slate-300 {
179
+ color: #cbd5e1;
180
+ }
181
+
182
+ .text-slate-400 {
183
+ color: #94a3b8;
184
+ }
185
+
186
+ .text-indigo-400 {
187
+ color: #818cf8;
188
+ }
189
+
190
+ .max-w-2xl {
191
+ max-width: 42rem;
192
+ }
193
+
194
+ .text-lg {
195
+ font-size: 1.125rem;
196
+ }
197
+
198
+ .text-sm {
199
+ font-size: 0.875rem;
200
+ }
201
+
202
+ .text-xs {
203
+ font-size: 0.75rem;
204
+ }
205
+
206
+ .hidden {
207
+ display: none;
208
+ }
209
+
210
+ @media (min-width: 640px) {
211
+ .sm\\:inline {
212
+ display: inline;
213
+ }
214
+ }
215
+
216
+ @media (min-width: 768px) {
217
+ .md\\:flex {
218
+ display: flex;
219
+ }
220
+ }
221
+
222
+ @media (min-width: 1024px) {
223
+ .lg\\:py-24 {
224
+ padding-top: 6rem;
225
+ padding-bottom: 6rem;
226
+ }
227
+
228
+ .lg\\:text-6xl {
229
+ font-size: 3.75rem;
230
+ }
231
+ }
232
+
233
+ /* Base link styles */
234
+ .link {
235
+ color: rgb(165 180 252);
236
+ transition: all 0.2s ease;
237
+ }
238
+ .link:hover {
239
+ text-decoration: underline;
240
+ color: rgb(129 140 248);
241
+ }
242
+ .btn-primary {
243
+ @apply inline-flex items-center gap-2 px-3 py-2 rounded-xl bg-indigo-500 hover:bg-indigo-400 text-white font-semibold shadow-glow transition;
244
+ }
245
+ .btn-secondary {
246
+ @apply inline-flex items-center gap-2 px-3 py-2 rounded-xl bg-slate-800 hover:bg-slate-700 text-slate-100 border border-white/10 transition;
247
+ }
248
+ .btn-ghost {
249
+ @apply inline-flex items-center gap-2 px-3 py-2 rounded-xl text-indigo-300 hover:text-white hover:bg-white/5 transition;
250
+ }
251
+ .btn-icon {
252
+ @apply inline-flex items-center justify-center w-10 h-10 rounded-xl bg-slate-800 hover:bg-slate-700 border border-white/10 transition;
253
+ }
254
+ .icon { width: 20px; height: 20px; }
255
+ .section { @apply py-16 lg:py-24; }
256
+
257
+ /* Reduce gap specifically between Architecture and Training sections */
258
+ #architecture {
259
+ padding-bottom: 2rem !important;
260
+ }
261
+
262
+ #training {
263
+ padding-top: 2rem !important;
264
+ }
265
+ .container { @apply max-w-7xl mx-auto px-4; }
266
+ .section-header h2 {
267
+ @apply text-3xl lg:text-4xl font-extrabold;
268
+ position: relative;
269
+ display: block;
270
+ text-align: center;
271
+ background: linear-gradient(135deg, #f1f5f9 0%, #818cf8 50%, #f1f5f9 100%);
272
+ background-size: 200% 200%;
273
+ -webkit-background-clip: text;
274
+ -webkit-text-fill-color: transparent;
275
+ background-clip: text;
276
+ animation: gradientShift 3s ease-in-out infinite;
277
+ text-shadow: 0 0 30px rgba(129, 140, 248, 0.3);
278
+ margin-bottom: 0.5rem;
279
+ }
280
+
281
+ .section-header h2::before {
282
+ content: '';
283
+ position: absolute;
284
+ top: 0;
285
+ left: 0;
286
+ right: 0;
287
+ bottom: 0;
288
+ background: linear-gradient(135deg, #818cf8, #a855f7, #ec4899);
289
+ border-radius: 0.5rem;
290
+ padding: 0.25rem;
291
+ z-index: -1;
292
+ opacity: 0;
293
+ transition: opacity 0.3s ease;
294
+ animation: pulseGlow 2s ease-in-out infinite;
295
+ }
296
+
297
+ .section-header h2:hover::before {
298
+ opacity: 0.1;
299
+ }
300
+
301
+ @keyframes gradientShift {
302
+ 0%, 100% {
303
+ background-position: 0% 50%;
304
+ }
305
+ 50% {
306
+ background-position: 100% 50%;
307
+ }
308
+ }
309
+
310
+ @keyframes pulseGlow {
311
+ 0%, 100% {
312
+ box-shadow: 0 0 20px rgba(129, 140, 248, 0.2);
313
+ }
314
+ 50% {
315
+ box-shadow: 0 0 40px rgba(129, 140, 248, 0.4);
316
+ }
317
+ }
318
+ .section-header p {
319
+ color: #94a3b8;
320
+ font-size: 0.95rem;
321
+ line-height: 1.5;
322
+ font-style: italic;
323
+ text-align: left;
324
+ margin-top: 0.75rem;
325
+ margin-bottom: 0;
326
+ max-width: none;
327
+ }
328
+
329
+ .section-header {
330
+ text-align: left;
331
+ margin-bottom: 2.5rem;
332
+ }
333
+ .card {
334
+ @apply rounded-2xl bg-slate-900/60 border border-white/10 backdrop-blur;
335
+ transition: all 0.3s ease;
336
+ position: relative;
337
+ overflow: hidden;
338
+ }
339
+
340
+ .card::before {
341
+ content: '';
342
+ position: absolute;
343
+ top: 0;
344
+ left: 0;
345
+ right: 0;
346
+ height: 2px;
347
+ background: linear-gradient(90deg, transparent, rgba(129, 140, 248, 0.5), transparent);
348
+ transform: translateX(-100%);
349
+ transition: transform 0.6s ease;
350
+ }
351
+
352
+ .card:hover::before {
353
+ transform: translateX(100%);
354
+ }
355
+
356
+ .card:hover {
357
+ transform: translateY(-4px);
358
+ border-color: rgba(129, 140, 248, 0.3);
359
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
360
+ }
361
+ .card.glass {
362
+ @apply bg-slate-900/50;
363
+ }
364
+ .card-body { @apply p-6; }
365
+ .card-title { @apply text-lg font-semibold mb-2; }
366
+ .feature {
367
+ @apply rounded-2xl p-6 bg-slate-900/60 border border-white/10 backdrop-blur;
368
+ }
369
+ .feature-icon { width: 28px; height: 28px; color: rgb(129 140 248); @apply mb-3; }
370
+ .chip {
371
+ @apply inline-flex items-center px-4 py-2 rounded-full text-sm font-medium transition-all duration-300;
372
+ background: linear-gradient(135deg, rgba(129, 140, 248, 0.1), rgba(168, 85, 247, 0.1));
373
+ border: 1px solid rgba(129, 140, 248, 0.2);
374
+ color: #cbd5e1;
375
+ position: relative;
376
+ overflow: hidden;
377
+ backdrop-filter: blur(10px);
378
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
379
+ }
380
+
381
+ .chip::before {
382
+ content: '';
383
+ position: absolute;
384
+ top: 0;
385
+ left: -100%;
386
+ width: 100%;
387
+ height: 100%;
388
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
389
+ transition: left 0.5s ease;
390
+ }
391
+
392
+ .chip:hover::before {
393
+ left: 100%;
394
+ }
395
+
396
+ .chip:hover {
397
+ background: linear-gradient(135deg, rgba(129, 140, 248, 0.2), rgba(168, 85, 247, 0.2));
398
+ border-color: rgba(129, 140, 248, 0.4);
399
+ color: #f1f5f9;
400
+ transform: translateY(-2px);
401
+ box-shadow: 0 4px 15px rgba(129, 140, 248, 0.2);
402
+ }
403
+
404
+ .chip:active {
405
+ transform: translateY(0);
406
+ box-shadow: 0 2px 8px rgba(129, 140, 248, 0.3);
407
+ }
408
+ .tabs {
409
+ @apply flex flex-wrap gap-3;
410
+ justify-content: center;
411
+ margin-bottom: 2rem;
412
+ }
413
+
414
+ .tab {
415
+ @apply px-6 py-3 rounded-2xl bg-slate-800/50 border border-white/10 text-slate-200 transition-all duration-300;
416
+ position: relative;
417
+ overflow: hidden;
418
+ font-weight: 600;
419
+ font-size: 0.95rem;
420
+ min-width: 140px;
421
+ text-align: center;
422
+ backdrop-filter: blur(10px);
423
+ }
424
+
425
+ .tab::before {
426
+ content: '';
427
+ position: absolute;
428
+ top: 0;
429
+ left: -100%;
430
+ width: 100%;
431
+ height: 100%;
432
+ background: linear-gradient(90deg, transparent, rgba(129, 140, 248, 0.2), transparent);
433
+ transition: left 0.6s ease;
434
+ }
435
+
436
+ .tab:hover::before {
437
+ left: 100%;
438
+ }
439
+
440
+ .tab:hover {
441
+ transform: translateY(-2px);
442
+ border-color: rgba(129, 140, 248, 0.3);
443
+ box-shadow: 0 8px 25px rgba(129, 140, 248, 0.15);
444
+ background: rgba(129, 140, 248, 0.1);
445
+ }
446
+
447
+ .tab.active {
448
+ @apply bg-gradient-to-r from-indigo-500/30 to-purple-500/30 border-indigo-400/60 text-indigo-100;
449
+ transform: translateY(-2px);
450
+ box-shadow: 0 10px 30px rgba(129, 140, 248, 0.3);
451
+ background: linear-gradient(135deg, rgba(129, 140, 248, 0.2), rgba(168, 85, 247, 0.2));
452
+ }
453
+
454
+ .tab.active::after {
455
+ content: '';
456
+ position: absolute;
457
+ bottom: 0;
458
+ left: 50%;
459
+ transform: translateX(-50%);
460
+ width: 60%;
461
+ height: 3px;
462
+ background: linear-gradient(90deg, #818cf8, #a855f7);
463
+ border-radius: 2px;
464
+ animation: pulseGlow 2s ease-in-out infinite;
465
+ }
466
+ .diagram {
467
+ display: none;
468
+ opacity: 0;
469
+ transform: translateY(20px);
470
+ transition: all 0.3s ease;
471
+ min-height: 300px;
472
+ margin: 0;
473
+ padding: 0;
474
+ }
475
+
476
+ .diagram.visible {
477
+ display: block;
478
+ opacity: 1;
479
+ transform: translateY(0);
480
+ }
481
+ pre.mermaid {
482
+ @apply rounded-2xl bg-slate-900/70 border border-white/10 p-4 overflow-auto;
483
+ text-align: center;
484
+ display: flex;
485
+ justify-content: center;
486
+ align-items: center;
487
+ min-height: 300px;
488
+ }
489
+
490
+ pre.mermaid svg {
491
+ max-width: 100%;
492
+ height: auto;
493
+ margin: 0 auto;
494
+ display: block;
495
+ }
496
+
497
+ /* Ensure Mermaid diagrams are properly centered */
498
+ .diagram.visible {
499
+ display: block;
500
+ width: 100%;
501
+ }
502
+
503
+ .diagram pre.mermaid {
504
+ width: 100%;
505
+ max-width: 100%;
506
+ }
507
+ .metric { @apply bg-slate-900/60 border border-white/10 rounded-2xl p-6 text-center; }
508
+ .metric-value { @apply text-4xl font-extrabold text-indigo-300; }
509
+ .metric-label { @apply text-slate-400 mt-1; }
510
+ .list {
511
+ @apply pl-5 space-y-2 text-slate-300;
512
+ list-style: none;
513
+ }
514
+
515
+ .list li {
516
+ position: relative;
517
+ padding-left: 1.5rem;
518
+ line-height: 1.6;
519
+ transition: all 0.2s ease;
520
+ }
521
+
522
+ .list li::before {
523
+ content: '▶';
524
+ position: absolute;
525
+ left: 0;
526
+ top: 0;
527
+ color: #818cf8;
528
+ font-size: 0.75rem;
529
+ transition: all 0.2s ease;
530
+ }
531
+
532
+ .list li:hover {
533
+ color: #f1f5f9;
534
+ transform: translateX(4px);
535
+ }
536
+
537
+ .list li:hover::before {
538
+ color: #a855f7;
539
+ transform: scale(1.2);
540
+ }
541
+ .avatar {
542
+ @apply rounded-2xl bg-slate-800 border border-white/10 p-6 text-center font-semibold;
543
+ transition: all 0.3s ease;
544
+ position: relative;
545
+ overflow: hidden;
546
+ min-width: 120px;
547
+ min-height: 80px;
548
+ display: flex;
549
+ align-items: center;
550
+ justify-content: center;
551
+ }
552
+
553
+ .avatar::before {
554
+ content: '';
555
+ position: absolute;
556
+ top: 0;
557
+ left: -100%;
558
+ width: 100%;
559
+ height: 100%;
560
+ background: linear-gradient(90deg, transparent, rgba(129, 140, 248, 0.2), transparent);
561
+ transition: left 0.6s ease;
562
+ }
563
+
564
+ .avatar:hover::before {
565
+ left: 100%;
566
+ }
567
+
568
+ .avatar:hover {
569
+ transform: translateY(-4px);
570
+ border-color: rgba(129, 140, 248, 0.4);
571
+ box-shadow: 0 10px 25px rgba(129, 140, 248, 0.2);
572
+ background: linear-gradient(135deg, rgba(129, 140, 248, 0.1), rgba(168, 85, 247, 0.1));
573
+ }
574
+
575
+ /* Enhanced Team section styling */
576
+ #team .container {
577
+ text-align: center;
578
+ }
579
+
580
+ .team-info {
581
+ margin-top: 2rem;
582
+ }
583
+
584
+ .university-info {
585
+ margin-bottom: 3rem;
586
+ display: flex;
587
+ flex-direction: column;
588
+ align-items: center;
589
+ gap: 0.5rem;
590
+ }
591
+
592
+ .university-name {
593
+ font-size: 1.5rem;
594
+ font-weight: 700;
595
+ background: linear-gradient(135deg, #818cf8, #a855f7, #ec4899);
596
+ -webkit-background-clip: text;
597
+ -webkit-text-fill-color: transparent;
598
+ background-clip: text;
599
+ animation: gradientShift 3s ease-in-out infinite;
600
+ text-shadow: 0 0 20px rgba(129, 140, 248, 0.3);
601
+ }
602
+
603
+ .course-code {
604
+ font-size: 1.1rem;
605
+ font-weight: 600;
606
+ color: #94a3b8;
607
+ background: rgba(129, 140, 248, 0.1);
608
+ padding: 0.5rem 1rem;
609
+ border-radius: 1rem;
610
+ border: 1px solid rgba(129, 140, 248, 0.2);
611
+ display: inline-block;
612
+ }
613
+
614
+ .team-members {
615
+ display: flex;
616
+ justify-content: center;
617
+ flex-wrap: wrap;
618
+ gap: 1.5rem;
619
+ margin-top: 2rem;
620
+ }
621
+
622
+ .member-card {
623
+ display: flex;
624
+ flex-direction: column;
625
+ align-items: center;
626
+ gap: 0.75rem;
627
+ padding: 1.5rem;
628
+ background: rgba(15, 23, 42, 0.6);
629
+ border: 1px solid rgba(255, 255, 255, 0.1);
630
+ border-radius: 1rem;
631
+ transition: all 0.3s ease;
632
+ position: relative;
633
+ overflow: hidden;
634
+ min-width: 120px;
635
+ backdrop-filter: blur(10px);
636
+ }
637
+
638
+ .member-card::before {
639
+ content: '';
640
+ position: absolute;
641
+ top: 0;
642
+ left: -100%;
643
+ width: 100%;
644
+ height: 100%;
645
+ background: linear-gradient(90deg, transparent, rgba(129, 140, 248, 0.1), transparent);
646
+ transition: left 0.6s ease;
647
+ }
648
+
649
+ .member-card:hover::before {
650
+ left: 100%;
651
+ }
652
+
653
+ .member-card:hover {
654
+ transform: translateY(-5px);
655
+ border-color: rgba(129, 140, 248, 0.4);
656
+ box-shadow: 0 15px 35px rgba(129, 140, 248, 0.2);
657
+ background: rgba(129, 140, 248, 0.05);
658
+ }
659
+
660
+ .member-avatar {
661
+ width: 60px;
662
+ height: 60px;
663
+ border-radius: 50%;
664
+ background: linear-gradient(135deg, #818cf8, #a855f7);
665
+ display: flex;
666
+ align-items: center;
667
+ justify-content: center;
668
+ font-size: 1.5rem;
669
+ font-weight: 700;
670
+ color: white;
671
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
672
+ box-shadow: 0 8px 20px rgba(129, 140, 248, 0.3);
673
+ transition: all 0.3s ease;
674
+ }
675
+
676
+ .member-card:hover .member-avatar {
677
+ transform: scale(1.1);
678
+ box-shadow: 0 12px 25px rgba(129, 140, 248, 0.4);
679
+ }
680
+
681
+ .member-name {
682
+ font-size: 1rem;
683
+ font-weight: 600;
684
+ color: #e2e8f0;
685
+ transition: color 0.3s ease;
686
+ }
687
+
688
+ .member-card:hover .member-name {
689
+ color: #818cf8;
690
+ }
691
+
692
+ /* Responsive design for team members */
693
+ @media (max-width: 768px) {
694
+ .team-members {
695
+ gap: 1rem;
696
+ }
697
+
698
+ .member-card {
699
+ padding: 1rem;
700
+ min-width: 100px;
701
+ }
702
+
703
+ .member-avatar {
704
+ width: 50px;
705
+ height: 50px;
706
+ font-size: 1.25rem;
707
+ }
708
+
709
+ .university-name {
710
+ font-size: 1.25rem;
711
+ }
712
+ }
713
+ /* Enhanced shadow and animation utilities */
714
+ .shadow-glow {
715
+ box-shadow: var(--shadow-glow);
716
+ transition: box-shadow 0.3s ease;
717
+ }
718
+ .shadow-glow:hover {
719
+ box-shadow: 0 0 30px rgba(99,102,241,0.4), 0 0 60px rgba(99,102,241,0.3);
720
+ }
721
+
722
+ .animate-pulse-slow {
723
+ animation: pulse-slow 8s ease-in-out infinite;
724
+ }
725
+
726
+ @keyframes pulse-slow {
727
+ 0%, 100% { transform: scale(1); opacity: .7; }
728
+ 50% { transform: scale(1.05); opacity: 1; }
729
+ }
730
+
731
+ /* Additional animations */
732
+ @keyframes fadeInUp {
733
+ from {
734
+ opacity: 0;
735
+ transform: translateY(30px);
736
+ }
737
+ to {
738
+ opacity: 1;
739
+ transform: translateY(0);
740
+ }
741
+ }
742
+
743
+ @keyframes slideInRight {
744
+ from {
745
+ opacity: 0;
746
+ transform: translateX(30px);
747
+ }
748
+ to {
749
+ opacity: 1;
750
+ transform: translateX(0);
751
+ }
752
+ }
753
+
754
+ .animate-fade-in-up {
755
+ animation: fadeInUp 0.6s ease-out;
756
+ }
757
+
758
+ .animate-slide-in-right {
759
+ animation: slideInRight 0.6s ease-out;
760
+ }
761
+
762
+ /* Enhanced button states */
763
+ .btn-primary:active {
764
+ transform: translateY(1px);
765
+ box-shadow: 0 5px 15px rgba(99,102,241,0.3);
766
+ }
767
+
768
+ .btn-secondary:active {
769
+ transform: translateY(1px);
770
+ }
771
+
772
+ .btn-ghost:active {
773
+ transform: translateY(1px);
774
+ }
775
+
776
+ /* Enhanced card interactions */
777
+ .card {
778
+ transition: all 0.3s ease;
779
+ }
780
+
781
+ .card:hover {
782
+ transform: translateY(-2px);
783
+ box-shadow: 0 20px 40px rgba(0,0,0,0.3);
784
+ }
785
+
786
+ .card.glass:hover {
787
+ background: rgba(15, 23, 42, 0.7);
788
+ backdrop-filter: blur(20px);
789
+ }
790
+
791
+ /* Enhanced feature cards */
792
+ .feature {
793
+ transition: all 0.3s ease;
794
+ }
795
+
796
+ .feature:hover {
797
+ transform: translateY(-4px);
798
+ background: rgba(15, 23, 42, 0.8);
799
+ border-color: rgba(99, 102, 241, 0.3);
800
+ }
801
+
802
+ .feature-icon {
803
+ transition: all 0.3s ease;
804
+ }
805
+
806
+ .feature:hover .feature-icon {
807
+ color: rgb(99, 102, 241);
808
+ transform: scale(1.1);
809
+ }
810
+
811
+ /* Enhanced chip interactions */
812
+ .chip {
813
+ transition: all 0.2s ease;
814
+ }
815
+
816
+ .chip:hover {
817
+ background: rgba(99, 102, 241, 0.1);
818
+ border-color: rgba(99, 102, 241, 0.3);
819
+ color: rgb(129, 140, 248);
820
+ transform: translateY(-1px);
821
+ }
822
+
823
+ /* Enhanced tab interactions */
824
+ .tab {
825
+ transition: all 0.2s ease;
826
+ position: relative;
827
+ overflow: hidden;
828
+ }
829
+
830
+ .tab::before {
831
+ content: '';
832
+ position: absolute;
833
+ top: 0;
834
+ left: -100%;
835
+ width: 100%;
836
+ height: 100%;
837
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
838
+ transition: left 0.5s ease;
839
+ }
840
+
841
+ .tab:hover::before {
842
+ left: 100%;
843
+ }
844
+
845
+ .tab:hover {
846
+ transform: translateY(-1px);
847
+ }
848
+
849
+ .tab.active {
850
+ background: linear-gradient(135deg, rgba(99, 102, 241, 0.2), rgba(79, 70, 229, 0.1));
851
+ box-shadow: 0 4px 15px rgba(99, 102, 241, 0.2);
852
+ }
853
+
854
+ /* Enhanced diagram styling */
855
+ pre.mermaid {
856
+ transition: all 0.3s ease;
857
+ position: relative;
858
+ }
859
+
860
+ pre.mermaid:hover {
861
+ border-color: rgba(99, 102, 241, 0.3);
862
+ box-shadow: 0 10px 30px rgba(0,0,0,0.2);
863
+ }
864
+
865
+ /* Enhanced metric cards */
866
+ .metric {
867
+ transition: all 0.3s ease;
868
+ position: relative;
869
+ overflow: hidden;
870
+ background: rgba(15, 23, 42, 0.6);
871
+ border: 1px solid rgba(255, 255, 255, 0.1);
872
+ border-radius: 1rem;
873
+ padding: 1.5rem;
874
+ text-align: center;
875
+ min-height: 120px;
876
+ display: flex;
877
+ flex-direction: column;
878
+ justify-content: center;
879
+ align-items: center;
880
+ }
881
+
882
+ .metric::before {
883
+ content: '';
884
+ position: absolute;
885
+ top: 0;
886
+ left: 0;
887
+ right: 0;
888
+ height: 2px;
889
+ background: linear-gradient(90deg, transparent, rgb(99, 102, 241), transparent);
890
+ transform: translateX(-100%);
891
+ transition: transform 0.6s ease;
892
+ }
893
+
894
+ .metric:hover::before {
895
+ transform: translateX(100%);
896
+ }
897
+
898
+ .metric:hover {
899
+ transform: translateY(-4px);
900
+ border-color: rgba(99, 102, 241, 0.4);
901
+ background: rgba(15, 23, 42, 0.8);
902
+ box-shadow: 0 10px 30px rgba(99, 102, 241, 0.2);
903
+ }
904
+
905
+ .metric-value {
906
+ transition: all 0.3s ease;
907
+ font-size: 2.5rem;
908
+ font-weight: 800;
909
+ color: rgb(129, 140, 248);
910
+ margin: 0;
911
+ text-align: center;
912
+ width: 100%;
913
+ display: block;
914
+ position: relative;
915
+ z-index: 2;
916
+ }
917
+
918
+ .metric:hover .metric-value {
919
+ color: rgb(99, 102, 241);
920
+ transform: scale(1.1);
921
+ text-shadow: 0 0 20px rgba(99, 102, 241, 0.5);
922
+ }
923
+
924
+ .metric-label {
925
+ transition: all 0.3s ease;
926
+ color: rgb(148, 163, 184);
927
+ font-size: 0.875rem;
928
+ font-weight: 500;
929
+ margin-top: 0.5rem;
930
+ text-align: center;
931
+ width: 100%;
932
+ position: relative;
933
+ z-index: 2;
934
+ }
935
+
936
+ .metric:hover .metric-label {
937
+ color: rgb(203, 213, 225);
938
+ transform: translateY(-2px);
939
+ }
940
+
941
+ /* Add a subtle glow effect on hover */
942
+ .metric::after {
943
+ content: '';
944
+ position: absolute;
945
+ top: 50%;
946
+ left: 50%;
947
+ width: 0;
948
+ height: 0;
949
+ background: radial-gradient(circle, rgba(99, 102, 241, 0.1) 0%, transparent 70%);
950
+ border-radius: 50%;
951
+ transform: translate(-50%, -50%);
952
+ transition: all 0.3s ease;
953
+ z-index: 1;
954
+ }
955
+
956
+ .metric:hover::after {
957
+ width: 200px;
958
+ height: 200px;
959
+ }
960
+
961
+ /* Enhanced avatar styling */
962
+ .avatar {
963
+ transition: all 0.3s ease;
964
+ position: relative;
965
+ overflow: hidden;
966
+ }
967
+
968
+ .avatar::before {
969
+ content: '';
970
+ position: absolute;
971
+ top: 0;
972
+ left: 0;
973
+ right: 0;
974
+ bottom: 0;
975
+ background: linear-gradient(45deg, transparent, rgba(99, 102, 241, 0.1), transparent);
976
+ transform: translateX(-100%) translateY(-100%);
977
+ transition: transform 0.6s ease;
978
+ }
979
+
980
+ .avatar:hover::before {
981
+ transform: translateX(100%) translateY(100%);
982
+ }
983
+
984
+ .avatar:hover {
985
+ transform: translateY(-2px);
986
+ border-color: rgba(99, 102, 241, 0.3);
987
+ background: rgba(99, 102, 241, 0.05);
988
+ }
989
+
990
+ /* Enhanced text justification and spacing */
991
+ .section p, .section li, .section div:not(.btn-primary):not(.btn-secondary):not(.btn-ghost):not(.tab):not(.chip):not(.metric-value):not(.metric-label) {
992
+ text-align: justify;
993
+ text-justify: inter-word;
994
+ hyphens: auto;
995
+ }
996
+
997
+ /* Ensure proper margins for all sections */
998
+ .section {
999
+ margin-left: 2rem;
1000
+ margin-right: 2rem;
1001
+ }
1002
+
1003
+ @media (max-width: 768px) {
1004
+ .section {
1005
+ margin-left: 1rem;
1006
+ margin-right: 1rem;
1007
+ }
1008
+ }
1009
+
1010
+ /* Enhanced responsive improvements */
1011
+ @media (max-width: 1024px) {
1012
+ .container {
1013
+ padding-left: 1rem;
1014
+ padding-right: 1rem;
1015
+ }
1016
+
1017
+ .section {
1018
+ padding-top: 4rem;
1019
+ padding-bottom: 4rem;
1020
+ }
1021
+
1022
+ .section-header h2 {
1023
+ font-size: 2.5rem;
1024
+ }
1025
+ }
1026
+
1027
+ @media (max-width: 768px) {
1028
+ .section-header h2 {
1029
+ font-size: 2rem;
1030
+ line-height: 1.2;
1031
+ }
1032
+
1033
+ .section-header p {
1034
+ font-size: 0.9rem;
1035
+ }
1036
+
1037
+ .card-body {
1038
+ padding: 1rem;
1039
+ }
1040
+
1041
+ .feature {
1042
+ padding: 1rem;
1043
+ }
1044
+
1045
+ .metric-value {
1046
+ font-size: 2rem;
1047
+ }
1048
+
1049
+ .tabs {
1050
+ flex-direction: column;
1051
+ gap: 0.5rem;
1052
+ }
1053
+
1054
+ .tab {
1055
+ text-align: center;
1056
+ padding: 0.75rem 1rem;
1057
+ }
1058
+
1059
+ /* Hero section mobile improvements */
1060
+ .hero h1 {
1061
+ font-size: 2.5rem;
1062
+ line-height: 1.1;
1063
+ }
1064
+
1065
+ .hero p {
1066
+ font-size: 1rem;
1067
+ }
1068
+
1069
+ /* Button improvements for mobile */
1070
+ .btn-primary,
1071
+ .btn-secondary,
1072
+ .btn-ghost {
1073
+ padding: 0.75rem 1.5rem;
1074
+ font-size: 0.9rem;
1075
+ }
1076
+
1077
+ /* Chip improvements for mobile */
1078
+ .chip {
1079
+ padding: 0.5rem 1rem;
1080
+ font-size: 0.8rem;
1081
+ }
1082
+
1083
+ /* Diagram improvements for mobile */
1084
+ pre.mermaid {
1085
+ font-size: 0.8rem;
1086
+ padding: 1rem;
1087
+ overflow-x: auto;
1088
+ }
1089
+
1090
+ /* Metric cards mobile layout */
1091
+ .metric {
1092
+ padding: 1rem;
1093
+ }
1094
+
1095
+ .metric-value {
1096
+ font-size: 1.75rem;
1097
+ }
1098
+
1099
+ /* Avatar improvements for mobile */
1100
+ .avatar {
1101
+ padding: 1rem;
1102
+ font-size: 0.9rem;
1103
+ }
1104
+
1105
+ /* Navigation improvements */
1106
+ nav {
1107
+ display: none;
1108
+ }
1109
+
1110
+ /* Header mobile layout */
1111
+ header .flex {
1112
+ gap: 1rem;
1113
+ }
1114
+
1115
+ /* Feature grid mobile */
1116
+ .grid.md\\:grid-cols-3 {
1117
+ grid-template-columns: 1fr;
1118
+ gap: 1rem;
1119
+ }
1120
+
1121
+ .grid.md\\:grid-cols-2 {
1122
+ grid-template-columns: 1fr;
1123
+ gap: 1rem;
1124
+ }
1125
+
1126
+ .grid.lg\\:grid-cols-2 {
1127
+ grid-template-columns: 1fr;
1128
+ gap: 1rem;
1129
+ }
1130
+
1131
+ .grid.lg\\:grid-cols-3 {
1132
+ grid-template-columns: 1fr;
1133
+ gap: 1rem;
1134
+ }
1135
+
1136
+ .grid.md\\:grid-cols-5 {
1137
+ grid-template-columns: repeat(2, 1fr);
1138
+ gap: 0.75rem;
1139
+ }
1140
+ }
1141
+
1142
+ @media (max-width: 480px) {
1143
+ .container {
1144
+ padding-left: 0.75rem;
1145
+ padding-right: 0.75rem;
1146
+ }
1147
+
1148
+ .section {
1149
+ padding-top: 3rem;
1150
+ padding-bottom: 3rem;
1151
+ }
1152
+
1153
+ .section-header h2 {
1154
+ font-size: 1.75rem;
1155
+ }
1156
+
1157
+ .hero h1 {
1158
+ font-size: 2rem;
1159
+ }
1160
+
1161
+ .hero p {
1162
+ font-size: 0.9rem;
1163
+ }
1164
+
1165
+ .btn-primary,
1166
+ .btn-secondary,
1167
+ .btn-ghost {
1168
+ padding: 0.625rem 1.25rem;
1169
+ font-size: 0.85rem;
1170
+ }
1171
+
1172
+ .chip {
1173
+ padding: 0.375rem 0.75rem;
1174
+ font-size: 0.75rem;
1175
+ }
1176
+
1177
+ .metric-value {
1178
+ font-size: 1.5rem;
1179
+ }
1180
+
1181
+ .avatar {
1182
+ padding: 0.75rem;
1183
+ font-size: 0.8rem;
1184
+ }
1185
+
1186
+ .grid.md\\:grid-cols-5 {
1187
+ grid-template-columns: 1fr;
1188
+ gap: 0.5rem;
1189
+ }
1190
+
1191
+ /* Stack hero content vertically on very small screens */
1192
+ .hero .grid {
1193
+ grid-template-columns: 1fr;
1194
+ gap: 2rem;
1195
+ }
1196
+
1197
+ .hero .grid > div:first-child {
1198
+ order: 2;
1199
+ }
1200
+
1201
+ .hero .grid > div:last-child {
1202
+ order: 1;
1203
+ }
1204
+ }
1205
+
1206
+ /* Print styles */
1207
+ @media print {
1208
+ .btn-primary,
1209
+ .btn-secondary,
1210
+ .btn-ghost,
1211
+ .btn-icon {
1212
+ background: none !important;
1213
+ color: black !important;
1214
+ border: 1px solid black !important;
1215
+ }
1216
+
1217
+ .card,
1218
+ .feature {
1219
+ border: 1px solid #ccc !important;
1220
+ background: white !important;
1221
+ }
1222
+
1223
+ .shadow-glow {
1224
+ box-shadow: none !important;
1225
+ }
1226
+
1227
+ .animate-pulse-slow {
1228
+ animation: none !important;
1229
+ }
1230
+ }
1231
+
1232
+ /* Focus states for accessibility */
1233
+ .btn-primary:focus,
1234
+ .btn-secondary:focus,
1235
+ .btn-ghost:focus,
1236
+ .tab:focus,
1237
+ .chip:focus {
1238
+ outline: 2px solid rgb(99, 102, 241);
1239
+ outline-offset: 2px;
1240
+ }
1241
+
1242
+ /* Loading states */
1243
+ .loading {
1244
+ position: relative;
1245
+ overflow: hidden;
1246
+ }
1247
+
1248
+ .loading::after {
1249
+ content: '';
1250
+ position: absolute;
1251
+ top: 0;
1252
+ left: -100%;
1253
+ width: 100%;
1254
+ height: 100%;
1255
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
1256
+ animation: loading 1.5s infinite;
1257
+ }
1258
+
1259
+ @keyframes loading {
1260
+ 0% { left: -100%; }
1261
+ 100% { left: 100%; }
1262
+ }
index.html ADDED
@@ -0,0 +1,479 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="scroll-smooth">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>MedAI — COS30018 Multi‑Agent Clinical Reasoning</title>
7
+ <meta name="description" content="Swinburne COS30018 MedAI — Multi‑Agent Clinical Reasoning System with Agentic RAG, safety rails, and rigorous evaluation." />
8
+ <link rel="icon" href="assets/logo.svg">
9
+ <!-- Tailwind (CDN) -->
10
+ <script src="https://cdn.tailwindcss.com"></script>
11
+ <script>
12
+ // Ensure Tailwind is loaded before configuring
13
+ if (typeof tailwind !== 'undefined') {
14
+ tailwind.config = {
15
+ darkMode: 'class',
16
+ theme: {
17
+ extend: {
18
+ fontFamily: { inter: ['Inter', 'ui-sans-serif', 'system-ui'] },
19
+ boxShadow: {
20
+ glow: '0 0 20px rgba(99,102,241,0.3), 0 0 40px rgba(99,102,241,0.2)'
21
+ },
22
+ backgroundImage: {
23
+ 'grid': 'linear-gradient(to right, rgba(255,255,255,0.06) 1px, transparent 1px), linear-gradient(to bottom, rgba(255,255,255,0.06) 1px, transparent 1px)'
24
+ },
25
+ spacing: {
26
+ '18': '4.5rem',
27
+ '88': '22rem'
28
+ }
29
+ }
30
+ }
31
+ };
32
+ } else {
33
+ console.warn('Tailwind CSS not loaded');
34
+ }
35
+ </script>
36
+ <!-- AOS (Animate On Scroll) -->
37
+ <link href="https://unpkg.com/aos@2.3.4/dist/aos.css" rel="stylesheet" />
38
+ <script defer src="https://unpkg.com/aos@2.3.4/dist/aos.js"></script>
39
+ <!-- Lucide Icons -->
40
+ <script src="https://unpkg.com/lucide@latest"></script>
41
+ <!-- Mermaid -->
42
+ <script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js"></script>
43
+ <script>
44
+ mermaid.initialize({
45
+ startOnLoad: true,
46
+ theme: 'dark',
47
+ securityLevel: 'loose',
48
+ fontFamily: 'Inter, ui-sans-serif, system-ui',
49
+ flowchart: {
50
+ useMaxWidth: true,
51
+ htmlLabels: true
52
+ }
53
+ });
54
+ </script>
55
+ <link rel="preconnect" href="https://fonts.googleapis.com">
56
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
57
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
58
+ <link rel="stylesheet" href="assets/styles.css">
59
+ </head>
60
+ <body class="bg-slate-950 text-slate-100 font-inter">
61
+ <!-- Background decoration -->
62
+ <div class="fixed inset-0 -z-10 overflow-hidden pointer-events-none">
63
+ <div class="absolute -top-40 -left-40 w-[60rem] h-[60rem] rounded-full bg-gradient-to-tr from-indigo-500/30 via-blue-400/20 to-cyan-300/10 blur-3xl animate-pulse-slow"></div>
64
+ <div class="absolute -bottom-40 -right-40 w-[60rem] h-[60rem] rounded-full bg-gradient-to-tr from-fuchsia-500/20 via-indigo-500/10 to-sky-400/10 blur-3xl animate-pulse-slow delay-700"></div>
65
+ </div>
66
+
67
+ <!-- Navbar -->
68
+ <header class="sticky top-0 z-50 backdrop-blur supports-[backdrop-filter]:bg-slate-900/60 border-b border-white/10" role="banner">
69
+ <div class="max-w-7xl mx-auto px-4 py-3 flex items-center justify-between">
70
+ <div class="flex items-center gap-3">
71
+ <img src="assets/logo.svg" class="w-9 h-9" alt="MedAI logo" width="36" height="36" />
72
+ <span class="font-extrabold tracking-tight text-xl">MedAI</span>
73
+ <span class="text-slate-400 hidden sm:inline" aria-label="Course code">• COS30018</span>
74
+ </div>
75
+ <nav class="hidden md:flex items-center gap-6 text-sm" role="navigation" aria-label="Main navigation">
76
+ <a href="#overview" class="link" aria-label="Go to Overview section">Overview</a>
77
+ <a href="#capabilities" class="link" aria-label="Go to Capabilities section">Capabilities</a>
78
+ <a href="#architecture" class="link" aria-label="Go to Architecture section">Architecture</a>
79
+ <a href="#training" class="link" aria-label="Go to Training section">Training</a>
80
+ <a href="#evaluation" class="link" aria-label="Go to Evaluation section">Evaluation</a>
81
+ <a href="#team" class="link" aria-label="Go to Team section">Team</a>
82
+ </nav>
83
+ <div class="flex items-center gap-3">
84
+ <a href="https://huggingface.co/spaces/MedAI-COS30018/MedicalDiagnosisSystem" target="_blank" rel="noopener noreferrer" class="btn-primary" aria-label="Open live application in new tab">Live App</a>
85
+ <button id="themeToggle" aria-label="Toggle between light and dark theme" class="btn-icon" type="button">
86
+ <i data-lucide="sun-medium" class="icon" aria-hidden="true"></i>
87
+ </button>
88
+ </div>
89
+ </div>
90
+ </header>
91
+
92
+ <!-- Hero -->
93
+ <section class="relative" role="banner" aria-labelledby="hero-title">
94
+ <div class="max-w-7xl mx-auto px-4 py-16 lg:py-24">
95
+ <div class="grid lg:grid-cols-2 gap-12 items-center">
96
+ <div data-aos="fade-right" data-aos-duration="700">
97
+ <h1 id="hero-title" class="text-4xl lg:text-6xl font-extrabold leading-tight">
98
+ Multi‑Agent <span class="text-indigo-400">Clinical Reasoning</span> System
99
+ </h1>
100
+ <p class="mt-5 text-slate-300 text-lg max-w-2xl">
101
+ Safety‑first medical assistant coordinating Diagnostics, Pharmacology, and Triage agents via an MCP orchestrator,
102
+ grounded by Agentic RAG over EMR/EHR and PubMed, and rigorously evaluated on MedMCQA and PubMedQA.
103
+ </p>
104
+ <div class="mt-8 flex flex-wrap gap-3" role="group" aria-label="Action buttons">
105
+ <a class="btn-secondary" href="https://huggingface.co/spaces/MedAI-COS30018/MedAI_Processing" target="_blank" rel="noopener noreferrer" aria-label="Open data processing application">Data Processing</a>
106
+ <a class="btn-ghost" href="#architecture" aria-label="Scroll to architecture section">See Architecture</a>
107
+ </div>
108
+ <div class="mt-6 flex items-center gap-6 text-sm text-slate-400" role="contentinfo">
109
+ <span>Unit: COS30018 (Intelligent Systems)</span>
110
+ <span aria-hidden="true">•</span>
111
+ <span>School: Swinburne University of Technology</span>
112
+ </div>
113
+ </div>
114
+ <div class="relative" data-aos="fade-left" data-aos-duration="700">
115
+ <div class="card glass shadow-glow" role="complementary" aria-labelledby="glance-title">
116
+ <div class="p-6">
117
+ <h3 id="glance-title" class="font-semibold text-slate-200 mb-3">At a Glance</h3>
118
+ <ul class="space-y-2 text-slate-300" role="list">
119
+ <li>• 500k+ curated & synthetic cases</li>
120
+ <li>• LoRA/QLoRA, Knowledge Distillation, GRPO</li>
121
+ <li>• Agentic RAG (Node & Graph) with citations</li>
122
+ <li>• Safety rails, HIL, uncertainty flags</li>
123
+ <li>• HPC‑reproducible training</li>
124
+ </ul>
125
+ <div class="mt-6 flex gap-3" role="group" aria-label="External resources">
126
+ <a class="chip" href="https://huggingface.co/MedAI-COS30018/MedicalDiagnosisSystem" target="_blank" rel="noopener noreferrer" aria-label="Visit Live App">Live App</a>
127
+ <a class="chip" href="https://huggingface.co/MedAI-COS30018" target="_blank" rel="noopener noreferrer" aria-label="Visit Hugging Face organization">HF Org</a>
128
+ <a class="chip" href="https://huggingface.co/collections/MedAI-COS30018/finetuning-68bbe0b045db4ed5aac5e9a2" target="_blank" rel="noopener noreferrer" aria-label="View fine-tuning datasets">Finetune Datasets</a>
129
+ <a class="chip" href="https://huggingface.co/collections/MedAI-COS30018/rag-68bbe244bfa8ce6132fd5242" target="_blank" rel="noopener noreferrer" aria-label="View RAG datasets">RAG Datasets</a>
130
+ </div>
131
+ </div>
132
+ <div class="border-t border-white/10 p-4 text-xs text-slate-400">
133
+ <span>Phase 1 prototype: Multimodal + naïve‑RAG + MCP</span>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </div>
138
+ </div>
139
+ </section>
140
+
141
+ <!-- Overview -->
142
+ <section id="overview" class="section">
143
+ <div class="container">
144
+ <div class="section-header" data-aos="fade-up">
145
+ <h2>Overview</h2>
146
+ <p>Accuracy, traceability, and safety via multi‑agent orchestration and evidence‑grounded generation.</p>
147
+ </div>
148
+ <div class="grid md:grid-cols-3 gap-6">
149
+ <div class="feature" data-aos="zoom-in-up">
150
+ <i data-lucide="stethoscope" class="feature-icon"></i>
151
+ <h3>Specialist Agents</h3>
152
+ <p>Diagnostics (differentials + red flags), Pharmacology (DDIs, dosing), and Triage (urgency & disposition).</p>
153
+ </div>
154
+ <div class="feature" data-aos="zoom-in-up" data-aos-delay="100">
155
+ <i data-lucide="workflow" class="feature-icon"></i>
156
+ <h3>Reasoning Orchestrator</h3>
157
+ <p>MCP planner routes tasks, fuses evidence, and enforces self‑consistency with safe refusal and uncertainty flags.</p>
158
+ </div>
159
+ <div class="feature" data-aos="zoom-in-up" data-aos-delay="200">
160
+ <i data-lucide="library" class="feature-icon"></i>
161
+ <h3>Agentic RAG</h3>
162
+ <p>Graph & Node RAG over EMR/EHR + PubMed with section‑aware chunking, source allowlists, and citations.</p>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ </section>
167
+
168
+ <!-- Capabilities -->
169
+ <section id="capabilities" class="section">
170
+ <div class="container">
171
+ <div class="section-header" data-aos="fade-up">
172
+ <h2>Core Capabilities</h2>
173
+ <p>Modeling & optimization to drive accurate, inspectable clinical reasoning.</p>
174
+ </div>
175
+ <div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
176
+ <div class="card" data-tilt data-tilt-max="6">
177
+ <div class="card-body">
178
+ <h4 class="card-title">LoRA/QLoRA</h4>
179
+ <p>Parameter‑efficient adapters let us fine‑tune 7–13B models on modest GPUs while retaining high performance.</p>
180
+ </div>
181
+ </div>
182
+ <div class="card" data-tilt data-tilt-max="6">
183
+ <div class="card-body">
184
+ <h4 class="card-title">Knowledge Distillation</h4>
185
+ <p>Teacher→Student compression to deliver fast, strong specialists with small runtime footprints.</p>
186
+ </div>
187
+ </div>
188
+ <div class="card" data-tilt data-tilt-max="6">
189
+ <div class="card-body">
190
+ <h4 class="card-title">GRPO Reasoning</h4>
191
+ <p>Reinforcement learning variant targeting multi‑step, self‑consistent reasoning with lower compute costs.</p>
192
+ </div>
193
+ </div>
194
+ <div class="card" data-tilt data-tilt-max="6">
195
+ <div class="card-body">
196
+ <h4 class="card-title">QAC + Counterfactuals</h4>
197
+ <p>Paraphrasing, chunking, and “what‑if” synthesis improve robustness across presentation styles.</p>
198
+ </div>
199
+ </div>
200
+ <div class="card" data-tilt data-tilt-max="6">
201
+ <div class="card-body">
202
+ <h4 class="card-title">Safety Rails</h4>
203
+ <p>Allowlists, section filters, and citation‑required answers reduce hallucinations and protect privacy.</p>
204
+ </div>
205
+ </div>
206
+ <div class="card" data-tilt data-tilt-max="6">
207
+ <div class="card-body">
208
+ <h4 class="card-title">HPC Reproducibility</h4>
209
+ <p>Deterministic seeds, LR scheduling, and checkpointing ensure auditability and consistent results.</p>
210
+ </div>
211
+ </div>
212
+ </div>
213
+ </div>
214
+ </section>
215
+
216
+ <!-- Architecture -->
217
+ <section id="architecture" class="section" aria-labelledby="architecture-title">
218
+ <div class="container">
219
+ <div class="section-header" data-aos="fade-up">
220
+ <h2 id="architecture-title">Architecture</h2>
221
+ <p>Click tabs to switch between layers.</p>
222
+ </div>
223
+ <div class="tabs mb-6" role="tablist" aria-label="Architecture layers">
224
+ <button class="tab active" data-target="#arch-l1" role="tab" aria-selected="true" aria-controls="arch-l1" id="tab-l1">System Diagram</button>
225
+ <button class="tab" data-target="#arch-l2" role="tab" aria-selected="false" aria-controls="arch-l2" id="tab-l2">RAG Internals</button>
226
+ <button class="tab" data-target="#arch-l3" role="tab" aria-selected="false" aria-controls="arch-l3" id="tab-l3">Sequence Diagram</button>
227
+ </div>
228
+
229
+ <div id="arch-l1" class="diagram visible" role="tabpanel" aria-labelledby="tab-l1" aria-hidden="false" style="display: block;">
230
+ <pre class="mermaid" aria-label="System Architecture Diagram">
231
+ flowchart LR
232
+ U(["Clinician UI / EMR"]) -->|"symptoms, meds, files"| MCP["MCP Orchestrator<br/>FastAPI routing, planning, safety, tracing"]
233
+ MCP --> DX["Diagnostics Agent"]
234
+ MCP --> RX["Pharmacology Agent"]
235
+ subgraph RAG["Agentic RAG"]
236
+ QR["Query Router"] --> RET["Retriever"]
237
+ RET --> SR["Safety Rails"]
238
+ end
239
+ DX --> RAG
240
+ RX --> RAG
241
+ SR --> KB[("Med KB / PubMed")]
242
+ SR --> EMR[("EMR/EHR summaries")]
243
+ DX --> FUSE["Evidence Fusion + Self-Consistency"]
244
+ RX --> FUSE
245
+ FUSE --> OUT{{"Final Report<br/>summary, plan, citations, cautions"}}
246
+ OUT --> QA["Evaluation & QA<br/>MedMCQA, PubMedQA, similarity audits"]
247
+ </pre>
248
+ </div>
249
+
250
+ <div id="arch-l2" class="diagram" role="tabpanel" aria-labelledby="tab-l2" aria-hidden="true" style="display: none;">
251
+ <pre class="mermaid" aria-label="RAG Internals Architecture Diagram">
252
+ sequenceDiagram
253
+ autonumber
254
+ participant MCP as Orchestrator (MCP)
255
+ participant QR as Query Router
256
+ participant RW as Rewriter / Disambiguator
257
+ participant RET as Retriever (vector + keyword)
258
+ participant SR as Safety Rails
259
+ participant LTM as VectorDB / LTM
260
+ participant KB as Med KB (PubMed / Guidelines)
261
+ participant EMR as EMR Summarizer
262
+ participant EVID as Evidence Bundle
263
+
264
+ MCP->>QR: Build query context (symptoms, vitals, meds, files, LTM hints)
265
+ QR->>RW: Route + transform query
266
+
267
+ alt Disambiguation needed
268
+ RW->>RW: Expand synonyms / codes / abbreviations
269
+ else Well-formed query
270
+ RW-->>QR: Passthrough
271
+ end
272
+
273
+ RW->>RET: Search request (text + embedding)
274
+
275
+ par Vector search
276
+ RET->>LTM: kNN on embeddings (cosine)
277
+ LTM-->>RET: top-k chunks + scores
278
+ and Keyword filter
279
+ RET->>KB: Keyword/BM25 filter
280
+ KB-->>RET: filtered docs
281
+ end
282
+
283
+ RET->>SR: Candidate bundle {doc, section, score, source}
284
+ SR->>SR: Apply allowlist, section filters, dedupe, PII scrub
285
+ SR->>SR: Compute threshold τ and coverage/confidence
286
+
287
+ alt Low similarity (score < τ)
288
+ SR-->>MCP: Low-confidence → ask clarify / broaden search
289
+ else Sufficient evidence
290
+ SR-->>EVID: Vetted bundle
291
+ note right of EVID: Citations + provenance map
292
+ EVID->>LTM: Write traces (embeds, query, ids, similarity)
293
+ opt EMR context needed
294
+ QR->>EMR: Request patient summary (PHI-safe)
295
+ EMR-->>EVID: Labs, meds, history snippet
296
+ end
297
+ EVID-->>MCP: Evidence bundle + citations
298
+ end
299
+ </pre>
300
+ </div>
301
+
302
+ <div id="arch-l3" class="diagram" role="tabpanel" aria-labelledby="tab-l3" aria-hidden="true" style="display: none;">
303
+ <pre class="mermaid" aria-label="Single Turn Sequence Diagram">
304
+ sequenceDiagram
305
+ participant C as Clinician
306
+ participant MCP as Orchestrator (MCP)
307
+ participant RAG as RAG (Router→Retriever→Safety)
308
+ participant AG as Agents (Dx/Rx/Triage)
309
+ participant DB as VectorDB/LTM
310
+ participant OUT as Evidence Fusion
311
+ C->>MCP: case description
312
+ MCP->>RAG: retrieve evidence
313
+ RAG->>DB: similarity search
314
+ DB-->>RAG: top-k docs
315
+ RAG-->>MCP: evidence bundle + citations
316
+ MCP->>AG: delegated tasks
317
+ AG-->>OUT: candidate answers + rationales
318
+ OUT-->>C: final report + citations + cautions
319
+ OUT->>DB: write traces/embeddings
320
+ </pre>
321
+ </div>
322
+ </div>
323
+ </section>
324
+
325
+ <!-- Training & Reproducibility -->
326
+ <section id="training" class="section">
327
+ <div class="container">
328
+ <div class="section-header" data-aos="fade-up">
329
+ <h2>Data, Training & Reproducibility</h2>
330
+ <p>From 500k+ cases to specialized, efficient agents.</p>
331
+ </div>
332
+ <div class="grid lg:grid-cols-2 gap-6">
333
+ <div class="card">
334
+ <div class="card-body">
335
+ <h4 class="card-title">Datasets & Augmentation</h4>
336
+ <ul class="list">
337
+ <li>500k+ curated & synthetic clinical cases across specialties</li>
338
+ <li>QAC paraphrasing & chunking, self‑consistency sampling</li>
339
+ <li>Counterfactual case generation, back‑translation</li>
340
+ </ul>
341
+ <div class="mt-4 flex gap-3 flex-wrap">
342
+ <a class="chip" target="_blank" href="https://huggingface.co/collections/MedAI-COS30018/finetuning-68bbe0b045db4ed5aac5e9a2">Fine‑tuning Collection</a>
343
+ <a class="chip" target="_blank" href="https://huggingface.co/collections/MedAI-COS30018/rag-68bbe244bfa8ce6132fd5242">RAG Collection</a>
344
+ <a class="chip" target="_blank" href="https://huggingface.co/spaces/MedAI-COS30018/MedAI_Processing">Ingestion Pipeline</a>
345
+ </div>
346
+ </div>
347
+ </div>
348
+ <div class="card">
349
+ <div class="card-body">
350
+ <h4 class="card-title">Fine‑Tuning & KD</h4>
351
+ <ul class="list">
352
+ <li>Teacher→Student Knowledge Distillation</li>
353
+ <li>LoRA/QLoRA adapters, GRPO for reasoning</li>
354
+ <li>HPC runs: deterministic seeds, LR schedules, checkpoints</li>
355
+ </ul>
356
+ <div class="mt-4 flex gap-3 flex-wrap">
357
+ <a class="chip" target="_blank" href="https://hackmd.io/@ngFNmXW1RVOfNb7b3NYBJg/instruction">KD Procedure</a>
358
+ <a class="chip" target="_blank" href="https://hackmd.io/@ngFNmXW1RVOfNb7b3NYBJg/bench">Benchmarks Plan</a>
359
+ </div>
360
+ </div>
361
+ </div>
362
+ </div>
363
+ </div>
364
+ </section>
365
+
366
+ <!-- Evaluation -->
367
+ <section id="evaluation" class="section">
368
+ <div class="container">
369
+ <div class="section-header" data-aos="fade-up">
370
+ <h2>Evaluation & Safety</h2>
371
+ <p>Benchmarks, semantic audits, and runtime guards.</p>
372
+ </div>
373
+ <div class="grid lg:grid-cols-3 gap-6">
374
+ <div class="metric">
375
+ <div class="metric-value" data-count="500000">0</div>
376
+ <div class="metric-label">Cases Curated</div>
377
+ </div>
378
+ <div class="metric">
379
+ <div class="metric-value" data-count="3">0</div>
380
+ <div class="metric-label">Specialist Agents</div>
381
+ </div>
382
+ <div class="metric">
383
+ <div class="metric-value" data-count="2">0</div>
384
+ <div class="metric-label">Benchmarks</div>
385
+ </div>
386
+ </div>
387
+ <div class="mt-8 grid md:grid-cols-2 gap-6">
388
+ <div class="card">
389
+ <div class="card-body">
390
+ <h4 class="card-title">Benchmarks</h4>
391
+ <p>MedMCQA (medical exam QA) and PubMedQA (research abstract QA). Complemented by semantic similarity audits with biomedical embeddings.</p>
392
+ </div>
393
+ </div>
394
+ <div class="card">
395
+ <div class="card-body">
396
+ <h4 class="card-title">Runtime Guards</h4>
397
+ <p>Uncertainty prompts, refusal policies for out‑of‑scope, citation‑required answers, and HIL oversight to ensure safety.</p>
398
+ </div>
399
+ </div>
400
+ </div>
401
+ </div>
402
+ </section>
403
+
404
+ <!-- Team -->
405
+ <section id="team" class="section">
406
+ <div class="container">
407
+ <div class="section-header" data-aos="fade-up">
408
+ <h2>Team</h2>
409
+ <div class="team-info">
410
+ <div class="university-info">
411
+ <span class="university-name">Swinburne University of Technology</span>
412
+ <span class="course-code">COS30018</span>
413
+ </div>
414
+ <div class="team-members">
415
+ <div class="member-card" data-aos="zoom-in" data-aos-delay="100">
416
+ <!-- <div class="member-avatar">L</div> -->
417
+ <span class="member-name">Liam</span>
418
+ </div>
419
+ <div class="member-card" data-aos="zoom-in" data-aos-delay="200">
420
+ <!-- <div class="member-avatar">H</div> -->
421
+ <span class="member-name">Henry</span>
422
+ </div>
423
+ <div class="member-card" data-aos="zoom-in" data-aos-delay="300">
424
+ <!-- <div class="member-avatar">H</div> -->
425
+ <span class="member-name">Hai</span>
426
+ </div>
427
+ <div class="member-card" data-aos="zoom-in" data-aos-delay="400">
428
+ <!-- <div class="member-avatar">D</div> -->
429
+ <span class="member-name">Dylan</span>
430
+ </div>
431
+ <div class="member-card" data-aos="zoom-in" data-aos-delay="500">
432
+ <!-- <div class="member-avatar">V</div> -->
433
+ <span class="member-name">Vinh</span>
434
+ </div>
435
+ </div>
436
+ </div>
437
+ </div>
438
+ </div>
439
+ </section>
440
+
441
+ <!-- Footer -->
442
+ <footer class="py-10 border-t border-white/10 text-center text-slate-400">
443
+ <div class="container">
444
+ <div class="flex justify-center gap-6 mb-3">
445
+ <a class="link" target="_blank" href="https://huggingface.co/MedAI-COS30018">HF Org</a>
446
+ <a class="link" target="_blank" href="https://huggingface.co/spaces/MedAI-COS30018/MedicalDiagnosisSystem">Live App</a>
447
+ <a class="link" target="_blank" href="https://huggingface.co/spaces/MedAI-COS30018/MedAI_Processing">Data Processing</a>
448
+ </div>
449
+ <div class="text-xs">© 2025 Swinburne University · MedAI (COS30018). For research and educational use only.</div>
450
+ </div>
451
+ </footer>
452
+
453
+ <script src="https://unpkg.com/vanilla-tilt@1.8.1/dist/vanilla-tilt.min.js"></script>
454
+ <script src="assets/app.js"></script>
455
+ <script>
456
+ // Wait for all resources to load before initializing
457
+ window.addEventListener('load', () => {
458
+ // Initialize AOS if available
459
+ if (typeof AOS !== 'undefined') {
460
+ AOS.init({
461
+ duration: 700,
462
+ once: true,
463
+ offset: 100,
464
+ easing: 'ease-in-out'
465
+ });
466
+ } else {
467
+ console.warn('AOS library not loaded');
468
+ }
469
+
470
+ // Initialize Lucide icons if available
471
+ if (typeof lucide !== 'undefined') {
472
+ lucide.createIcons();
473
+ } else {
474
+ console.warn('Lucide library not loaded');
475
+ }
476
+ });
477
+ </script>
478
+ </body>
479
+ </html>