Add NUC Portal - infrastructure dashboard

Next.js 16 dashboard for managing NUC services via Coolify API.
Features service cards with health indicators, deployment dashboard
with live log streaming, S3-backed preview images, SSE real-time
updates, and dark mode support. 18 services across 7 categories.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-02-18 15:17:25 +01:00
parent 8b503a549c
commit 9a0881e852
55 changed files with 15900 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
/* Google Fonts */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
@import "tailwindcss";
/* Configure Tailwind v4 dark mode to use .dark class */
@custom-variant dark (&:is(.dark, .dark *));
:root {
--background: #F8FAFC;
--foreground: #1E293B;
/* Surface Colors */
--surface-page: #F8FAFC;
--surface-card: #FFFFFF;
--surface-muted: #F1F5F9;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-surface-page: var(--surface-page);
--color-surface-card: var(--surface-card);
--color-surface-muted: var(--surface-muted);
/* Fonts */
--font-sans: 'Inter', sans-serif;
}
/* Dark mode */
.dark {
--background: #0C0A09;
--foreground: #FAFAF9;
--surface-page: #0C0A09;
--surface-card: #1C1917;
--surface-muted: #292524;
}
body {
background: var(--background);
color: var(--foreground);
font-family: 'Inter', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Custom scrollbar for dark mode */
.dark ::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.dark ::-webkit-scrollbar-track {
background: #1C1917;
}
.dark ::-webkit-scrollbar-thumb {
background: #44403C;
border-radius: 4px;
}
.dark ::-webkit-scrollbar-thumb:hover {
background: #57534E;
}
/* Line clamp utility */
.line-clamp-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Animation for loading states */
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.animate-spin {
animation: spin 1s linear infinite;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.animate-pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}