fix+feat: SPA routing, theme system, modern UI, setup wizard improvements

Fixes:
- Go server now serves index.html for all non-asset paths (SPA fallback)
- Null guard on data.documents prevents undefined.length TypeError
- App.vue waits for checkStatus() before rendering AppLayout (race condition)
- PWA manifest no longer references missing icon files
- index.html applies theme class before paint to prevent flash

Features:
- Theme store: dark/light toggle + 6 accent color presets + custom hex picker
- ThemeToggle component in header dropdown
- CSS custom properties for accent color (--accent-400/500/600/700)
- Tailwind accent-* color utilities driven by CSS vars
- SetupWizard: 3-step flow, password confirmation, LDAP test button,
  animated toggle, review step, proper error/success states
- Sidebar: loading skeleton, active page highlight, null-safe document list
- Global .input, .btn-primary, .btn-secondary, .card component classes
- Stub GraphQL responses for setup/login/testLdapConnection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 13:40:42 +02:00
parent 87821e8988
commit d93f3bb888
12 changed files with 799 additions and 146 deletions

View File

@@ -2,22 +2,113 @@
@tailwind components;
@tailwind utilities;
/* ── Accent color variables (updated at runtime by ThemeStore) ─────────────── */
:root {
--accent-400: 96 165 250; /* blue-400 */
--accent-500: 59 130 246; /* blue-500 */
--accent-600: 37 99 235; /* blue-600 */
--accent-700: 29 78 216; /* blue-700 */
}
/* ── Base element styles ────────────────────────────────────────────────────── */
@layer base {
html {
font-family: 'Inter', ui-sans-serif, system-ui;
-webkit-font-smoothing: antialiased;
}
/* AsciiDoc rendered output */
.adoc-content h1 { @apply text-2xl font-bold mb-4 mt-6; }
.adoc-content h2 { @apply text-xl font-semibold mb-3 mt-5; }
body {
@apply bg-white text-slate-900 dark:bg-slate-900 dark:text-slate-100;
transition: background-color 0.2s, color 0.2s;
}
* {
scrollbar-width: thin;
scrollbar-color: theme('colors.slate.600') transparent;
}
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
@apply bg-slate-300 dark:bg-slate-600 rounded-full;
}
}
/* ── Reusable component classes ────────────────────────────────────────────── */
@layer components {
.card {
@apply bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl;
}
.input {
@apply w-full bg-slate-50 dark:bg-slate-900
border border-slate-300 dark:border-slate-600
rounded-lg px-3 py-2 text-sm
text-slate-900 dark:text-slate-100
placeholder-slate-400 dark:placeholder-slate-500
focus:outline-none focus:ring-2 focus:ring-accent-500 focus:border-transparent
transition;
}
.btn-primary {
@apply inline-flex items-center justify-center gap-2
px-4 py-2 rounded-lg text-sm font-medium text-white
bg-accent-600 hover:bg-accent-500 active:bg-accent-700
disabled:opacity-50 disabled:cursor-not-allowed
transition;
}
.btn-secondary {
@apply inline-flex items-center justify-center gap-2
px-4 py-2 rounded-lg text-sm font-medium
bg-slate-100 dark:bg-slate-800
text-slate-700 dark:text-slate-300
hover:bg-slate-200 dark:hover:bg-slate-700
border border-slate-200 dark:border-slate-700
disabled:opacity-50 transition;
}
.btn-ghost {
@apply inline-flex items-center justify-center gap-2
px-3 py-1.5 rounded-lg text-sm
text-slate-600 dark:text-slate-400
hover:bg-slate-100 dark:hover:bg-slate-800
transition;
}
.label {
@apply block text-sm font-medium text-slate-700 dark:text-slate-300 mb-1.5;
}
}
/* ── AsciiDoc rendered output ──────────────────────────────────────────────── */
@layer utilities {
.adoc-content { @apply text-slate-800 dark:text-slate-200 leading-relaxed; }
.adoc-content h1 { @apply text-2xl font-bold mb-4 mt-6 text-slate-900 dark:text-white; }
.adoc-content h2 { @apply text-xl font-semibold mb-3 mt-5 text-slate-900 dark:text-white; }
.adoc-content h3 { @apply text-lg font-medium mb-2 mt-4; }
.adoc-content p { @apply mb-3 leading-relaxed; }
.adoc-content pre { @apply bg-surface-800 rounded-lg p-4 overflow-x-auto font-mono text-sm mb-4; }
.adoc-content code { @apply font-mono text-sm bg-surface-800 px-1 rounded; }
.adoc-content p { @apply mb-3; }
.adoc-content pre {
@apply bg-slate-100 dark:bg-slate-800/80
border border-slate-200 dark:border-slate-700
rounded-lg p-4 overflow-x-auto font-mono text-sm mb-4;
}
.adoc-content code {
@apply font-mono text-sm
bg-slate-100 dark:bg-slate-800
text-accent-600 dark:text-accent-400
px-1.5 py-0.5 rounded;
}
.adoc-content ul { @apply list-disc list-inside mb-3 space-y-1; }
.adoc-content ol { @apply list-decimal list-inside mb-3 space-y-1; }
.adoc-content blockquote { @apply border-l-4 border-slate-500 pl-4 italic text-slate-400 mb-3; }
.adoc-content blockquote {
@apply border-l-4 border-accent-500 pl-4 italic
text-slate-600 dark:text-slate-400 mb-3;
}
.adoc-content table { @apply w-full text-sm border-collapse mb-4; }
.adoc-content th { @apply bg-surface-800 px-3 py-2 text-left border border-slate-700; }
.adoc-content td { @apply px-3 py-2 border border-slate-700; }
.adoc-content th {
@apply bg-slate-100 dark:bg-slate-800
px-3 py-2 text-left
border border-slate-200 dark:border-slate-700 font-medium;
}
.adoc-content td { @apply px-3 py-2 border border-slate-200 dark:border-slate-700; }
}