diff --git a/frontend/index.html b/frontend/index.html
index 7fbee91..58c0395 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -5,6 +5,9 @@
Schaeffler Automat
+
+
+
diff --git a/frontend/src/index.css b/frontend/src/index.css
index f7a538a..f6ca417 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -49,20 +49,20 @@
============================================================ */
:root {
/* Surfaces */
- --color-bg-app: #f9fafb;
+ --color-bg-app: #f8f9fb;
--color-bg-surface: #ffffff;
- --color-bg-surface-hover: #f9fafb;
- --color-bg-muted: #f3f4f6;
+ --color-bg-surface-hover: #f5f6f8;
+ --color-bg-muted: #f1f3f5;
/* Text */
- --color-text: #111827;
- --color-text-secondary: #4b5563;
- --color-text-muted: #9ca3af;
+ --color-text: #18181b;
+ --color-text-secondary: #52525b;
+ --color-text-muted: #a1a1aa;
--color-text-inverse: #ffffff;
/* Borders */
- --color-border: #e5e7eb;
- --color-border-light: #f3f4f6;
+ --color-border: #e4e4e7;
+ --color-border-light: #f1f3f5;
/* Status — Success */
--color-status-success-bg: #dcfce7;
@@ -94,63 +94,63 @@
Applied via .dark class on
============================================================ */
:root.dark {
- /* Surfaces */
- --color-bg-app: #0f172a;
- --color-bg-surface: #1e293b;
- --color-bg-surface-hover: #334155;
- --color-bg-muted: #1e293b;
+ /* Surfaces — neutral grays instead of blue-slate */
+ --color-bg-app: #09090b;
+ --color-bg-surface: #18181b;
+ --color-bg-surface-hover: #27272a;
+ --color-bg-muted: #1c1c1f;
/* Text */
- --color-text: #f1f5f9;
- --color-text-secondary: #94a3b8;
- --color-text-muted: #64748b;
- --color-text-inverse: #0f172a;
+ --color-text: #fafafa;
+ --color-text-secondary: #a1a1aa;
+ --color-text-muted: #71717a;
+ --color-text-inverse: #09090b;
- /* Borders */
- --color-border: #334155;
- --color-border-light: #1e293b;
+ /* Borders — subtle */
+ --color-border: rgba(255, 255, 255, 0.08);
+ --color-border-light: rgba(255, 255, 255, 0.04);
/* Status — Success */
- --color-status-success-bg: rgba(34, 197, 94, 0.15);
+ --color-status-success-bg: rgba(34, 197, 94, 0.12);
--color-status-success-text: #4ade80;
/* Status — Warning */
- --color-status-warning-bg: rgba(234, 179, 8, 0.15);
+ --color-status-warning-bg: rgba(234, 179, 8, 0.12);
--color-status-warning-text: #facc15;
/* Status — Error */
- --color-status-error-bg: rgba(239, 68, 68, 0.15);
+ --color-status-error-bg: rgba(239, 68, 68, 0.12);
--color-status-error-text: #f87171;
/* Status — Info */
- --color-status-info-bg: rgba(59, 130, 246, 0.15);
+ --color-status-info-bg: rgba(59, 130, 246, 0.12);
--color-status-info-text: #60a5fa;
/* Extended badge colors */
- --color-badge-purple-bg: rgba(124, 58, 237, 0.2);
+ --color-badge-purple-bg: rgba(124, 58, 237, 0.15);
--color-badge-purple-text: #a78bfa;
- --color-badge-orange-bg: rgba(234, 88, 12, 0.2);
+ --color-badge-orange-bg: rgba(234, 88, 12, 0.15);
--color-badge-orange-text: #fb923c;
- --color-badge-teal-bg: rgba(13, 148, 136, 0.2);
+ --color-badge-teal-bg: rgba(13, 148, 136, 0.15);
--color-badge-teal-text: #2dd4bf;
}
/* Dark accent-light overrides (rgba instead of solid pastel) */
:root.dark,
:root.dark [data-accent="green"] {
- --color-accent-light: rgba(0, 137, 61, 0.15);
+ --color-accent-light: rgba(0, 137, 61, 0.12);
}
:root.dark [data-accent="blue"] {
- --color-accent-light: rgba(37, 99, 235, 0.15);
+ --color-accent-light: rgba(37, 99, 235, 0.12);
}
:root.dark [data-accent="purple"] {
- --color-accent-light: rgba(124, 58, 237, 0.15);
+ --color-accent-light: rgba(124, 58, 237, 0.12);
}
:root.dark [data-accent="amber"] {
- --color-accent-light: rgba(217, 119, 6, 0.15);
+ --color-accent-light: rgba(217, 119, 6, 0.12);
}
:root.dark [data-accent="teal"] {
- --color-accent-light: rgba(13, 148, 136, 0.15);
+ --color-accent-light: rgba(13, 148, 136, 0.12);
}
/* ============================================================
@@ -159,9 +159,14 @@
@layer base {
body {
@apply antialiased;
+ font-family: 'Inter', system-ui, -apple-system, sans-serif;
background-color: var(--color-bg-app);
color: var(--color-text);
transition: background-color 200ms ease, color 200ms ease;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
+ letter-spacing: -0.01em;
}
/* Native color scheme for form controls */
@@ -177,24 +182,57 @@
input[type="radio"] {
accent-color: var(--color-accent);
}
+
+ /* Better default scrollbar (thin, subtle) */
+ * {
+ scrollbar-width: thin;
+ scrollbar-color: var(--color-border) transparent;
+ }
+ *::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+ }
+ *::-webkit-scrollbar-track {
+ background: transparent;
+ }
+ *::-webkit-scrollbar-thumb {
+ background-color: var(--color-border);
+ border-radius: 3px;
+ }
+
+ /* Smoother global transitions */
+ a, button, input, select, textarea {
+ transition: all 150ms ease;
+ }
+
+ /* Better selection color */
+ ::selection {
+ background-color: var(--color-accent);
+ color: white;
+ }
}
/* ============================================================
COMPONENT CLASSES
============================================================ */
@layer components {
- /* Buttons */
+ /* ── Buttons ─────────────────────────────────────────────── */
.btn {
- @apply inline-flex items-center gap-2 px-4 py-2 rounded-md font-medium text-sm transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed;
+ @apply inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg font-medium text-sm transition-all duration-150 ease-out focus:outline-none focus:ring-2 focus:ring-offset-1 disabled:opacity-50 disabled:cursor-not-allowed;
}
.btn-primary {
- @apply btn;
+ @apply btn shadow-sm;
background-color: var(--color-accent);
color: var(--color-accent-text);
--tw-ring-color: var(--color-accent);
}
.btn-primary:hover:not(:disabled) {
background-color: var(--color-accent-hover);
+ transform: translateY(-0.5px);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
+ }
+ .btn-primary:active:not(:disabled) {
+ transform: translateY(0);
}
.btn-secondary {
@apply btn border;
@@ -205,21 +243,35 @@
}
.btn-secondary:hover:not(:disabled) {
background-color: var(--color-bg-surface-hover);
+ border-color: var(--color-text-muted);
}
.btn-danger {
- @apply btn bg-red-600 text-white hover:bg-red-700 focus:ring-red-500;
+ @apply btn bg-red-600 text-white shadow-sm hover:bg-red-700 focus:ring-red-500;
+ }
+ .btn-danger:hover:not(:disabled) {
+ transform: translateY(-0.5px);
}
- /* Cards */
+ /* Icon-only button variant */
+ .btn-icon {
+ @apply inline-flex items-center justify-center p-1.5 rounded-lg transition-all duration-150 ease-out hover:bg-surface-hover focus:outline-none focus:ring-1;
+ --tw-ring-color: var(--color-accent);
+ }
+
+ /* ── Cards ───────────────────────────────────────────────── */
.card {
- @apply rounded-lg border shadow-sm;
+ @apply rounded-xl border;
background-color: var(--color-bg-surface);
border-color: var(--color-border);
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.04), 0 1px 2px -1px rgba(0, 0, 0, 0.03);
+ }
+ :root.dark .card {
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.03);
}
- /* Badges */
+ /* ── Badges ──────────────────────────────────────────────── */
.badge {
- @apply inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium;
+ @apply inline-flex items-center px-2 py-0.5 rounded-md text-xs font-medium tracking-wide;
}
.badge-green {
@apply badge;
@@ -262,9 +314,9 @@
color: var(--color-badge-teal-text);
}
- /* Input base — replaces repeated inline input patterns */
+ /* ── Inputs ──────────────────────────────────────────────── */
.input-base {
- @apply w-full px-3 py-2 rounded-md text-sm border focus:outline-none focus:ring-2 transition-colors;
+ @apply w-full px-3 py-2 rounded-lg text-sm border focus:outline-none focus:ring-2 focus:ring-offset-0 transition-all duration-150;
background-color: var(--color-bg-surface);
color: var(--color-text);
border-color: var(--color-border);
@@ -279,7 +331,7 @@
/* Small input variant (used in admin tables) */
.input-sm {
- @apply px-2 py-1 rounded text-sm border focus:outline-none focus:ring-1 transition-colors;
+ @apply px-2 py-1 rounded-md text-sm border focus:outline-none focus:ring-1 focus:ring-offset-0 transition-all duration-150;
background-color: var(--color-bg-surface);
color: var(--color-text);
border-color: var(--color-border);
@@ -288,4 +340,41 @@
.input-sm:focus {
border-color: var(--color-accent);
}
+
+ /* ── Tables ──────────────────────────────────────────────── */
+ table th {
+ @apply text-xs uppercase tracking-wider font-semibold;
+ color: var(--color-text-muted);
+ letter-spacing: 0.05em;
+ }
+}
+
+/* ============================================================
+ UTILITY ENHANCEMENTS
+ ============================================================ */
+
+/* Smooth page transitions */
+.page-enter {
+ animation: fadeIn 200ms ease-out;
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(4px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+/* Pulse animation for loading states */
+@keyframes subtlePulse {
+ 0%, 100% { opacity: 1; }
+ 50% { opacity: 0.7; }
+}
+
+.animate-subtle-pulse {
+ animation: subtlePulse 2s ease-in-out infinite;
}
diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js
index c6b1223..dd619ef 100644
--- a/frontend/tailwind.config.js
+++ b/frontend/tailwind.config.js
@@ -4,6 +4,9 @@ export default {
darkMode: 'class',
theme: {
extend: {
+ fontFamily: {
+ sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
+ },
colors: {
// Semantic surface tokens
surface: {
@@ -53,6 +56,15 @@ export default {
ringColor: {
accent: 'var(--color-accent)',
},
+ boxShadow: {
+ 'card': '0 1px 3px 0 rgba(0, 0, 0, 0.04), 0 1px 2px -1px rgba(0, 0, 0, 0.03)',
+ 'card-hover': '0 4px 12px 0 rgba(0, 0, 0, 0.08), 0 2px 4px -1px rgba(0, 0, 0, 0.04)',
+ 'elevated': '0 8px 24px -4px rgba(0, 0, 0, 0.12), 0 4px 8px -2px rgba(0, 0, 0, 0.06)',
+ },
+ borderRadius: {
+ 'xl': '0.875rem',
+ '2xl': '1rem',
+ },
},
},
plugins: [],