Spaces:
Sleeping
Sleeping
Update templates/index.html
Browse files- templates/index.html +21 -17
templates/index.html
CHANGED
|
@@ -8,6 +8,7 @@
|
|
| 8 |
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Syne:wght@400;600;800&display=swap" rel="stylesheet" />
|
| 9 |
|
| 10 |
<style>
|
|
|
|
| 11 |
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
| 12 |
|
| 13 |
:root {
|
|
@@ -20,8 +21,8 @@
|
|
| 20 |
--muted: #6b6b80;
|
| 21 |
--success: #4dffb0;
|
| 22 |
--radius: 16px;
|
| 23 |
-
--mono:
|
| 24 |
-
--sans:
|
| 25 |
}
|
| 26 |
|
| 27 |
body {
|
|
@@ -35,9 +36,9 @@
|
|
| 35 |
padding: 40px 20px 80px;
|
| 36 |
}
|
| 37 |
|
| 38 |
-
|
| 39 |
body::before {
|
| 40 |
-
content:
|
| 41 |
position: fixed;
|
| 42 |
inset: 0;
|
| 43 |
background-image:
|
|
@@ -48,7 +49,7 @@
|
|
| 48 |
z-index: 0;
|
| 49 |
}
|
| 50 |
|
| 51 |
-
|
| 52 |
header {
|
| 53 |
text-align: center;
|
| 54 |
margin-bottom: 48px;
|
|
@@ -72,7 +73,7 @@
|
|
| 72 |
}
|
| 73 |
|
| 74 |
.logo-badge::before {
|
| 75 |
-
content:
|
| 76 |
width: 6px; height: 6px;
|
| 77 |
background: var(--accent);
|
| 78 |
border-radius: 50%;
|
|
@@ -102,7 +103,7 @@
|
|
| 102 |
letter-spacing: 0.05em;
|
| 103 |
}
|
| 104 |
|
| 105 |
-
|
| 106 |
.card {
|
| 107 |
width: 100%;
|
| 108 |
max-width: 640px;
|
|
@@ -117,7 +118,7 @@
|
|
| 117 |
|
| 118 |
.card + .card { margin-top: 24px; }
|
| 119 |
|
| 120 |
-
|
| 121 |
.field-label {
|
| 122 |
font-size: 11px;
|
| 123 |
letter-spacing: 0.12em;
|
|
@@ -128,7 +129,7 @@
|
|
| 128 |
display: block;
|
| 129 |
}
|
| 130 |
|
| 131 |
-
|
| 132 |
.model-selector {
|
| 133 |
display: grid;
|
| 134 |
grid-template-columns: 1fr 1fr;
|
|
@@ -267,6 +268,7 @@
|
|
| 267 |
opacity: 0.7;
|
| 268 |
}
|
| 269 |
|
|
|
|
| 270 |
.error-banner {
|
| 271 |
background: rgba(255, 80, 80, 0.1);
|
| 272 |
border: 1px solid rgba(255, 80, 80, 0.3);
|
|
@@ -278,7 +280,7 @@
|
|
| 278 |
margin-bottom: 24px;
|
| 279 |
}
|
| 280 |
|
| 281 |
-
|
| 282 |
.result-header {
|
| 283 |
display: flex;
|
| 284 |
align-items: center;
|
|
@@ -340,6 +342,7 @@
|
|
| 340 |
margin-top: 8px;
|
| 341 |
}
|
| 342 |
|
|
|
|
| 343 |
.prob-list { display: flex; flex-direction: column; gap: 10px; }
|
| 344 |
|
| 345 |
.prob-row {
|
|
@@ -380,7 +383,7 @@
|
|
| 380 |
.prob-row.top .prob-name { color: var(--text); font-weight: bold; }
|
| 381 |
.prob-row.top .prob-val { color: var(--success); }
|
| 382 |
|
| 383 |
-
|
| 384 |
.btn-reset {
|
| 385 |
margin-top: 24px;
|
| 386 |
display: block;
|
|
@@ -400,6 +403,7 @@
|
|
| 400 |
color: var(--accent);
|
| 401 |
}
|
| 402 |
|
|
|
|
| 403 |
footer {
|
| 404 |
margin-top: 48px;
|
| 405 |
font-size: 11px;
|
|
@@ -412,7 +416,7 @@
|
|
| 412 |
|
| 413 |
footer span { color: var(--accent); }
|
| 414 |
|
| 415 |
-
|
| 416 |
@media (max-width: 480px) {
|
| 417 |
.card { padding: 24px 18px; }
|
| 418 |
.model-btn .icon { font-size: 22px; }
|
|
@@ -428,14 +432,14 @@
|
|
| 428 |
<p class="subtitle">// 6 classes Β· PyTorch & TensorFlow Β· Custom CNN</p>
|
| 429 |
</header>
|
| 430 |
|
| 431 |
-
|
| 432 |
{% if error %}
|
| 433 |
<div class="card" style="max-width:640px;width:100%;position:relative;z-index:1;">
|
| 434 |
<div class="error-banner">β {{ error }}</div>
|
| 435 |
</div>
|
| 436 |
{% endif %}
|
| 437 |
|
| 438 |
-
|
| 439 |
{% if result %}
|
| 440 |
<div class="card">
|
| 441 |
|
|
@@ -467,7 +471,7 @@
|
|
| 467 |
{{ class_icons.get(cls, '') }} {{ cls }}
|
| 468 |
</span>
|
| 469 |
<div class="prob-bar-bg">
|
| 470 |
-
|
| 471 |
</div>
|
| 472 |
<span class="prob-val">{{ prob }}%</span>
|
| 473 |
</div>
|
|
@@ -477,7 +481,7 @@
|
|
| 477 |
<a href="/" class="btn-reset">β© Classify another image</a>
|
| 478 |
</div>
|
| 479 |
|
| 480 |
-
<!-- UPLOAD FORM -->
|
| 481 |
{% else %}
|
| 482 |
<div class="card">
|
| 483 |
<form method="POST" action="/predict" enctype="multipart/form-data" id="upload-form">
|
|
@@ -534,7 +538,7 @@
|
|
| 534 |
Custom CNN β no pretrained weights
|
| 535 |
</footer>
|
| 536 |
|
| 537 |
-
|
| 538 |
<script>
|
| 539 |
const dropZone = document.getElementById('drop-zone');
|
| 540 |
const fileInput = document.getElementById('file-input');
|
|
|
|
| 8 |
<link href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=Syne:wght@400;600;800&display=swap" rel="stylesheet" />
|
| 9 |
|
| 10 |
<style>
|
| 11 |
+
/* ββ Reset & CSS vars βββββββββββββββββββββββββββββββββββββββββββββ */
|
| 12 |
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
| 13 |
|
| 14 |
:root {
|
|
|
|
| 21 |
--muted: #6b6b80;
|
| 22 |
--success: #4dffb0;
|
| 23 |
--radius: 16px;
|
| 24 |
+
--mono: "Space Mono", monospace;
|
| 25 |
+
--sans: "Syne", sans-serif;
|
| 26 |
}
|
| 27 |
|
| 28 |
body {
|
|
|
|
| 36 |
padding: 40px 20px 80px;
|
| 37 |
}
|
| 38 |
|
| 39 |
+
/* ββ Animated grid background βββββββββββββββββββββββββββββββββββββ */
|
| 40 |
body::before {
|
| 41 |
+
content: "";
|
| 42 |
position: fixed;
|
| 43 |
inset: 0;
|
| 44 |
background-image:
|
|
|
|
| 49 |
z-index: 0;
|
| 50 |
}
|
| 51 |
|
| 52 |
+
/* ββ Header βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 53 |
header {
|
| 54 |
text-align: center;
|
| 55 |
margin-bottom: 48px;
|
|
|
|
| 73 |
}
|
| 74 |
|
| 75 |
.logo-badge::before {
|
| 76 |
+
content: "";
|
| 77 |
width: 6px; height: 6px;
|
| 78 |
background: var(--accent);
|
| 79 |
border-radius: 50%;
|
|
|
|
| 103 |
letter-spacing: 0.05em;
|
| 104 |
}
|
| 105 |
|
| 106 |
+
/* ββ Main card ββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 107 |
.card {
|
| 108 |
width: 100%;
|
| 109 |
max-width: 640px;
|
|
|
|
| 118 |
|
| 119 |
.card + .card { margin-top: 24px; }
|
| 120 |
|
| 121 |
+
/* ββ Form βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 122 |
.field-label {
|
| 123 |
font-size: 11px;
|
| 124 |
letter-spacing: 0.12em;
|
|
|
|
| 129 |
display: block;
|
| 130 |
}
|
| 131 |
|
| 132 |
+
/* Model selector */
|
| 133 |
.model-selector {
|
| 134 |
display: grid;
|
| 135 |
grid-template-columns: 1fr 1fr;
|
|
|
|
| 268 |
opacity: 0.7;
|
| 269 |
}
|
| 270 |
|
| 271 |
+
/* ββ Error banner βββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 272 |
.error-banner {
|
| 273 |
background: rgba(255, 80, 80, 0.1);
|
| 274 |
border: 1px solid rgba(255, 80, 80, 0.3);
|
|
|
|
| 280 |
margin-bottom: 24px;
|
| 281 |
}
|
| 282 |
|
| 283 |
+
/* ββ Result section βββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 284 |
.result-header {
|
| 285 |
display: flex;
|
| 286 |
align-items: center;
|
|
|
|
| 342 |
margin-top: 8px;
|
| 343 |
}
|
| 344 |
|
| 345 |
+
/* ββ Probability bars βββββββββββββββββββββββββββββββββββββββββββββ */
|
| 346 |
.prob-list { display: flex; flex-direction: column; gap: 10px; }
|
| 347 |
|
| 348 |
.prob-row {
|
|
|
|
| 383 |
.prob-row.top .prob-name { color: var(--text); font-weight: bold; }
|
| 384 |
.prob-row.top .prob-val { color: var(--success); }
|
| 385 |
|
| 386 |
+
/* ββ Try again button βββββββββββββββββββββββββββββββββββββββββββββ */
|
| 387 |
.btn-reset {
|
| 388 |
margin-top: 24px;
|
| 389 |
display: block;
|
|
|
|
| 403 |
color: var(--accent);
|
| 404 |
}
|
| 405 |
|
| 406 |
+
/* ββ Footer βββββββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 407 |
footer {
|
| 408 |
margin-top: 48px;
|
| 409 |
font-size: 11px;
|
|
|
|
| 416 |
|
| 417 |
footer span { color: var(--accent); }
|
| 418 |
|
| 419 |
+
/* ββ Responsive βββββββββββββββββββββββββββββββββββββββββββββββββββ */
|
| 420 |
@media (max-width: 480px) {
|
| 421 |
.card { padding: 24px 18px; }
|
| 422 |
.model-btn .icon { font-size: 22px; }
|
|
|
|
| 432 |
<p class="subtitle">// 6 classes Β· PyTorch & TensorFlow Β· Custom CNN</p>
|
| 433 |
</header>
|
| 434 |
|
| 435 |
+
<!-- Error banner (if any) -->
|
| 436 |
{% if error %}
|
| 437 |
<div class="card" style="max-width:640px;width:100%;position:relative;z-index:1;">
|
| 438 |
<div class="error-banner">β {{ error }}</div>
|
| 439 |
</div>
|
| 440 |
{% endif %}
|
| 441 |
|
| 442 |
+
<!-- ββ RESULT CARD βββββββββββββββββββββββββββββββββββββββββββββββββββββββ -->
|
| 443 |
{% if result %}
|
| 444 |
<div class="card">
|
| 445 |
|
|
|
|
| 471 |
{{ class_icons.get(cls, '') }} {{ cls }}
|
| 472 |
</span>
|
| 473 |
<div class="prob-bar-bg">
|
| 474 |
+
<div class="prob-bar-fill" :style="{ width: prob + '%' }"></div>
|
| 475 |
</div>
|
| 476 |
<span class="prob-val">{{ prob }}%</span>
|
| 477 |
</div>
|
|
|
|
| 481 |
<a href="/" class="btn-reset">β© Classify another image</a>
|
| 482 |
</div>
|
| 483 |
|
| 484 |
+
<!-- ββ UPLOAD FORM ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ -->
|
| 485 |
{% else %}
|
| 486 |
<div class="card">
|
| 487 |
<form method="POST" action="/predict" enctype="multipart/form-data" id="upload-form">
|
|
|
|
| 538 |
Custom CNN β no pretrained weights
|
| 539 |
</footer>
|
| 540 |
|
| 541 |
+
<!-- ββ JS: drag-drop, preview, loading state βββββββββββββββββββββββββββββ -->
|
| 542 |
<script>
|
| 543 |
const dropZone = document.getElementById('drop-zone');
|
| 544 |
const fileInput = document.getElementById('file-input');
|