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:
@@ -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; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user