filmm commited on
Commit
896f826
·
verified ·
1 Parent(s): 7589f08

Upload 3 files

Browse files
Files changed (3) hide show
  1. templates/index.html +266 -0
  2. templates/result.html +202 -0
  3. templates/upload.html +178 -0
templates/index.html ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>WhiteCell.AI – AI BIO LAB INTERFACE</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@600&display=swap" rel="stylesheet">
8
+ <style>
9
+ body {
10
+ margin: 0;
11
+ font-family: 'Orbitron', sans-serif;
12
+ background: radial-gradient(ellipse at center, #050b14 0%, #000000 100%);
13
+ color: #e0f2ff;
14
+ overflow-x: hidden;
15
+ }
16
+
17
+ header {
18
+ display: flex;
19
+ justify-content: space-between;
20
+ align-items: center;
21
+ padding: 1rem 2rem;
22
+ background: rgba(2, 6, 17, 0.3); /* ใสกว่าของเดิม */
23
+ backdrop-filter: blur(10px); /* เพิ่มเบลอ */
24
+ box-shadow: 0 0 15px rgba(0, 238, 255, 0.1); /* เรืองแสงเบา ๆ */
25
+ border-bottom: 1px solid rgba(0, 255, 255, 0.05);
26
+
27
+ }
28
+
29
+ .logo {
30
+ font-size: 1.5rem;
31
+ color: #00d9ff;
32
+ display: flex;
33
+ align-items: center;
34
+ }
35
+
36
+ nav a {
37
+ color: #8eefff;
38
+ margin-left: 1.5rem;
39
+ text-decoration: none;
40
+ transition: 0.3s;
41
+ }
42
+
43
+ nav a:hover {
44
+ color: #ffffff;
45
+ text-shadow: 0 0 10px #00eaff;
46
+ }
47
+
48
+ main {
49
+ text-align: center;
50
+ padding: 6rem 2rem 4rem;
51
+ }
52
+
53
+ h1 {
54
+ font-size: 2.5rem;
55
+ margin-bottom: 1rem;
56
+ text-shadow: 0 0 20px #00eaff;
57
+ }
58
+
59
+ .btn-launch {
60
+ padding: 1rem 2rem;
61
+ border: none;
62
+ background: #00bfff;
63
+ color: white;
64
+ font-size: 1.2rem;
65
+ border-radius: 1rem;
66
+ cursor: pointer;
67
+ box-shadow: 0 0 20px #00eaff;
68
+ transition: transform 0.3s, box-shadow 0.3s;
69
+ text-decoration: none; /* ✅ สำคัญ: ลบเส้นใต้ */
70
+ display: inline-block; /* ✅ ให้ปุ่มมีขนาดตามเนื้อหา */
71
+ }
72
+
73
+ .btn-launch:hover {
74
+ transform: scale(1.05);
75
+ box-shadow: 0 0 30px #00eaff;
76
+ }
77
+
78
+ .background-animation {
79
+ position: fixed;
80
+ top: 0;
81
+ left: 0;
82
+ width: 100vw;
83
+ height: 100vh;
84
+ background: radial-gradient(circle at 30% 30%, #0a1628 0%, #020611 100%);
85
+ z-index: -1;
86
+ overflow: hidden;
87
+ }
88
+
89
+ #stars div {
90
+ position: absolute;
91
+ width: 2px;
92
+ height: 2px;
93
+ background-color: rgba(255, 255, 255, 0.8);
94
+ border-radius: 50%;
95
+ animation: twinkle 4s infinite ease-in-out;
96
+ }
97
+
98
+ nav a {
99
+ position: relative;
100
+ color: #8eefff;
101
+ margin-left: 1.5rem;
102
+ text-decoration: none;
103
+ transition: 0.3s;
104
+ }
105
+
106
+ nav a::after {
107
+ content: "";
108
+ position: absolute;
109
+ width: 0%;
110
+ height: 2px;
111
+ bottom: -4px;
112
+ left: 0;
113
+ background: #00eaff;
114
+ box-shadow: 0 0 8px #00eaff;
115
+ transition: width 0.3s ease;
116
+ }
117
+
118
+ nav a:hover::after {
119
+ width: 100%;
120
+ }
121
+
122
+ .logo:hover {
123
+ animation: glitch 0.5s infinite;
124
+ text-shadow: 0 0 5px #0ff, 0 0 10px #0ff;
125
+ }
126
+
127
+ @keyframes glitch {
128
+ 0% { transform: translate(0); }
129
+ 20% { transform: translate(-1px, 1px); }
130
+ 40% { transform: translate(1px, -1px); }
131
+ 60% { transform: translate(-1px, -1px); }
132
+ 80% { transform: translate(1px, 1px); }
133
+ 100% { transform: translate(0); }
134
+ }
135
+
136
+
137
+ @keyframes twinkle {
138
+ 0%, 100% {
139
+ opacity: 0.2;
140
+ transform: scale(1);
141
+ }
142
+ 50% {
143
+ opacity: 1;
144
+ transform: scale(1.4);
145
+ }
146
+ }
147
+
148
+ @keyframes pulse-bg {
149
+ from { background-position: 0 0; }
150
+ to { background-position: 40px 40px; }
151
+ }
152
+
153
+ .scene {
154
+ width: 300px;
155
+ height: 300px;
156
+ perspective: 1000px;
157
+ margin: 0 auto 2rem;
158
+ }
159
+
160
+ .dna {
161
+ width: 100%;
162
+ height: 100%;
163
+ position: relative;
164
+ transform-style: preserve-3d;
165
+ animation: rotate 12s linear infinite;
166
+ }
167
+
168
+ .pair {
169
+ position: absolute;
170
+ top: 50%;
171
+ left: 50%;
172
+ transform-style: preserve-3d;
173
+ }
174
+
175
+ .ball {
176
+ width: 14px;
177
+ height: 14px;
178
+ border-radius: 50%;
179
+ background: rgba(0, 255, 255, 0.9);
180
+ box-shadow: 0 0 10px rgba(0, 255, 255, 0.8);
181
+ position: absolute;
182
+ }
183
+
184
+ .connector {
185
+ width: 60px;
186
+ height: 2px;
187
+ background: linear-gradient(to right, rgba(0,255,255,0.6), rgba(255,255,255,0.2), rgba(0,255,255,0.6));
188
+ position: absolute;
189
+ top: 6px;
190
+ left: -30px;
191
+ transform-origin: center;
192
+ }
193
+
194
+ @keyframes rotate {
195
+ 0% { transform: rotateY(0deg); }
196
+ 100% { transform: rotateY(360deg); }
197
+ }
198
+ </style>
199
+ </head>
200
+ <body>
201
+ <!-- ✅ พื้นหลัง + จุดแสง -->
202
+ <div class="background-animation">
203
+ <div id="stars"></div>
204
+ </div>
205
+
206
+ <header>
207
+ <div class="logo">🧬 WhiteCell.AI</div>
208
+ <nav>
209
+ <a href="/upload" class="btn btn-primary">Upload</a>
210
+ <a href="#scan">Scan</a>
211
+ <a href="#results">Results</a>
212
+ <a href="#assistant">Assistant</a>
213
+ </nav>
214
+ </header>
215
+
216
+ <main>
217
+ <div class="scene">
218
+ <div class="dna" id="dna"></div>
219
+ </div>
220
+ <h1>AI-Powered Blood Cell Detection</h1>
221
+ <a href="/upload" class="btn-launch">🧬 Launch AI Scan</a>
222
+ </main>
223
+
224
+ <script>
225
+ const dna = document.getElementById('dna');
226
+ const pairs = 40;
227
+ for (let i = 0; i < pairs; i++) {
228
+ const pair = document.createElement('div');
229
+ pair.className = 'pair';
230
+ const angle = (i / pairs) * 360;
231
+ const y = (i - pairs / 2) * 8;
232
+ pair.style.transform = `rotateY(${angle}deg) translateZ(120px) translateY(${y}px)`;
233
+
234
+ const ball1 = document.createElement('div');
235
+ ball1.className = 'ball';
236
+ ball1.style.left = '-40px';
237
+
238
+ const ball2 = document.createElement('div');
239
+ ball2.className = 'ball';
240
+ ball2.style.left = '40px';
241
+
242
+ const connector = document.createElement('div');
243
+ connector.className = 'connector';
244
+ connector.style.transform = `rotate(${i % 2 === 0 ? 30 : -30}deg)`;
245
+
246
+ pair.appendChild(ball1);
247
+ pair.appendChild(ball2);
248
+ pair.appendChild(connector);
249
+ dna.appendChild(pair);
250
+ }
251
+
252
+ // ✅ จุดแสงแบบดาว
253
+ const starsContainer = document.getElementById('stars');
254
+ for (let i = 0; i < 100; i++) {
255
+ const star = document.createElement('div');
256
+ star.style.top = Math.random() * 100 + 'vh';
257
+ star.style.left = Math.random() * 100 + 'vw';
258
+ const size = (Math.random() * 1.5 + 1);
259
+ star.style.width = size + 'px';
260
+ star.style.height = size + 'px';
261
+ star.style.animationDuration = (Math.random() * 4 + 3) + 's';
262
+ starsContainer.appendChild(star);
263
+ }
264
+ </script>
265
+ </body>
266
+ </html>
templates/result.html ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Scan Result</title>
6
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@600&display=swap" rel="stylesheet">
7
+ <style>
8
+ body {
9
+ font-family: 'Orbitron', sans-serif;
10
+ background: radial-gradient(circle at center, #050b14 0%, #000000 100%);
11
+ color: #e0f2ff;
12
+ text-align: center;
13
+ padding: 2rem;
14
+ margin: 0;
15
+ overflow-x: hidden;
16
+ }
17
+
18
+ /* ✅ พื้นหลังอวกาศ */
19
+ .space-bg {
20
+ position: fixed;
21
+ top: 0; left: 0;
22
+ width: 100vw; height: 100vh;
23
+ z-index: -1;
24
+ background: radial-gradient(ellipse at center, #0c1a2b, #000);
25
+ overflow: hidden;
26
+ }
27
+
28
+ .star {
29
+ position: absolute;
30
+ width: 2px;
31
+ height: 2px;
32
+ background: white;
33
+ border-radius: 50%;
34
+ animation: twinkle 3s infinite ease-in-out;
35
+ }
36
+
37
+ @keyframes twinkle {
38
+ 0%, 100% { opacity: 0.2; transform: scale(1); }
39
+ 50% { opacity: 1; transform: scale(1.5); }
40
+ }
41
+
42
+ .uploaded-image {
43
+ max-width: 600px;
44
+ width: 100%;
45
+ height: auto;
46
+ border-radius: 1rem;
47
+ margin: 1rem 0;
48
+ box-shadow: 0 0 20px #00eaff;
49
+ }
50
+
51
+ .result-box {
52
+ margin-top: 1.5rem;
53
+ background: rgba(0, 255, 255, 0.07);
54
+ padding: 1.8rem;
55
+ border-radius: 1.5rem;
56
+ box-shadow: 0 0 25px rgba(0, 255, 255, 0.15);
57
+ max-width: 700px;
58
+ margin-left: auto;
59
+ margin-right: auto;
60
+ }
61
+
62
+ .btn {
63
+ padding: 0.8rem 2rem;
64
+ background: #00bfff;
65
+ border: none;
66
+ color: white;
67
+ font-size: 1.1rem;
68
+ border-radius: 1rem;
69
+ margin-top: 2rem;
70
+ cursor: pointer;
71
+ box-shadow: 0 0 20px #00eaff;
72
+ text-decoration: none;
73
+ }
74
+
75
+ .btn:hover {
76
+ box-shadow: 0 0 30px #00ffff;
77
+ transform: scale(1.05);
78
+ }
79
+
80
+ .score, .highlight {
81
+ font-size: 1.3rem;
82
+ margin: 0.6rem 0;
83
+ }
84
+
85
+ .highlight span {
86
+ color: #00eaff;
87
+ font-weight: bold;
88
+ }
89
+
90
+ .risk-level {
91
+ font-size: 1.5rem;
92
+ margin-top: 1.5rem;
93
+ }
94
+
95
+ .risk-low { color: #6aff6a; }
96
+ .risk-medium { color: #ffe066; }
97
+ .risk-high { color: #ff4d4d; }
98
+
99
+ .combined-risk-box {
100
+ margin-top: 1.5rem;
101
+ font-size: 1.8rem;
102
+ color: #00ffff;
103
+ font-weight: bold;
104
+ text-shadow: 0 0 10px #00ffff;
105
+ }
106
+
107
+ .info-box {
108
+ margin-top: 1rem;
109
+ font-size: 1.05rem;
110
+ color: #9cefff;
111
+ }
112
+
113
+ summary {
114
+ cursor: pointer;
115
+ font-size: 1.1rem;
116
+ color: #00eaff;
117
+ }
118
+
119
+ details p {
120
+ margin-top: 1rem;
121
+ line-height: 1.6;
122
+ font-size: 0.95rem;
123
+ color: #c4f1ff;
124
+ }
125
+ </style>
126
+ </head>
127
+ <body>
128
+ <!-- ✅ พื้นหลังอวกาศแบบเคลื่อนไหว -->
129
+ <div class="space-bg" id="space-bg"></div>
130
+
131
+ <h1>🔬 AI Scan Result</h1>
132
+
133
+ <p>🧪 Original Image:</p>
134
+ <img src="{{ url_for('static', filename='uploads/' + filename) }}" class="uploaded-image" alt="Original Image">
135
+
136
+ <h2>🧬 Image with Detection:</h2>
137
+ <img src="{{ url_for('static', filename=marked_filename) }}" class="uploaded-image" alt="Detected Image">
138
+
139
+ <div class="result-box">
140
+ <div class="highlight">🧬 ปกเซลล์ผิดปกติ (Blast): <span>{{ abnormal_cells }}</span> เซลล์</div>
141
+ <div class="highlight">➡️ ความเสี่ยงจาก Blast = <span class="count" data-target="{{ blast_risk }}">0</span>%</div>
142
+ <div class="highlight">🧠 HuggingFace Model: <span class="count" data-target="{{ huggingface_score }}">0</span>% โอกาสเป็นลูคีเมีย</div>
143
+
144
+ <div class="risk-level {% if combined_risk < 20 %}risk-low{% elif combined_risk < 60 %}risk-medium{% else %}risk-high{% endif %}">
145
+ ✅ สรุปผล: ความเสี่ยงระดับ
146
+ <strong>
147
+ {% if combined_risk < 20 %}ต่ำ
148
+ {% elif combined_risk < 60 %}ปานกลาง
149
+ {% else %}สูง
150
+ {% endif %}
151
+ </strong>
152
+ </div>
153
+
154
+ <div class="combined-risk-box">💡 ความเสี่ยงรวม: <span class="count" data-target="{{ combined_risk }}">0</span>%</div>
155
+ <div class="info-box">📋 ปัจจัยเสริม: {{ sex }} อายุ {{ age }} ปี</div>
156
+ </div>
157
+
158
+ <a href="/" class="btn">🔁 Scan Another</a>
159
+
160
+ <details style="margin-top: 2rem;">
161
+ <summary>❓ อธิบายผลการตรวจ</summary>
162
+ <p>
163
+ 🔹 <strong>ความเสี่ยงจาก Blast</strong>: คำนวณจากจำนวนเซลล์เม็ดเลือดขาวที่มีลักษณะผิดปกติ (Blast) เทียบกับเซลล��เม็ดเลือดขาวทั้งหมดที่ตรวจพบในภาพ<br><br>
164
+ 🔹 <strong>HuggingFace Model</strong>: วิเคราะห์ภาพรวมด้วยโมเดล AI ที่ผ่านการเทรนมาสำหรับแยกแยะภาพกลุ่มผู้ป่วยลูคีเมียและไม่เป็นลูคีเมีย โดยประเมินความเสี่ยงจากมุมมองรวมของภาพ<br><br>
165
+ 📌 หากค่าทั้งสองมีความต่างกันมาก แนะนำให้ปรึกษาแพทย์เพื่อยืนยันผล และไม่ควรตัดสินใจรักษาโดยยึดจาก AI เพียงอย่างเดียว
166
+ </p>
167
+ </details>
168
+
169
+ <!-- ✅ Animated Number Counter -->
170
+ <script>
171
+ const counters = document.querySelectorAll('.count');
172
+ counters.forEach(counter => {
173
+ counter.innerText = '0';
174
+ const update = () => {
175
+ const target = +counter.getAttribute('data-target');
176
+ const current = +counter.innerText;
177
+ const increment = target / 60;
178
+
179
+ if (current < target) {
180
+ counter.innerText = (current + increment).toFixed(1);
181
+ setTimeout(update, 20);
182
+ } else {
183
+ counter.innerText = target.toFixed(1);
184
+ }
185
+ };
186
+ update();
187
+ });
188
+
189
+ // ⭐ ใส่ดาวในพื้นหลัง
190
+ const bg = document.getElementById('space-bg');
191
+ for (let i = 0; i < 80; i++) {
192
+ const star = document.createElement('div');
193
+ star.classList.add('star');
194
+ star.style.top = `${Math.random() * 100}vh`;
195
+ star.style.left = `${Math.random() * 100}vw`;
196
+ star.style.animationDuration = `${Math.random() * 3 + 2}s`;
197
+ star.style.opacity = Math.random();
198
+ bg.appendChild(star);
199
+ }
200
+ </script>
201
+ </body>
202
+ </html>
templates/upload.html ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>WhiteCell.AI – Upload</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@600&display=swap" rel="stylesheet">
8
+ <style>
9
+ body {
10
+ margin: 0;
11
+ font-family: 'Orbitron', sans-serif;
12
+ background: radial-gradient(ellipse at center, #050b14 0%, #000000 100%);
13
+ color: #e0f2ff;
14
+ height: 100vh;
15
+ display: flex;
16
+ justify-content: center;
17
+ align-items: center;
18
+ overflow: hidden;
19
+ }
20
+
21
+ .background-animation {
22
+ position: fixed;
23
+ top: 0;
24
+ left: 0;
25
+ width: 100vw;
26
+ height: 100vh;
27
+ background: radial-gradient(circle at 30% 30%, #0a1628 0%, #020611 100%);
28
+ z-index: -1;
29
+ overflow: hidden;
30
+ }
31
+
32
+ #stars div {
33
+ position: absolute;
34
+ width: 2px;
35
+ height: 2px;
36
+ background-color: rgba(255, 255, 255, 0.8);
37
+ border-radius: 50%;
38
+ animation: twinkle 4s infinite ease-in-out;
39
+ }
40
+
41
+ @keyframes twinkle {
42
+ 0%, 100% { opacity: 0.2; transform: scale(1); }
43
+ 50% { opacity: 1; transform: scale(1.4); }
44
+ }
45
+
46
+ .upload-panel {
47
+ background: rgba(0, 255, 255, 0.05);
48
+ padding: 2.5rem;
49
+ border-radius: 1.5rem;
50
+ border: 1px solid rgba(0, 255, 255, 0.2);
51
+ box-shadow: 0 0 30px rgba(0, 255, 255, 0.2);
52
+ text-align: center;
53
+ max-width: 420px;
54
+ width: 100%;
55
+ }
56
+
57
+ h2 {
58
+ font-size: 1.6rem;
59
+ color: #00ffff;
60
+ text-shadow: 0 0 10px #00ffff;
61
+ margin-bottom: 1rem;
62
+ }
63
+
64
+ label {
65
+ font-size: 0.9rem;
66
+ color: #8eefff;
67
+ }
68
+
69
+ select, input[type="number"] {
70
+ padding: 0.5rem 1rem;
71
+ border-radius: 0.7rem;
72
+ border: 1px solid #00eaff;
73
+ background: #06131f;
74
+ color: #e0f2ff;
75
+ width: 200px;
76
+ margin-top: 0.3rem;
77
+ margin-bottom: 1rem;
78
+ text-align: center;
79
+ }
80
+
81
+ .drop-zone {
82
+ border: 2px dashed #00eaff;
83
+ padding: 1.5rem;
84
+ border-radius: 1rem;
85
+ width: 90%;
86
+ cursor: pointer;
87
+ position: relative;
88
+ background: rgba(0, 255, 255, 0.03);
89
+ margin-bottom: 1rem;
90
+ }
91
+
92
+ .drop-zone input[type="file"] {
93
+ position: absolute;
94
+ width: 100%;
95
+ height: 100%;
96
+ opacity: 0;
97
+ cursor: pointer;
98
+ top: 0;
99
+ left: 0;
100
+ }
101
+
102
+ .file-name {
103
+ margin-top: 0.6rem;
104
+ font-size: 0.85rem;
105
+ color: #8eefff;
106
+ }
107
+
108
+ .start-button {
109
+ background: #00bfff;
110
+ border: none;
111
+ color: white;
112
+ padding: 0.9rem 2rem;
113
+ border-radius: 1rem;
114
+ font-size: 1.1rem;
115
+ box-shadow: 0 0 20px #00eaff;
116
+ cursor: pointer;
117
+ transition: all 0.3s ease;
118
+ }
119
+
120
+ .start-button:hover {
121
+ box-shadow: 0 0 30px #00ffff;
122
+ transform: scale(1.05);
123
+ }
124
+ </style>
125
+ </head>
126
+ <body>
127
+ <!-- ⭐ พื้นหลังอวกาศ -->
128
+ <div class="background-animation">
129
+ <div id="stars"></div>
130
+ </div>
131
+
132
+ <!-- 🧬 กล่องอัปโหลด -->
133
+ <div class="upload-panel">
134
+ <h2>🧬 Upload Microscopic Image</h2>
135
+ <form method="POST" enctype="multipart/form-data" action="/upload">
136
+ <label>เพศ:</label><br>
137
+ <select name="sex" required>
138
+ <option value="">เลือกเพศ</option>
139
+ <option value="male">ชาย</option>
140
+ <option value="female">หญิง</option>
141
+ </select><br>
142
+
143
+ <label>อายุ:</label><br>
144
+ <input type="number" name="age" min="1" max="120" required><br>
145
+
146
+ <div class="drop-zone">
147
+ <label for="fileInput" class="start-button">📂 Choose Image</label>
148
+ <input type="file" name="file" id="fileInput" required style="display: none;" onchange="updateFileName()">
149
+ <p id="file-name">No file selected...</p>
150
+ </div>
151
+
152
+
153
+ <button type="submit" class="start-button">🚀 Begin AI Scan</button>
154
+ </form>
155
+ </div>
156
+
157
+ <!-- ✨ Script จุดดาว -->
158
+ <script>
159
+ const starsContainer = document.getElementById('stars');
160
+ for (let i = 0; i < 100; i++) {
161
+ const star = document.createElement('div');
162
+ star.style.top = Math.random() * 100 + 'vh';
163
+ star.style.left = Math.random() * 100 + 'vw';
164
+ const size = Math.random() * 1.5 + 1;
165
+ star.style.width = size + 'px';
166
+ star.style.height = size + 'px';
167
+ star.style.animationDuration = (Math.random() * 4 + 3) + 's';
168
+ starsContainer.appendChild(star);
169
+ }
170
+
171
+ function updateFileName() {
172
+ const input = document.getElementById('fileInput');
173
+ const nameDisplay = document.getElementById('file-name');
174
+ nameDisplay.textContent = input.files.length > 0 ? input.files[0].name : "No file selected...";
175
+ }
176
+ </script>
177
+ </body>
178
+ </html>