Modernize frontend: new design system, redesign all pages
- 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.
This commit is contained in:
+138
-129
@@ -19,18 +19,22 @@ const contactDetails = [
|
||||
|
||||
const legalNotes = [
|
||||
{
|
||||
icon: 'mdi-account-voice',
|
||||
title: 'Verantwortlich für den Inhalt',
|
||||
text: 'Julia Beispiel, Musterstraße 42, 12345 Musterstadt, Deutschland (Testdaten).',
|
||||
},
|
||||
{
|
||||
icon: 'mdi-scale-balance',
|
||||
title: 'EU-Streitbeilegung',
|
||||
text: 'Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung bereit: https://ec.europa.eu/consumers/odr/. Wir sind nicht verpflichtet und nicht bereit, an einem Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.',
|
||||
text: 'Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung bereit. Wir sind nicht verpflichtet und nicht bereit, an einem Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teilzunehmen.',
|
||||
},
|
||||
{
|
||||
icon: 'mdi-shield-check-outline',
|
||||
title: 'Haftung für Inhalte',
|
||||
text: 'Als Diensteanbieter sind wir für eigene Inhalte nach den allgemeinen Gesetzen verantwortlich. Für fremde Inhalte, auf die wir verweisen, übernehmen wir keine Gewähr. Dieses Impressum enthält ausschließlich Demo-Angaben.',
|
||||
},
|
||||
{
|
||||
icon: 'mdi-link-variant',
|
||||
title: 'Haftung für Links',
|
||||
text: 'Unsere Seiten enthalten Links zu externen Webseiten Dritter. Für deren Inhalte ist stets der jeweilige Anbieter verantwortlich. Bei Bekanntwerden von Rechtsverletzungen werden derartige Links umgehend entfernt.',
|
||||
},
|
||||
@@ -39,30 +43,39 @@ const legalNotes = [
|
||||
|
||||
<template>
|
||||
<v-container fluid class="impressum-page hoard-page">
|
||||
<section class="impressum-hero hoard-panel hoard-panel-gradient">
|
||||
<div class="hero-copy">
|
||||
<p class="hero-kicker hoard-kicker">Rechtliche Angaben</p>
|
||||
<section class="impressum-hero hoard-panel hoard-panel-gradient hoard-spotlight">
|
||||
<div class="impressum-hero__copy">
|
||||
<p class="hoard-kicker hoard-kicker--wide">Rechtliche Angaben</p>
|
||||
<h1>Impressum</h1>
|
||||
<p class="hero-lead">
|
||||
Diese Seite ist im Hoard-Design aufgebaut und mit Testdaten gefüllt. Ersetze die Angaben
|
||||
vor einem produktiven Einsatz mit deinen echten Unternehmensdaten.
|
||||
<p class="impressum-hero__lead">
|
||||
Diese Seite ist im Hoard-Design aufgebaut und mit Testdaten gefüllt. Vor produktivem
|
||||
Einsatz bitte alle Angaben durch echte Unternehmensdaten ersetzen.
|
||||
</p>
|
||||
|
||||
<div class="hero-meta">
|
||||
<span class="meta-pill">Testdaten</span>
|
||||
<span class="meta-text">Stand: 17. April 2026</span>
|
||||
<div class="impressum-hero__meta">
|
||||
<span class="hoard-chip hoard-chip--brand">
|
||||
<v-icon icon="mdi-information-outline" size="14" /> Testdaten
|
||||
</span>
|
||||
<span class="hoard-chip">
|
||||
<v-icon icon="mdi-calendar-month-outline" size="14" /> Stand: 26. April 2026
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hero-actions hoard-action-row">
|
||||
<v-btn color="primary" prepend-icon="mdi-home" to="/welcome">Zur Startseite</v-btn>
|
||||
<div class="impressum-hero__actions hoard-action-row">
|
||||
<v-btn variant="elevated" prepend-icon="mdi-home-outline" to="/welcome">
|
||||
Zur Startseite
|
||||
</v-btn>
|
||||
<v-btn variant="outlined" prepend-icon="mdi-login" to="/login">Zum Login</v-btn>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="details-grid">
|
||||
<article class="detail-card hoard-panel">
|
||||
<h2>Anbieterangaben</h2>
|
||||
<header class="detail-card__head">
|
||||
<span class="hoard-icon-tile"><v-icon icon="mdi-domain" size="20" /></span>
|
||||
<h2>Anbieterangaben</h2>
|
||||
</header>
|
||||
<dl class="detail-list">
|
||||
<div v-for="entry in companyDetails" :key="entry.label" class="detail-item">
|
||||
<dt>{{ entry.label }}</dt>
|
||||
@@ -72,7 +85,10 @@ const legalNotes = [
|
||||
</article>
|
||||
|
||||
<article class="detail-card hoard-panel">
|
||||
<h2>Kontakt</h2>
|
||||
<header class="detail-card__head">
|
||||
<span class="hoard-icon-tile"><v-icon icon="mdi-email-outline" size="20" /></span>
|
||||
<h2>Kontakt</h2>
|
||||
</header>
|
||||
<dl class="detail-list">
|
||||
<div v-for="entry in contactDetails" :key="entry.label" class="detail-item">
|
||||
<dt>{{ entry.label }}</dt>
|
||||
@@ -84,7 +100,10 @@ const legalNotes = [
|
||||
</article>
|
||||
|
||||
<article class="detail-card hoard-panel">
|
||||
<h2>Register und Steuer</h2>
|
||||
<header class="detail-card__head">
|
||||
<span class="hoard-icon-tile"><v-icon icon="mdi-clipboard-text-outline" size="20" /></span>
|
||||
<h2>Register & Steuer</h2>
|
||||
</header>
|
||||
<dl class="detail-list">
|
||||
<div v-for="entry in registerDetails" :key="entry.label" class="detail-item">
|
||||
<dt>{{ entry.label }}</dt>
|
||||
@@ -95,15 +114,21 @@ const legalNotes = [
|
||||
</section>
|
||||
|
||||
<section class="notes-section hoard-panel">
|
||||
<header class="notes-head">
|
||||
<p class="notes-kicker hoard-kicker">Rechtliche Hinweise</p>
|
||||
<header class="hoard-section-head">
|
||||
<p class="hoard-kicker">Rechtliche Hinweise</p>
|
||||
<h2>Wichtige Zusatzinformationen</h2>
|
||||
<p>Standardklauseln, die im Produktivbetrieb durch eine juristische Prüfung ersetzt werden sollten.</p>
|
||||
</header>
|
||||
|
||||
<div class="notes-grid">
|
||||
<article v-for="note in legalNotes" :key="note.title" class="note-card">
|
||||
<h3>{{ note.title }}</h3>
|
||||
<p>{{ note.text }}</p>
|
||||
<span class="hoard-icon-tile">
|
||||
<v-icon :icon="note.icon" size="20" />
|
||||
</span>
|
||||
<div>
|
||||
<h3>{{ note.title }}</h3>
|
||||
<p>{{ note.text }}</p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
@@ -112,66 +137,50 @@ const legalNotes = [
|
||||
|
||||
<style scoped>
|
||||
.impressum-page {
|
||||
--hoard-page-width: 1120px;
|
||||
--hoard-page-width: 1180px;
|
||||
}
|
||||
|
||||
/* ---------- Hero ---------- */
|
||||
.impressum-hero {
|
||||
--hoard-gradient-angle: 125deg;
|
||||
--hoard-gradient-start: color-mix(in srgb, var(--color-primary-100) 40%, var(--color-surface) 60%);
|
||||
--hoard-gradient-angle: 130deg;
|
||||
--hoard-gradient-start: color-mix(in srgb, var(--color-primary-100) 60%, var(--color-surface) 40%);
|
||||
--hoard-gradient-end: var(--color-surface);
|
||||
--hoard-gradient-end-stop: 56%;
|
||||
--hoard-gradient-end-stop: 65%;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
grid-template-columns: minmax(0, 1.2fr) auto;
|
||||
gap: var(--space-6);
|
||||
align-items: end;
|
||||
padding: var(--space-8);
|
||||
padding: var(--space-10) var(--space-8);
|
||||
border-radius: var(--radius-xl);
|
||||
}
|
||||
|
||||
.hero-lead,
|
||||
.meta-text {
|
||||
.impressum-hero__copy h1 {
|
||||
margin: 0 0 var(--space-3);
|
||||
font-size: clamp(2rem, 1.4rem + 1.4vw, 2.6rem);
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.impressum-hero__lead {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: var(--space-3);
|
||||
font-size: 2.45rem;
|
||||
}
|
||||
|
||||
.hero-lead {
|
||||
max-width: 64ch;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: var(--font-size-md);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.hero-meta {
|
||||
.impressum-hero__meta {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
gap: var(--space-2);
|
||||
margin-top: var(--space-5);
|
||||
}
|
||||
|
||||
.meta-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 4px var(--space-3);
|
||||
border: 1px solid color-mix(in srgb, var(--color-primary-300) 60%, var(--color-border) 40%);
|
||||
border-radius: 999px;
|
||||
color: var(--color-primary-700);
|
||||
font-size: var(--font-size-sm);
|
||||
font-weight: 600;
|
||||
background-color: color-mix(in srgb, var(--color-primary-100) 82%, var(--color-surface) 18%);
|
||||
}
|
||||
|
||||
.meta-text {
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
.impressum-hero__actions {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* ---------- Detail cards ---------- */
|
||||
.details-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
@@ -181,13 +190,30 @@ h1 {
|
||||
.detail-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
padding: var(--space-5);
|
||||
gap: var(--space-4);
|
||||
padding: var(--space-6);
|
||||
transition:
|
||||
border-color var(--transition-fast),
|
||||
box-shadow var(--transition-fast),
|
||||
transform var(--transition-fast);
|
||||
}
|
||||
|
||||
h2 {
|
||||
.detail-card:hover {
|
||||
border-color: color-mix(in srgb, var(--color-primary-300) 50%, var(--color-border) 50%);
|
||||
box-shadow: var(--shadow-md);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.detail-card__head {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.detail-card h2 {
|
||||
margin: 0;
|
||||
font-size: 1.45rem;
|
||||
font-size: var(--font-size-xl);
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.detail-list {
|
||||
@@ -199,7 +225,7 @@ h2 {
|
||||
|
||||
.detail-item {
|
||||
padding-bottom: var(--space-3);
|
||||
border-bottom: 1px solid color-mix(in srgb, var(--color-border) 75%, var(--color-surface) 25%);
|
||||
border-bottom: 1px solid var(--color-border-subtle);
|
||||
}
|
||||
|
||||
.detail-item:last-child {
|
||||
@@ -210,21 +236,21 @@ h2 {
|
||||
dt {
|
||||
margin-bottom: var(--space-1);
|
||||
color: var(--color-text-muted);
|
||||
font-size: var(--font-size-sm);
|
||||
font-size: var(--font-size-2xs);
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 0;
|
||||
color: var(--color-text);
|
||||
font-size: var(--font-size-md);
|
||||
}
|
||||
|
||||
/* ---------- Notes ---------- */
|
||||
.notes-section {
|
||||
padding: var(--space-6);
|
||||
}
|
||||
|
||||
.notes-head {
|
||||
margin-bottom: var(--space-5);
|
||||
padding: var(--space-7);
|
||||
}
|
||||
|
||||
.notes-grid {
|
||||
@@ -234,15 +260,31 @@ dd {
|
||||
}
|
||||
|
||||
.note-card {
|
||||
padding: var(--space-4);
|
||||
border: 1px solid color-mix(in srgb, var(--color-border) 76%, var(--color-surface) 24%);
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: var(--space-4);
|
||||
align-items: flex-start;
|
||||
padding: var(--space-5);
|
||||
border: 1px solid var(--color-border-subtle);
|
||||
border-radius: var(--radius-md);
|
||||
background-color: color-mix(in srgb, var(--color-surface-alt) 72%, var(--color-surface) 28%);
|
||||
background-color: color-mix(in srgb, var(--color-surface-alt) 60%, var(--color-surface) 40%);
|
||||
transition:
|
||||
border-color var(--transition-fast),
|
||||
background-color var(--transition-fast),
|
||||
transform var(--transition-fast);
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 0 var(--space-2);
|
||||
font-size: 1.03rem;
|
||||
.note-card:hover {
|
||||
border-color: color-mix(in srgb, var(--color-primary-300) 40%, var(--color-border) 60%);
|
||||
background-color: var(--color-surface);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.note-card h3 {
|
||||
margin: 0 0 var(--space-1);
|
||||
font-size: var(--font-size-lg);
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.note-card p {
|
||||
@@ -250,36 +292,16 @@ h3 {
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.detail-card,
|
||||
.note-card {
|
||||
transition:
|
||||
border-color var(--transition-fast),
|
||||
box-shadow var(--transition-fast),
|
||||
transform var(--transition-fast);
|
||||
}
|
||||
|
||||
.detail-card:hover,
|
||||
.note-card:hover {
|
||||
border-color: color-mix(in srgb, var(--color-primary-300) 46%, var(--color-border) 54%);
|
||||
box-shadow: var(--shadow-md);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.impressum-hero,
|
||||
.detail-card,
|
||||
.notes-section {
|
||||
animation: hoard-soft-enter 260ms both;
|
||||
animation: hoard-soft-enter 280ms both;
|
||||
}
|
||||
|
||||
.detail-card:nth-child(2) {
|
||||
animation-delay: 80ms;
|
||||
}
|
||||
|
||||
.detail-card:nth-child(3),
|
||||
.notes-section {
|
||||
animation-delay: 120ms;
|
||||
}
|
||||
.detail-card:nth-child(2) { animation-delay: 80ms; }
|
||||
.detail-card:nth-child(3) { animation-delay: 140ms; }
|
||||
.notes-section { animation-delay: 200ms; }
|
||||
}
|
||||
|
||||
@media (width <= 1080px) {
|
||||
@@ -289,19 +311,14 @@ h3 {
|
||||
}
|
||||
|
||||
@media (width <= 960px) {
|
||||
.impressum-hero,
|
||||
.notes-section {
|
||||
padding: var(--space-5);
|
||||
}
|
||||
|
||||
.impressum-hero {
|
||||
grid-template-columns: 1fr;
|
||||
align-items: start;
|
||||
padding: var(--space-7);
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
.impressum-hero__actions {
|
||||
justify-content: flex-start;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.details-grid,
|
||||
@@ -309,40 +326,32 @@ h3 {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
:deep(.hero-actions .v-btn) {
|
||||
min-height: 44px;
|
||||
.notes-section {
|
||||
padding: var(--space-6);
|
||||
}
|
||||
}
|
||||
|
||||
@media (width <= 600px) {
|
||||
.impressum-hero,
|
||||
.notes-section {
|
||||
padding: var(--space-4);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.9rem;
|
||||
}
|
||||
|
||||
.hero-meta {
|
||||
margin-top: var(--space-4);
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.hero-actions .v-btn) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.notes-section,
|
||||
.detail-card {
|
||||
padding: var(--space-4);
|
||||
padding: var(--space-5);
|
||||
}
|
||||
|
||||
.impressum-hero__actions {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.impressum-hero__actions .v-btn) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.impressum-hero__meta {
|
||||
margin-top: var(--space-4);
|
||||
}
|
||||
|
||||
.note-card {
|
||||
padding: var(--space-3);
|
||||
padding: var(--space-4);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user