- Convert codexInfo.md to CLAUDE.md as the central project context. - Rewrite GUI/style.md with a modernized, file-first direction (layered surfaces, refined typography, motion budget, ambient gradients). - Refresh global tokens in global.css, page-layouts.css and surface-patterns.css: extended palette (primary 050/800, surface elevated, border subtle), four-tier shadow system, dark-mode parity, new utilities (hoard-chip, hoard-icon-tile, hoard-spotlight, hoard-section-head, hoard-divider-soft, status pulse dot). - Rebuild Layout.vue: premium app shell with brand halo, animated active-indicator, account pill with avatar/initials, drawer footer card, refined banner stack and footer. - Redesign every route while preserving routing and API contracts: Home, Login, ChangePassword, Dashboard, AdminUsers, AdminUserDetail, Impressum, 404, Forbidden. Adds search/admin stats, password hint list, dashboard greeting with avatar, modernized hero/spotlight treatments and consistent mobile layouts (safe-areas, 44/48px tap targets). - Drop @fontsource/roboto import in vuetify.ts and load Inter via the rsms.me CSS in index.html; update Vuetify defaults and palette to match the new tokens.
15 KiB
Hoard – Style Guide
Zielbild
Hoard soll wirken wie eine moderne, produktive Dateiverwaltung im Browser – ruhig, klar und mit hoher visueller Sorgfalt. Die Grundphilosophie bleibt dateiorientiert: Inhalte, Dateinamen, Pfade und Aktionen stehen im Vordergrund, nicht UI-Effekte. Gleichzeitig darf sich Hoard hochwertig und präzise anfühlen – „polished" statt „fancy", näher an einer modernen Linear-/Vercel-/Notion-Sidebar als an einer alten Admin-UI.
Die Gestaltung folgt drei Prinzipien:
- Dateien zuerst – Inhalte, Namen, Strukturen und Aktionen sind optisch dominant, nicht die Chrome.
- Ruhe mit Charakter – viel Weißraum, klare Flächen, ausgewählte Akzente. Wenig Elemente, aber jedes mit Sorgfalt.
- Grün als Identität, nicht als Dauerfeuer – die Markenfarbe wird gezielt für Auswahl, Primäraktionen, Status und Branding eingesetzt – nicht flächendeckend.
Modernisierungs-Direktive
Beim Redesign gilt zusätzlich:
- Hochwertige App-Shell: Sidebar und Topbar dürfen sich „premium" anfühlen (klare Hierarchie, animierter Active-Indicator, gradient-tinged Brand-Bereich).
- Layered Surfaces: Statt einer einzigen Surface-Farbe gibt es eine kleine Surface-Hierarchie (
surface,surface-alt,surface-elevated) mit subtil gestaffelten Schatten. - Microinteractions: kurze, präzise Hover-/Active-/Focus-Animationen (160–240 ms). Keine wabernden, dauerhaften Bewegungen.
- Ambient Gradients: Hero-/Brand-Bereiche dürfen sehr weiche, breit gestreute Verläufe in Markenfarbe haben. Arbeitsflächen bleiben funktional und ruhig.
- Typografische Präzision: klare Größen-Hierarchie, ruhige Headlines, viel
letter-spacingDisziplin, keine dekorativen Schriften. - Konsistente Iconographie: ausschließlich MDI Outline-Icons mit gleicher Größe und Farbverhalten.
- Light- und Dark-Mode gleichwertig: alle neuen Stile müssen in beiden Modi funktional und ästhetisch tragen, ausschließlich über Tokens (
color-mix, CSS-Variablen) gelöst.
Was weiterhin tabu ist:
- kein Glassmorphism (echte Backdrop-Blur-Karten),
- kein Neon-/Gaming-Look,
- keine harten, durchgängigen Kontraste,
- keine Mehrfarbigkeit aus dem Akzent-Setup,
- keine dauerhaften Animationen oder Parallax-Spielereien.
Visuelle Identität
Markenwirkung basiert auf neutralen, leicht warmen Flächen mit kontrolliertem Grün. Das Grün stammt aus dem Logo (Stapel-/Ordner-Idee) und steht für Ablage, Struktur und „self-hosted tool" statt „Social App". Akzent-Lime nur als gezielter Akzent-Glow im Branding und in Marketing-Sektionen.
Die App ist light-first, Dark-Mode ist gleichwertig zu pflegen. Neue Komponenten beziehen Farben aus Design-Tokens.
Farbpalette
Primärfarben (Light)
- Primary 800:
#10421E– tiefster Markenton, Texte auf Light-Surface. - Primary 700:
#1C652F– Primärbuttons, aktive Icons, Fokusrahmen. - Primary 600:
#2E7D32– Hover-Zustände, aktive Navigation. - Primary 500:
#3C8F42– ausgewählte Einträge, Badges, bestätigende States. - Primary 300:
#A8D5A2– weiche Hintergründe für Auswahlflächen. - Primary 100:
#EAF5E8– sehr subtile Hervorhebungen, Tints. - Primary 050:
#F4FAF1– fast unsichtbare Pflasterfläche für Hero-Glows.
Akzent
- Accent Lime:
#B7E36B– sparsam: Logo-Glow, kleine Highlights, Upload-Fortschritt.
Neutrale (Light)
- Background:
#F5F8F2 - Background Tint:
#EEF3EA– ambient Hintergrund-Verlauf. - Surface:
#FFFFFF– Karten, Panels, Dialoge. - Surface Alt:
#F1F4EE– Toolbar, Tabellenkopf, Sekundärflächen. - Surface Elevated:
#FBFCF8– höhere Layer (Drawer-Inhalt, Dropdowns). - Border:
#DCE3D6 - Border Strong:
#C5CFBE - Border Subtle:
#E8EDE2– innere Trennlinien.
Text (Light)
- Text Primary:
#1A2A1E - Text Secondary:
#5A6A5E - Text Muted:
#7B897F - Text On Primary:
#FFFFFF
Dark Mode
Dark-Mode wird vollständig über Tokens gespiegelt. Eckwerte:
- Background:
#0E1115 - Surface:
#161A20 - Surface Alt:
#1B2028 - Surface Elevated:
#1F252E - Border:
#2A323D - Border Strong:
#3A4452 - Text Primary:
#E9EFF3 - Text Secondary:
#B6BEC8 - Primary 700 (dark):
#5FB968 - Primary 600 (dark):
#4EA758 - Primary 100 (dark):
#1F2922
Status
- Success:
#2E7D32 - Warning:
#B7791F - Danger:
#C0392B - Info:
#2F6FB3
Typografie
Neutral, gut lesbar, unauffällig modern – keine dekorativen Schriften.
Stack: Inter, "Segoe UI", Roboto, system-ui, sans-serif
Skala (rem-orientiert, fixe px-Breakpoints, keine viewport-Skalierung):
--font-size-2xs: 11px – Status-Labels, Mini-Meta.--font-size-xs: 12px – Tabellenmeta, Helper-Text.--font-size-sm: 13px – sekundärer UI-Text.--font-size-md: 14px – Standard-UI-Text, Listen.--font-size-lg: 16px – akzentuierte UI-Hervorhebung.--font-size-xl: 20px – Bereichsüberschriften.--font-size-2xl: 26px – Seitenüberschriften.--font-size-3xl: 32px – Display-Headlines (Hero).--font-size-display: 44px – sehr seltene Marketing-Display-Texte.
Gewichte:
- 400 für Fließtext.
- 500 für UI-Text und Labels.
- 600 für Titel, Kicker, aktive Items.
- 700 nur sehr gezielt (Display-Headlines, Logo-Wortmarke).
Letter-Spacing-Disziplin:
- Display-Headlines: leicht negatives Tracking (
-0.01embis-0.02em). - Kicker/Labels (uppercase):
0.05embis0.08em. - Standard:
0.
Spacing
Modulare Skala in 4er-Schritten:
--space-1: 4px
--space-2: 8px
--space-3: 12px
--space-4: 16px
--space-5: 20px
--space-6: 24px
--space-7: 28px
--space-8: 32px
--space-10: 40px
--space-12: 48px
--space-16: 64px
Hauptseiten: --hoard-page-width 1120–1200px, Padding orientiert sich an --space-6/--space-8.
Formensprache (Border-Radien)
--radius-xs: 6px – kleine Pills, Status-Badges.--radius-sm: 10px – Buttons, kleine Controls.--radius-md: 14px – Inputs, Dropdowns, Listzeilen.--radius-lg: 18px – Cards, Panels.--radius-xl: 22px – Hero-Shells, Modals.--radius-full: 999px – nur für Avatar/Tag-Pills.
Keine pillenförmigen Vollflächen als Grundstil.
Schatten & Tiefe
Mehrstufiges, sehr ruhiges Schatten-System:
--shadow-xs: 0 1px 1px rgba(20, 30, 22, 0.04);
--shadow-sm: 0 2px 6px rgba(20, 30, 22, 0.06);
--shadow-md: 0 8px 22px rgba(20, 30, 22, 0.08);
--shadow-lg: 0 18px 44px rgba(20, 30, 22, 0.12);
--shadow-glow: 0 12px 36px rgba(28, 101, 47, 0.18);
Regeln:
- Panels:
--shadow-sm. - Hover-Lift max. 2 px, nur bei klar interaktiven Elementen.
- Dropdowns/Modals:
--shadow-mdbis--shadow-lg. --shadow-glowausschließlich für Brand-Bereiche (Login-Hero, Welcome-Hero).- Keine farbigen Schatten in Arbeitsflächen.
Motion
- Standard-Easing:
cubic-bezier(0.2, 0, 0, 1). --transition-fast: 160 ms (Hover, Buttons, Listzeilen).--transition-medium: 220 ms (Route-Wechsel, Banner).--transition-slow: 320 ms (Hero-Enter, Drawer).- Globale Page-Enter-Animation: weicher Y-Slide + Fade (≤ 8 px).
prefers-reduced-motion: alle Transitions auf 1 ms reduzieren, keine Translates.
App-Shell
Topbar
- Höhe ca. 64 px, opaker
surface-Hintergrund, dünne Bottom-Border. - Branding links: Icon + Wortmarke + dezenter Subtext („Self-hosted Workspace").
- Page-Kontext (Name + Beschreibung) als sekundäre Info, nur ab
>1180px. - Rechts: Theme-Toggle, Account-Menü oder Login-Button.
- Subtile bottom shadow (
--shadow-xs).
Sidebar
- Breite 268–284 px, Hintergrund
surface-alt, leicht abgesetzt. - Active-Indicator: linker, animierter, vertikaler Strich (
--color-primary-600) + grüne Tint-Fläche + dunklerer Text. - Hover: leichte Tint-Fläche, kein Scaling.
- Sektionen mit Kicker-Labels (
Navigation,Admin). - Mindesthöhe pro Item: 44 px (Desktop), 48 px (Mobile).
- Mobile = Bottom-Sheet-Drawer mit abgerundeten Top-Ecken.
Footer
- Sehr ruhig, kompakt,
surfacemit dünner oberer Border. - Links nur auf rechtlich/strukturell wichtige Routen (Impressum etc.).
- Mobile: in Grid mit Tap-Größen ≥ 44 px.
Komponenten
Cards / Panels
- Hintergrund:
surfacemit subtilem 180°-Verlauf zusurface-alt. - Border:
--color-border. - Radius:
--radius-lg. - Padding:
--space-6(Standard), kleinere Inhalte--space-4. - Hover (nur klar interaktive Cards): Border in Primary-300-Mix,
--shadow-md, 2 px Y-Lift.
Buttons
- Primary: grüner Hintergrund (
--color-primary-700), weiße Schrift,--shadow-xs. Hover:--color-primary-600+ leichter Glow. Active: ohne Lift. - Outlined: transparenter Hintergrund,
--color-border-strong, dunkler Text. Hover: leichte Primary-Tint-Fläche, Border zu Primary-Mix. - Text/Tertiary: für Zeilenaktionen, Toolbar, Nav. Hover: Surface-Tint.
- Icon-Buttons: mind. 40×40 (Desktop), 44×44 (Mobile).
- Letter-Spacing 0, kein Uppercase.
- Pro Bereich genau eine Primäraktion.
Inputs
- Outline-Variante,
surfaceHintergrund. - Border
--color-border-strong, Focus-Ring 3 px Primary-300-Tint + Primary-600-Border. - Labels oberhalb (Vuetify-Outlined-Label), keine reinen Placeholder.
- Mind. 44 px Höhe auf Mobile.
Listen / Tabellen
- Tabelle:
surfaceHintergrund, abgesetzter Tabellen-Header (surface-alt). - Hover: sehr subtile Primary-Tint-Tönung.
- Selected Row: Primary-100 Hintergrund,
--color-primary-700Text. - Border-Bottom in
--color-border-subtle. hoard-list-row(Datei-/Item-Zeilen): luftiges Padding, klare Spalten,transform: translateX(2px)beim Hover.
Status-Pills (hoard-status)
- Kompakt,
--radius-xs, mit dezentem Text/Background-Tint pro Status (Success/Info/Warning/Danger/Neutral). - Optional kleines Punktindikator-Dot vor dem Text.
Banner-Stack
- Position: fixiert unten rechts (Desktop), unten zentriert (Mobile).
- Stapelbar, einzeln dismissable.
- Opake Hintergründe,
--shadow-md, sauber lesbar auf jedem Inhalt. - Enter/Leave: 180 ms Fade + 10 px Y.
Hero-/Marketing-Bereiche
- Erlauben einen ambient Verlauf (
hoard-panel-gradient+ Variablen). - Optional dezenter „Spotlight"-Glow (radialer Verlauf,
--color-primary-300mit niedriger Opazität, blur). - Inhaltsbreite max ~64ch.
- Display-Headlines mit
--font-size-3xloder--font-size-display(nur Hero). - Hero-Tags (
hoard-chip/hoard-tag) als kompakte, dezent gerahmte Pills.
Vorschau-Bereich (Files)
- PDF-Vorschau: neutraler Hintergrund, weiße „Papier"-Fläche mit
--shadow-md, genug Rand. Controls minimal. - Bildvorschau: dunklerer neutraler Viewer-Hintergrund nur, wenn das Bild dadurch besser wirkt; UI-Chrome konsistent.
- Markdown-Editor/Reader: wirkt wie ein Arbeitsdokument, nicht wie Blogpost. Lesbreite ~70ch, klare Heading-Hierarchie, sehr ruhige Codeblöcke.
Empty-/Loading-States
- Empty: kleines Outline-Icon in Primary-Tint, kurzer Titel, ein Satz Begründung, eine klare CTA.
- Loading: Skeletons (graue Pulslinien) bevorzugt, ansonsten ein kleiner zentraler Spinner mit beschreibendem Text. Keine flackernden Spinner-Felder.
Responsive Verhalten
Desktop ist Hauptfokus, Mobile muss aber sauber funktionieren.
Breakpoints
@media (width <= 1180px)– Topbar-Kontextleiste verkürzen.@media (width <= 960px)– Sidebar wird Bottom-Drawer; Karten-/Grid-Bereiche werden einspaltig; Spacing wird reduziert.@media (width <= 600px)– CTAs full-width; Schriften minimal kompakter; Footer als Grid; Status-Pills behalten Lesbarkeit.
Pflicht
- Desktop-Baseregeln nicht anfassen, nur Mobile-Overrides per Media Query.
- Touch-Größen: Buttons ≥ 44 px, Icon-Buttons ≥ 44×44, Nav-Items ≥ 48 px.
- Safe-Areas via
env(safe-area-inset-*)(Topbar-Padding, Footer/Drawer Bottom). - Banner-Stack respektiert Safe-Area Bottom.
- Pflicht-Viewports im QA:
360x800,390x844,768x1024,1024x768,>=1280– jeweils Light + Dark.
Interaktionsprinzipien
- Primäraktionen klar sichtbar.
- Destruktives nie direkt neben Standardaktion.
- Dateizeilen sind klickbar, dürfen aber nicht wie Buttons aussehen.
- Hover, Active und Selected klar unterscheidbar (unterschiedliche Tints/Outlines).
- Fokus für Tastaturbedienung immer sichtbar (
outline: 2px solid var(--color-primary-500); outline-offset: 2px).
Designregeln für die Umsetzung
Immer
- Tokens nutzen (Farben, Spacing, Radius, Shadow).
- Patterns wiederverwenden (
hoard-panel,hoard-page,hoard-action-row,hoard-kicker,hoard-status,hoard-chip,hoard-spotlight). - Light- und Dark-Mode gleichwertig prüfen.
- Animationen kurz halten und
prefers-reduced-motionrespektieren.
Vermeiden
- zu viele Karten ohne Funktion,
- zu viele Akzentfarben gleichzeitig,
- harte 1:1-Kontraste,
- echte Glasflächen / Backdrop-Blur,
- dauernde Bewegungen,
- Schriftgrößen, die mit der Viewport-Breite skalieren.
Beispiel: Design-Tokens
:root {
/* Surfaces */
--color-bg: #f5f8f2;
--color-bg-tint: #eef3ea;
--color-surface: #ffffff;
--color-surface-alt: #f1f4ee;
--color-surface-elevated: #fbfcf8;
--color-border: #dce3d6;
--color-border-strong: #c5cfbe;
--color-border-subtle: #e8ede2;
/* Text */
--color-text: #1a2a1e;
--color-text-secondary: #5a6a5e;
--color-text-muted: #7b897f;
--color-text-on-primary: #ffffff;
/* Brand */
--color-primary-800: #10421e;
--color-primary-700: #1c652f;
--color-primary-600: #2e7d32;
--color-primary-500: #3c8f42;
--color-primary-300: #a8d5a2;
--color-primary-100: #eaf5e8;
--color-primary-050: #f4faf1;
--color-accent-lime: #b7e36b;
/* Status */
--color-success: #2e7d32;
--color-warning: #b7791f;
--color-danger: #c0392b;
--color-info: #2f6fb3;
/* Radius */
--radius-xs: 6px;
--radius-sm: 10px;
--radius-md: 14px;
--radius-lg: 18px;
--radius-xl: 22px;
--radius-full: 999px;
/* Shadows */
--shadow-xs: 0 1px 1px rgba(20, 30, 22, 0.04);
--shadow-sm: 0 2px 6px rgba(20, 30, 22, 0.06);
--shadow-md: 0 8px 22px rgba(20, 30, 22, 0.08);
--shadow-lg: 0 18px 44px rgba(20, 30, 22, 0.12);
--shadow-glow: 0 12px 36px rgba(28, 101, 47, 0.18);
/* Spacing */
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 20px;
--space-6: 24px;
--space-7: 28px;
--space-8: 32px;
--space-10: 40px;
--space-12: 48px;
--space-16: 64px;
/* Motion */
--transition-fast: 160ms cubic-bezier(0.2, 0, 0, 1);
--transition-medium: 220ms cubic-bezier(0.2, 0, 0, 1);
--transition-slow: 320ms cubic-bezier(0.2, 0, 0, 1);
}
Kurzfassung als Design-Leitlinie
Wenn du bei einer UI-Entscheidung unsicher bist:
Lieber präzise als spektakulär. Lieber ruhige Flächen mit Charakter als visuelle Effekte. Grün ist Identität, nicht Dekoration. Jedes Element muss eine Funktion haben – sonst fliegt es raus.