ai2 / static /style.css
Gokul
Deploy DR Diagnostic Platform v9.5 — Material Design 3 UI with Grad-CAM++ explainability
034e09f
Raw
History Blame Contribute Delete
15.3 kB
/* ============================================================
DR Diagnostic Platform — Material Design 3 Premium Stylesheet
============================================================ */
:root {
/* Primary Palette — Deep Indigo / Teal */
--md-primary: #1a237e;
--md-primary-light: #534bae;
--md-primary-dark: #000051;
--md-secondary: #00897b;
--md-secondary-light: #4ebaaa;
--md-secondary-dark: #005b4f;
--md-on-primary: #ffffff;
/* Surface & Background */
--md-surface: #ffffff;
--md-surface-variant: #f5f6fa;
--md-surface-elevated: #ffffff;
--md-background: #f0f2f5;
--md-on-surface: #1c1b1f;
--md-on-surface-variant: #49454f;
--md-outline: #dde1e6;
/* Elevation Shadows */
--shadow-1: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.06);
--shadow-2: 0 4px 6px rgba(0,0,0,0.07), 0 2px 4px rgba(0,0,0,0.06);
--shadow-3: 0 10px 25px rgba(0,0,0,0.08), 0 4px 10px rgba(0,0,0,0.05);
--shadow-4: 0 20px 40px rgba(0,0,0,0.1), 0 8px 16px rgba(0,0,0,0.06);
/* Typography */
--font-primary: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
/* Border Radius */
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 16px;
--radius-xl: 24px;
/* Transitions */
--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-standard: 300ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-emphasis: 500ms cubic-bezier(0.4, 0, 0.2, 1);
}
/* Reset */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(--font-primary);
background: var(--md-background);
color: var(--md-on-surface);
line-height: 1.6;
min-height: 100vh;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* ============================================================
Header
============================================================ */
.app-header {
background: linear-gradient(135deg, var(--md-primary) 0%, var(--md-primary-light) 100%);
color: var(--md-on-primary);
padding: 0 24px;
box-shadow: var(--shadow-3);
position: sticky;
top: 0;
z-index: 100;
}
.header-content {
max-width: 1200px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 0;
gap: 16px;
}
.header-brand {
display: flex;
align-items: center;
gap: 16px;
}
.header-icon {
font-size: 36px;
opacity: 0.95;
}
.header-title {
font-size: 22px;
font-weight: 700;
letter-spacing: -0.3px;
line-height: 1.2;
}
.header-subtitle {
font-size: 13px;
font-weight: 400;
opacity: 0.8;
margin-top: 2px;
}
.header-badge {
display: flex;
gap: 8px;
flex-shrink: 0;
}
.badge-version, .badge-model {
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.3px;
}
.badge-version {
background: rgba(255,255,255,0.2);
backdrop-filter: blur(10px);
}
.badge-model {
background: var(--md-secondary);
color: #fff;
}
/* ============================================================
Main Content
============================================================ */
.app-main {
max-width: 1000px;
margin: 0 auto;
padding: 32px 24px;
}
/* ============================================================
Upload Section
============================================================ */
.upload-card {
background: var(--md-surface);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-2);
overflow: hidden;
transition: box-shadow var(--transition-standard);
}
.upload-card:hover {
box-shadow: var(--shadow-3);
}
.upload-zone {
padding: 48px 32px;
border: 2px dashed var(--md-outline);
border-radius: var(--radius-lg);
margin: 24px;
cursor: pointer;
transition: all var(--transition-standard);
display: flex;
align-items: center;
justify-content: center;
min-height: 300px;
}
.upload-zone:hover, .upload-zone.drag-over {
border-color: var(--md-primary);
background: rgba(26, 35, 126, 0.03);
}
.upload-content {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 8px;
}
.upload-icon {
font-size: 64px;
color: var(--md-primary);
opacity: 0.6;
margin-bottom: 8px;
}
.upload-title {
font-size: 22px;
font-weight: 600;
color: var(--md-on-surface);
}
.upload-desc {
font-size: 14px;
color: var(--md-on-surface-variant);
max-width: 360px;
}
.upload-formats {
font-size: 12px;
color: var(--md-on-surface-variant);
opacity: 0.7;
margin-top: 4px;
}
.upload-btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 28px;
background: var(--md-primary);
color: var(--md-on-primary);
border: none;
border-radius: var(--radius-xl);
font-family: var(--font-primary);
font-size: 14px;
font-weight: 600;
cursor: pointer;
margin-top: 16px;
transition: all var(--transition-fast);
box-shadow: var(--shadow-1);
}
.upload-btn:hover {
background: var(--md-primary-light);
box-shadow: var(--shadow-2);
transform: translateY(-1px);
}
.upload-preview {
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.upload-preview img {
max-width: 100%;
max-height: 400px;
border-radius: var(--radius-md);
object-fit: contain;
}
.remove-btn {
position: absolute;
top: -8px;
right: -8px;
width: 36px;
height: 36px;
border-radius: 50%;
background: #ef5350;
color: #fff;
border: 3px solid var(--md-surface);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
box-shadow: var(--shadow-2);
transition: all var(--transition-fast);
}
.remove-btn:hover {
background: #d32f2f;
transform: scale(1.1);
}
.remove-btn .material-icons-round {
font-size: 18px;
}
.analyze-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
width: calc(100% - 48px);
margin: 0 24px 24px;
padding: 16px;
background: linear-gradient(135deg, var(--md-secondary), var(--md-secondary-dark));
color: #fff;
border: none;
border-radius: var(--radius-md);
font-family: var(--font-primary);
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all var(--transition-standard);
box-shadow: var(--shadow-2);
}
.analyze-btn:hover:not(:disabled) {
box-shadow: var(--shadow-3);
transform: translateY(-1px);
}
.analyze-btn:disabled {
opacity: 0.4;
cursor: not-allowed;
transform: none;
}
/* ============================================================
Loading Section
============================================================ */
.loading-section {
display: flex;
justify-content: center;
padding: 48px 0;
}
.loading-card {
background: var(--md-surface);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-3);
padding: 48px 64px;
text-align: center;
}
.loading-spinner {
width: 56px;
height: 56px;
border: 4px solid var(--md-outline);
border-top-color: var(--md-primary);
border-radius: 50%;
animation: spin 1s linear infinite;
margin: 0 auto 24px;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.loading-title {
font-size: 20px;
font-weight: 600;
margin-bottom: 8px;
}
.loading-desc {
font-size: 14px;
color: var(--md-on-surface-variant);
margin-bottom: 32px;
}
.loading-steps {
display: flex;
gap: 24px;
justify-content: center;
}
.loading-step {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
font-size: 12px;
font-weight: 500;
color: var(--md-outline);
transition: color var(--transition-standard);
}
.loading-step .material-icons-round {
font-size: 24px;
}
.loading-step.active {
color: var(--md-primary);
}
/* ============================================================
Results Section
============================================================ */
.results-section {
display: flex;
flex-direction: column;
gap: 20px;
}
.fade-in {
animation: fadeInUp 0.6s ease-out;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Primary Result */
.result-primary {
background: var(--md-surface);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-3);
padding: 32px;
display: flex;
align-items: center;
gap: 32px;
}
.severity-indicator {
flex-shrink: 0;
width: 200px;
padding: 24px;
border-radius: var(--radius-lg);
border: 3px solid;
text-align: center;
transition: all var(--transition-emphasis);
}
.severity-grade {
font-size: 48px;
font-weight: 800;
line-height: 1;
}
.severity-label {
font-size: 18px;
font-weight: 600;
margin-top: 8px;
}
.severity-risk {
font-size: 13px;
font-weight: 600;
margin-top: 4px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.confidence-section {
flex: 1;
}
.confidence-title {
font-size: 14px;
font-weight: 600;
color: var(--md-on-surface-variant);
margin-bottom: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.confidence-bar-container {
height: 12px;
background: var(--md-surface-variant);
border-radius: 6px;
overflow: hidden;
}
.confidence-bar {
height: 100%;
border-radius: 6px;
width: 0;
transition: width 1s cubic-bezier(0.4, 0, 0.2, 1);
}
.confidence-value {
display: block;
font-size: 28px;
font-weight: 700;
margin-top: 12px;
color: var(--md-on-surface);
font-family: var(--font-mono);
}
/* Metrics Grid */
.metrics-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.metric-card {
background: var(--md-surface);
border-radius: var(--radius-md);
box-shadow: var(--shadow-1);
padding: 20px;
display: flex;
align-items: center;
gap: 16px;
transition: box-shadow var(--transition-fast);
}
.metric-card:hover {
box-shadow: var(--shadow-2);
}
.metric-icon {
font-size: 28px;
color: var(--md-secondary);
background: rgba(0, 137, 123, 0.08);
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-md);
}
.metric-value {
font-size: 20px;
font-weight: 700;
font-family: var(--font-mono);
color: var(--md-on-surface);
display: block;
}
.metric-label {
font-size: 12px;
color: var(--md-on-surface-variant);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.3px;
}
/* Probabilities Card */
.probabilities-card {
background: var(--md-surface);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-2);
padding: 28px;
}
.card-title {
font-size: 16px;
font-weight: 600;
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 20px;
color: var(--md-on-surface);
}
.card-title .material-icons-round {
font-size: 20px;
color: var(--md-primary);
}
.prob-row {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 12px;
}
.prob-label {
width: 130px;
font-size: 13px;
font-weight: 500;
color: var(--md-on-surface-variant);
flex-shrink: 0;
}
.prob-track {
flex: 1;
height: 10px;
background: var(--md-surface-variant);
border-radius: 5px;
overflow: hidden;
}
.prob-fill {
height: 100%;
border-radius: 5px;
transition: width 1s cubic-bezier(0.4, 0, 0.2, 1);
}
.prob-value {
width: 60px;
text-align: right;
font-size: 13px;
font-weight: 600;
font-family: var(--font-mono);
color: var(--md-on-surface);
flex-shrink: 0;
}
/* Visual Cards */
.visuals-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.visual-card {
background: var(--md-surface);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-2);
padding: 24px;
}
.visual-container {
background: #0a0a0a;
border-radius: var(--radius-md);
padding: 8px;
display: flex;
justify-content: center;
align-items: center;
min-height: 250px;
}
.visual-container img {
max-width: 100%;
max-height: 350px;
border-radius: var(--radius-sm);
object-fit: contain;
}
.no-gradcam {
color: #666;
font-size: 14px;
font-style: italic;
text-align: center;
padding: 40px;
}
/* Disclaimer */
.disclaimer-card {
background: linear-gradient(135deg, #fff3e0, #ffe0b2);
border: 1px solid #ffcc02;
border-radius: var(--radius-md);
padding: 20px 24px;
display: flex;
gap: 16px;
align-items: flex-start;
}
.disclaimer-icon {
font-size: 28px;
color: #e65100;
flex-shrink: 0;
margin-top: 2px;
}
.disclaimer-title {
font-size: 14px;
font-weight: 700;
color: #bf360c;
margin-bottom: 4px;
text-transform: uppercase;
letter-spacing: 0.3px;
}
.disclaimer-text {
font-size: 13px;
color: #4e342e;
line-height: 1.5;
}
/* New Analysis Button */
.new-analysis-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
width: 100%;
padding: 16px;
background: var(--md-primary);
color: var(--md-on-primary);
border: none;
border-radius: var(--radius-md);
font-family: var(--font-primary);
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all var(--transition-standard);
box-shadow: var(--shadow-2);
}
.new-analysis-btn:hover {
background: var(--md-primary-light);
box-shadow: var(--shadow-3);
transform: translateY(-1px);
}
/* ============================================================
Footer
============================================================ */
.app-footer {
text-align: center;
padding: 32px 24px 40px;
color: var(--md-on-surface-variant);
font-size: 13px;
}
.footer-meta {
margin-top: 4px;
font-size: 12px;
opacity: 0.6;
}
/* ============================================================
Responsive
============================================================ */
@media (max-width: 768px) {
.header-content {
flex-direction: column;
text-align: center;
}
.header-brand {
flex-direction: column;
gap: 8px;
}
.result-primary {
flex-direction: column;
text-align: center;
}
.severity-indicator {
width: 100%;
max-width: 240px;
}
.metrics-grid {
grid-template-columns: 1fr;
}
.visuals-grid {
grid-template-columns: 1fr;
}
.loading-steps {
flex-direction: column;
gap: 12px;
}
.upload-zone {
padding: 32px 16px;
margin: 16px;
}
.analyze-btn {
margin: 0 16px 16px;
width: calc(100% - 32px);
}
}