Files
supervisor-ui/app/globals.css
Sebastian Krüger e0cfd371c0
Some checks failed
Build and Push Docker Image to Gitea / build-and-push (push) Failing after 1m22s
feat: initial commit - Supervisor UI with Next.js 16 and Tailwind CSS 4
- Modern web interface for Supervisor process management
- Built with Next.js 16 (App Router) and Tailwind CSS 4
- Full XML-RPC client implementation for Supervisor API
- Real-time process monitoring with auto-refresh
- Process control: start, stop, restart operations
- Modern dashboard with system status and statistics
- Dark/light theme with OKLCH color system
- Docker multi-stage build with runtime env var configuration
- Gitea CI/CD workflow for automated builds
- Comprehensive documentation (README, IMPLEMENTATION, DEPLOYMENT)

Features:
- Backend proxy pattern for secure API communication
- React Query for state management and caching
- TypeScript strict mode with Zod validation
- Responsive design with mobile support
- Health check endpoint for monitoring
- Non-root user security in Docker

Environment Variables:
- SUPERVISOR_HOST, SUPERVISOR_PORT
- SUPERVISOR_USERNAME, SUPERVISOR_PASSWORD (optional)
- Configurable at build-time and runtime

🤖 Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 18:23:51 +01:00

330 lines
6.9 KiB
CSS

@import "tailwindcss";
@plugin "@tailwindcss/typography";
@plugin "@tailwindcss/forms";
/* Content source definitions for Tailwind v4 */
@source "../components/**/*.{js,ts,jsx,tsx}";
@source "../lib/**/*.{js,ts,jsx,tsx}";
@source "./**/*.{js,ts,jsx,tsx}";
/* Custom dark mode variant */
@custom-variant dark (&:is(.dark *));
/* Color System - Supervisor Theme */
:root {
/* Base colors using OKLCH for perceptual uniformity */
--background: oklch(98% 0 0);
--foreground: oklch(20% 0 0);
/* Cards and panels */
--card: oklch(100% 0 0);
--card-foreground: oklch(20% 0 0);
/* Primary - Process management (blue-green) */
--primary: oklch(55% 0.15 220);
--primary-foreground: oklch(98% 0 0);
/* Secondary - System status (slate) */
--secondary: oklch(75% 0.03 250);
--secondary-foreground: oklch(20% 0 0);
/* Accent - Highlights (cyan) */
--accent: oklch(65% 0.12 200);
--accent-foreground: oklch(98% 0 0);
/* Success - Running state (green) */
--success: oklch(60% 0.15 140);
--success-foreground: oklch(98% 0 0);
/* Warning - Stopped/paused (yellow) */
--warning: oklch(75% 0.15 90);
--warning-foreground: oklch(20% 0 0);
/* Destructive - Fatal/error (red) */
--destructive: oklch(55% 0.20 25);
--destructive-foreground: oklch(98% 0 0);
/* Muted - Disabled states */
--muted: oklch(92% 0.01 250);
--muted-foreground: oklch(55% 0.01 250);
/* Borders and inputs */
--border: oklch(88% 0.01 250);
--input: oklch(88% 0.01 250);
--ring: oklch(55% 0.15 220);
/* Chart colors */
--chart-1: oklch(55% 0.15 220);
--chart-2: oklch(60% 0.15 140);
--chart-3: oklch(75% 0.15 90);
--chart-4: oklch(55% 0.20 25);
--chart-5: oklch(65% 0.12 200);
/* Radius */
--radius: 0.5rem;
}
.dark {
--background: oklch(15% 0.01 250);
--foreground: oklch(95% 0 0);
--card: oklch(18% 0.01 250);
--card-foreground: oklch(95% 0 0);
--primary: oklch(65% 0.15 220);
--primary-foreground: oklch(15% 0 0);
--secondary: oklch(25% 0.03 250);
--secondary-foreground: oklch(95% 0 0);
--accent: oklch(55% 0.12 200);
--accent-foreground: oklch(15% 0 0);
--success: oklch(55% 0.15 140);
--success-foreground: oklch(15% 0 0);
--warning: oklch(65% 0.15 90);
--warning-foreground: oklch(15% 0 0);
--destructive: oklch(60% 0.20 25);
--destructive-foreground: oklch(98% 0 0);
--muted: oklch(20% 0.01 250);
--muted-foreground: oklch(60% 0.01 250);
--border: oklch(25% 0.01 250);
--input: oklch(25% 0.01 250);
--ring: oklch(65% 0.15 220);
--chart-1: oklch(65% 0.15 220);
--chart-2: oklch(55% 0.15 140);
--chart-3: oklch(65% 0.15 90);
--chart-4: oklch(60% 0.20 25);
--chart-5: oklch(55% 0.12 200);
}
/* Map colors to Tailwind utilities */
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
/* Custom animations */
--animate-fade-in: fadeIn 0.3s ease-in-out;
--animate-slide-up: slideUp 0.4s ease-out;
--animate-slide-down: slideDown 0.4s ease-out;
--animate-slide-in-right: slideInRight 0.3s ease-out;
--animate-slide-in-left: slideInLeft 0.3s ease-out;
--animate-scale-in: scaleIn 0.2s ease-out;
--animate-bounce-gentle: bounceGentle 0.5s ease-in-out;
--animate-shimmer: shimmer 2s infinite;
--animate-pulse-slow: pulseSlow 3s ease-in-out infinite;
--animate-spin-slow: spinSlow 3s linear infinite;
}
/* Global Styles */
html {
scroll-behavior: smooth;
}
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
font-feature-settings: "rlig" 1, "calt" 1;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
@apply bg-muted;
}
::-webkit-scrollbar-thumb {
@apply bg-muted-foreground/30 rounded;
}
::-webkit-scrollbar-thumb:hover {
@apply bg-muted-foreground/50;
}
/* Screen reader only */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
/* Disable transitions during theme change */
.disable-transitions * {
transition: none !important;
}
/* Animation Keyframes */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideUp {
from {
transform: translateY(10px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes slideDown {
from {
transform: translateY(-10px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes slideInRight {
from {
transform: translateX(-10px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideInLeft {
from {
transform: translateX(10px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes scaleIn {
from {
transform: scale(0.95);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
@keyframes bounceGentle {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-5px);
}
}
@keyframes shimmer {
0% {
background-position: -1000px 0;
}
100% {
background-position: 1000px 0;
}
}
@keyframes pulseSlow {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
@keyframes spinSlow {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* Prose styles for log viewers */
.prose-log {
@apply font-mono text-sm;
white-space: pre-wrap;
word-break: break-all;
}
/* Process state indicators */
.process-running {
@apply bg-success/10 text-success border-success/20;
}
.process-stopped {
@apply bg-muted text-muted-foreground border-border;
}
.process-starting {
@apply bg-warning/10 text-warning border-warning/20;
}
.process-stopping {
@apply bg-warning/10 text-warning border-warning/20;
}
.process-fatal {
@apply bg-destructive/10 text-destructive border-destructive/20;
}
.process-unknown {
@apply bg-muted text-muted-foreground border-border;
}