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: [],