Technisches Accessibility-Audit ergab sechs behebbare Punkte, alle jetzt gefixt: - Skip-to-Content-Link ganz oben auf jeder Seite (WCAG 2.4.1) - Fehler-/Statusmeldungen (Checkout, Login, Rezension, Gate-/Verwaltungs-Code) jetzt mit role="alert"/aria-live, damit Screenreader sie automatisch ansagen (WCAG 4.1.3) - Warenkorb-Icon hatte fälschlich das "Konto"-Label geerbt, sagt jetzt korrekt "Warenkorb" (WCAG 4.1.2/2.4.4), dafür t.nav.cart in allen 4 Sprachen neu ergänzt - Sichtbarer Fokus-Ring beim Mengenfeld auf der Produktseite wiederhergestellt (WCAG 2.4.7) - Placeholder-only Formularfelder (Gate-Zugangscode, Verwaltungs-Suche/Filter/Tracking) haben jetzt echte Labels (sichtbar per sr-only-Klasse oder aria-label) statt nur Platzhaltertext (WCAG 1.3.1/3.3.2) - Übersprungene Überschriften-Ebenen (h1→h3 ohne h2) in Checkout, Warenkorb, Kontakt, Konto korrigiert (WCAG 1.3.1) Reine Accessibility-Nachrüstung, keine funktionale Änderung. Kleinstunternehmer-Ausnahme (§3 Abs.3 BFSG) greift hier vermutlich, aber vorsorglich sauber umgesetzt. Co-Authored-By: Claude Sonnet 5 <[email protected]>
3556 lines
156 KiB
CSS
3556 lines
156 KiB
CSS
/*
|
||
Van's DIY & Bastelbedarf — Design-System
|
||
Farbwerte 1:1 aus dem Vault: "Van Van – Homepage/02 Logo & Branding/Branding.md"
|
||
Nicht ohne Rücksprache ändern — sind bereits WCAG-kontrastgeprüft.
|
||
*/
|
||
|
||
/*
|
||
Fonts: aktuell per Google-Fonts-<link> in Layout.astro eingebunden (siehe dort).
|
||
TODO Phase 2: Fraunces + Inter self-hosten (woff2, DSGVO/Performance), sobald Zeit ist —
|
||
Vorgehen wie bei bild.py/fonts_holen.sh im Bild-KI-Projekt (CSS2-API abfragen, .woff2-URLs
|
||
aus der Antwort extrahieren, lokal unter public/fonts/ ablegen, @font-face umstellen).
|
||
*/
|
||
|
||
:root {
|
||
/* Farben */
|
||
--c-black: #0a0910;
|
||
--c-anthracite: #1b1a22;
|
||
--c-anthracite-light: #252333;
|
||
--c-purple: #2e1b47;
|
||
--c-purple-deep: #1b1226;
|
||
--c-text: #f4f1f7;
|
||
--c-text-muted: #b7aec4;
|
||
--c-accent: #5fd3ec;
|
||
--c-accent-hover: #3ca9c2;
|
||
--c-sale: #e7879a;
|
||
--c-purple-glow: #9b7fd6; /* heller Violett-Ton NUR für Verlaufs-Ränder/Deko, nicht für Text */
|
||
|
||
/* Typografie */
|
||
--font-head: "Fraunces", "Playfair Display", Georgia, serif;
|
||
--font-body: "Inter", "Manrope", system-ui, sans-serif;
|
||
|
||
/* Form */
|
||
--radius-s: 10px;
|
||
--radius-m: 16px;
|
||
--radius-l: 22px;
|
||
--shadow-card: 0 12px 30px -12px rgba(46, 27, 71, 0.55);
|
||
--shadow-card-hover: 0 18px 40px -12px rgba(95, 211, 236, 0.25);
|
||
--ease: cubic-bezier(0.22, 1, 0.36, 1);
|
||
--container: 1220px;
|
||
}
|
||
|
||
* { box-sizing: border-box; }
|
||
html { scroll-behavior: smooth; }
|
||
|
||
/* Für Screenreader vorhanden, visuell aber unsichtbar — für Formularfelder, die aus Platz-/
|
||
Layoutgründen keinen sichtbaren <label>-Text bekommen (z.B. Icon-/Placeholder-only Suchfelder
|
||
in der Verwaltung), damit sie trotzdem einen echten zugänglichen Namen haben (WCAG 1.3.1/3.3.2)
|
||
statt sich allein auf den (beim Tippen verschwindenden) Placeholder zu verlassen. */
|
||
.sr-only {
|
||
position: absolute;
|
||
width: 1px; height: 1px;
|
||
padding: 0; margin: -1px;
|
||
overflow: hidden;
|
||
clip: rect(0, 0, 0, 0);
|
||
white-space: nowrap;
|
||
border: 0;
|
||
}
|
||
|
||
body {
|
||
margin: 0;
|
||
background: var(--c-black);
|
||
color: var(--c-text);
|
||
font-family: var(--font-body);
|
||
line-height: 1.6;
|
||
-webkit-font-smoothing: antialiased;
|
||
}
|
||
|
||
h1, h2, h3, h4 {
|
||
font-family: var(--font-head);
|
||
font-weight: 600;
|
||
line-height: 1.15;
|
||
margin: 0 0 0.5em;
|
||
letter-spacing: -0.01em;
|
||
}
|
||
h1 { font-size: clamp(2.2rem, 4vw + 1rem, 3.6rem); }
|
||
h2 { font-size: clamp(1.7rem, 2vw + 1rem, 2.4rem); }
|
||
h3 { font-size: 1.3rem; }
|
||
p { margin: 0 0 1em; color: var(--c-text-muted); }
|
||
|
||
a { color: inherit; text-decoration: none; }
|
||
|
||
img { max-width: 100%; display: block; }
|
||
|
||
.container {
|
||
width: 100%;
|
||
max-width: var(--container);
|
||
margin-inline: auto;
|
||
padding-inline: 1.5rem;
|
||
}
|
||
|
||
.section { padding: clamp(3rem, 6vw, 6rem) 0; }
|
||
.section-tight { padding: clamp(2rem, 3vw, 3rem) 0; }
|
||
|
||
.eyebrow {
|
||
display: inline-block;
|
||
font-size: 0.8rem;
|
||
letter-spacing: 0.14em;
|
||
text-transform: uppercase;
|
||
color: var(--c-accent);
|
||
font-weight: 600;
|
||
margin-bottom: 0.9rem;
|
||
}
|
||
|
||
.lead { font-size: 1.15rem; color: var(--c-text); opacity: 0.9; }
|
||
|
||
.text-center { text-align: center; }
|
||
.small { font-size: 0.85rem; color: var(--c-text-muted); }
|
||
|
||
/* Buttons */
|
||
.btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0.5em;
|
||
padding: 0.85em 1.7em;
|
||
border-radius: var(--radius-l);
|
||
font-weight: 600;
|
||
font-size: 0.98rem;
|
||
border: 1px solid transparent;
|
||
cursor: pointer;
|
||
transition: transform 0.25s var(--ease), background 0.25s var(--ease), box-shadow 0.25s var(--ease), border-color 0.25s var(--ease);
|
||
}
|
||
.btn:hover { transform: translateY(-2px); }
|
||
.btn:active { transform: translateY(0); }
|
||
|
||
.btn-primary {
|
||
background: linear-gradient(135deg, var(--c-accent), var(--c-accent-hover));
|
||
color: #08181c;
|
||
box-shadow: var(--shadow-card-hover);
|
||
}
|
||
.btn-primary:hover { box-shadow: 0 20px 45px -14px rgba(95, 211, 236, 0.45); }
|
||
|
||
.btn-outline {
|
||
background: transparent;
|
||
color: var(--c-text);
|
||
border-color: rgba(244, 241, 247, 0.25);
|
||
}
|
||
.btn-outline:hover { border-color: var(--c-accent); color: var(--c-accent); }
|
||
|
||
.btn-block { width: 100%; }
|
||
.btn-row { display: flex; gap: 0.9rem; flex-wrap: wrap; margin-top: 1.5rem; }
|
||
|
||
/* Cards — Verlaufs-Rand statt trockenem Einzelfarb-Strich (Signature-Look der Seite) */
|
||
.card {
|
||
position: relative;
|
||
isolation: isolate;
|
||
border: 1.5px solid transparent;
|
||
border-radius: var(--radius-m);
|
||
background:
|
||
linear-gradient(165deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(135deg, rgba(95, 211, 236, 0.5), rgba(155, 127, 214, 0.4) 45%, rgba(231, 135, 154, 0.32)) border-box;
|
||
padding: 1.6rem;
|
||
box-shadow: var(--shadow-card);
|
||
transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), filter 0.3s var(--ease);
|
||
}
|
||
.card::before {
|
||
/* dezenter Glanz-Schimmer oben, wie ein Lichtreflex auf Glas — macht den Rand "speziell" statt flach */
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: inherit;
|
||
padding: 1.5px;
|
||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.35), transparent 40%);
|
||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||
-webkit-mask-composite: xor;
|
||
mask-composite: exclude;
|
||
pointer-events: none;
|
||
z-index: 1;
|
||
opacity: 0.6;
|
||
}
|
||
.card:hover {
|
||
transform: translateY(-4px);
|
||
box-shadow: var(--shadow-card-hover);
|
||
filter: brightness(1.06);
|
||
}
|
||
|
||
/* Klickbare Navigations-Kacheln (Produktkarten, Kategorien) bekommen den Verlaufs-Rand extra
|
||
kräftig — das sind die "Kisten, wo man draufdrückt um auf eine neue Seite zu kommen". */
|
||
a.card {
|
||
background:
|
||
linear-gradient(165deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(135deg, var(--c-accent), var(--c-purple-glow) 45%, var(--c-sale) 100%) border-box;
|
||
}
|
||
a.card:hover {
|
||
box-shadow: var(--shadow-card-hover), 0 0 0 1px rgba(95, 211, 236, 0.25);
|
||
}
|
||
|
||
/* Grid utils */
|
||
.grid { display: grid; gap: 1.5rem; }
|
||
.grid-2 { grid-template-columns: repeat(2, 1fr); }
|
||
.grid-3 { grid-template-columns: repeat(3, 1fr); }
|
||
.grid-4 { grid-template-columns: repeat(4, 1fr); }
|
||
@media (max-width: 900px) { .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); } }
|
||
@media (max-width: 620px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }
|
||
|
||
/* Der Haupt-Shop (/shop/) wickelt jede Produktkarte zusätzlich in ein .product-slot-Div ein
|
||
(nötig für den Filter/Sortier-JS-Code, das einzelne Karten ein-/ausblendet). CSS Grid streckt
|
||
dieses Div zwar automatisch auf die volle Zeilenhöhe, die Karte DARIN füllte diese Höhe aber
|
||
nicht aus (ein normales <div> reicht "stretch" nicht an sein Kind weiter) — dadurch wirkten
|
||
Karten mit kurzem Text kleiner als Karten mit langem Text in derselben Reihe. Fix: das Slot-Div
|
||
selbst zum Flex-Container machen, dessen einziges Kind (die Karte) sich per Flex-Stretch auf
|
||
die volle Höhe ausdehnt — Karten in derselben Zeile sind dadurch überall gleich groß. */
|
||
.product-slot { display: flex; }
|
||
.product-slot > a { flex: 1; }
|
||
|
||
/* Badges — sitzen direkt auf Produktfotos (unterschiedlichste Hintergründe/Farben), deshalb
|
||
braucht die Pille genug eigene Kraft, um immer lesbar zu bleiben: kräftigerer (weniger
|
||
transparenter) Hintergrund + eigener Rand in derselben Farbe + dezenter Schlagschatten hinterm
|
||
Text. Farbton und Grundstil bleiben exakt gleich, nur die Durchsetzungskraft ist höher. */
|
||
.badge {
|
||
display: inline-block;
|
||
font-size: 0.72rem;
|
||
font-weight: 700;
|
||
letter-spacing: 0.04em;
|
||
text-transform: uppercase;
|
||
padding: 0.3em 0.75em;
|
||
border-radius: 999px;
|
||
background: rgba(95, 211, 236, 0.34);
|
||
border: 1px solid rgba(95, 211, 236, 0.6);
|
||
color: var(--c-accent);
|
||
text-shadow: 0 1px 3px rgba(10, 9, 16, 0.65);
|
||
}
|
||
.badge-sale { background: rgba(231, 135, 154, 0.36); border-color: rgba(231, 135, 154, 0.6); color: var(--c-sale); }
|
||
.badge-sold-out { background: rgba(183, 174, 196, 0.32); border-color: rgba(183, 174, 196, 0.55); color: var(--c-text-muted); }
|
||
|
||
/* Placeholder art (kein echtes Produktfoto vorhanden) */
|
||
.img-placeholder {
|
||
position: relative;
|
||
border-radius: var(--radius-m);
|
||
overflow: hidden;
|
||
background:
|
||
radial-gradient(circle at 30% 20%, rgba(95, 211, 236, 0.18), transparent 55%),
|
||
linear-gradient(155deg, var(--c-purple), var(--c-purple-deep));
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0.3rem;
|
||
color: var(--c-text-muted);
|
||
font-size: 0.85rem;
|
||
text-align: center;
|
||
padding: 1rem;
|
||
min-height: 160px;
|
||
}
|
||
.img-placeholder::after {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
background-image: repeating-linear-gradient(135deg, rgba(244,241,247,0.03) 0 2px, transparent 2px 14px);
|
||
}
|
||
|
||
/* Echtes Produktfoto (von VanVan im Adminbereich hochgeladen) — ersetzt den Platzhalter, sobald
|
||
`bilder` am Produkt gesetzt ist. Gleiche Maße/Ecken wie der Platzhalter, damit beim Hochladen
|
||
des ersten Fotos nichts im Layout springt. */
|
||
.product-photo {
|
||
display: block;
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
border-radius: var(--radius-m);
|
||
}
|
||
.product-media .product-photo { aspect-ratio: 1 / 1; }
|
||
.thumb.product-photo { cursor: pointer; transition: box-shadow 0.2s var(--ease); }
|
||
|
||
/* Portrait-Frame — edler Bilderrahmen für Porträtfotos (Startseite, Über die Kreative, ...) */
|
||
.portrait-frame {
|
||
position: relative;
|
||
isolation: isolate;
|
||
}
|
||
.portrait-frame::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: -6%;
|
||
z-index: -1;
|
||
background:
|
||
radial-gradient(circle at 30% 20%, rgba(95, 211, 236, 0.35), transparent 60%),
|
||
radial-gradient(circle at 75% 80%, rgba(231, 135, 154, 0.22), transparent 55%);
|
||
filter: blur(38px);
|
||
opacity: 0.85;
|
||
border-radius: inherit;
|
||
}
|
||
.portrait-frame .portrait-img,
|
||
.portrait-frame img {
|
||
display: block;
|
||
width: 100%;
|
||
height: auto;
|
||
aspect-ratio: 1 / 1;
|
||
object-fit: cover;
|
||
border-radius: var(--radius-l);
|
||
border: 1px solid rgba(244, 241, 247, 0.08);
|
||
box-shadow: var(--shadow-card), 0 0 0 6px rgba(10, 9, 16, 0.6), 0 0 0 7px rgba(95, 211, 236, 0.18);
|
||
transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease);
|
||
}
|
||
/* Auch der "Foto folgt"-Platzhalter bekommt den gleichen edlen Rahmen/Ring wie ein echtes Foto —
|
||
vorher blieb er innerhalb eines Portrait-Frames (z.B. Charakter ohne Produkt) unauffällig
|
||
randlos, während echte Fotos schon den Ring hatten. Behält seine eigene Flex-Zentrierung für
|
||
den "Produktfoto folgt"-Text bei (nur display wird hier NICHT überschrieben). */
|
||
.portrait-frame .img-placeholder {
|
||
aspect-ratio: 1 / 1;
|
||
border-radius: var(--radius-l);
|
||
border: 1px solid rgba(244, 241, 247, 0.08);
|
||
box-shadow: var(--shadow-card), 0 0 0 6px rgba(10, 9, 16, 0.6), 0 0 0 7px rgba(95, 211, 236, 0.18);
|
||
transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease);
|
||
}
|
||
.portrait-frame:hover .portrait-img,
|
||
.portrait-frame:hover img,
|
||
.portrait-frame:hover .img-placeholder {
|
||
transform: translateY(-4px) scale(1.015);
|
||
box-shadow: var(--shadow-card-hover), 0 0 0 6px rgba(10, 9, 16, 0.6), 0 0 0 7px rgba(95, 211, 236, 0.32);
|
||
}
|
||
.portrait-badge {
|
||
position: absolute;
|
||
bottom: -1.1rem;
|
||
right: -1.1rem;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.4em;
|
||
padding: 0.7em 1.1em;
|
||
border-radius: 999px;
|
||
background: linear-gradient(135deg, var(--c-accent), var(--c-accent-hover));
|
||
color: #08181c;
|
||
font-family: var(--font-head);
|
||
font-weight: 700;
|
||
font-size: 0.85rem;
|
||
letter-spacing: 0.01em;
|
||
box-shadow: 0 10px 26px -8px rgba(95, 211, 236, 0.55), 0 0 0 5px var(--c-black);
|
||
transform: rotate(-4deg);
|
||
white-space: nowrap;
|
||
}
|
||
@media (max-width: 620px) {
|
||
.portrait-badge { right: 0.4rem; bottom: -0.9rem; font-size: 0.78rem; padding: 0.6em 0.9em; }
|
||
}
|
||
|
||
.todo-note {
|
||
border: 1px dashed rgba(95, 211, 236, 0.4);
|
||
border-radius: var(--radius-s);
|
||
padding: 0.9rem 1.1rem;
|
||
font-size: 0.85rem;
|
||
color: var(--c-text-muted);
|
||
margin-top: 1.5rem;
|
||
}
|
||
|
||
.legal-note {
|
||
border-left: 3px solid var(--c-accent);
|
||
background: rgba(95, 211, 236, 0.08);
|
||
padding: 1rem 1.3rem;
|
||
border-radius: var(--radius-s);
|
||
margin-bottom: 2rem;
|
||
font-size: 0.92rem;
|
||
}
|
||
|
||
hr.divider {
|
||
border: none;
|
||
border-top: 1px solid rgba(244, 241, 247, 0.08);
|
||
margin: 2.5rem 0;
|
||
}
|
||
|
||
table { width: 100%; border-collapse: collapse; margin: 1.5rem 0; }
|
||
th, td { text-align: left; padding: 0.7rem 0.9rem; border-bottom: 1px solid rgba(244,241,247,0.08); }
|
||
th { color: var(--c-text); font-family: var(--font-head); font-weight: 600; }
|
||
|
||
form.frm { display: grid; gap: 1rem; max-width: 560px; }
|
||
.frm label { display: block; font-size: 0.85rem; color: var(--c-text-muted); margin-bottom: 0.35rem; }
|
||
.frm input, .frm select, .frm textarea {
|
||
width: 100%;
|
||
padding: 0.75em 0.9em;
|
||
border-radius: var(--radius-s);
|
||
border: 1px solid rgba(244, 241, 247, 0.15);
|
||
background: var(--c-anthracite);
|
||
color: var(--c-text);
|
||
font-family: var(--font-body);
|
||
font-size: 0.95rem;
|
||
}
|
||
.frm input:focus, .frm select:focus, .frm textarea:focus,
|
||
a:focus-visible, button:focus-visible {
|
||
outline: 2px solid var(--c-accent);
|
||
outline-offset: 2px;
|
||
}
|
||
.frm .checkbox-row { display: flex; gap: 0.6rem; align-items: flex-start; font-size: 0.88rem; color: var(--c-text-muted); }
|
||
.frm .checkbox-row input { width: auto; margin-top: 0.2rem; }
|
||
|
||
/* ============================================================
|
||
Login: Social-Login-Buttons, Passwort-Sichtbarkeit, DSGVO-Hinweis
|
||
In Deutschland/DACH übliche Anmelde-Alternativen zur reinen E-Mail/Passwort-
|
||
Anmeldung (siehe Recherche: PayPal-Login ist wegen der PayPal-Marktdominanz
|
||
in DE besonders verbreitet, neben Google). Apple bewusst NICHT dabei — auf
|
||
ausdrücklichen Wunsch entfernt (Apple verlangt fürs Web-Login zwingend das
|
||
kostenpflichtige Apple Developer Program, 99 $/Jahr, siehe Vault-Notiz). Die
|
||
Buttons sind bewusst NICHT funktional (kein echtes OAuth ohne Backend) — ein
|
||
Klick zeigt einen ehrlichen Hinweis statt eine vorgetäuschte Anmeldung.
|
||
============================================================ */
|
||
.social-login { display: grid; gap: 0.6rem; }
|
||
.btn-social {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0.6em;
|
||
width: 100%;
|
||
padding: 0.7em 1em;
|
||
border-radius: var(--radius-s);
|
||
border: 1px solid rgba(244, 241, 247, 0.16);
|
||
background: var(--c-anthracite);
|
||
color: var(--c-text);
|
||
font-family: var(--font-body);
|
||
font-size: 0.92rem;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
transition: background 0.15s var(--ease), border-color 0.15s var(--ease), transform 0.1s var(--ease);
|
||
}
|
||
.btn-social:hover { background: var(--c-anthracite-light); border-color: rgba(244, 241, 247, 0.3); }
|
||
.btn-social:active { transform: scale(0.99); }
|
||
.btn-social svg { flex-shrink: 0; }
|
||
.btn-social-paypal .social-icon-badge {
|
||
display: inline-flex; align-items: center; justify-content: center;
|
||
width: 18px; height: 18px; border-radius: 50%;
|
||
background: #003087; color: #fff; font-family: var(--font-head); font-weight: 700; font-size: 0.72rem;
|
||
flex-shrink: 0;
|
||
}
|
||
.social-note {
|
||
display: none;
|
||
font-size: 0.82rem;
|
||
color: var(--c-text-muted);
|
||
background: color-mix(in srgb, var(--c-accent) 10%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--c-accent) 25%, transparent);
|
||
border-radius: var(--radius-s);
|
||
padding: 0.6em 0.8em;
|
||
margin: -0.2rem 0 0;
|
||
}
|
||
.social-divider { display: flex; align-items: center; gap: 0.8em; color: var(--c-text-muted); font-size: 0.82rem; margin: 0.1rem 0; }
|
||
.social-divider::before, .social-divider::after { content: ""; flex: 1; height: 1px; background: rgba(244, 241, 247, 0.14); }
|
||
.pw-field { position: relative; }
|
||
.pw-field input { padding-right: 2.6em; }
|
||
.pw-toggle {
|
||
position: absolute;
|
||
top: 50%;
|
||
right: 0.5em;
|
||
transform: translateY(-50%);
|
||
background: none;
|
||
border: none;
|
||
color: var(--c-text-muted);
|
||
cursor: pointer;
|
||
padding: 0.3em;
|
||
display: flex;
|
||
border-radius: var(--radius-s);
|
||
}
|
||
.pw-toggle:hover { color: var(--c-text); }
|
||
.login-consent { color: var(--c-text-muted); margin-top: -0.3rem; }
|
||
|
||
/* ============================================================
|
||
Sprach-Umschalter + Konto-Button (Header)
|
||
============================================================ */
|
||
.lang-switch { position: relative; }
|
||
.lang-switch-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.4em;
|
||
background:
|
||
linear-gradient(155deg, color-mix(in srgb, var(--globe-color) 16%, var(--c-anthracite-light)), color-mix(in srgb, var(--globe-color) 5%, var(--c-anthracite)));
|
||
border: 1px solid color-mix(in srgb, var(--c-purple-glow) 55%, rgba(244, 241, 247, 0.14));
|
||
color: var(--c-text);
|
||
border-radius: 999px;
|
||
padding: 0.45em 0.9em 0.45em 0.55em;
|
||
font-size: 0.92rem;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
box-shadow:
|
||
inset 0 1px 0 color-mix(in srgb, var(--globe-glow, var(--globe-color)) 20%, transparent),
|
||
0 3px 12px -6px color-mix(in srgb, var(--globe-color) 55%, transparent);
|
||
transition: border-color 0.2s var(--ease), box-shadow 0.25s var(--ease), transform 0.2s var(--ease);
|
||
}
|
||
.lang-switch-btn:hover {
|
||
border-color: color-mix(in srgb, var(--c-purple-glow) 85%, transparent);
|
||
box-shadow:
|
||
inset 0 1px 0 color-mix(in srgb, var(--globe-glow, var(--globe-color)) 30%, transparent),
|
||
0 6px 18px -6px color-mix(in srgb, var(--globe-color) 70%, transparent);
|
||
transform: translateY(-1px);
|
||
}
|
||
.lang-switch-btn .chevron { font-size: 0.6rem; opacity: 0.7; color: var(--globe-color); transition: transform 0.2s var(--ease); }
|
||
.lang-switch.open .lang-switch-btn .chevron { transform: rotate(180deg); }
|
||
.lang-switch-menu {
|
||
position: absolute;
|
||
top: calc(100% + 0.6rem);
|
||
/* Wie auf der Dogfather-Referenzseite (assets/css/main.css, .nav-dropdown) und wie beim
|
||
Konto-Menü: ECHT zentriert unter dem auslösenden Knopf (left:50% + translateX(-50%))
|
||
statt rechtsbündig an dessen Kante. Vorher stand hier "right: 0", wodurch das Menü
|
||
sichtbar nach links versetzt unter dem Knopf hing, weil es breiter ist als der Knopf. */
|
||
left: 50%;
|
||
right: auto;
|
||
transform: translateX(-50%);
|
||
/* Wie beim Konto-Menü: so breit wie der Inhalt, aber nie schmaler als der Knopf darüber —
|
||
statt einer festen Zahl, die je nach Sprache/Textlänge nicht mehr passt. */
|
||
min-width: 100%;
|
||
width: max-content;
|
||
background: var(--c-anthracite-light);
|
||
border: 1px solid rgba(244, 241, 247, 0.1);
|
||
border-radius: var(--radius-m);
|
||
box-shadow: var(--shadow-card);
|
||
padding: 0.4rem;
|
||
display: none;
|
||
flex-direction: column;
|
||
gap: 0.15rem;
|
||
z-index: 60;
|
||
}
|
||
.lang-switch.open .lang-switch-menu { display: flex; }
|
||
.lang-switch-menu a {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.6em;
|
||
padding: 0.55em 0.7em;
|
||
border-radius: var(--radius-s);
|
||
font-size: 0.88rem;
|
||
opacity: 0.72;
|
||
transition: background 0.15s var(--ease), opacity 0.15s var(--ease);
|
||
}
|
||
.lang-switch-menu a:hover { background: color-mix(in srgb, var(--globe-color) 12%, transparent); opacity: 1; }
|
||
.lang-switch-menu a[aria-current="true"] { opacity: 1; font-weight: 700; }
|
||
.lang-switch-menu a[aria-current="true"] .lang-globe {
|
||
box-shadow:
|
||
0 0 0 3px color-mix(in srgb, var(--globe-color) 45%, transparent),
|
||
0 0 14px 2px color-mix(in srgb, var(--globe-glow, var(--globe-color)) 70%, transparent);
|
||
}
|
||
|
||
/* Sprachname im Farbverlauf der Nationalflagge (2 kräftigste Streifenfarben, Weiß/Schwarz
|
||
ausgelassen weil auf dunklem Grund unsichtbar bzw. zu hart) — Globus und Schrift wirken
|
||
dadurch wie ein zusammengehöriges, flaggenfarbenes Element. */
|
||
.lang-label {
|
||
background: linear-gradient(90deg, var(--globe-color, var(--c-text)), var(--globe-glow, var(--globe-color)));
|
||
background-clip: text;
|
||
-webkit-background-clip: text;
|
||
color: transparent;
|
||
text-shadow: 0 0 10px color-mix(in srgb, var(--globe-glow, var(--globe-color)) 35%, transparent);
|
||
transition: filter 0.2s var(--ease);
|
||
}
|
||
.lang-switch-btn:hover .lang-label,
|
||
.lang-switch-menu a:hover .lang-label {
|
||
filter: brightness(1.25) saturate(1.2);
|
||
}
|
||
|
||
/* Globus-Icon statt Flaggen-Emoji: trägt die echten Nationalflaggen-Farben als rotierende
|
||
Farbscheibe (siehe `flag` in i18n/config.ts) — dreht sich dauerhaft langsam wie ein
|
||
Modellglobus, wird schneller beim Hover. Eine zweite, FESTE Ebene obendrüber sorgt für
|
||
Glanzlicht + Schattenseite (3D-Kugel-Wirkung), damit die Farben plastisch statt flach wirken. */
|
||
.lang-globe {
|
||
position: relative;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 26px;
|
||
height: 26px;
|
||
border-radius: 50%;
|
||
overflow: hidden;
|
||
isolation: isolate;
|
||
color: rgba(10, 9, 16, 0.55);
|
||
/* Dezenter "Polarlicht"-Schimmer: mehrere weiche, unterschiedlich gefärbte Glow-Schichten
|
||
(Lila der Seite + Flaggenfarbe + Akzent-Türkis) statt eines einzelnen harten Farbrings. */
|
||
box-shadow:
|
||
0 0 0 1px color-mix(in srgb, var(--c-purple-glow) 55%, transparent),
|
||
0 3px 5px -1px color-mix(in srgb, black 55%, transparent),
|
||
0 0 7px 1px color-mix(in srgb, var(--globe-glow, var(--globe-color)) 40%, transparent),
|
||
0 0 13px 3px color-mix(in srgb, var(--c-purple-glow) 22%, transparent),
|
||
0 0 18px 4px color-mix(in srgb, var(--c-accent) 12%, transparent);
|
||
transition: box-shadow 0.25s var(--ease), transform 0.25s var(--ease);
|
||
flex-shrink: 0;
|
||
}
|
||
.lang-globe::after {
|
||
/* fixe Lichtquelle: bleibt stehen, während die Flaggenfarben darunter rotieren */
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 2;
|
||
background:
|
||
radial-gradient(circle at 28% 22%, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0) 30%),
|
||
radial-gradient(circle at 75% 78%, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0) 55%);
|
||
mix-blend-mode: overlay;
|
||
pointer-events: none;
|
||
}
|
||
.lang-globe-rotor {
|
||
position: absolute;
|
||
inset: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
/* Weiche, ineinander fließende Übergänge statt harter 120°-Segmente — gleicher Stil (Flaggen-
|
||
farben, Rotation), nur eleganter/fließender statt wie ein Tortendiagramm. */
|
||
background: conic-gradient(from 0deg, var(--flag-1) 0%, var(--flag-2) 33%, var(--flag-3) 66%, var(--flag-1) 100%);
|
||
animation: globe-spin 6s linear infinite;
|
||
}
|
||
.lang-globe:hover .lang-globe-rotor { animation-duration: 1.6s; }
|
||
@keyframes globe-spin {
|
||
from { transform: rotate(0deg); }
|
||
to { transform: rotate(360deg); }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.lang-globe-rotor { animation: none; }
|
||
}
|
||
.lang-globe svg { position: relative; z-index: 1; opacity: 0.55; filter: drop-shadow(0 0 1px rgba(10, 9, 16, 0.6)); }
|
||
.lang-switch-btn .lang-globe { width: 24px; height: 24px; }
|
||
.lang-switch-btn:hover .lang-globe,
|
||
.lang-switch-menu a:hover .lang-globe {
|
||
box-shadow:
|
||
0 0 0 1px color-mix(in srgb, var(--c-purple-glow) 75%, transparent),
|
||
0 3px 6px -1px color-mix(in srgb, black 55%, transparent),
|
||
0 0 10px 2px color-mix(in srgb, var(--globe-glow, var(--globe-color)) 55%, transparent),
|
||
0 0 18px 4px color-mix(in srgb, var(--c-purple-glow) 30%, transparent),
|
||
0 0 24px 6px color-mix(in srgb, var(--c-accent) 18%, transparent);
|
||
transform: scale(1.12);
|
||
}
|
||
|
||
.account-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.5em;
|
||
padding: 0.55em 1.1em 0.55em 0.6em;
|
||
border-radius: 999px;
|
||
background: linear-gradient(135deg, rgba(95, 211, 236, 0.16), rgba(46, 27, 71, 0.4));
|
||
border: 1px solid rgba(95, 211, 236, 0.3);
|
||
color: var(--c-text);
|
||
font-size: 0.92rem;
|
||
font-weight: 600;
|
||
transition: border-color 0.2s var(--ease), transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
|
||
}
|
||
.account-btn:hover {
|
||
border-color: var(--c-accent);
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 8px 20px -8px rgba(95, 211, 236, 0.4);
|
||
}
|
||
.account-btn .account-icon {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 29px;
|
||
height: 29px;
|
||
border-radius: 50%;
|
||
background: linear-gradient(155deg, var(--c-accent), var(--c-purple));
|
||
color: var(--c-black);
|
||
font-size: 0.86rem;
|
||
}
|
||
@media (max-width: 860px) {
|
||
.account-btn .account-label { display: none; }
|
||
.account-btn { padding: 0.5em; }
|
||
}
|
||
|
||
/* Konto-Menü in der Kopfzeile — ersetzt den "Anmelden"-Button sobald auf diesem Gerät ein
|
||
(Demo-)Konto angemeldet ist (siehe Layout.astro-Script + scripts/account.ts). Gleicher
|
||
Verlaufsrand-Knopf-Look wie account-btn, damit der Wechsel nicht wie ein Bruch wirkt. */
|
||
.account-area { position: relative; }
|
||
.account-menu { position: relative; display: none; align-items: center; }
|
||
.account-menu-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.5em;
|
||
padding: 0.4em 0.9em 0.4em 0.4em;
|
||
border-radius: 999px;
|
||
background: linear-gradient(135deg, rgba(95, 211, 236, 0.16), rgba(46, 27, 71, 0.4));
|
||
border: 1px solid rgba(95, 211, 236, 0.3);
|
||
color: var(--c-text);
|
||
font-size: 0.92rem;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
transition: border-color 0.2s var(--ease), transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
|
||
}
|
||
.account-menu-btn:hover {
|
||
border-color: var(--c-accent);
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 8px 20px -8px rgba(95, 211, 236, 0.4);
|
||
}
|
||
.account-avatar {
|
||
width: 29px;
|
||
height: 29px;
|
||
border-radius: 50%;
|
||
background: linear-gradient(155deg, var(--c-accent), var(--c-purple));
|
||
background-size: cover;
|
||
background-position: center;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: var(--c-black);
|
||
font-size: 0.86rem;
|
||
font-weight: 800;
|
||
flex-shrink: 0;
|
||
}
|
||
.account-menu-btn .chevron { font-size: 0.6rem; opacity: 0.7; transition: transform 0.2s var(--ease); }
|
||
.account-menu.open .account-menu-btn .chevron { transform: rotate(180deg); }
|
||
.account-dropdown {
|
||
position: absolute;
|
||
top: calc(100% + 0.6rem);
|
||
/* Wie auf der Dogfather-Referenzseite (assets/css/main.css, .nav-dropdown): ECHT zentriert
|
||
unter dem auslösenden Knopf (left:50% + translateX(-50%)) statt rechtsbündig an dessen
|
||
Kante ausgerichtet — bleibt so auch bei unterschiedlich breiten Benutzernamen mittig. */
|
||
left: 50%;
|
||
right: auto;
|
||
transform: translateX(-50%);
|
||
/* KEINE feste Breite mehr: Das Menü ist genau so breit wie sein Inhalt, aber nie schmaler als
|
||
der Knopf darüber (min-width: 100% = Breite des .account-menu-Wrappers). Vorher stand hier
|
||
eine feste Zahl (erst 190px, dann 168px) — die passt aber nie zu jedem Fall, weil der Knopf
|
||
je nach Länge des Benutzernamens unterschiedlich breit ist: Bei einem kurzen Namen wie
|
||
"qciga" ragte die Kiste dadurch sichtbar über den Knopf hinaus. So passt es sich von selbst
|
||
an jeden Namen und jede Sprache an. */
|
||
min-width: 100%;
|
||
width: max-content;
|
||
background: var(--c-anthracite-light);
|
||
border: 1px solid rgba(244, 241, 247, 0.1);
|
||
border-radius: var(--radius-m);
|
||
box-shadow: var(--shadow-card);
|
||
padding: 0.4rem;
|
||
display: none;
|
||
flex-direction: column;
|
||
gap: 0.15rem;
|
||
z-index: 60;
|
||
}
|
||
.account-menu.open .account-dropdown { display: flex; }
|
||
.account-dropdown a,
|
||
.account-dropdown button {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0.5em;
|
||
width: 100%;
|
||
text-align: center;
|
||
background: none;
|
||
border: none;
|
||
color: var(--c-text);
|
||
/* Etwas kompakter als vorher (Dogfather-Referenz: .55rem .7rem, .92rem Schrift) — wirkte bei
|
||
nur 2 Einträgen sonst unnötig groß/aufgebläht. */
|
||
padding: 0.5em 0.65em;
|
||
border-radius: var(--radius-s);
|
||
font-size: 0.88rem;
|
||
cursor: pointer;
|
||
transition: background 0.15s var(--ease);
|
||
}
|
||
/* Feste Icon-Spalte, statt das Emoji einfach vor den Text zu schreiben — sonst starten "Mein
|
||
Konto" und "Abmelden" je nach Emoji-Breite an leicht unterschiedlichen Stellen und wirken
|
||
unausgerichtet. Mit fixer Breite + zentriertem Icon stehen alle Labels exakt untereinander. */
|
||
.account-dropdown-icon { flex-shrink: 0; width: 1.1em; text-align: center; font-size: 0.95em; }
|
||
.account-dropdown a:hover,
|
||
.account-dropdown button:hover { background: color-mix(in srgb, var(--c-accent) 12%, transparent); }
|
||
@media (max-width: 860px) {
|
||
.account-menu-btn .account-username { display: none; }
|
||
.account-menu-btn { padding: 0.4em; }
|
||
}
|
||
|
||
/* ============================================================
|
||
Geteilte Seiten-Layouts (von allen Sprachversionen genutzt,
|
||
damit DE/EN/CH/FR immer exakt gleich aussehen)
|
||
============================================================ */
|
||
|
||
/* Startseite: Hero + Kategorie-Kacheln + Kreative-Sektion */
|
||
.hero { position: relative; overflow: hidden; padding: clamp(3.5rem, 8vw, 7rem) 0; background: radial-gradient(circle at 15% 20%, rgba(46,27,71,0.9), var(--c-black) 60%); }
|
||
.hero-watermark {
|
||
position: absolute;
|
||
left: 50%;
|
||
top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
width: min(85vw, 900px);
|
||
opacity: 0.045;
|
||
filter: grayscale(1);
|
||
pointer-events: none;
|
||
z-index: 0;
|
||
}
|
||
.hero-inner { position: relative; max-width: 640px; }
|
||
.hero h1 { margin-bottom: 0.7em; }
|
||
|
||
/* Zweispaltiges Hero-Layout: Foto-Collage links, Text rechts */
|
||
.hero-content {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: grid;
|
||
grid-template-columns: minmax(280px, 0.95fr) 1.1fr;
|
||
gap: clamp(2rem, 5vw, 4.5rem);
|
||
align-items: center;
|
||
}
|
||
@media (max-width: 900px) {
|
||
.hero-content { grid-template-columns: 1fr; }
|
||
.hero-inner { max-width: none; }
|
||
}
|
||
|
||
/* Foto-Collage: 4 handgefertigte Produktfotos, versetzt & leicht gedreht arrangiert wie ein
|
||
kuratiertes Moodboard statt eines steifen Rasters — jedes Foto trägt denselben
|
||
Verlaufs-Rand wie unsere Produktkarten (Signature-Look, siehe a.card), damit es sich
|
||
erkennbar in die restliche Seite einfügt statt wie ein Fremdkörper zu wirken. */
|
||
.hero-gallery {
|
||
position: relative;
|
||
width: 100%;
|
||
max-width: 440px;
|
||
aspect-ratio: 1 / 1.08;
|
||
margin-inline: auto;
|
||
}
|
||
.hero-photo {
|
||
position: absolute;
|
||
overflow: hidden;
|
||
border-radius: var(--radius-l);
|
||
border: 2.5px solid transparent;
|
||
background:
|
||
linear-gradient(165deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(135deg, var(--c-accent), var(--c-purple-glow) 45%, var(--c-sale) 100%) border-box;
|
||
box-shadow: var(--shadow-card);
|
||
transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease), z-index 0s;
|
||
}
|
||
.hero-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||
.hero-photo:hover { transform: scale(1.06) rotate(0deg) !important; box-shadow: var(--shadow-card-hover); z-index: 5 !important; }
|
||
|
||
.hero-photo-1 { width: 58%; aspect-ratio: 3 / 4; top: 0; left: 0; transform: rotate(-4deg); z-index: 3; }
|
||
.hero-photo-2 { width: 44%; aspect-ratio: 1 / 1; top: 3%; right: 0; transform: rotate(5deg); z-index: 2; }
|
||
.hero-photo-3 { width: 40%; aspect-ratio: 4 / 5; bottom: 4%; left: 12%; transform: rotate(6deg); z-index: 4; }
|
||
.hero-photo-4 { width: 38%; aspect-ratio: 1 / 1; bottom: -1%; right: 8%; transform: rotate(-6deg); z-index: 1; }
|
||
|
||
@media (max-width: 900px) {
|
||
.hero-gallery { max-width: 380px; margin-bottom: 1rem; }
|
||
}
|
||
@media (max-width: 760px) { .hero-watermark { opacity: 0.035; } }
|
||
|
||
.category-card { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 0.4rem; }
|
||
.cat-icon { font-size: 2.1rem; }
|
||
.category-card h3 { margin-bottom: 0.2rem; }
|
||
|
||
.section-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 1.3rem; }
|
||
.section-head a { color: var(--c-accent); }
|
||
|
||
.creator-section { align-items: center; }
|
||
.creator-photo { max-width: 420px; margin-inline: auto; }
|
||
/* Das echte Foto (vanvan-portrait.png, 1122×1402 ≈ 4/5) ist hochkant, nicht quadratisch — die
|
||
allgemeine .portrait-frame-Regel erzwingt aber ein 1:1-Seitenverhältnis, wodurch der untere
|
||
Teil des Fotos (der zweite Plushie im Arm) abgeschnitten wurde. Eigenes Seitenverhältnis nah am
|
||
Original, damit das komplette Foto sichtbar bleibt — gleiches Muster wie schon bei .portrait auf
|
||
der "Über die Kreative"-Seite gelöst. */
|
||
.creator-photo .portrait-img,
|
||
.creator-photo img { aspect-ratio: 4 / 5; }
|
||
|
||
/* "Über die Kreative" / Charakter-Vorstellung (Unterkategorie-Familienseiten) */
|
||
.intro { align-items: stretch; grid-template-columns: 1fr 1fr; gap: 1.6rem; }
|
||
.intro h2 a { color: inherit; transition: color 0.2s var(--ease); }
|
||
.intro h2 a:hover { color: var(--c-accent); }
|
||
|
||
/* Foto UND Text bekommen auf den Charakter-Vorstellungen jeweils die gleiche "Kisten"-Optik wie
|
||
die Produktkarten (Verlaufsrand, siehe .card) — zwei gleichwertige, gerahmte Boxen nebeneinander
|
||
statt freischwebendem Text neben einem Foto ohne Rahmen. */
|
||
.intro .portrait-frame.portrait,
|
||
.intro .intro-text {
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
border: 1.5px solid transparent;
|
||
border-radius: var(--radius-m);
|
||
background:
|
||
linear-gradient(165deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(135deg, var(--c-accent), var(--c-purple-glow) 45%, var(--c-sale) 100%) border-box;
|
||
padding: 1.7rem;
|
||
box-shadow: var(--shadow-card);
|
||
transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), filter 0.3s var(--ease);
|
||
}
|
||
.intro .portrait-frame.portrait:hover {
|
||
transform: translateY(-4px);
|
||
box-shadow: var(--shadow-card-hover);
|
||
filter: brightness(1.06);
|
||
}
|
||
.intro .portrait-frame.portrait::before { display: none; }
|
||
/* Das Foto selbst braucht innerhalb der neuen Karte keinen zweiten Ring mehr — die Karte rahmt
|
||
schon, ein zusätzlicher Rand würde nur "doppelt gerahmt" aussehen.
|
||
WICHTIG: hier bewusst KEIN eigenes aspect-ratio mehr setzen — diese Regel ist (durch die
|
||
Kombination .intro + .portrait-frame + .portrait) spezifischer als die weiter unten stehende
|
||
".portrait img { aspect-ratio: 2/3 }"-Korrektur und hat sie dadurch lautlos wieder auf 1:1
|
||
zurückgesetzt. Genau das hat den bereits einmal gefixten Bug (Oktopus-Plushie unten
|
||
abgeschnitten) auf der "Über die Kreative"-Seite erneut verursacht. */
|
||
.intro .portrait-frame.portrait img,
|
||
.intro .portrait-frame.portrait .img-placeholder {
|
||
border: none;
|
||
box-shadow: none;
|
||
border-radius: var(--radius-s);
|
||
}
|
||
|
||
/* "Über die Kreative": VanVans Geschichte steht direkt NEBEN ihrem Foto (statt darunter als
|
||
eigener Block). Weil die Textspalte dadurch deutlich höher wird als das Foto, wird hier oben
|
||
ausgerichtet statt gestreckt — sonst würde die Fotokarte mit viel leerem Raum mitwachsen.
|
||
Das Foto bleibt beim Lesen sichtbar (sticky), solange genug Platz da ist. */
|
||
/* NUR im zweispaltigen Layout (ab 901px): oben ausrichten statt strecken + Foto bleibt beim
|
||
Lesen sichtbar. Bewusst NICHT global gesetzt — unterhalb von 900px stehen Foto und Text
|
||
ohnehin untereinander, und dort führt `align-items: start` zu einem echten Fehler: die
|
||
Grid-Zeile wird dann anhand des geschätzten Bild-Seitenverhältnisses berechnet und fällt
|
||
~100px zu niedrig aus, wodurch das Foto in den Text darunter hineinragt (gemessen: 80px
|
||
Überlappung). Mit dem Standardverhalten (stretch) tritt das nicht auf. */
|
||
@media (min-width: 901px) {
|
||
.intro-story { align-items: start; }
|
||
.intro-story .portrait-frame.portrait { position: sticky; top: 6.5rem; }
|
||
}
|
||
/* text-wrap: balance verteilt die Zeilen der Überschrift gleichmäßig — sonst rutscht bei
|
||
breiten Fenstern nur das 🩵 allein in eine eigene Zeile. */
|
||
.intro-story-text h1 { margin-bottom: 0.6rem; text-wrap: balance; }
|
||
.intro-story-text h2 {
|
||
margin-top: 2rem;
|
||
font-size: clamp(1.4rem, 2.4vw, 1.8rem);
|
||
}
|
||
.intro-story-text p { max-width: 60ch; }
|
||
|
||
/* Wechselt innerhalb einer Tier-Familie ab: Foto links/rechts, Text jeweils gegenüber — sorgt
|
||
für optische Abwechslung, sobald mehrere Varianten einer Serie eigene Seiten bekommen. */
|
||
.intro-reverse .portrait-frame.portrait { order: 2; }
|
||
.intro-reverse .intro-text { order: 1; }
|
||
@media (max-width: 800px) {
|
||
.intro { grid-template-columns: 1fr; gap: 1.5rem; }
|
||
.intro-reverse .portrait-frame.portrait, .intro-reverse .intro-text { order: initial; }
|
||
}
|
||
/* Breiter als vorher (war 440px) + Seitenverhältnis nah am Originalfoto (900x1353 ≈ 2/3)
|
||
statt 3/4 — vorher wurde oben/unten so stark beschnitten, dass das Plushie neben VanVan
|
||
(Oktopus) nur noch als Ecke sichtbar war. So ist das ganze Foto inkl. beider Plushies zu sehen. */
|
||
.portrait { max-width: 540px; }
|
||
.portrait .portrait-img,
|
||
.portrait img { aspect-ratio: 2 / 3; }
|
||
|
||
/* Pull-Quote: elegantes, hervorgehobenes Zitat — genutzt für VanVans Zitat auf der Startseite
|
||
("Die Kreative") und den Abschluss-Satz auf "Über die Kreative". Serif-Kursiv + Akzent-Rand
|
||
statt einfachem Fließtext, damit es sich sichtbar abhebt, aber im Stil der Seite bleibt. */
|
||
.pull-quote {
|
||
position: relative;
|
||
font-family: var(--font-head);
|
||
font-style: italic;
|
||
font-weight: 500;
|
||
font-size: clamp(1.2rem, 1.1rem + 1vw, 1.55rem);
|
||
line-height: 1.55;
|
||
color: var(--c-text);
|
||
padding: 0.2rem 0 0.2rem 1.4rem;
|
||
border-left: 3px solid var(--c-accent);
|
||
margin: 1.4rem 0;
|
||
}
|
||
.pull-quote-center {
|
||
text-align: center;
|
||
border-left: none;
|
||
border-top: 1px solid rgba(95, 211, 236, 0.3);
|
||
border-bottom: 1px solid rgba(95, 211, 236, 0.3);
|
||
padding: 1.6rem 1rem;
|
||
max-width: 720px;
|
||
margin-inline: auto;
|
||
}
|
||
|
||
/* Story-Abschnitte ("Über die Kreative"): wiederkehrende h2+Absätze mit klarer Struktur und
|
||
sanftem Einblenden beim Scrollen (dezente Verbesserung, kein Redesign). */
|
||
.story-section { padding-block: 1.6rem; }
|
||
.story-section:not(:last-child) { border-bottom: 1px solid rgba(244, 241, 247, 0.07); }
|
||
.story-section h2 { color: var(--c-text); }
|
||
.story-section p { max-width: 68ch; }
|
||
.story-section.is-visible { animation: story-fade-up 0.7s var(--ease) both; }
|
||
@keyframes story-fade-up {
|
||
from { opacity: 0; transform: translateY(18px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.story-section.is-visible { animation: none; }
|
||
}
|
||
|
||
/* Unterkategorie-Chips auf den Hauptkategorie-Seiten — mittig, mit demselben Verlaufsrand-Stil
|
||
wie die Karten der Seite (siehe .card), statt schlichter Einzelfarb-Pillen. Wirkt dadurch
|
||
"speziell" und zur Marke passend, bleibt aber ruhig/professionell statt aufdringlich. */
|
||
.subcategory-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin: 1.6rem 0 2.5rem; }
|
||
.subcategory-chip {
|
||
position: relative;
|
||
isolation: isolate;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 0.65em 1.4em;
|
||
border-radius: 999px;
|
||
font-size: 0.92rem;
|
||
font-weight: 700;
|
||
color: var(--c-text);
|
||
border: 1.5px solid transparent;
|
||
background:
|
||
linear-gradient(165deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(135deg, var(--c-accent), var(--c-purple-glow) 50%, var(--c-sale) 100%) border-box;
|
||
box-shadow: var(--shadow-card);
|
||
transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), filter 0.25s var(--ease);
|
||
}
|
||
.subcategory-chip:hover { transform: translateY(-3px); box-shadow: var(--shadow-card-hover); filter: brightness(1.1); }
|
||
|
||
/* Persönliche Vorstellung eines Plushie-Charakters auf seiner Unterkategorie-Seite (z.B.
|
||
"Hallo, ich bin Frieda ..."). Dezente Box im Kartenstil des Shops, kein neues Designelement. */
|
||
.character-intro {
|
||
max-width: 640px;
|
||
margin: 1.6rem 0 2rem;
|
||
padding: 1.4rem 1.6rem;
|
||
border-radius: var(--radius-l);
|
||
background: var(--c-anthracite);
|
||
border: 1px solid rgba(244, 241, 247, 0.1);
|
||
border-left: 3px solid var(--c-accent);
|
||
}
|
||
.character-intro p { margin: 0; white-space: pre-line; }
|
||
.character-intro p:first-child { font-family: var(--font-head); font-weight: 600; color: var(--c-text); margin-bottom: 0.5em; }
|
||
|
||
/* "Willst du mehr über X erfahren?" + Link-Button — sowohl innerhalb der character-intro-Box
|
||
(falls noch kein echtes Produkt zugeordnet ist) als auch frei im Intro-Layout (sobald ein
|
||
echtes Produkt featured wird). */
|
||
.character-more { margin-top: 1rem; }
|
||
.character-more p { margin: 0 0 0.6em; color: var(--c-text-muted); }
|
||
|
||
/* Seiten-Banner (Shop, Sale, ...): echtes Foto/Grafik als Kopfbild mit Verlauf-Überblendung
|
||
unten, damit Titel/Text darauf lesbar bleiben — ersetzt die reine Text-Kopfzeile durch ein
|
||
echtes visuelles Signal, wie im Pflichtenheft für "Bannerplätze" gefordert. */
|
||
.page-banner {
|
||
position: relative;
|
||
/* aspect-ratio statt fester min-height, damit das Bild bei background-size:cover NICHT
|
||
oben/unten beschnitten wird — die Box hat exakt das Seitenverhältnis des Fotos, jedes
|
||
Banner setzt seinen eigenen Wert per Inline-Style (--banner-ratio). */
|
||
aspect-ratio: var(--banner-ratio, 1600 / 729);
|
||
display: flex;
|
||
align-items: flex-end;
|
||
background-size: cover;
|
||
background-position: center;
|
||
border-radius: var(--radius-l);
|
||
overflow: hidden;
|
||
margin-inline: auto;
|
||
margin-top: 1.5rem;
|
||
}
|
||
.page-banner::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
background:
|
||
linear-gradient(180deg, rgba(10, 9, 16, 0.15) 0%, rgba(10, 9, 16, 0.55) 55%, rgba(10, 9, 16, 0.92) 100%),
|
||
linear-gradient(100deg, rgba(46, 27, 71, 0.35), transparent 55%);
|
||
}
|
||
.page-banner-content { position: relative; z-index: 1; padding: 1.8rem clamp(1.25rem, 4vw, 2.5rem); }
|
||
.page-banner-content .eyebrow { color: var(--c-accent); }
|
||
.page-banner-content h1 { margin-bottom: 0.35em; text-shadow: 0 2px 12px rgba(0,0,0,0.5); }
|
||
.page-banner-content .lead { color: var(--c-text); max-width: 620px; }
|
||
|
||
/* Shop-Übersicht + Kategorie-Seiten */
|
||
.shop-layout { display: grid; grid-template-columns: 240px 1fr; gap: 2rem; align-items: start; }
|
||
.filters h3 { margin-bottom: 1rem; }
|
||
.filter-group { margin-bottom: 1.2rem; }
|
||
.filter-group label, #f-kategorie-label { display: block; font-size: 0.85rem; color: var(--c-text-muted); margin-bottom: 0.4rem; }
|
||
.filter-group select, .filter-group input[type="range"] { width: 100%; }
|
||
.filters select, .shop-toolbar select {
|
||
background: var(--c-anthracite); color: var(--c-text);
|
||
border: 1px solid rgba(244,241,247,0.15); border-radius: var(--radius-s); padding: 0.5em 0.7em;
|
||
}
|
||
|
||
/* Kategorie-Filter im Shop: eigenes Dropdown statt nativem <select> mit optgroups. Grund: die
|
||
Tier-Unterkategorien (Kuh, Hase, Wal, ...) waren in der schmucklosen Browser-eigenen
|
||
Optgroup-Liste zwar technisch vorhanden, aber kaum als eigene, auswählbare Zeilen zu erkennen.
|
||
Hier bekommen sie denselben "Karte mit Verlaufsrand"-Look wie der Rest der Seite, klar
|
||
eingerückt unter ihrer Hauptkategorie, mit demselben Namen wie auf den Kategorie-Seiten. */
|
||
.cat-filter { position: relative; width: 100%; }
|
||
.cat-filter-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 0.6em;
|
||
width: 100%;
|
||
background: var(--c-anthracite);
|
||
color: var(--c-text);
|
||
border: 1.5px solid transparent;
|
||
background:
|
||
linear-gradient(165deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(135deg, rgba(95, 211, 236, 0.5), rgba(155, 127, 214, 0.4) 45%, rgba(231, 135, 154, 0.32)) border-box;
|
||
border-radius: var(--radius-s);
|
||
padding: 0.55em 0.8em;
|
||
font-size: 0.95rem;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
text-align: left;
|
||
transition: box-shadow 0.2s var(--ease);
|
||
}
|
||
.cat-filter-btn:hover { box-shadow: var(--shadow-card); }
|
||
.cat-filter-btn .chevron { font-size: 0.65rem; opacity: 0.7; color: var(--c-accent); transition: transform 0.2s var(--ease); flex-shrink: 0; }
|
||
.cat-filter.open .cat-filter-btn .chevron { transform: rotate(180deg); }
|
||
.cat-filter-menu {
|
||
position: absolute;
|
||
top: calc(100% + 0.5rem);
|
||
left: 0;
|
||
right: 0;
|
||
max-height: min(60vh, 420px);
|
||
overflow-y: auto;
|
||
overflow-x: hidden;
|
||
box-sizing: border-box;
|
||
background: var(--c-anthracite-light);
|
||
border: 1px solid rgba(244, 241, 247, 0.12);
|
||
border-radius: var(--radius-m);
|
||
box-shadow: var(--shadow-card);
|
||
padding: 0.5rem;
|
||
display: none;
|
||
flex-direction: column;
|
||
gap: 0.1rem;
|
||
z-index: 60;
|
||
}
|
||
.cat-filter.open .cat-filter-menu { display: flex; }
|
||
.cat-filter-group { display: flex; flex-direction: column; gap: 0.1rem; margin-top: 0.5rem; }
|
||
.cat-filter-group:first-of-type { margin-top: 0.2rem; }
|
||
.cat-filter-group-label {
|
||
padding: 0.3em 0.6em 0.1em;
|
||
font-size: 0.72rem;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
color: var(--c-accent);
|
||
font-weight: 700;
|
||
}
|
||
.cat-filter-option {
|
||
display: block;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
text-align: left;
|
||
background: none;
|
||
border: none;
|
||
color: var(--c-text);
|
||
padding: 0.5em 0.6em;
|
||
border-radius: var(--radius-s);
|
||
font-size: 0.9rem;
|
||
cursor: pointer;
|
||
transition: background 0.15s var(--ease);
|
||
overflow-wrap: break-word;
|
||
}
|
||
.cat-filter-option:hover { background: color-mix(in srgb, var(--c-accent) 14%, transparent); }
|
||
.cat-filter-option[aria-selected="true"] { background: color-mix(in srgb, var(--c-accent) 20%, transparent); font-weight: 700; }
|
||
.cat-filter-option.cat-filter-sub { padding-left: 1.4em; font-size: 0.88rem; opacity: 0.92; }
|
||
.cat-filter-option.cat-filter-sub::before { content: "— "; opacity: 0.6; }
|
||
/* Zeilen des Mindestbewertung-Filters: Herzen und das "+" nebeneinander auf einer Linie. */
|
||
.cat-filter-option.rating-option { display: flex; align-items: center; gap: 0.45em; }
|
||
.rating-plus { color: var(--c-text-muted); font-weight: 700; }
|
||
/* Auch im geschlossenen Knopf sollen die Herzen sauber neben dem Pfeil sitzen. */
|
||
.cat-filter-btn .heart-rating { vertical-align: middle; }
|
||
.shop-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.2rem; }
|
||
.legal-hint { margin-top: 2rem; }
|
||
.breadcrumb { margin-bottom: 0.6rem; font-size: 0.95rem; }
|
||
.breadcrumb a { color: var(--c-accent); font-weight: 600; }
|
||
.breadcrumb a:hover { text-decoration: underline; }
|
||
/* Aktuelle Ebene (Haupt-/Unterkategorie, Produktname) hebt sich etwas vom "Shop"-Wurzel-Link ab. */
|
||
.breadcrumb strong { color: var(--c-text); font-weight: 700; }
|
||
|
||
/* Überschrift über der "weitere Produkte"-Reihe auf Unterkategorie-Seiten — macht klar, dass da
|
||
noch mehr Produkte derselben Reihe kommen (Charakter-Familie), egal wie viele es am Ende sind. */
|
||
.more-variants-label { text-transform: uppercase; letter-spacing: 0.08em; color: var(--c-text-muted); margin-bottom: 0.8rem; }
|
||
|
||
/* Persönliche Charaktergeschichten (Hallo-ich-bin-Texte) auf den Tier-Familien-Seiten — eigene,
|
||
volle Breite Karten übereinander gestapelt, GETRENNT von den Shop-Karten darunter (die zeigen
|
||
nur noch Foto/Preis/Kaufinfos, keine Geschichten). */
|
||
.character-stories { display: flex; flex-direction: column; gap: 1rem; margin-bottom: 0.6rem; }
|
||
|
||
/* Die Story-Karte bekommt einen eigenen, "besonderen" Auftritt statt der schlichten Basis-Karte:
|
||
ein großes, dezentes Anführungszeichen als Wasserzeichen (reine Formatierung, kein neuer Text),
|
||
einen sanften Marken-Farbschimmer rund um die Box (Verlauf aus den Signature-Farben Cyan/Lila/
|
||
Rosa, wie beim Verlaufsrand der Karten) und ein eigens gestalteter "hier"-Button im
|
||
Verlaufs-Look statt schlichtem Outline-Rahmen. */
|
||
.character-story {
|
||
position: relative;
|
||
overflow: hidden;
|
||
isolation: isolate;
|
||
padding: 2.2rem 2.4rem 2rem;
|
||
box-shadow:
|
||
var(--shadow-card),
|
||
0 0 46px -14px color-mix(in srgb, var(--c-accent) 40%, transparent),
|
||
0 0 80px -22px color-mix(in srgb, var(--c-sale) 28%, transparent);
|
||
}
|
||
.character-story:hover {
|
||
box-shadow:
|
||
var(--shadow-card-hover),
|
||
0 0 60px -12px color-mix(in srgb, var(--c-accent) 50%, transparent),
|
||
0 0 100px -18px color-mix(in srgb, var(--c-sale) 36%, transparent);
|
||
}
|
||
.character-story::after {
|
||
content: "“";
|
||
position: absolute;
|
||
z-index: 0;
|
||
top: -0.3rem;
|
||
right: 1rem;
|
||
font-family: var(--font-head);
|
||
font-size: 7rem;
|
||
line-height: 1;
|
||
color: transparent;
|
||
background: linear-gradient(160deg, var(--c-accent), var(--c-purple-glow) 55%, var(--c-sale));
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
opacity: 0.18;
|
||
pointer-events: none;
|
||
user-select: none;
|
||
}
|
||
.character-story > * { position: relative; z-index: 1; }
|
||
.character-story h3 {
|
||
margin: 0.2rem 0 0.7rem;
|
||
font-size: 1.5rem;
|
||
background: linear-gradient(120deg, var(--c-text) 45%, var(--c-accent) 130%);
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
color: transparent;
|
||
}
|
||
.character-story p { margin: 0 0 1.1rem; max-width: 62ch; font-size: 1.02rem; color: var(--c-text-muted); }
|
||
.character-story .character-more-lead {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
gap: 0.55em;
|
||
margin-bottom: 0;
|
||
}
|
||
.character-story .btn {
|
||
background: linear-gradient(135deg, var(--c-accent), var(--c-purple-glow));
|
||
color: #08181c;
|
||
border-color: transparent;
|
||
font-weight: 700;
|
||
box-shadow: var(--shadow-card);
|
||
}
|
||
.character-story .btn:hover {
|
||
box-shadow: var(--shadow-card-hover), 0 10px 24px -8px color-mix(in srgb, var(--c-accent) 55%, transparent);
|
||
transform: translateY(-2px);
|
||
}
|
||
@media (max-width: 640px) {
|
||
.character-story { padding: 1.8rem 1.6rem 1.7rem; }
|
||
.character-story::after { font-size: 5rem; top: -0.2rem; }
|
||
}
|
||
|
||
/* Charakter-Karten ohne zugeordnetes Produkt (noch kein Foto/Preis) — gleiche Optik wie die
|
||
echten Produktkarten (ProductCard.astro), damit die Reihe einheitlich aussieht. */
|
||
.character-card { display: flex; flex-direction: column; gap: 0.6rem; padding: 1rem; }
|
||
.character-card .product-media { position: relative; }
|
||
/* Gleiche Bildhöhe wie ein echtes Produktfoto (siehe ProductCard.astro .product-media
|
||
.img-placeholder) — vorher griff hier nur die allgemeine .img-placeholder-Mindesthöhe
|
||
(160px), wodurch die Platzhalter-Karten kleiner/anders proportioniert wirkten als die
|
||
Karte mit echtem Foto daneben. */
|
||
.character-card .product-media .img-placeholder { aspect-ratio: 1 / 1; min-height: 0; }
|
||
.character-card h3 { font-size: 1.15rem; margin: 0.1rem 0 0; }
|
||
.character-card-desc { margin: 0; color: var(--c-text-muted); font-size: 0.92rem; }
|
||
|
||
/* Kontaktseite: "Direkter Kontakt" + "Antwortzeit" bekommen eine eigene, auffälligere Kiste
|
||
statt schlichtem freiem Text neben dem Formular — passend zum restlichen Verlaufsrand-/
|
||
Glow-Look der Seite (siehe .card, .character-story), aber ohne deren Anführungszeichen-
|
||
Wasserzeichen, weil es hier nicht um eine Zitat-Vorstellung geht, sondern um wichtige
|
||
Kontaktinfos, die etwas mehr Aufmerksamkeit verdienen. */
|
||
.contact-highlight {
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
gap: 0.2rem;
|
||
background:
|
||
linear-gradient(165deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(135deg, var(--c-accent), var(--c-purple-glow) 45%, var(--c-sale) 100%) border-box;
|
||
box-shadow:
|
||
var(--shadow-card),
|
||
0 0 46px -14px color-mix(in srgb, var(--c-accent) 40%, transparent),
|
||
0 0 80px -22px color-mix(in srgb, var(--c-sale) 28%, transparent);
|
||
}
|
||
.contact-highlight:hover {
|
||
box-shadow:
|
||
var(--shadow-card-hover),
|
||
0 0 60px -12px color-mix(in srgb, var(--c-accent) 50%, transparent),
|
||
0 0 100px -18px color-mix(in srgb, var(--c-sale) 36%, transparent);
|
||
}
|
||
.contact-highlight h3 {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.5em;
|
||
margin: 0 0 0.5rem;
|
||
font-size: 1.25rem;
|
||
background: linear-gradient(120deg, var(--c-text) 45%, var(--c-accent) 130%);
|
||
background-clip: text;
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
color: transparent;
|
||
}
|
||
.contact-highlight h3:not(:first-child) { margin-top: 1.3rem; }
|
||
.contact-highlight p { margin: 0 0 0.3rem; }
|
||
.contact-highlight p:last-child { margin-bottom: 0; }
|
||
|
||
/* "Unterkategorien"-Beschriftung auf der Hauptkategorie-Seite — vorher reiner grauer
|
||
Kleinschrift-Text, kaum von Fließtext zu unterscheiden. Jetzt: Akzentfarbe statt Grau, ein
|
||
kleines Icon und zwei kurze Verlaufslinien links/rechts (dezenter "Trenner"-Look statt
|
||
auffälliger Balken), damit auf einen Blick klar ist: hier beginnt ein neuer Abschnitt. */
|
||
.section-label-sub {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0.6em;
|
||
font-size: 0.78rem;
|
||
letter-spacing: 0.16em;
|
||
text-transform: uppercase;
|
||
font-weight: 600;
|
||
color: var(--c-accent);
|
||
margin: 0 0 1rem;
|
||
}
|
||
.section-label-sub::before,
|
||
.section-label-sub::after {
|
||
content: "";
|
||
height: 1px;
|
||
width: clamp(1.6rem, 6vw, 3.2rem);
|
||
background: linear-gradient(90deg, transparent, var(--c-purple-glow), transparent);
|
||
opacity: 0.7;
|
||
}
|
||
|
||
/* Hauptkategorie-Überschrift zwischen den Unterkategorie-Chips und der eigentlichen
|
||
Produktreihe auf der Kategorie-Seite — macht klar, welche Hauptkategorie man gerade
|
||
durchstöbert. Deutlich kräftiger als die "Unterkategorien"-Beschriftung (größer, mit
|
||
Verlaufs-Icon-Kreis und einem schmalen Leucht-Trenner darunter), weil sie die eigentliche
|
||
Produktreihe einleitet — bewusst nicht übertrieben (kein neuer Farbton, keine Animation). */
|
||
.kategorie-section-label {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0.55em;
|
||
text-align: center;
|
||
font-size: 1.3rem;
|
||
color: var(--c-accent);
|
||
margin: 2.2rem 0 0;
|
||
}
|
||
/* Das Kategorie-Emoji steht frei neben der Überschrift — vorher saß es in einem farbigen
|
||
Kreis, der auf Wunsch entfernt wurde (der Kreis hat das Emoji eher eingesperrt als
|
||
hervorgehoben und passte nicht zum ruhigen Rest der Seite). */
|
||
.kategorie-section-label .label-icon {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 1.35rem;
|
||
line-height: 1;
|
||
}
|
||
.kategorie-section-label-rule {
|
||
height: 2px;
|
||
width: clamp(3.5rem, 16vw, 7rem);
|
||
margin: 0.9rem auto 1.3rem;
|
||
border-radius: 999px;
|
||
background: linear-gradient(90deg, transparent, var(--c-accent), var(--c-purple-glow), var(--c-sale), transparent);
|
||
opacity: 0.85;
|
||
}
|
||
@media (max-width: 800px) { .shop-layout { grid-template-columns: 1fr; } }
|
||
|
||
/* Produktseite — großes Bild bekommt denselben edlen "Rahmen"-Look wie die Porträtfotos der
|
||
Seite (dunkler Ring + Akzent-Leuchtrand), statt einfach randlos zu schweben. */
|
||
.product-detail { align-items: start; }
|
||
.product-hero {
|
||
aspect-ratio: 1/1;
|
||
border: 1px solid rgba(244, 241, 247, 0.08);
|
||
box-shadow:
|
||
var(--shadow-card),
|
||
0 0 0 6px rgba(10, 9, 16, 0.6),
|
||
0 0 0 7px color-mix(in srgb, var(--c-accent) 30%, transparent),
|
||
0 0 26px 2px color-mix(in srgb, var(--c-accent) 12%, transparent);
|
||
transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
|
||
}
|
||
.product-hero:hover {
|
||
transform: translateY(-3px);
|
||
box-shadow:
|
||
var(--shadow-card-hover),
|
||
0 0 0 6px rgba(10, 9, 16, 0.6),
|
||
0 0 0 7px color-mix(in srgb, var(--c-accent) 45%, transparent),
|
||
0 0 32px 4px color-mix(in srgb, var(--c-accent) 20%, transparent);
|
||
}
|
||
.thumb-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.7rem; margin-top: 0.9rem; }
|
||
.thumb {
|
||
aspect-ratio: 1/1;
|
||
min-height: 0;
|
||
border: 1px solid rgba(244, 241, 247, 0.08);
|
||
box-shadow: 0 0 0 3px rgba(10, 9, 16, 0.6), 0 0 0 4px rgba(244, 241, 247, 0.08);
|
||
}
|
||
.thumb.product-photo:hover { box-shadow: 0 0 0 3px rgba(10, 9, 16, 0.6), 0 0 0 4px var(--c-accent); }
|
||
.badge-row { display: flex; gap: 0.5rem; margin-bottom: 0.8rem; flex-wrap: wrap; }
|
||
|
||
/* Persönlicher Kundenbereich (/konto/angemeldet/) — Ansicht für angemeldete Kund:innen mit
|
||
Bestellhistorie, Sendungsverfolgung, Wunschliste und Profildaten. Nutzt durchgehend die
|
||
bestehende Karten-/Badge-Optik der Seite, damit sich nichts fremd anfühlt. */
|
||
/* Die Begrüßungs-Karte ganz oben im Kundenbereich darf ruhig "die Spezielle" sein — wandernder
|
||
Mehrfarb-Verlaufsrand, ein sanfter Farbschein im Hintergrund, ein leiser Glanz-Sweep, der
|
||
regelmäßig durchläuft, ein pulsierender Leucht-Ring um den Avatar und zwei funkelnde
|
||
Sternchen. Dieselbe Formsprache wie beim "Meine Daten"-Knopf, nur größer und ruhiger, damit
|
||
der Text weiterhin gut lesbar bleibt. */
|
||
.account-head {
|
||
position: relative;
|
||
overflow: hidden;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
gap: 1.5rem;
|
||
flex-wrap: wrap;
|
||
border: 1.5px solid transparent;
|
||
background:
|
||
linear-gradient(165deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(120deg, #9b7fd6, var(--c-accent), #e3b23c, var(--c-sale), #9b7fd6) border-box;
|
||
background-size: 100% 100%, 300% 100%;
|
||
animation: account-head-border-shift 9s ease-in-out infinite;
|
||
}
|
||
.account-head::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
background: radial-gradient(60% 90% at 10% 15%, color-mix(in srgb, #9b7fd6 22%, transparent), transparent 70%);
|
||
pointer-events: none;
|
||
}
|
||
.account-head::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
left: -60%;
|
||
width: 35%;
|
||
height: 100%;
|
||
background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.13), transparent);
|
||
transform: skewX(-18deg);
|
||
animation: account-head-shine 6s ease-in-out infinite;
|
||
pointer-events: none;
|
||
}
|
||
.account-head > * { position: relative; z-index: 1; }
|
||
.account-head-identity { display: flex; align-items: center; gap: 1rem; }
|
||
.account-head-actions { margin-left: auto; display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; }
|
||
/* Eigene volle Zeile unten in der Kopfkarte für den "Meine Daten"-Button — dank flex-wrap auf
|
||
.account-head bricht dieser 100%-breite Block automatisch in eine neue Zeile um, der Button
|
||
selbst bleibt rechtsbündig. Passt sich damit jeder Kartenhöhe an, ganz ohne absolute Positionierung. */
|
||
.account-head-daten-row { width: 100%; display: flex; justify-content: flex-end; margin-top: 0.9rem; }
|
||
.account-head h1 { margin: 0.2rem 0 0.5rem; }
|
||
.account-head .lead { margin: 0; max-width: 52ch; }
|
||
.account-head-sparkle {
|
||
position: absolute;
|
||
font-size: 0.9rem;
|
||
pointer-events: none;
|
||
z-index: 1;
|
||
}
|
||
.account-head-sparkle-1 { top: 1.1rem; right: 8.5rem; animation: account-nav-sparkle-twinkle 2.6s ease-in-out infinite; }
|
||
.account-head-sparkle-2 { bottom: 1.3rem; right: 3.2rem; font-size: 0.7rem; animation: account-nav-sparkle-twinkle 3.4s ease-in-out infinite 0.6s; }
|
||
@keyframes account-head-border-shift {
|
||
0%, 100% { background-position: 0 0, 0% 50%; }
|
||
50% { background-position: 0 0, 100% 50%; }
|
||
}
|
||
@keyframes account-head-shine {
|
||
0% { left: -60%; }
|
||
35%, 100% { left: 130%; }
|
||
}
|
||
/* Großer Avatar (Kopfzeile des Dashboards + Profil-Bereich) — gleiches Prinzip wie der kleine
|
||
Avatar im Header-Konto-Menü (Foto als Hintergrundbild, sonst erster Buchstabe des Namens). */
|
||
.account-avatar-lg {
|
||
width: 56px;
|
||
height: 56px;
|
||
border-radius: 50%;
|
||
background: linear-gradient(155deg, var(--c-accent), var(--c-purple));
|
||
background-size: cover;
|
||
background-position: center;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: var(--c-black);
|
||
font-size: 1.4rem;
|
||
font-weight: 800;
|
||
flex-shrink: 0;
|
||
}
|
||
.account-head-identity .account-avatar-lg {
|
||
width: 84px;
|
||
height: 84px;
|
||
font-size: 2.1rem;
|
||
animation: account-avatar-glow 3.6s ease-in-out infinite;
|
||
}
|
||
@media (max-width: 500px) { .account-head-identity .account-avatar-lg { width: 68px; height: 68px; font-size: 1.7rem; } }
|
||
@keyframes account-avatar-glow {
|
||
0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-accent) 35%, transparent), 0 0 16px -4px color-mix(in srgb, #9b7fd6 55%, transparent); }
|
||
50% { box-shadow: 0 0 0 3px color-mix(in srgb, #e3b23c 40%, transparent), 0 0 22px -2px color-mix(in srgb, #e3b23c 65%, transparent); }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.account-head, .account-head::after, .account-head-sparkle-1, .account-head-sparkle-2, .account-head-identity .account-avatar-lg {
|
||
animation: none;
|
||
}
|
||
}
|
||
@media (max-width: 500px) { .account-head-identity { flex-wrap: wrap; } }
|
||
/* Kontobereich-Schnellnavigation: statt drei einzelner, loser Kästchen EINE zusammenhängende
|
||
Leiste direkt über den zugehörigen Abschnitten — jedes Segment ist ein echter Filter-Knopf:
|
||
Klick zeigt NUR den passenden Bereich (Bestellungen/Wunschliste/nur offene Sendungen) und
|
||
blendet den Rest aus, mit eigener Akzentfarbe und Icon passend zur jeweiligen Abschnitts-
|
||
überschrift (📦/🩵/🚚 wie schon bei den Bestellstatus-Icons). Der aktive Knopf bleibt farbig
|
||
unterstrichen und hinterlegt, damit immer klar ist, welcher Filter gerade aktiv ist. */
|
||
.account-nav {
|
||
display: flex;
|
||
margin-top: 1.2rem;
|
||
border-radius: var(--radius-l);
|
||
overflow: hidden;
|
||
border: 1.5px solid rgba(244, 241, 247, 0.14);
|
||
background: linear-gradient(155deg, var(--c-anthracite-light), var(--c-anthracite));
|
||
box-shadow: 0 12px 28px -18px rgba(0, 0, 0, 0.65);
|
||
}
|
||
/* Alle vier Knöpfe haben jetzt dieselbe "besondere" Formsprache wie vorher nur "Meine Daten":
|
||
ein sanft wanderndes Mehrfarb-Verlaufslicht im eigenen Farbton, ein pulsierender Glanzrand
|
||
und ein funkelndes Sternchen — nur die Farbe unterscheidet sich pro Knopf (--nav-color).
|
||
Bewusst gedeckt genug, um nicht kitschig zu wirken, aber klar erkennbar "premium". */
|
||
.account-nav-item {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 0.2rem;
|
||
padding: 1.15rem 1rem;
|
||
text-decoration: none;
|
||
color: var(--c-text);
|
||
position: relative;
|
||
scroll-margin-top: 1.5rem;
|
||
transition: background 0.2s var(--ease);
|
||
/* Reset, da jetzt <button> statt <a> — soll optisch identisch bleiben. */
|
||
border-top: none;
|
||
border-right: none;
|
||
border-bottom: none;
|
||
background-color: transparent;
|
||
font: inherit;
|
||
cursor: pointer;
|
||
background-image: linear-gradient(
|
||
120deg,
|
||
color-mix(in srgb, var(--nav-color, var(--c-accent)) 20%, transparent),
|
||
color-mix(in srgb, var(--nav-color, var(--c-accent)) 8%, transparent),
|
||
color-mix(in srgb, var(--nav-color, var(--c-accent)) 20%, transparent)
|
||
);
|
||
background-size: 300% 100%;
|
||
animation: account-nav-item-shift 7s ease-in-out infinite, account-nav-item-glow 3.2s ease-in-out infinite;
|
||
animation-delay: var(--nav-delay, 0s);
|
||
}
|
||
.account-nav-item + .account-nav-item { border-left: 1px solid rgba(244, 241, 247, 0.12); }
|
||
.account-nav-item::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
height: 3px;
|
||
background: var(--nav-color, var(--c-accent));
|
||
transform: scaleX(0);
|
||
transition: transform 0.25s var(--ease);
|
||
}
|
||
.account-nav-item:hover { background-color: color-mix(in srgb, var(--nav-color, var(--c-accent)) 14%, transparent); }
|
||
.account-nav-item:hover::after, .account-nav-item:focus-visible::after { transform: scaleX(1); }
|
||
.account-nav-item.is-active { background-color: color-mix(in srgb, var(--nav-color, var(--c-accent)) 20%, transparent); }
|
||
.account-nav-item.is-active::after { transform: scaleX(1); }
|
||
.account-nav-icon { font-size: 1.35rem; }
|
||
.account-nav-value { font-family: var(--font-head); font-size: 1.7rem; font-weight: 700; color: var(--nav-color, var(--c-accent)); line-height: 1; }
|
||
.account-nav-label {
|
||
font-size: 0.82rem;
|
||
text-align: center;
|
||
font-weight: 700;
|
||
background-image: linear-gradient(90deg, var(--nav-color, var(--c-accent)), color-mix(in srgb, var(--nav-color, var(--c-accent)) 40%, #fff));
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
}
|
||
.account-nav-orders { --nav-color: #9b7fd6; --nav-delay: 0s; }
|
||
.account-nav-open { --nav-color: var(--c-accent); --nav-delay: 0.4s; }
|
||
.account-nav-wishlist { --nav-color: var(--c-sale); --nav-delay: 0.8s; }
|
||
.account-nav-loyalty { --nav-color: #6ecb8f; --nav-delay: 1.6s; }
|
||
/* Sobald der Treuebonus wirklich freigeschaltet ist (10/10), bekommt sein Knopf zusätzlich zur
|
||
normalen "Premium"-Optik noch einen kräftigeren, schneller pulsierenden Rahmen — soll auf
|
||
keinen Fall übersehen werden, wenn die Belohnung bereit ist. */
|
||
.account-nav-loyalty.is-ready { animation-duration: 1.4s, 1.1s; }
|
||
.account-nav-loyalty.is-ready::after { height: 4px; }
|
||
.account-nav-abo { --nav-color: #e3b23c; --nav-delay: 2s; }
|
||
.account-nav-abo.is-ready { animation-duration: 1.4s, 1.1s; }
|
||
.account-nav-abo.is-ready::after { height: 4px; }
|
||
|
||
/* Treuebonus-Fortschrittskarte im Inhaltsbereich — eigener grüner Farbton, sonst dieselbe
|
||
"besondere" Formsprache wie die anderen Konto-Karten (siehe .profile-card). */
|
||
.loyalty-card { position: relative; overflow: hidden; display: flex; flex-direction: column; gap: 0.9rem; }
|
||
.loyalty-inner { display: flex; flex-direction: column; gap: 0.9rem; }
|
||
/* Gesperrter Zustand ohne aktives Abo: soll bewusst NICHT ausgegraut/unattraktiv wirken (der
|
||
Treuebonus soll als Anreiz fürs Abo dienen), sondern klar als "gibt's schon, nur noch
|
||
freischalten" — daher derselbe Kartenrahmen wie im freigeschalteten Zustand, nur mit
|
||
Schloss-Titel in Gold (passend zur Abo-Farbwelt) und direktem Call-to-Action zum Abo. */
|
||
.loyalty-locked-title { margin: 0; font-weight: 800; font-size: 1.1rem; color: #e3b23c; }
|
||
.loyalty-progress-bar {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 12px;
|
||
border-radius: 999px;
|
||
background: rgba(244, 241, 247, 0.1);
|
||
overflow: hidden;
|
||
border: 1px solid rgba(244, 241, 247, 0.14);
|
||
}
|
||
.loyalty-progress-fill {
|
||
height: 100%;
|
||
width: 0%;
|
||
border-radius: 999px;
|
||
background: linear-gradient(90deg, #6ecb8f, #5fd3ec);
|
||
transition: width 0.5s var(--ease);
|
||
}
|
||
/* Balken + Ziel-Symbol als Reihe — das 🎁 sitzt bewusst AUSSERHALB des Balkens (statt per
|
||
::after am Rand), damit "overflow:hidden" (für die inneren Meilenstein-Punkte nötig) es nicht
|
||
anschneidet. */
|
||
.loyalty-progress-track { display: flex; align-items: center; gap: 0.5rem; }
|
||
.loyalty-progress-track .loyalty-progress-bar { flex: 1; }
|
||
.loyalty-progress-goal-icon { flex-shrink: 0; font-size: 1.05rem; }
|
||
/* Zehn Meilenstein-Striche im Balken selbst — machen "6 von 10" auf einen Blick als echte
|
||
Sammelkarte greifbar, statt nur eine abstrakte Prozent-Füllung zu zeigen. */
|
||
.loyalty-progress-dots { position: absolute; inset: 0; pointer-events: none; }
|
||
.loyalty-progress-dot {
|
||
position: absolute;
|
||
top: 0;
|
||
bottom: 0;
|
||
width: 2px;
|
||
background: rgba(10, 9, 16, 0.3);
|
||
transform: translateX(-50%);
|
||
}
|
||
.loyalty-progress-text { font-weight: 700; font-size: 1.05rem; margin: 0; }
|
||
.loyalty-explainer { color: var(--c-text-muted); margin: 0.4rem 0 0; }
|
||
.loyalty-last-redeemed { color: var(--c-text-muted); margin: -0.5rem 0 0; }
|
||
|
||
/* Stat-Kacheln (siehe .abo-stat-grid/.abo-stat-tile für die geteilte Basis) — die Treuebonus-
|
||
eigene Hervorhebungsfarbe ist Grün statt Gold, passend zum restlichen Treuebonus-Auftritt
|
||
(Fortschrittsbalken, Nav-Kachel, Stern). */
|
||
.loyalty-stat-tile-highlight { background: color-mix(in srgb, #6ecb8f 12%, transparent); border-color: color-mix(in srgb, #6ecb8f 38%, transparent); }
|
||
.loyalty-stat-tile-highlight .abo-stat-value { color: #6ecb8f; }
|
||
|
||
/* "Bonus bereit"-Karte — gleiches Prinzip wie .abo-reward-ready (leicht pulsierender Rahmen,
|
||
soll als "hier wartet was Kostenloses" auffallen), nur in Grün statt Gold. */
|
||
.loyalty-ready-block {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.9rem;
|
||
padding: 0.8rem 1.1rem;
|
||
border-radius: var(--radius-l);
|
||
background: linear-gradient(155deg, color-mix(in srgb, #6ecb8f 16%, var(--c-anthracite-light)), var(--c-anthracite));
|
||
border: 1.5px solid color-mix(in srgb, #6ecb8f 45%, transparent);
|
||
animation: loyalty-ready-glow 2.6s ease-in-out infinite;
|
||
}
|
||
@keyframes loyalty-ready-glow {
|
||
0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, #6ecb8f 35%, transparent), 0 0 14px -6px color-mix(in srgb, #6ecb8f 55%, transparent); }
|
||
50% { box-shadow: 0 0 0 1px color-mix(in srgb, #6ecb8f 55%, transparent), 0 0 22px -4px color-mix(in srgb, #6ecb8f 75%, transparent); }
|
||
}
|
||
.loyalty-ready-icon { font-size: 1.9rem; flex-shrink: 0; }
|
||
.loyalty-ready-body { display: flex; flex-direction: column; gap: 0.35rem; }
|
||
.loyalty-ready-body strong { font-size: 0.95rem; }
|
||
.loyalty-ready-body p { margin: 0; }
|
||
@media (prefers-reduced-motion: reduce) { .loyalty-ready-block { animation: none; } }
|
||
|
||
/* Kurze Sammel-Regeln als Icon-Liste statt Fließtext — schneller erfassbar. */
|
||
.loyalty-rules { list-style: none; margin: 0.2rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; font-size: 0.86rem; color: var(--c-text-muted); }
|
||
.loyalty-rules li { display: flex; align-items: flex-start; gap: 0.5em; }
|
||
.loyalty-card-sparkle { position: absolute; font-size: 0.85rem; pointer-events: none; z-index: 1; }
|
||
.loyalty-card-sparkle-1 { top: 1.1rem; right: 1.3rem; animation: account-nav-sparkle-twinkle 2.7s ease-in-out infinite; }
|
||
.loyalty-card-sparkle-2 { bottom: 1.2rem; left: 1.3rem; font-size: 0.7rem; animation: account-nav-sparkle-twinkle 3.5s ease-in-out infinite 0.5s; }
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.loyalty-card-sparkle-1, .loyalty-card-sparkle-2 { animation: none; }
|
||
}
|
||
|
||
/* Warenkorb: Treuebonus-Banner + Auswahl direkt an der betroffenen Zeile. */
|
||
.loyalty-banner {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.9rem;
|
||
border-radius: var(--radius-m);
|
||
border: 1.5px solid color-mix(in srgb, #6ecb8f 45%, transparent);
|
||
background: linear-gradient(120deg, color-mix(in srgb, #6ecb8f 20%, transparent), color-mix(in srgb, #5fd3ec 14%, transparent));
|
||
padding: 1rem 1.2rem;
|
||
margin-bottom: 1rem;
|
||
}
|
||
.loyalty-banner-icon { font-size: 1.6rem; flex-shrink: 0; }
|
||
.loyalty-banner strong { display: block; margin-bottom: 0.15em; }
|
||
.loyalty-banner p { margin: 0; color: var(--c-text-muted); font-size: 0.9rem; }
|
||
.loyalty-select {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.4em;
|
||
font-size: 0.82rem;
|
||
font-weight: 600;
|
||
color: var(--c-text-muted);
|
||
cursor: pointer;
|
||
white-space: nowrap;
|
||
}
|
||
.loyalty-select input { accent-color: #6ecb8f; width: auto; }
|
||
.cart-item.loyalty-selected { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, #6ecb8f 60%, transparent); border-radius: var(--radius-s); }
|
||
.loyalty-selected-badge { color: #6ecb8f; font-weight: 700; font-size: 0.82rem; white-space: nowrap; }
|
||
.account-nav-sparkle {
|
||
position: absolute;
|
||
top: 0.55rem;
|
||
right: 0.9rem;
|
||
font-size: 0.85rem;
|
||
animation: account-nav-sparkle-twinkle 2.4s ease-in-out infinite;
|
||
animation-delay: var(--nav-delay, 0s);
|
||
pointer-events: none;
|
||
/* Emoji-Glyphen lassen sich nicht per color: einfärben — ein farbiger Schein passend zur
|
||
jeweiligen Kistenfarbe (--nav-color) sorgt trotzdem dafür, dass jedes Funkeln sichtbar
|
||
"seine eigene" Farbe trägt, statt überall gleich neutral-gelb zu wirken. */
|
||
filter: drop-shadow(0 0 4px color-mix(in srgb, var(--nav-color, var(--c-accent)) 75%, transparent));
|
||
}
|
||
/* Abo UND Treuebonus sollen sich klar von den restlichen Kisten abheben — derselbe große,
|
||
kräftig leuchtende Stern (🌟 statt ✨) mit derselben "Premium"-Bewegung, ABER jede Kiste
|
||
färbt ihren eigenen Stern automatisch in ihrer eigenen --nav-color ein (Abo = Gold, Treue-
|
||
bonus = Grün) statt eines hartkodierten Farbtons — so bleibt der STIL identisch/"besonders",
|
||
nur die Farbe unterscheidet die beiden klar voneinander, ganz ohne Duplizierung der Regel. */
|
||
.account-nav-abo .account-nav-sparkle,
|
||
.account-nav-loyalty .account-nav-sparkle {
|
||
font-size: 1.15rem;
|
||
animation-name: abo-nav-sparkle-twinkle;
|
||
animation-duration: 1.8s;
|
||
filter: drop-shadow(0 0 7px color-mix(in srgb, var(--nav-color, #e3b23c) 85%, transparent)) drop-shadow(0 0 2px #fff);
|
||
}
|
||
@keyframes abo-nav-sparkle-twinkle {
|
||
0%, 100% { opacity: 0.55; transform: scale(0.85) rotate(-10deg); }
|
||
50% { opacity: 1; transform: scale(1.35) rotate(10deg); }
|
||
}
|
||
@keyframes account-nav-item-shift {
|
||
0%, 100% { background-position: 0% 50%; }
|
||
50% { background-position: 100% 50%; }
|
||
}
|
||
@keyframes account-nav-item-glow {
|
||
0%, 100% { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--nav-color, var(--c-accent)) 40%, transparent), 0 0 14px -6px color-mix(in srgb, var(--nav-color, var(--c-accent)) 55%, transparent); }
|
||
50% { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--nav-color, var(--c-accent)) 65%, transparent), 0 0 20px -4px color-mix(in srgb, var(--nav-color, var(--c-accent)) 75%, transparent); }
|
||
}
|
||
@keyframes account-nav-sparkle-twinkle {
|
||
0%, 100% { opacity: 0.35; transform: scale(0.8) rotate(-8deg); }
|
||
50% { opacity: 1; transform: scale(1.2) rotate(8deg); }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.account-nav-item { animation: none; }
|
||
.account-nav-sparkle { animation: none; }
|
||
}
|
||
@media (max-width: 560px) {
|
||
.account-nav { flex-direction: column; }
|
||
.account-nav-item + .account-nav-item { border-left: none; border-top: 1px solid rgba(244, 241, 247, 0.12); }
|
||
}
|
||
|
||
.order-list { display: flex; flex-direction: column; gap: 1.1rem; }
|
||
|
||
/* Aufklappbereich für Bestellungen, die älter als ein Monat sind (siehe konto/angemeldet.astro).
|
||
Bewusst zurückhaltend gestaltet: Es ist ein Archiv-Zugang, kein Hauptinhalt — soll die
|
||
aktuellen Bestellungen darüber nicht optisch überstrahlen. */
|
||
/* Steht bewusst GANZ OBEN im Bestellungen-Bereich, noch vor der neuesten Bestellung (siehe
|
||
konto/angemeldet.astro) — deshalb margin-bottom statt margin-top: der Abstand wird jetzt
|
||
VOR der ersten Bestellkarte gebraucht, nicht mehr danach. */
|
||
.order-archive { margin: 0.3rem 0 1.2rem; display: flex; flex-direction: column; gap: 0.9rem; }
|
||
.order-archive[hidden] { display: none; }
|
||
.order-archive-toggle {
|
||
align-self: flex-start;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.55em;
|
||
padding: 0.5em 1em;
|
||
border-radius: 999px;
|
||
border: 1px dashed rgba(244, 241, 247, 0.22);
|
||
background: transparent;
|
||
color: var(--c-text-muted);
|
||
font-family: inherit;
|
||
font-size: 0.88rem;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
transition: border-color 0.2s var(--ease), color 0.2s var(--ease), background 0.2s var(--ease);
|
||
}
|
||
.order-archive-toggle:hover {
|
||
border-color: var(--c-accent);
|
||
border-style: solid;
|
||
color: var(--c-text);
|
||
background: color-mix(in srgb, var(--c-accent) 10%, transparent);
|
||
}
|
||
.order-archive-icon { font-size: 1em; }
|
||
.order-archive-chevron { font-size: 0.7em; transition: transform 0.2s var(--ease); }
|
||
.order-archive.is-open .order-archive-chevron { transform: rotate(180deg); }
|
||
.order-archive-panel { display: flex; flex-direction: column; gap: 1.1rem; }
|
||
.order-archive-panel[hidden] { display: none; }
|
||
.order-archive-search { position: relative; display: flex; align-items: center; }
|
||
.order-archive-search-icon { position: absolute; left: 0.85em; font-size: 0.9rem; opacity: 0.6; pointer-events: none; }
|
||
.order-archive-search input {
|
||
width: 100%;
|
||
padding: 0.6em 0.9em 0.6em 2.4em;
|
||
border-radius: var(--radius-m);
|
||
border: 1px solid rgba(244, 241, 247, 0.14);
|
||
background: var(--c-anthracite-light);
|
||
color: var(--c-text);
|
||
font-family: inherit;
|
||
font-size: 0.92rem;
|
||
}
|
||
.order-archive-search input:focus-visible { outline: 2px solid var(--c-accent); outline-offset: 1px; }
|
||
.order-archive-nohits { color: var(--c-text-muted); margin: 0; }
|
||
.order-archive-nohits[hidden] { display: none; }
|
||
.order-card { display: flex; flex-direction: column; gap: 0.9rem; }
|
||
.order-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
|
||
.order-no { display: block; font-weight: 700; font-size: 1.02rem; }
|
||
.order-meta { color: var(--c-text-muted); }
|
||
|
||
/* Bestellstatus muss auf einen Blick klar unterscheidbar sein — "noch unterwegs" vs. "schon
|
||
angekommen" sind bewusst NICHT nur an der kleinen Textfarbe der Pille erkennbar, sondern an
|
||
der GANZEN Karte: eigene Randfarbe + dezenter Farbschein an der linken Kante + ein Icon direkt
|
||
in der Status-Pille. Genau wie bei den Zahlungskarten im Checkout (siehe .pay-card) — kräftig
|
||
genug, um sofort aufzufallen, aber gedeckt genug fürs dunkle Gesamtbild. */
|
||
.order-card { position: relative; border-left: 4px solid var(--status-color, rgba(244, 241, 247, 0.2)); }
|
||
.order-card::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
background: linear-gradient(90deg, color-mix(in srgb, var(--status-color, transparent) 14%, transparent), transparent 45%);
|
||
pointer-events: none;
|
||
border-radius: inherit;
|
||
}
|
||
.order-card > * { position: relative; z-index: 1; }
|
||
.order-card {
|
||
overflow: hidden;
|
||
animation: order-card-glow 3.6s ease-in-out infinite;
|
||
}
|
||
.order-card::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
left: -60%;
|
||
width: 30%;
|
||
height: 100%;
|
||
background: linear-gradient(100deg, transparent, color-mix(in srgb, var(--status-color, #fff) 16%, transparent), transparent);
|
||
transform: skewX(-18deg);
|
||
animation: account-head-shine 8s ease-in-out infinite;
|
||
pointer-events: none;
|
||
}
|
||
@keyframes order-card-glow {
|
||
0%, 100% { box-shadow: -2px 0 10px -6px color-mix(in srgb, var(--status-color, transparent) 50%, transparent); }
|
||
50% { box-shadow: -2px 0 16px -4px color-mix(in srgb, var(--status-color, transparent) 70%, transparent); }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) { .order-card, .order-card::after { animation: none; } }
|
||
|
||
.order-card-zahlungOffen { --status-color: #e08a3c; }
|
||
.order-card-bezahlt { --status-color: #9b7fd6; }
|
||
.order-card-bearbeitung { --status-color: #e3b23c; }
|
||
.order-card-versandVorbereitet { --status-color: #e3b23c; }
|
||
.order-card-versendet { --status-color: var(--c-accent); }
|
||
.order-card-abgeschlossen { --status-color: #7ec8a0; }
|
||
.order-card-storniert { --status-color: var(--c-sale); }
|
||
|
||
.order-status { display: inline-flex; align-items: center; gap: 0.4em; }
|
||
.order-status::before { font-size: 0.95em; }
|
||
.order-status-zahlungOffen::before { content: "⏳"; }
|
||
.order-status-bezahlt::before { content: "💳"; }
|
||
.order-status-bearbeitung::before { content: "⚙️"; }
|
||
.order-status-versandVorbereitet::before { content: "📦"; }
|
||
.order-status-versendet::before { content: "🚚"; }
|
||
.order-status-abgeschlossen::before { content: "✅"; }
|
||
.order-status-storniert::before { content: "❌"; }
|
||
|
||
.order-status-zahlungOffen { background: color-mix(in srgb, #e08a3c 30%, transparent); border-color: color-mix(in srgb, #e08a3c 55%, transparent); color: #ffd9ae; }
|
||
.order-status-bezahlt { background: color-mix(in srgb, #9b7fd6 32%, transparent); border-color: color-mix(in srgb, #9b7fd6 55%, transparent); color: #d9cdf5; }
|
||
.order-status-bearbeitung { background: color-mix(in srgb, #e3b23c 30%, transparent); border-color: color-mix(in srgb, #e3b23c 55%, transparent); color: #f6dda0; }
|
||
.order-status-versandVorbereitet { background: color-mix(in srgb, #e3b23c 30%, transparent); border-color: color-mix(in srgb, #e3b23c 55%, transparent); color: #f6dda0; }
|
||
.order-status-versendet { background: color-mix(in srgb, var(--c-accent) 34%, transparent); border-color: color-mix(in srgb, var(--c-accent) 55%, transparent); }
|
||
.order-status-abgeschlossen { background: rgba(126, 200, 160, 0.28); border-color: rgba(126, 200, 160, 0.5); color: #cfeee0; }
|
||
.order-status-storniert { background: color-mix(in srgb, var(--c-sale) 30%, transparent); border-color: color-mix(in srgb, var(--c-sale) 55%, transparent); color: #ffd7de; }
|
||
|
||
/* Status-Dropdown direkt in der Bestellkarte (Verwaltungsseite) — sofortiges Ändern ohne
|
||
separate Bearbeiten-Seite, mit kurzer "gespeichert"-Bestätigung statt stillem Erfolg. */
|
||
.verwaltung-status-edit { display: flex; align-items: center; gap: 0.6rem; }
|
||
.verwaltung-status-select {
|
||
padding: 0.4rem 0.7rem;
|
||
border-radius: var(--radius-s);
|
||
border: 1.5px solid rgba(244, 241, 247, 0.18);
|
||
background: var(--c-anthracite);
|
||
color: var(--c-text);
|
||
font-size: 0.85rem;
|
||
font-family: inherit;
|
||
}
|
||
.verwaltung-status-saved { color: #7ec8a0; font-weight: 600; white-space: nowrap; }
|
||
.order-items { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
|
||
.order-items li { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.95rem; color: var(--c-text-muted); }
|
||
.order-item-price { color: var(--c-text); white-space: nowrap; }
|
||
.order-item-right { display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap; }
|
||
.review-link { color: var(--c-accent); font-weight: 600; white-space: nowrap; }
|
||
.review-link:hover { text-decoration: underline; }
|
||
.review-done-badge { background: rgba(126, 200, 160, 0.28); border-color: rgba(126, 200, 160, 0.5); color: #cfeee0; white-space: nowrap; }
|
||
.order-card-foot { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; border-top: 1px dashed rgba(244, 241, 247, 0.14); padding-top: 0.9rem; }
|
||
.order-total { font-size: 1.05rem; }
|
||
.order-total strong { color: var(--c-accent); }
|
||
.order-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
|
||
.order-tracking-no { margin: 0; color: var(--c-text-muted); }
|
||
.order-tracking-no code { font-size: 0.9em; letter-spacing: 0.02em; }
|
||
|
||
/* Rechnung direkt auf der Seite ansehen (natives <dialog>) — kein Download nötig, öffnet sich
|
||
sofort als Overlay über der aktuellen Ansicht. */
|
||
.invoice-dialog {
|
||
border: none;
|
||
padding: 0;
|
||
background: transparent;
|
||
color: var(--c-text);
|
||
max-width: min(94vw, 580px);
|
||
width: 100%;
|
||
}
|
||
.invoice-dialog::backdrop { background: rgba(6, 5, 10, 0.75); backdrop-filter: blur(3px); }
|
||
.invoice-card {
|
||
background: linear-gradient(165deg, var(--c-anthracite-light), var(--c-anthracite));
|
||
border: 1.5px solid rgba(244, 241, 247, 0.16);
|
||
border-radius: var(--radius-l);
|
||
padding: 1.8rem;
|
||
max-height: 85vh;
|
||
overflow-y: auto;
|
||
box-shadow: var(--shadow-card);
|
||
}
|
||
.invoice-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; margin-bottom: 1rem; }
|
||
.invoice-head h3 { margin: 0; }
|
||
.invoice-meta { margin: 0.3rem 0 0; font-size: 0.88rem; color: var(--c-text-muted); }
|
||
.invoice-close {
|
||
background: none;
|
||
border: 1px solid rgba(244, 241, 247, 0.2);
|
||
border-radius: 50%;
|
||
width: 32px;
|
||
height: 32px;
|
||
color: var(--c-text);
|
||
cursor: pointer;
|
||
flex-shrink: 0;
|
||
font-size: 1.1rem;
|
||
line-height: 1;
|
||
}
|
||
.invoice-close:hover { border-color: var(--c-accent); color: var(--c-accent); }
|
||
.invoice-parties { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; margin: 1.3rem 0; }
|
||
.invoice-parties h4 { margin: 0 0 0.35em; font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--c-accent); }
|
||
.invoice-parties p { margin: 0; font-size: 0.9rem; color: var(--c-text-muted); line-height: 1.55; }
|
||
@media (max-width: 480px) { .invoice-parties { grid-template-columns: 1fr; } }
|
||
.invoice-table { width: 100%; border-collapse: collapse; margin-top: 0.6rem; }
|
||
.invoice-table th, .invoice-table td { text-align: left; padding: 0.55em 0.35em; border-bottom: 1px solid rgba(244, 241, 247, 0.1); font-size: 0.9rem; }
|
||
.invoice-table th { color: var(--c-text-muted); font-weight: 600; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; }
|
||
.invoice-table th:last-child, .invoice-table td:last-child,
|
||
.invoice-table th:nth-child(2), .invoice-table td:nth-child(2),
|
||
.invoice-table th:nth-child(3), .invoice-table td:nth-child(3) { text-align: right; }
|
||
.invoice-total-row td { font-weight: 700; color: var(--c-accent); border-bottom: none; padding-top: 0.8em; font-size: 1rem; }
|
||
.invoice-vat-note { margin: 1.1rem 0 0; font-size: 0.8rem; color: var(--c-text-muted); }
|
||
.invoice-foot { display: flex; justify-content: flex-end; margin-top: 1.4rem; }
|
||
/* "Meine Daten" ist der persönlichste Bereich im Kundenkonto — bekommt deshalb dieselbe
|
||
"mega besondere" Behandlung wie die Begrüßungs-Karte ganz oben: wandernder Mehrfarb-
|
||
Verlaufsrand, sanfter Farbschein, ein durchlaufender Glanz-Sweep und funkelnde Sternchen. */
|
||
.profile-card {
|
||
position: relative;
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
gap: 1.3rem;
|
||
border: 1.5px solid transparent;
|
||
background:
|
||
linear-gradient(165deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(120deg, #e3b23c, var(--c-sale), #9b7fd6, var(--c-accent), #e3b23c) border-box;
|
||
background-size: 100% 100%, 300% 100%;
|
||
animation: account-head-border-shift 10s ease-in-out infinite;
|
||
}
|
||
.profile-card::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
background: radial-gradient(60% 90% at 90% 10%, color-mix(in srgb, #e3b23c 20%, transparent), transparent 70%);
|
||
pointer-events: none;
|
||
}
|
||
.profile-card::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
left: -60%;
|
||
width: 35%;
|
||
height: 100%;
|
||
background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.12), transparent);
|
||
transform: skewX(-18deg);
|
||
animation: account-head-shine 7s ease-in-out infinite 1s;
|
||
pointer-events: none;
|
||
}
|
||
.profile-card > * { position: relative; z-index: 1; }
|
||
.profile-card .specs { margin-top: 0; width: 100%; }
|
||
.profile-card-sparkle { position: absolute; font-size: 0.85rem; pointer-events: none; z-index: 1; }
|
||
.profile-card-sparkle-1 { top: 1.1rem; right: 1.3rem; animation: account-nav-sparkle-twinkle 2.8s ease-in-out infinite; }
|
||
.profile-card-sparkle-2 { bottom: 1.2rem; left: 1.3rem; font-size: 0.7rem; animation: account-nav-sparkle-twinkle 3.6s ease-in-out infinite 0.7s; }
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.profile-card, .profile-card::after, .profile-card-sparkle-1, .profile-card-sparkle-2 { animation: none; }
|
||
}
|
||
.profile-photo-row { display: flex; align-items: center; gap: 1.1rem; }
|
||
.profile-photo-btn { display: inline-block; cursor: pointer; }
|
||
.profile-field { display: flex; flex-direction: column; gap: 0.4rem; }
|
||
.profile-field label { font-size: 0.85rem; color: var(--c-text-muted); }
|
||
.profile-field-row { display: flex; gap: 0.6rem; }
|
||
.profile-field-row input { flex: 1; }
|
||
|
||
/* DSGVO-Selbstbedienung (Art. 15/17/20) — nur bei echter Server-Sitzung eingeblendet, siehe
|
||
istEchteSitzung in angemeldet.astro. */
|
||
.profile-dsgvo-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.7rem; margin-top: 1.2rem; padding-top: 1.2rem; border-top: 1px solid rgba(255, 255, 255, 0.12); }
|
||
.profile-dsgvo-actions #dsgvo-delete-btn { color: var(--c-sale); border-color: var(--c-sale); }
|
||
|
||
/* Kundenrezensionen — Herzen in Lila-Babyblau statt Sterne (siehe HeartRating.astro), damit
|
||
Bewertungen sich erkennbar in die restliche Seite einfügen statt wie ein fremdes Bewertungs-
|
||
Widget zu wirken. */
|
||
.review-summary-link { display: inline-flex; text-decoration: none; margin: 0.3rem 0 0.9rem; }
|
||
.review-summary-link:hover .heart-value { color: var(--c-accent); }
|
||
.review-summary-row { margin-bottom: 1.6rem; }
|
||
.review-list { display: flex; flex-direction: column; gap: 1rem; }
|
||
.review-card { gap: 0.5rem; display: flex; flex-direction: column; }
|
||
.review-card-head { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; }
|
||
.review-name { font-weight: 700; }
|
||
.review-date { color: var(--c-text-muted); margin-left: auto; }
|
||
.review-card p { color: var(--c-text-muted); }
|
||
|
||
/* Bewertungsformular auf der Produktseite — eigene Karte unter der Rezensionsliste, gleicher
|
||
.frm-Look (Formularfelder) wie Kontakt-/Login-Formulare der Seite. */
|
||
.review-form-card { margin-top: 1.6rem; }
|
||
.review-form-card h3 { margin-top: 0; }
|
||
.review-form-card form { display: flex; flex-direction: column; gap: 1rem; margin-top: 1rem; }
|
||
.review-form-card label { display: block; font-size: 0.85rem; color: var(--c-text-muted); margin-bottom: 0.4rem; }
|
||
.review-form-card input[type="text"],
|
||
.review-form-card textarea {
|
||
width: 100%;
|
||
background: var(--c-anthracite);
|
||
color: var(--c-text);
|
||
border: 1px solid rgba(244, 241, 247, 0.15);
|
||
border-radius: var(--radius-s);
|
||
padding: 0.6em 0.8em;
|
||
font-family: inherit;
|
||
font-size: 0.95rem;
|
||
resize: vertical;
|
||
}
|
||
.review-form-row { display: flex; flex-direction: column; gap: 0.4rem; }
|
||
.review-form-label { font-size: 0.85rem; color: var(--c-text-muted); }
|
||
.review-login-note, .review-order-note { color: var(--c-text-muted); }
|
||
.review-order-note { color: var(--c-accent); font-weight: 600; }
|
||
|
||
/* Klickbare Herzen-Auswahl im Formular — größer als die Anzeige-Herzen, deutlich als Steuerelement
|
||
erkennbar (Hand-Cursor, sanftes Aufskalieren bei Hover). */
|
||
.heart-picker { display: inline-flex; gap: 0.2em; }
|
||
.heart-pick {
|
||
background: none;
|
||
border: none;
|
||
padding: 0.1em;
|
||
cursor: pointer;
|
||
line-height: 0;
|
||
transition: transform 0.15s var(--ease);
|
||
}
|
||
.heart-pick:hover { transform: scale(1.15); }
|
||
/* Bewertungszeile auf der Produktkarte — dicht unter dem Titel, kein zusätzlicher Abstand nötig,
|
||
da .product-card schon einen einheitlichen gap zwischen allen Kindern hat. */
|
||
.product-card .heart-rating { margin-top: -0.2rem; }
|
||
|
||
.price-row-detail { display: flex; align-items: baseline; gap: 0.8rem; margin-bottom: 0.2rem; flex-wrap: wrap; }
|
||
.price-detail { font-size: 1.8rem; font-weight: 700; color: var(--c-accent); }
|
||
/* Durchgestrichener alter Preis bei Rabatt — global, damit das auch auf der Produktseite gilt
|
||
(ProductCard.astro hatte die gleiche Regel bereits scoped, hier fehlte sie sitesweit). */
|
||
.price-old { color: var(--c-text-muted); text-decoration: line-through; font-size: 1.1rem; }
|
||
.badge-rabatt { background: #ff5f7e; color: #fff; border-color: #ff5f7e; }
|
||
.mengenrabatt-list { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5em; }
|
||
.mengenrabatt-list li {
|
||
background: color-mix(in srgb, #ff5f7e 14%, transparent);
|
||
border: 1px solid color-mix(in srgb, #ff5f7e 35%, transparent);
|
||
color: #ff5f7e;
|
||
border-radius: var(--radius-s);
|
||
padding: 0.25em 0.6em;
|
||
font-weight: 600;
|
||
}
|
||
/* flex-wrap: falls der "In den Warenkorb"-Button mal langen Text bekommt (z.B. Lagerbestand-
|
||
Hinweise), soll er in eine neue Zeile umbrechen statt die Mengen-Steuerung daneben zu
|
||
verdecken. */
|
||
.qty-row { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; margin: 1.4rem 0 0.5rem; }
|
||
.qty-row .qty-stepper { flex-shrink: 0; }
|
||
|
||
/* Große, leicht zu treffende Mengen-Steuerung auf der Produktseite (ersetzt die winzigen
|
||
Browser-Standard-Pfeile eines <input type="number">). */
|
||
.qty-stepper {
|
||
display: flex;
|
||
align-items: center;
|
||
border: 1px solid rgba(244, 241, 247, 0.16);
|
||
border-radius: 999px;
|
||
background: var(--c-anthracite);
|
||
overflow: hidden;
|
||
}
|
||
.qty-stepper button {
|
||
width: 44px;
|
||
height: 44px;
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--c-text);
|
||
font-size: 1.3rem;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
transition: background 0.15s var(--ease), color 0.15s var(--ease);
|
||
flex-shrink: 0;
|
||
}
|
||
.qty-stepper button:hover { background: color-mix(in srgb, var(--c-accent) 18%, transparent); color: var(--c-accent); }
|
||
.qty-stepper input {
|
||
width: 3rem;
|
||
height: 44px;
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--c-text);
|
||
text-align: center;
|
||
font-size: 1.05rem;
|
||
font-weight: 700;
|
||
-moz-appearance: textfield;
|
||
}
|
||
.qty-stepper input::-webkit-outer-spin-button,
|
||
.qty-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
|
||
/* Kein echtes outline (würde durch das runde .qty-stepper-Gehäuse eckig herausragen), aber
|
||
deswegen NICHT ersatzlos entfernt (WCAG 2.4.7 "Focus Visible") — stattdessen ein innen
|
||
liegender Ring per box-shadow, der sich sauber an die abgerundete Form anschmiegt. */
|
||
.qty-stepper input:focus {
|
||
outline: none;
|
||
box-shadow: inset 0 0 0 2px var(--c-accent);
|
||
}
|
||
.specs { margin-top: 1.5rem; }
|
||
.specs th { width: 40%; color: var(--c-text-muted); font-weight: 500; font-family: var(--font-body); }
|
||
|
||
/* FAQ */
|
||
.faq-list { display: grid; gap: 1rem; max-width: 760px; }
|
||
.faq-item summary { cursor: pointer; font-family: var(--font-head); font-weight: 600; color: var(--c-text); list-style: none; display: block; }
|
||
.faq-item summary::-webkit-details-marker { display: none; }
|
||
.faq-item summary::before { content: "+ "; color: var(--c-accent); }
|
||
.faq-item[open] summary::before { content: "- "; }
|
||
.faq-item p { margin-top: 0.8rem; margin-bottom: 0; }
|
||
|
||
/* Kontakt */
|
||
.contact-layout { align-items: start; }
|
||
|
||
/* Warenkorb */
|
||
.cart-layout { display: grid; grid-template-columns: 1fr 340px; gap: 2rem; align-items: start; }
|
||
.cart-item {
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 1.1rem;
|
||
padding: 1.1rem 0.4rem;
|
||
transition: background 0.2s var(--ease);
|
||
border-radius: var(--radius-s);
|
||
}
|
||
.cart-item:hover { background: rgba(244, 241, 247, 0.02); }
|
||
|
||
/* Trennung zwischen Warenkorb-Positionen als kleines "Knopf an der Naht"-Detail statt einer
|
||
nüchternen Linie — fließender Verlauf in den drei Marken-Farben (wie der Karten-Rand der
|
||
Seite), mit einem kleinen glänzenden Knopf in der Mitte als Anspielung auf's Nähen/Basteln.
|
||
Bleibt dezent (schmal, sanftes Leuchten) statt aufdringlich. */
|
||
.cart-item:not(:last-child)::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0.4rem;
|
||
right: 0.4rem;
|
||
bottom: 0;
|
||
height: 1.5px;
|
||
background: linear-gradient(
|
||
90deg,
|
||
transparent,
|
||
var(--c-accent) 15%,
|
||
var(--c-purple-glow) 50%,
|
||
var(--c-sale) 85%,
|
||
transparent
|
||
);
|
||
opacity: 0.75;
|
||
}
|
||
.cart-item:not(:last-child)::before {
|
||
content: "";
|
||
position: absolute;
|
||
left: 50%;
|
||
bottom: -4px;
|
||
z-index: 1;
|
||
width: 9px;
|
||
height: 9px;
|
||
border-radius: 50%;
|
||
transform: translateX(-50%);
|
||
background: radial-gradient(circle at 35% 30%, #fff, var(--c-accent) 45%, var(--c-purple-glow) 100%);
|
||
box-shadow: 0 0 9px 2px color-mix(in srgb, var(--c-purple-glow) 55%, transparent);
|
||
}
|
||
|
||
/* Checkbox "jetzt kaufen" — abgewählte Artikel bleiben sichtbar im Warenkorb liegen, zählen aber
|
||
nicht mehr zur Summe/zum Checkout, bis sie wieder angehakt werden. */
|
||
.cart-item .buy-toggle {
|
||
appearance: none;
|
||
width: 21px;
|
||
height: 21px;
|
||
border-radius: 6px;
|
||
border: 2px solid rgba(244, 241, 247, 0.3);
|
||
flex-shrink: 0;
|
||
display: grid;
|
||
place-content: center;
|
||
cursor: pointer;
|
||
transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
|
||
}
|
||
.cart-item .buy-toggle::before {
|
||
content: "";
|
||
width: 12px;
|
||
height: 12px;
|
||
clip-path: polygon(14% 44%, 0 65%, 45% 100%, 100% 16%, 80% 0%, 43% 68%);
|
||
transform: scale(0);
|
||
transition: transform 0.15s var(--ease);
|
||
background: #08181c;
|
||
}
|
||
.cart-item .buy-toggle:checked {
|
||
border-color: var(--c-accent);
|
||
background: linear-gradient(135deg, var(--c-accent), var(--c-accent-hover));
|
||
}
|
||
.cart-item .buy-toggle:checked::before { transform: scale(1); }
|
||
.cart-item.deselected { opacity: 0.55; }
|
||
.cart-item.deselected:hover { opacity: 0.8; }
|
||
.kept-in-cart-badge { color: var(--c-text-muted); margin-top: 0.15rem; }
|
||
.cart-item .thumb {
|
||
width: 76px;
|
||
height: 76px;
|
||
flex-shrink: 0;
|
||
border-radius: var(--radius-m);
|
||
overflow: hidden;
|
||
border: 1px solid rgba(244, 241, 247, 0.1);
|
||
box-shadow: 0 3px 10px -3px rgba(0, 0, 0, 0.5);
|
||
}
|
||
.cart-item .thumb.img-placeholder { font-size: 0.6rem; padding: 0.3rem; min-height: 0; }
|
||
.cart-item .info { flex: 1; min-width: 0; }
|
||
.cart-item .info strong { display: block; font-family: var(--font-head); font-size: 1rem; margin-bottom: 0.2rem; }
|
||
.cart-item .info .small { color: var(--c-text-muted); }
|
||
.cart-item .qty-controls {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0;
|
||
border: 1px solid rgba(244, 241, 247, 0.14);
|
||
border-radius: 999px;
|
||
overflow: hidden;
|
||
background: var(--c-anthracite);
|
||
flex-shrink: 0;
|
||
}
|
||
.cart-item .qty-controls button {
|
||
width: 30px;
|
||
height: 30px;
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--c-text);
|
||
font-size: 1rem;
|
||
cursor: pointer;
|
||
transition: background 0.15s var(--ease), color 0.15s var(--ease);
|
||
}
|
||
.cart-item .qty-controls button:hover { background: color-mix(in srgb, var(--c-accent) 18%, transparent); color: var(--c-accent); }
|
||
.cart-item .qty-controls span { min-width: 1.6em; text-align: center; font-weight: 600; font-size: 0.92rem; }
|
||
.cart-item .line-total { min-width: 5.5em; text-align: right; font-weight: 700; color: var(--c-text); flex-shrink: 0; }
|
||
.cart-item .remove {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.3em;
|
||
color: var(--c-text-muted);
|
||
font-size: 0.78rem;
|
||
margin-left: 0.4rem;
|
||
flex-shrink: 0;
|
||
transition: color 0.15s var(--ease);
|
||
}
|
||
.cart-item .remove:hover { color: var(--c-sale); }
|
||
.summary-row { display: flex; justify-content: space-between; margin: 0.55rem 0; font-size: 0.92rem; color: var(--c-text-muted); }
|
||
.summary-row.total { color: var(--c-text); font-weight: 700; font-size: 1.2rem; margin-top: 0.3rem; }
|
||
.cart-summary h3 { display: flex; align-items: center; gap: 0.5em; }
|
||
.ship-country-row { display: flex; align-items: center; justify-content: space-between; gap: 0.6em; margin: 0.6rem 0; font-size: 0.85rem; color: var(--c-text-muted); }
|
||
.ship-country-row label { display: flex; align-items: center; gap: 0.4em; white-space: nowrap; }
|
||
.ship-country-row select {
|
||
background: var(--c-anthracite);
|
||
color: var(--c-text);
|
||
border: 1px solid rgba(244, 241, 247, 0.16);
|
||
border-radius: var(--radius-s);
|
||
padding: 0.35em 0.6em;
|
||
font-size: 0.85rem;
|
||
cursor: pointer;
|
||
}
|
||
.ship-country-row select:focus { outline: none; border-color: var(--c-accent); }
|
||
.free-shipping-badge {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.5em;
|
||
margin: 0.7rem 0;
|
||
padding: 0.6em 0.9em;
|
||
border-radius: var(--radius-s);
|
||
background: color-mix(in srgb, var(--c-accent) 12%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--c-accent) 35%, transparent);
|
||
color: var(--c-accent);
|
||
font-size: 0.85rem;
|
||
font-weight: 600;
|
||
}
|
||
.discount-row { color: #ff5f7e; font-weight: 600; }
|
||
.mengenrabatt-badge { color: #ff5f7e; font-weight: 600; margin-top: 0.15rem; }
|
||
.coupon-row { margin: 0.7rem 0; }
|
||
.coupon-row label { display: block; font-size: 0.85rem; color: var(--c-text-muted); margin-bottom: 0.35em; }
|
||
.coupon-input-group { display: flex; gap: 0.5em; }
|
||
.coupon-input-group input {
|
||
flex: 1;
|
||
min-width: 0;
|
||
background: var(--c-anthracite);
|
||
color: var(--c-text);
|
||
border: 1px solid rgba(244, 241, 247, 0.16);
|
||
border-radius: var(--radius-s);
|
||
padding: 0.5em 0.7em;
|
||
font-size: 0.88rem;
|
||
}
|
||
.coupon-input-group input:focus { outline: none; border-color: var(--c-accent); }
|
||
.btn-sm { padding: 0.5em 0.9em; font-size: 0.85rem; white-space: nowrap; }
|
||
#coupon-status { margin-top: 0.4em; color: var(--c-accent); }
|
||
#coupon-status a { color: var(--c-text-muted); margin-left: 0.5em; }
|
||
#coupon-status a:hover { color: var(--c-sale); }
|
||
@media (max-width: 800px) { .cart-layout { grid-template-columns: 1fr; } }
|
||
|
||
/* Checkout */
|
||
.checkout-layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 2rem; align-items: start; }
|
||
/* Das Checkout-Formular soll die volle Spaltenbreite ausnutzen — .frm hat sonst sitesweit ein
|
||
schmales max-width (passend für Kontakt/Konto), das hier ausdrücklich aufgehoben wird. */
|
||
#checkout-form { max-width: none; }
|
||
|
||
/* "1. Zahlungsart" und "2. Kontakt & Lieferadresse" nebeneinander statt gestapelt, getrennt
|
||
durch eine dezente Verlaufslinie mit kleinem Garnrollen-Symbol in der Mitte — spielt auf
|
||
"Bastelbedarf" an (wie eine Naht zwischen zwei Stoffteilen), bleibt aber ruhig & professionell. */
|
||
.checkout-split { display: grid; grid-template-columns: 1fr auto 1fr; gap: 1.7rem; align-items: start; }
|
||
.checkout-split-col h3:first-child { margin-top: 0; }
|
||
.checkout-split-divider {
|
||
align-self: stretch;
|
||
position: relative;
|
||
width: 30px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.checkout-split-divider::before {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0.2rem;
|
||
bottom: 0.2rem;
|
||
left: 50%;
|
||
width: 1px;
|
||
background: linear-gradient(
|
||
180deg,
|
||
transparent,
|
||
color-mix(in srgb, var(--c-accent) 55%, transparent) 12%,
|
||
color-mix(in srgb, var(--c-purple-glow) 55%, transparent) 50%,
|
||
color-mix(in srgb, var(--c-accent) 55%, transparent) 88%,
|
||
transparent
|
||
);
|
||
}
|
||
.checkout-split-divider span {
|
||
position: relative;
|
||
z-index: 1;
|
||
width: 30px;
|
||
height: 30px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: var(--c-anthracite);
|
||
border: 1px solid color-mix(in srgb, var(--c-accent) 45%, transparent);
|
||
box-shadow: 0 0 12px -2px color-mix(in srgb, var(--c-accent) 45%, transparent);
|
||
font-size: 0.95rem;
|
||
}
|
||
/* WICHTIG: deutlich HÖHERER Umbruchpunkt als .checkout-layout (800px, siehe unten) — nicht
|
||
derselbe. Grund: .checkout-layout ist bereits eine Zweispalte (Formular | Zusammenfassung),
|
||
.checkout-split spaltet das FORMULAR selbst nochmal in zwei Spalten (Zahlung | Versand).
|
||
Zwei verschachtelte Zweispalten-Layouts brauchen zusammen deutlich mehr Platz als eine
|
||
einzelne — bei gleichem oder zu niedrigem Umbruchpunkt bleibt eine breite Zone (ca. 800–
|
||
1000px), in der die äußere Spalte noch nicht umbricht, aber schon nicht mehr genug Platz für
|
||
die innere Zweispalte übrig ist: die Zahlungskarte wurde dort auf ca. 90px zusammengequetscht.
|
||
Gefunden beim Testen der neuen PayPal-Kachel, betraf aber die ganze Zahlungsspalte. Deshalb
|
||
bricht die innere Spalte JETZT schon deutlich früher (bei 1024px) um, lange bevor die äußere
|
||
Spalte überhaupt eng wird. */
|
||
@media (max-width: 1024px) {
|
||
.checkout-split { grid-template-columns: 1fr; gap: 0; }
|
||
.checkout-split-divider { width: auto; min-height: 0; height: 44px; margin: 0.2rem 0; }
|
||
.checkout-split-divider::before { top: 50%; bottom: auto; left: 0.2rem; right: 0.2rem; width: auto; height: 1px; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--c-accent) 55%, transparent), transparent); }
|
||
}
|
||
|
||
/* Sidebar (Gutschein + Versandhinweis): dezenter Akzentstreifen links + "genähte" gestrichelte
|
||
Trennung zwischen den beiden Blöcken statt einer nüchternen durchgezogenen Linie. */
|
||
.checkout-aside { position: relative; padding-left: 1.9rem; }
|
||
.checkout-aside::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 1.5rem;
|
||
bottom: 1.5rem;
|
||
left: 1.05rem;
|
||
width: 3px;
|
||
border-radius: 2px;
|
||
background: linear-gradient(180deg, var(--c-accent), var(--c-purple-glow) 55%, var(--c-sale));
|
||
opacity: 0.85;
|
||
}
|
||
.checkout-aside .coupon-row label { font-weight: 700; color: var(--c-text); font-size: 0.95rem; }
|
||
.checkout-aside h3 { display: flex; align-items: center; gap: 0.5em; margin-bottom: 0.5em; }
|
||
.checkout-aside hr.stitched {
|
||
border: none;
|
||
border-top: 1.5px dashed rgba(244, 241, 247, 0.22);
|
||
margin: 1.2rem 0;
|
||
}
|
||
|
||
/* Zahlungsart als richtige, klickbare Auswahlkarten statt Standard-Radiobuttons — passend zum
|
||
restlichen "Karten mit Verlaufsrand"-Stil der Seite (siehe .card). Jede Karte klappt SOFORT
|
||
beim Anklicken den passenden "Verbinden"-Bereich direkt in sich selbst auf (reines CSS über
|
||
:has(), kein Zwischenschritt, kein separates Panel weiter unten). */
|
||
.payment-options { display: grid; gap: 0.85rem; }
|
||
/* Kräftigere Markenfarbigkeit pro Karte, auch im Ruhezustand (nicht erst bei Hover/Auswahl):
|
||
ein sanfter Farbschein aus der Ecke ("Glow"), ein feiner Farbstreifen oben und ein dezenter
|
||
Glanz-Sweep beim Hover — bewusst schon deutlich sichtbar, aber gedeckt genug fürs dunkle
|
||
Gesamtbild, kein grelles Regenbogen-Grid. */
|
||
.pay-card {
|
||
position: relative;
|
||
isolation: isolate;
|
||
border: 1.5px solid color-mix(in srgb, var(--brand-color, var(--c-accent)) 38%, rgba(244, 241, 247, 0.14));
|
||
border-radius: var(--radius-l);
|
||
background:
|
||
radial-gradient(130% 160% at 0% 0%, color-mix(in srgb, var(--brand-color, var(--c-accent)) 26%, transparent), transparent 62%),
|
||
linear-gradient(155deg, var(--c-anthracite), color-mix(in srgb, var(--c-anthracite) 85%, #000));
|
||
box-shadow: 0 8px 20px -14px color-mix(in srgb, var(--brand-color, var(--c-accent)) 60%, transparent);
|
||
transition: border-color 0.2s var(--ease), background 0.25s var(--ease), box-shadow 0.25s var(--ease), transform 0.2s var(--ease);
|
||
overflow: hidden;
|
||
}
|
||
.pay-card::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0 0 auto 0;
|
||
height: 3px;
|
||
background: linear-gradient(90deg, transparent, var(--brand-color, var(--c-accent)), transparent);
|
||
opacity: 0.65;
|
||
z-index: 1;
|
||
}
|
||
.pay-card::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
left: -60%;
|
||
width: 40%;
|
||
height: 100%;
|
||
background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.16), transparent);
|
||
transform: skewX(-18deg);
|
||
transition: left 0.65s ease;
|
||
pointer-events: none;
|
||
z-index: 1;
|
||
}
|
||
.pay-card:hover::after { left: 130%; }
|
||
.pay-card:hover {
|
||
border-color: color-mix(in srgb, var(--brand-color, var(--c-accent)) 70%, transparent);
|
||
transform: translateY(-3px);
|
||
box-shadow: 0 16px 30px -14px color-mix(in srgb, var(--brand-color, var(--c-accent)) 70%, transparent);
|
||
}
|
||
.pay-card:has(input:checked) {
|
||
border-color: var(--brand-color, var(--c-accent));
|
||
background:
|
||
radial-gradient(130% 160% at 0% 0%, color-mix(in srgb, var(--brand-color, var(--c-accent)) 38%, transparent), transparent 62%),
|
||
linear-gradient(155deg, color-mix(in srgb, var(--brand-color, var(--c-accent)) 20%, var(--c-anthracite)), color-mix(in srgb, var(--c-anthracite) 85%, #000));
|
||
box-shadow: 0 0 0 1.5px var(--brand-color, var(--c-accent)), 0 18px 34px -12px color-mix(in srgb, var(--brand-color, var(--c-accent)) 78%, transparent);
|
||
}
|
||
.pay-card:has(input:checked)::before { opacity: 1; }
|
||
.pay-card:has(input:checked) .pay-option span:not(.pay-icon) { color: var(--brand-color, var(--c-accent)); }
|
||
|
||
.pay-option {
|
||
position: relative;
|
||
z-index: 2;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 1.1em;
|
||
padding: 1.15em 1.3em;
|
||
font-size: 1.02rem;
|
||
font-weight: 700;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* Icon-Badge im echten Markenlogo-Stil (farbige Kachel + Wortmarke) statt schlichtem Emoji —
|
||
groß und mit sanftem Verlauf/Glanz, wirkt "fertig", nicht wie ein Platzhalter. */
|
||
.pay-option .pay-icon {
|
||
width: 52px;
|
||
height: 52px;
|
||
border-radius: 14px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 1.6rem;
|
||
font-weight: 800;
|
||
font-style: italic;
|
||
letter-spacing: -0.03em;
|
||
line-height: 1;
|
||
flex-shrink: 0;
|
||
position: relative;
|
||
z-index: 2;
|
||
box-shadow: 0 6px 18px -4px color-mix(in srgb, var(--brand-color, var(--c-accent)) 65%, rgba(0, 0, 0, 0.6)), inset 0 1px 0 rgba(255, 255, 255, 0.22);
|
||
background-image: linear-gradient(160deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0) 55%);
|
||
background-blend-mode: overlay;
|
||
}
|
||
.pay-option .pay-icon.pay-icon-emoji { font-size: 1.7rem; font-style: normal; }
|
||
|
||
.pay-icon-cc svg { display: block; }
|
||
.pay-option .pay-sub { display: block; font-weight: 400; font-size: 0.8rem; color: var(--c-text-muted); margin-top: 0.1em; }
|
||
|
||
/* Kreditkarte: statt einem einzelnen Icon zwei echte Marken-Badges (Visa + Mastercard)
|
||
nebeneinander, in unveränderten Originalfarben (Visa-Blau bzw. Mastercard Rot/Orange) —
|
||
genau die Kombination, die auf einer Kreditkarten-Zahlungsoption üblich und von beiden
|
||
Marken als "Acceptance Mark" vorgesehen ist. */
|
||
.pay-icon-cards { display: flex; align-items: center; gap: 0.5em; flex-shrink: 0; height: 52px; position: relative; z-index: 2; }
|
||
.mini-card {
|
||
width: 46px;
|
||
height: 32px;
|
||
border-radius: 6px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 4px 14px -3px var(--mini-glow, rgba(0, 0, 0, 0.5)), inset 0 1px 0 rgba(255, 255, 255, 0.35);
|
||
}
|
||
.mini-card-visa { background: #fff; --mini-glow: rgba(20, 52, 203, 0.55); --mini-base: #fff; }
|
||
.mini-card-mastercard { background: #16161f; --mini-glow: rgba(235, 0, 27, 0.45); --mini-base: #16161f; }
|
||
|
||
/* Marken-Icon-Badges (PayPal, Klarna): echtes Markenlogo (SVG) mittig auf einer Kachel in der
|
||
jeweiligen offiziellen Markenfarbe statt einem groben Buchstaben-Platzhalter. */
|
||
.pay-icon-brand svg { display: block; }
|
||
|
||
/* Der "Verbinden"-Bereich sitzt DIREKT in der Karte selbst und klappt beim Anklicken sofort auf —
|
||
kein separates Panel, kein zweiter Klick nötig. */
|
||
.pay-panel-inline {
|
||
display: none;
|
||
padding: 0.2rem 1.3em 1.3em;
|
||
border-top: 1px dashed rgba(244, 241, 247, 0.16);
|
||
margin: 0 1.3em;
|
||
}
|
||
.pay-card:has(input:checked) .pay-panel-inline { display: block; padding-top: 1rem; }
|
||
.pay-panel-inline p { margin: 0 0 0.8em; color: var(--c-text-muted); font-size: 0.88rem; }
|
||
.pay-connect-btn { width: 100%; }
|
||
.pay-connect-btn[disabled] { opacity: 0.75; cursor: default; }
|
||
.pay-connect-status { margin: 0.7em 0 0; font-size: 0.88rem; color: var(--c-accent); font-weight: 600; }
|
||
|
||
/* Kleine Visa/Mastercard-Hinweis-Badges direkt neben "PayPal" — zeigt, dass Kartenzahlung über
|
||
den PayPal-Gast-Checkout ebenfalls möglich ist (Kartendaten laufen dabei komplett über PayPals
|
||
eigene, PCI-DSS-zertifizierte Oberfläche, nie über unsere Seite — siehe Recherche zur
|
||
Kreditkarten-Rechtslage: eine eigene Karten-Eingabemaske wäre PCI-DSS-pflichtig und für einen
|
||
kleinen Shop praktisch nicht stemmbar). */
|
||
.pay-sub-cards { display: inline-flex; align-items: center; gap: 0.3em; margin-left: 0.5em; vertical-align: middle; }
|
||
.pay-sub-cards .mini-card { width: 26px; height: 18px; border-radius: 4px; }
|
||
.pay-sub-cards .mini-card svg { width: 16px; height: auto; }
|
||
|
||
/* ============================================================================
|
||
PayPal-Kachel: eigens "besonders" gestaltet (ausdrücklicher Wunsch) — exakt
|
||
in der Mitte geteilt, obere Hälfte PayPal-Markenfarben + Wortmarke, untere
|
||
Hälfte die Visa-/Mastercard-Hinweis-Badges. Animierter Verlaufsrand, sanftes
|
||
Glitzern und ein leuchtender Mittelsteg statt der schlichten Icon-Zeile, wie
|
||
sie die Überweisung-Karte daneben weiterhin hat — damit PayPal als Haupt-
|
||
zahlungsart bewusst heraussticht. ============================================================================ */
|
||
.pay-option-paypal-split { display: block; padding: 1.05em; }
|
||
.pay-option-paypal-split .pp-tile {
|
||
position: relative;
|
||
isolation: isolate;
|
||
display: flex;
|
||
flex-direction: column;
|
||
border-radius: 20px;
|
||
overflow: hidden;
|
||
/* Feste Höhe statt min-height: nur mit einer DEFINIERTEN Gesamthöhe teilen die beiden
|
||
flex:1-Hälften unten den Platz auch wirklich exakt 50/50 auf. Mit auto-Höhe (nur
|
||
min-height) richtet sich ein Flex-Container stattdessen nach dem tatsächlichen Inhalt
|
||
jeder Hälfte — bei unterschiedlich viel Inhalt (hier: Badge+Wortmarke oben vs. schmalerer
|
||
Kartenhinweis unten) verschiebt sich die Trennlinie dann sichtbar aus der Mitte. */
|
||
height: 220px;
|
||
border: 1.5px solid transparent;
|
||
background:
|
||
linear-gradient(var(--c-anthracite), var(--c-anthracite)) padding-box,
|
||
linear-gradient(115deg, #1fb2ff, #9b7fd6, #1fb2ff, #003087, #1fb2ff) border-box;
|
||
background-size: 100% 100%, 260% 100%;
|
||
animation: pp-tile-border-shift 9s ease-in-out infinite;
|
||
box-shadow: 0 14px 30px -16px rgba(0, 48, 135, 0.75);
|
||
transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
|
||
}
|
||
.pay-option-paypal-split:hover .pp-tile { transform: translateY(-2px); box-shadow: 0 20px 38px -14px rgba(0, 112, 186, 0.85); }
|
||
@keyframes pp-tile-border-shift {
|
||
0%, 100% { background-position: 0 0, 0% 50%; }
|
||
50% { background-position: 0 0, 100% 50%; }
|
||
}
|
||
.pp-tile-shine {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
left: -60%;
|
||
width: 35%;
|
||
height: 100%;
|
||
background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.22), transparent);
|
||
transform: skewX(-18deg);
|
||
animation: account-head-shine 6s ease-in-out infinite 1s;
|
||
pointer-events: none;
|
||
z-index: 3;
|
||
}
|
||
.pp-sparkle { position: absolute; font-size: 0.8rem; z-index: 3; pointer-events: none; filter: drop-shadow(0 0 4px rgba(255, 255, 255, 0.5)); }
|
||
.pp-sparkle-1 { top: 0.6rem; right: 0.9rem; animation: account-nav-sparkle-twinkle 2.6s ease-in-out infinite; }
|
||
.pp-sparkle-2 { bottom: 0.7rem; left: 0.9rem; font-size: 0.65rem; animation: account-nav-sparkle-twinkle 3.3s ease-in-out infinite 0.7s; }
|
||
|
||
/* Exakt hälftig per flex:1 auf beiden Zonen — bei ungleichem Inhalt bleibt die Trennlinie
|
||
trotzdem immer genau mittig, weil beide Hälften gleich viel Raum beanspruchen. */
|
||
.pp-half { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.5em; padding: 0.8rem 1.1rem; position: relative; z-index: 2; }
|
||
.pp-half-top {
|
||
background:
|
||
radial-gradient(120% 160% at 12% 0%, rgba(255, 255, 255, 0.24), transparent 55%),
|
||
linear-gradient(135deg, #1ea7ff 0%, #0b4fb0 55%, #002569 100%);
|
||
}
|
||
.pp-half-bottom {
|
||
/* Linksbündig statt zentriert: rechts bleibt bewusst Platz frei für die Radio-Markierung
|
||
(siehe .pay-option-paypal-split input), damit sie nicht auf der Mastercard-Karte landet —
|
||
genau die Anordnung aus dem Referenz-Screenshot (Text/Karten links, Auswahlpunkt rechts). */
|
||
align-items: flex-start;
|
||
padding-right: 2.6rem;
|
||
/* Eigene Farbgebung statt eines Blau-Abklatschs der PayPal-Hälfte darüber: ein sanftes
|
||
Visa-Blau unten links, ein Mastercard-Orange/Rot oben rechts — beide Markenfarben klingen
|
||
im dunklen Untergrund nur an (niedrige Deckkraft), damit Text und Karten weiterhin klar
|
||
lesbar bleiben, die untere Hälfte aber sichtbar "ihre eigene" ist. */
|
||
background:
|
||
radial-gradient(130% 170% at 4% 100%, color-mix(in srgb, #1434cb 24%, transparent), transparent 58%),
|
||
radial-gradient(130% 170% at 96% 0%, color-mix(in srgb, #ff5f1f 20%, transparent), transparent 58%),
|
||
linear-gradient(160deg, #15151f, #0a0a10);
|
||
}
|
||
.pp-badge {
|
||
width: 46px;
|
||
height: 46px;
|
||
border-radius: 13px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: linear-gradient(160deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0) 60%), rgba(0, 20, 60, 0.35);
|
||
box-shadow: 0 6px 16px -4px rgba(0, 10, 40, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35);
|
||
}
|
||
.pp-wordmark { font-size: 1.3rem; font-weight: 800; letter-spacing: -0.02em; line-height: 1; }
|
||
.pp-word-pay { color: #fff; }
|
||
.pp-word-pal { color: #bfe4ff; }
|
||
|
||
/* Leuchtender Mittelsteg statt einer schlichten Linie — genau die Stelle, an der die Kachel
|
||
"in der Mitte, in der Breite getrennt" ist. */
|
||
.pp-divider { position: relative; z-index: 3; height: 2px; background: linear-gradient(90deg, transparent, #bfe4ff 15%, #fff 50%, #bfe4ff 85%, transparent); box-shadow: 0 0 14px 1px rgba(191, 228, 255, 0.65); flex-shrink: 0; }
|
||
|
||
.pp-cards-caption { color: rgba(244, 241, 247, 0.75); font-size: 0.85rem; font-weight: 400; text-align: left; }
|
||
.pp-cards-row { display: flex; align-items: center; gap: 0.55em; }
|
||
/* Dasselbe Politur-Niveau wie das PayPal-Badge oben (.pp-badge): weicher Glanz-Verlauf oben
|
||
links, kräftiger Schlagschatten in der jeweiligen Markenfarbe, dezenter innerer Lichtrand —
|
||
nur die Grundfarbe bleibt markengetreu (Visa weiß, Mastercard schwarz), siehe --mini-base. */
|
||
.mini-card-lg {
|
||
width: 48px;
|
||
height: 48px;
|
||
border-radius: 13px;
|
||
flex-shrink: 0;
|
||
background-image: linear-gradient(160deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0) 60%);
|
||
background-color: var(--mini-base, #fff);
|
||
box-shadow: 0 6px 16px -4px var(--mini-glow, rgba(0, 0, 0, 0.5)), inset 0 1px 0 rgba(255, 255, 255, 0.35);
|
||
transition: transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
|
||
}
|
||
.pay-option-paypal-split:hover .mini-card-lg { transform: translateY(-1px); }
|
||
.mini-card-lg svg { width: 27px; height: auto; }
|
||
|
||
/* Der native Radio-Knopf ist bei dieser Kachel keine Zeile mehr, sondern eine eigene, kleine
|
||
Markierung unten rechts auf der Kachel — genau wie im Referenz-Screenshot. */
|
||
.pay-option-paypal-split input[type="radio"] {
|
||
position: absolute;
|
||
right: 0.9rem;
|
||
bottom: 0.85rem;
|
||
z-index: 4;
|
||
margin-left: 0;
|
||
background: rgba(9, 12, 24, 0.35);
|
||
backdrop-filter: blur(2px);
|
||
}
|
||
.pay-option-paypal-split input[type="radio"]:checked { border-color: #fff; }
|
||
.pay-option-paypal-split input[type="radio"]:checked::before { background: #fff; }
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.pay-option-paypal-split .pp-tile { animation: none; }
|
||
.pp-tile-shine, .pp-sparkle-1, .pp-sparkle-2 { animation: none; }
|
||
}
|
||
/* Überschreibt gezielt die generische Regel ".pay-card:has(input:checked) .pay-option
|
||
span:not(.pay-icon)" (weiter oben) mit höherer Selektor-Spezifität — sonst würde die
|
||
PayPal-Wortmarke und der Kartenhinweis im ausgewählten Zustand auf die einfarbige
|
||
Markenfarbe umspringen und auf dem blauen Verlaufshintergrund kaum noch lesbar sein. */
|
||
.pay-card:has(input:checked) .pay-option-paypal-split .pp-wordmark .pp-word-pay { color: #fff; }
|
||
.pay-card:has(input:checked) .pay-option-paypal-split .pp-wordmark .pp-word-pal { color: #bfe4ff; }
|
||
.pay-card:has(input:checked) .pay-option-paypal-split .pp-tile .pp-half-bottom .pp-cards-caption { color: rgba(244, 241, 247, 0.75); }
|
||
|
||
/* Der große "Jetzt zahlungspflichtig bestellen"-Knopf gehört NUR zur Überweisung (Vorkasse) —
|
||
bei PayPal läuft die Zahlung ausschließlich über die echten PayPal-Smart-Buttons oben (siehe
|
||
#paypal-button-container), die selbst die Bestellung auslösen, sobald die Zahlung bei PayPal
|
||
bestätigt ist. Der Knopf würde bei ausgewähltem PayPal sonst fälschlich eine "Bestellung ohne
|
||
Zahlung" ermöglichen — deshalb hier komplett ausgeblendet, kein Fallback, keine Ausnahme. */
|
||
#checkout-form:has(input[name="pay"][value="paypal"]:checked) #order-submit-btn { display: none; }
|
||
#checkout-form:has(input[name="pay"][value="paypal"]:checked) #order-submit-hint { display: block; }
|
||
#order-submit-hint {
|
||
display: none;
|
||
margin: 0 0 1rem;
|
||
padding: 0.9em 1.1em;
|
||
border-radius: var(--radius-m);
|
||
border: 1px solid color-mix(in srgb, var(--c-accent) 35%, transparent);
|
||
background: color-mix(in srgb, var(--c-accent) 8%, transparent);
|
||
font-size: 0.88rem;
|
||
color: var(--c-text-muted);
|
||
text-align: center;
|
||
}
|
||
|
||
/* Bankverbindung (Vorkasse) — echte, direkt aus dem Adminbereich gespeiste Kontodaten. */
|
||
.bank-details {
|
||
display: grid;
|
||
gap: 0.5rem;
|
||
font-size: 0.92rem;
|
||
}
|
||
.bank-details .bank-row { display: flex; justify-content: space-between; gap: 1em; padding: 0.4em 0; border-bottom: 1px dashed rgba(244, 241, 247, 0.14); }
|
||
.bank-details .bank-row:last-child { border-bottom: none; }
|
||
.bank-details .bank-row span:first-child { color: var(--c-text-muted); }
|
||
.bank-details .bank-row span:last-child { font-weight: 700; letter-spacing: 0.02em; }
|
||
.pay-option input[type="radio"] {
|
||
appearance: none;
|
||
width: 22px;
|
||
height: 22px;
|
||
border-radius: 50%;
|
||
border: 2px solid rgba(244, 241, 247, 0.3);
|
||
margin-left: auto;
|
||
flex-shrink: 0;
|
||
display: grid;
|
||
place-content: center;
|
||
cursor: pointer;
|
||
transition: border-color 0.2s var(--ease);
|
||
}
|
||
.pay-option input[type="radio"]::before {
|
||
content: "";
|
||
width: 12px;
|
||
height: 12px;
|
||
border-radius: 50%;
|
||
transform: scale(0);
|
||
transition: transform 0.15s var(--ease);
|
||
background: var(--brand-color, var(--c-accent));
|
||
}
|
||
.pay-option input[type="radio"]:checked::before { transform: scale(1); }
|
||
.pay-option input[type="radio"]:checked { border-color: var(--brand-color, var(--c-accent)); }
|
||
|
||
.checkout-summary .row { display: flex; justify-content: space-between; font-size: 0.9rem; padding: 0.35rem 0; color: var(--c-text-muted); }
|
||
/* Rechnungs-Positionsliste in der Warenkorb-Zusammenfassung — dieselbe Klasse wie im Checkout,
|
||
nur mit etwas Abstand zur folgenden Zwischensumme. */
|
||
.cart-summary #summary-items { margin-bottom: 0.6rem; padding-bottom: 0.4rem; border-bottom: 1px dashed rgba(244, 241, 247, 0.14); }
|
||
|
||
/* "Gesamt"-Zeile wie ein Kassenbon-Abriss: gestrichelte Trennlinie + Summe in Marken-Verlauf,
|
||
damit der Endbetrag klar heraussticht statt einfach nur fett zu sein. */
|
||
.checkout-summary .row.total {
|
||
font-weight: 700;
|
||
font-size: 1.3rem;
|
||
padding-top: 0.9rem;
|
||
margin-top: 0.5rem;
|
||
border-top: 1.5px dashed rgba(244, 241, 247, 0.22);
|
||
}
|
||
.checkout-summary .row.total span:first-child { color: var(--c-text); font-size: 0.75rem; letter-spacing: 0.06em; text-transform: uppercase; align-self: center; font-weight: 700; }
|
||
.checkout-summary .row.total span:last-child {
|
||
background: linear-gradient(135deg, var(--c-accent), var(--c-purple-glow));
|
||
-webkit-background-clip: text;
|
||
background-clip: text;
|
||
color: transparent;
|
||
}
|
||
|
||
/* Eigene, zum Radio-Button passende Checkbox statt nüchternem Browser-Kästchen. */
|
||
.frm .checkbox-row input[type="checkbox"] {
|
||
appearance: none;
|
||
width: 21px;
|
||
height: 21px;
|
||
border-radius: 6px;
|
||
border: 2px solid rgba(244, 241, 247, 0.3);
|
||
flex-shrink: 0;
|
||
display: grid;
|
||
place-content: center;
|
||
cursor: pointer;
|
||
transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
|
||
}
|
||
.frm .checkbox-row input[type="checkbox"]::before {
|
||
content: "";
|
||
width: 12px;
|
||
height: 12px;
|
||
clip-path: polygon(14% 44%, 0 65%, 45% 100%, 100% 16%, 80% 0%, 43% 68%);
|
||
transform: scale(0);
|
||
transition: transform 0.15s var(--ease);
|
||
background: #08181c;
|
||
}
|
||
.frm .checkbox-row input[type="checkbox"]:checked {
|
||
border-color: var(--c-accent);
|
||
background: linear-gradient(135deg, var(--c-accent), var(--c-accent-hover));
|
||
}
|
||
.frm .checkbox-row input[type="checkbox"]:checked::before { transform: scale(1); }
|
||
|
||
@media (max-width: 800px) { .checkout-layout { grid-template-columns: 1fr; } }
|
||
.danke { max-width: 560px; margin-inline: auto; }
|
||
|
||
/* Konto */
|
||
.account-grid { align-items: start; }
|
||
|
||
/* "Mein Abo verwalten"-Button neben Abmelden: bewusst deutlich auffälliger als der normale
|
||
btn-outline-Rahmen der übrigen Kopfzeile — eigener Gold/Lila-Farbverlauf, wanderndes Glanzlicht
|
||
und ein leicht pulsierender Schein, damit der Einstieg ins neue Abosystem sofort ins Auge
|
||
fällt (explizit vom Kunden gewünscht: "ein mega geiler Button ... neben dem Abmelden"). */
|
||
.btn-abo-hero {
|
||
position: relative;
|
||
overflow: hidden;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.5rem;
|
||
padding: 0.7rem 1.3rem;
|
||
border-radius: var(--radius-l);
|
||
border: 1.5px solid transparent;
|
||
background:
|
||
linear-gradient(155deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(120deg, #e3b23c, #9b7fd6, var(--c-accent), #e3b23c) border-box;
|
||
background-size: 100% 100%, 300% 100%;
|
||
color: #f9e9b8;
|
||
font-weight: 800;
|
||
font-size: 0.95rem;
|
||
letter-spacing: 0.01em;
|
||
cursor: pointer;
|
||
animation: abo-hero-border-shift 5s ease-in-out infinite, abo-hero-glow 2.4s ease-in-out infinite;
|
||
transition: transform 0.2s var(--ease);
|
||
}
|
||
.btn-abo-hero:hover { transform: translateY(-2px) scale(1.03); }
|
||
.btn-abo-hero::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
left: -60%;
|
||
width: 35%;
|
||
height: 100%;
|
||
background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.35), transparent);
|
||
transform: skewX(-18deg);
|
||
animation: account-head-shine 3.4s ease-in-out infinite;
|
||
pointer-events: none;
|
||
}
|
||
.btn-abo-hero-sparkle { display: inline-block; animation: account-nav-sparkle-twinkle 2.2s ease-in-out infinite; }
|
||
@keyframes abo-hero-border-shift {
|
||
0%, 100% { background-position: 0 0, 0% 50%; }
|
||
50% { background-position: 0 0, 100% 50%; }
|
||
}
|
||
@keyframes abo-hero-glow {
|
||
0%, 100% { box-shadow: 0 0 0 2px color-mix(in srgb, #e3b23c 30%, transparent), 0 0 16px -4px color-mix(in srgb, #e3b23c 60%, transparent); }
|
||
50% { box-shadow: 0 0 0 2px color-mix(in srgb, #9b7fd6 40%, transparent), 0 0 24px -2px color-mix(in srgb, #9b7fd6 70%, transparent); }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) { .btn-abo-hero, .btn-abo-hero::after, .btn-abo-hero-sparkle { animation: none; } }
|
||
|
||
/* "Meine Daten"-Button unten rechts in der Kopfkarte — dasselbe Premium-Prinzip wie der Abo-Held
|
||
oben (wanderndes Mehrfarb-Verlaufslicht am Rand + Glanzlicht + funkelndes Sternchen), aber in
|
||
Teal/Lila statt Gold, damit er sich klar von Abo-bezogenen Elementen abhebt und stattdessen zur
|
||
Akzentfarbe der Kopfkarte selbst passt (siehe "MEIN KONTO"-Eyebrow). */
|
||
.btn-daten-hero {
|
||
position: relative;
|
||
overflow: hidden;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.5rem;
|
||
padding: 0.7rem 1.3rem;
|
||
border-radius: var(--radius-l);
|
||
border: 1.5px solid transparent;
|
||
background:
|
||
linear-gradient(155deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(120deg, var(--c-accent), #9b7fd6, var(--c-accent)) border-box;
|
||
background-size: 100% 100%, 300% 100%;
|
||
color: #d6f7ff;
|
||
font-weight: 800;
|
||
font-size: 0.95rem;
|
||
letter-spacing: 0.01em;
|
||
cursor: pointer;
|
||
animation: daten-hero-border-shift 5s ease-in-out infinite, daten-hero-glow 2.4s ease-in-out infinite;
|
||
transition: transform 0.2s var(--ease);
|
||
}
|
||
.btn-daten-hero:hover { transform: translateY(-2px) scale(1.03); }
|
||
.btn-daten-hero::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
left: -60%;
|
||
width: 35%;
|
||
height: 100%;
|
||
background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.35), transparent);
|
||
transform: skewX(-18deg);
|
||
animation: account-head-shine 3.4s ease-in-out infinite;
|
||
pointer-events: none;
|
||
}
|
||
.btn-daten-hero-sparkle { display: inline-block; animation: account-nav-sparkle-twinkle 2.2s ease-in-out infinite; }
|
||
@keyframes daten-hero-border-shift {
|
||
0%, 100% { background-position: 0 0, 0% 50%; }
|
||
50% { background-position: 0 0, 100% 50%; }
|
||
}
|
||
@keyframes daten-hero-glow {
|
||
0%, 100% { box-shadow: 0 0 0 2px color-mix(in srgb, var(--c-accent) 30%, transparent), 0 0 16px -4px color-mix(in srgb, var(--c-accent) 60%, transparent); }
|
||
50% { box-shadow: 0 0 0 2px color-mix(in srgb, #9b7fd6 40%, transparent), 0 0 24px -2px color-mix(in srgb, #9b7fd6 70%, transparent); }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) { .btn-daten-hero, .btn-daten-hero::after, .btn-daten-hero-sparkle { animation: none; } }
|
||
|
||
/* Abosystem: drei Planvergleichs-Karten + Statuskarte + Benachrichtigungsliste. Soll insgesamt
|
||
deutlich "wertiger" aussehen als ein normaler Formular-/Tabellenbereich — durchgehend mit
|
||
Icons, Farbverläufen, echten Fortschrittsbalken statt reinem Text und leicht animierten
|
||
Akzenten, damit sich das Abo auf den ersten Blick nach einem Premium-Feature anfühlt. */
|
||
.abo-plans { margin: 1.4rem 0 1.6rem; }
|
||
.abo-plan-card {
|
||
position: relative;
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0.5rem;
|
||
border: 1.5px solid rgba(244, 241, 247, 0.14);
|
||
transition: border-color 0.2s var(--ease), transform 0.2s var(--ease), box-shadow 0.2s var(--ease);
|
||
}
|
||
.abo-plan-card::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
background: radial-gradient(120% 60% at 50% -10%, color-mix(in srgb, var(--plan-color, var(--c-accent)) 16%, transparent), transparent 70%);
|
||
pointer-events: none;
|
||
}
|
||
.abo-plan-card > * { position: relative; z-index: 1; }
|
||
.abo-plan-card:hover { transform: translateY(-4px); box-shadow: 0 16px 32px -20px color-mix(in srgb, var(--plan-color, var(--c-accent)) 55%, transparent); }
|
||
.abo-plan-klein { --plan-color: #6ecb8f; }
|
||
.abo-plan-mittel { --plan-color: var(--c-accent); }
|
||
.abo-plan-gross { --plan-color: #e3b23c; }
|
||
.abo-plan-icon { font-size: 2.1rem; line-height: 1; filter: drop-shadow(0 2px 8px color-mix(in srgb, var(--plan-color, var(--c-accent)) 60%, transparent)); }
|
||
.abo-plan-card h3 { margin: 0; color: var(--plan-color, var(--c-accent)); }
|
||
.abo-plan-price { font-family: var(--font-head); font-size: 1.9rem; font-weight: 700; margin: 0; background-image: linear-gradient(120deg, var(--c-text), var(--plan-color, var(--c-accent))); -webkit-background-clip: text; background-clip: text; color: transparent; }
|
||
.abo-plan-price .small { -webkit-text-fill-color: var(--c-text-muted); color: var(--c-text-muted); }
|
||
.abo-plan-discount-chip {
|
||
align-self: flex-start;
|
||
font-weight: 800;
|
||
font-size: 0.9rem;
|
||
padding: 0.25rem 0.75rem;
|
||
border-radius: 999px;
|
||
background: color-mix(in srgb, var(--plan-color, var(--c-accent)) 26%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--plan-color, var(--c-accent)) 50%, transparent);
|
||
color: var(--plan-color, var(--c-accent));
|
||
}
|
||
.abo-plan-rewards { display: flex; gap: 0.4rem; flex-wrap: wrap; }
|
||
.abo-plan-reward-chip {
|
||
font-size: 0.78rem;
|
||
font-weight: 600;
|
||
padding: 0.2rem 0.6rem;
|
||
border-radius: 999px;
|
||
background: rgba(244, 241, 247, 0.06);
|
||
border: 1px solid rgba(244, 241, 247, 0.16);
|
||
color: var(--c-text-muted);
|
||
}
|
||
.abo-plan-reward-chip-gross { background: color-mix(in srgb, #e3b23c 16%, transparent); border-color: color-mix(in srgb, #e3b23c 40%, transparent); color: #f6dda0; }
|
||
.abo-plan-vorteil { margin: 0; color: var(--c-text-muted); flex-grow: 1; }
|
||
.abo-plan-card.is-current-plan {
|
||
border-color: var(--plan-color, var(--c-accent));
|
||
box-shadow: 0 0 0 1px color-mix(in srgb, var(--plan-color, var(--c-accent)) 55%, transparent), 0 0 28px -10px color-mix(in srgb, var(--plan-color, var(--c-accent)) 70%, transparent);
|
||
animation: abo-plan-current-glow 3.2s ease-in-out infinite;
|
||
}
|
||
@keyframes abo-plan-current-glow {
|
||
0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--plan-color, var(--c-accent)) 55%, transparent), 0 0 20px -10px color-mix(in srgb, var(--plan-color, var(--c-accent)) 65%, transparent); }
|
||
50% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--plan-color, var(--c-accent)) 70%, transparent), 0 0 32px -8px color-mix(in srgb, var(--plan-color, var(--c-accent)) 80%, transparent); }
|
||
}
|
||
.abo-plan-badge { align-self: flex-start; background: color-mix(in srgb, var(--plan-color, var(--c-accent)) 30%, transparent); border: 1px solid color-mix(in srgb, var(--plan-color, var(--c-accent)) 55%, transparent); border-radius: 999px; padding: 0.2rem 0.7rem; font-size: 0.78rem; font-weight: 700; }
|
||
.abo-plan-btn { align-self: flex-start; }
|
||
.abo-plan-btn:disabled { opacity: 0.6; cursor: default; }
|
||
.abo-plan-card.is-not-bookable { opacity: 0.55; filter: grayscale(0.3); }
|
||
|
||
.abo-status-card { margin-bottom: 1.4rem; }
|
||
.abo-status-card h3 { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
|
||
.abo-badge-active { background: rgba(126, 200, 160, 0.28); border-color: rgba(126, 200, 160, 0.5); color: #cfeee0; }
|
||
.abo-badge-inactive { background: color-mix(in srgb, var(--c-sale) 30%, transparent); border-color: color-mix(in srgb, var(--c-sale) 55%, transparent); }
|
||
|
||
/* Stat-Kacheln statt trockener Tabelle — jede Kennzahl bekommt ein eigenes Icon und mehr
|
||
optisches Gewicht, der Rabatt (der eigentliche "Wow"-Wert des Abos) sticht farblich heraus. */
|
||
.abo-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.7rem; margin: 0.2rem 0 1.1rem; }
|
||
.abo-stat-tile {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0.15rem;
|
||
padding: 0.8rem 0.9rem;
|
||
border-radius: var(--radius-m);
|
||
background: rgba(244, 241, 247, 0.045);
|
||
border: 1px solid rgba(244, 241, 247, 0.1);
|
||
}
|
||
.abo-stat-tile-highlight { background: color-mix(in srgb, #e3b23c 12%, transparent); border-color: color-mix(in srgb, #e3b23c 38%, transparent); }
|
||
.abo-stat-icon { font-size: 1.3rem; }
|
||
.abo-stat-label { font-size: 0.76rem; color: var(--c-text-muted); text-transform: uppercase; letter-spacing: 0.03em; }
|
||
.abo-stat-value { font-family: var(--font-head); font-size: 1.15rem; font-weight: 700; }
|
||
.abo-stat-tile-highlight .abo-stat-value { color: #e3b23c; }
|
||
|
||
/* Echte Fortschrittsbalken (wiederverwendet dieselbe Optik wie der Treuebonus-Balken) für den
|
||
Weg zum nächsten Teddy — deutlich greifbarer als reiner Fließtext. */
|
||
.abo-reward-progress-block { display: flex; flex-direction: column; gap: 0.8rem; margin-bottom: 0.4rem; }
|
||
.abo-reward-progress-head { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.88rem; font-weight: 600; }
|
||
.abo-reward-bar-gross { background: linear-gradient(90deg, #e3b23c, #f6dda0); }
|
||
|
||
/* "Diese Teddys hast du schon bekommen" — nennt jeden eingelösten Teddy namentlich mit Datum,
|
||
damit die Kundin keinen doppelt auswählt (siehe erhalteneTeddys in scripts/account.ts).
|
||
Früher war das nur ein schmaler Chip mit reinen Stückzahlen. */
|
||
.abo-erhalten-box {
|
||
align-self: stretch;
|
||
padding: 0.7rem 1rem 0.8rem;
|
||
border-radius: var(--radius-m);
|
||
background: rgba(126, 200, 160, 0.12);
|
||
border: 1px solid rgba(126, 200, 160, 0.32);
|
||
font-size: 0.9rem;
|
||
}
|
||
.abo-erhalten-box.is-leer { background: rgba(244, 241, 247, 0.05); border-color: rgba(244, 241, 247, 0.14); }
|
||
.abo-erhalten-titel { margin: 0; display: flex; align-items: center; gap: 0.5rem; font-weight: 600; }
|
||
.abo-erhalten-liste { list-style: none; margin: 0.55rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.55rem; }
|
||
.abo-erhalten-liste:empty { display: none; }
|
||
/* Mini-Foto + Text nebeneinander statt nur einem Emoji-Aufzähler davor — man soll auf einen
|
||
Blick sehen, WELCHER Teddy das war, nicht nur, dass es "irgendein" Teddy war. */
|
||
.abo-erhalten-eintrag { display: flex; align-items: center; gap: 0.7rem; }
|
||
.abo-erhalten-foto {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 10px;
|
||
flex-shrink: 0;
|
||
object-fit: cover;
|
||
box-shadow: 0 3px 10px -3px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||
}
|
||
/* Solange VanVan noch kein echtes Foto für den Teddy hochgeladen hat (siehe product.bilder im
|
||
Adminbereich): ein gestalteter Platzhalter statt eines kaputten Bild-Symbols — sobald ein
|
||
Foto hochgeladen wird, erscheint es hier automatisch, ohne Code-Änderung. */
|
||
.abo-erhalten-foto-platzhalter {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 1.2rem;
|
||
background: linear-gradient(160deg, rgba(126, 200, 160, 0.35), rgba(126, 200, 160, 0.12));
|
||
}
|
||
.abo-erhalten-text { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.5rem; min-width: 0; }
|
||
.abo-erhalten-name { font-weight: 600; }
|
||
.abo-erhalten-datum { color: var(--c-text-muted); font-size: 0.85em; }
|
||
.abo-erhalten-link { font-size: 0.85em; text-decoration: underline; }
|
||
|
||
.abo-praemien-block { border-top: 1px dashed rgba(244, 241, 247, 0.14); padding-top: 0.9rem; margin-top: 0.3rem; }
|
||
.abo-praemien-block h4 { margin: 0 0 0.4rem; }
|
||
.abo-praemien-row { display: flex; gap: 0.9rem; flex-wrap: wrap; }
|
||
|
||
/* Verfügbare Prämie: eigene, leicht pulsierende Karte statt eines schlichten Buttons — soll
|
||
klar als "hier wartet etwas Kostenloses auf dich" auffallen. */
|
||
.abo-reward-ready {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.8rem;
|
||
padding: 0.7rem 1rem;
|
||
border-radius: var(--radius-l);
|
||
background: linear-gradient(155deg, color-mix(in srgb, #e3b23c 16%, var(--c-anthracite-light)), var(--c-anthracite));
|
||
border: 1.5px solid color-mix(in srgb, #e3b23c 45%, transparent);
|
||
animation: abo-reward-ready-glow 2.6s ease-in-out infinite;
|
||
}
|
||
@keyframes abo-reward-ready-glow {
|
||
0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, #e3b23c 35%, transparent), 0 0 14px -6px color-mix(in srgb, #e3b23c 55%, transparent); }
|
||
50% { box-shadow: 0 0 0 1px color-mix(in srgb, #e3b23c 55%, transparent), 0 0 22px -4px color-mix(in srgb, #e3b23c 75%, transparent); }
|
||
}
|
||
.abo-reward-ready-icon { font-size: 1.8rem; }
|
||
.abo-reward-ready-body { display: flex; flex-direction: column; gap: 0.4rem; }
|
||
.abo-reward-ready-body strong { font-size: 0.92rem; }
|
||
|
||
.abo-actions { display: flex; gap: 0.7rem; flex-wrap: wrap; margin-top: 0.6rem; }
|
||
.abo-cancel-btn { border-color: color-mix(in srgb, var(--c-sale) 55%, transparent); color: var(--c-sale); }
|
||
|
||
/* Benachrichtigungen als kleine Timeline: farbiger Icon-Kreis je Ereignistyp statt einer
|
||
einheitlichen grauen Liste. */
|
||
.abo-notif-list { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; max-height: 320px; overflow-y: auto; }
|
||
.abo-notif-item {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 0.7rem;
|
||
padding: 0.55rem 0.8rem;
|
||
border-radius: var(--radius-m);
|
||
background: rgba(244, 241, 247, 0.05);
|
||
border-left: 3px solid transparent;
|
||
--notif-color: var(--c-text-muted);
|
||
}
|
||
.abo-notif-item.abo-notif-unread { border-left-color: var(--notif-color); background: color-mix(in srgb, var(--notif-color) 10%, transparent); }
|
||
.abo-notif-item.abo-notif-erfolg { --notif-color: #7ec8a0; }
|
||
.abo-notif-item.abo-notif-praemie { --notif-color: #e3b23c; }
|
||
.abo-notif-item.abo-notif-warnung { --notif-color: var(--c-sale); }
|
||
.abo-notif-item.abo-notif-abbruch { --notif-color: #e07a9c; }
|
||
.abo-notif-item.abo-notif-info { --notif-color: var(--c-accent); }
|
||
.abo-notif-icon {
|
||
flex-shrink: 0;
|
||
width: 30px;
|
||
height: 30px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 0.95rem;
|
||
background: color-mix(in srgb, var(--notif-color) 22%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--notif-color) 45%, transparent);
|
||
}
|
||
.abo-notif-body { display: flex; flex-direction: column; gap: 0.15rem; }
|
||
.abo-notif-date { color: var(--c-text-muted); }
|
||
@media (prefers-reduced-motion: reduce) { .abo-plan-card, .abo-plan-card.is-current-plan, .abo-reward-ready { animation: none; transition: none; } }
|
||
|
||
/* Vorschau-Umschalter (nur für qciga/vanvan sichtbar, siehe Layout.astro) — schwebt LINKS unten
|
||
über jeder Seite (rechts unten ist der Musik-Button, siehe weiter unten), damit man ohne
|
||
Seitenwechsel zwischen normalem Besucher/angemeldeter Kundin/Abonnentin hin- und herschalten
|
||
kann. */
|
||
#vandiy-preview-switcher { position: fixed; left: 1.2rem; bottom: 1.2rem; z-index: 200; }
|
||
#vandiy-preview-toggle {
|
||
width: 52px;
|
||
height: 52px;
|
||
border-radius: 50%;
|
||
border: 1.5px solid transparent;
|
||
background:
|
||
linear-gradient(155deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(120deg, #9b7fd6, var(--c-accent), #e3b23c) border-box;
|
||
font-size: 1.4rem;
|
||
cursor: pointer;
|
||
box-shadow: 0 10px 26px -10px rgba(0, 0, 0, 0.7);
|
||
transition: transform 0.2s var(--ease);
|
||
}
|
||
#vandiy-preview-toggle:hover { transform: scale(1.08); }
|
||
#vandiy-preview-panel {
|
||
display: none;
|
||
position: absolute;
|
||
left: 0;
|
||
bottom: calc(100% + 0.7rem);
|
||
min-width: 240px;
|
||
padding: 0.8rem;
|
||
border-radius: var(--radius-m);
|
||
background: var(--c-anthracite-light);
|
||
border: 1px solid rgba(244, 241, 247, 0.14);
|
||
box-shadow: var(--shadow-card);
|
||
flex-direction: column;
|
||
gap: 0.4rem;
|
||
}
|
||
#vandiy-preview-panel.open { display: flex; }
|
||
#vandiy-preview-current { margin: 0 0 0.3rem; color: var(--c-text-muted); }
|
||
#vandiy-preview-panel button[data-preview] {
|
||
text-align: left;
|
||
padding: 0.55em 0.7em;
|
||
border-radius: var(--radius-s);
|
||
border: 1px solid rgba(244, 241, 247, 0.12);
|
||
background: rgba(244, 241, 247, 0.04);
|
||
color: var(--c-text);
|
||
font-size: 0.88rem;
|
||
cursor: pointer;
|
||
transition: background 0.15s var(--ease);
|
||
}
|
||
#vandiy-preview-panel button[data-preview]:hover { background: color-mix(in srgb, var(--c-accent) 14%, transparent); }
|
||
@media (max-width: 500px) { #vandiy-preview-switcher { left: 0.7rem; bottom: 0.7rem; } }
|
||
|
||
/* Musik-Button: schwebt rechts unten auf JEDER Seite (Vorschau-Umschalter ist links unten, siehe
|
||
oben) — spielt Van-Vans Musik von Spotify, läuft dank transition:persist (Layout.astro) beim
|
||
Seitenwechsel einfach weiter statt neu zu starten. Gleiches Gestaltungsprinzip wie beim
|
||
Dogfather-Universe-Projekt: dunkler Knopf mit wandernder, weichgezeichneter Farbwolke
|
||
("Aurora") + durchlaufendem Lichtschimmer, deren Farben sich "chamäleonartig" an die jeweilige
|
||
Seite anpassen (siehe --music-c1/--music-c2, live per JS gesetzt — adaptMusicColors() im
|
||
Skript in Layout.astro). Ohne JS/Bild fällt der Knopf sauber auf die normalen Markenfarben
|
||
zurück. */
|
||
#vandiy-music-widget { position: fixed; right: 1.2rem; bottom: 1.2rem; z-index: 200; display: flex; flex-direction: column; align-items: flex-end; gap: 0.8rem; }
|
||
.music-toggle {
|
||
position: relative;
|
||
isolation: isolate;
|
||
overflow: hidden;
|
||
width: 54px;
|
||
height: 54px;
|
||
flex: none;
|
||
border-radius: 50%;
|
||
font-size: 1.45rem;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
color: #fff;
|
||
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
|
||
background: var(--c-black);
|
||
border: 1px solid color-mix(in srgb, var(--music-c1, var(--c-accent)) 55%, transparent);
|
||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.45), 0 0 24px color-mix(in srgb, var(--music-c1, var(--c-accent)) 35%, transparent);
|
||
transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), border-color 1.1s ease;
|
||
}
|
||
.music-toggle::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: -50%;
|
||
z-index: 0;
|
||
background:
|
||
radial-gradient(circle at 25% 30%, color-mix(in srgb, var(--music-c1, var(--c-accent)) 92%, transparent), transparent 58%),
|
||
radial-gradient(circle at 75% 72%, color-mix(in srgb, var(--music-c2, var(--c-purple-glow)) 92%, transparent), transparent 58%);
|
||
filter: blur(7px) saturate(1.3);
|
||
animation: music-aurora 10s ease-in-out infinite alternate;
|
||
transition: background 1.1s ease;
|
||
}
|
||
.music-toggle::after {
|
||
content: "";
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 1;
|
||
border-radius: 50%;
|
||
background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, 0.35) 49%, transparent 63%);
|
||
background-size: 240% 100%;
|
||
mix-blend-mode: overlay;
|
||
animation: music-shimmer 5s linear infinite;
|
||
pointer-events: none;
|
||
}
|
||
.music-toggle span { position: relative; z-index: 2; }
|
||
.music-toggle:hover, .music-toggle:focus-visible {
|
||
transform: translateY(-2px) scale(1.06);
|
||
box-shadow: 0 16px 38px rgba(0, 0, 0, 0.5), 0 0 34px color-mix(in srgb, var(--music-c1, var(--c-accent)) 55%, transparent);
|
||
}
|
||
#vandiy-music-widget.open .music-toggle { transform: rotate(12deg); }
|
||
@keyframes music-aurora {
|
||
0% { transform: translate(-4%, -3%) rotate(0deg); }
|
||
100% { transform: translate(4%, 3%) rotate(8deg); }
|
||
}
|
||
@keyframes music-shimmer {
|
||
0% { background-position: 200% 0; }
|
||
100% { background-position: -60% 0; }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) { .music-toggle::before, .music-toggle::after { animation: none; } }
|
||
|
||
.music-panel {
|
||
width: min(320px, calc(100vw - 2.4rem));
|
||
padding: 1rem 1.1rem 1.2rem;
|
||
border-radius: var(--radius-l);
|
||
border: 1px solid rgba(244, 241, 247, 0.14);
|
||
background: var(--c-anthracite-light);
|
||
box-shadow: var(--shadow-card);
|
||
animation: music-panel-in 0.22s ease-out;
|
||
}
|
||
.music-panel[hidden] { display: none; }
|
||
@keyframes music-panel-in { from { opacity: 0; transform: translateY(10px) scale(0.97); } to { opacity: 1; transform: none; } }
|
||
.music-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
|
||
.music-panel-intro { margin: 0.4rem 0 0.7rem; color: var(--c-text-muted); }
|
||
.music-close { background: none; border: 0; color: var(--c-text-muted); font-size: 1rem; line-height: 1; padding: 0.2rem 0.3rem; cursor: pointer; border-radius: 6px; }
|
||
.music-close:hover { color: var(--c-accent); }
|
||
.music-panel iframe { display: block; width: 100%; border: 0; border-radius: 12px; }
|
||
@media (max-width: 500px) { #vandiy-music-widget { right: 0.7rem; bottom: 0.7rem; } }
|
||
@media print { #vandiy-music-widget { display: none !important; } }
|
||
|
||
/* Interne Bestellverwaltung (/verwaltung/) — Status-Kacheln, Filterleiste, Auswertungs-Balken. */
|
||
|
||
/* "Kisten" — jede zusammengehörige Gruppe (Bestellstatus, Kennzahlen, Bestellliste, Bestseller,
|
||
Herkunft, Stammkundschaft) bekommt ihre eigene, klar abgegrenzte Box mit eigener Akzentfarbe
|
||
(--box-color, pro Kiste per inline style gesetzt) statt lose auf der Seite zu stehen. Auf
|
||
Wunsch ("alle Kisten sollen speziell speziell speziell sein, überrasch mich") noch eine Stufe
|
||
weiter aufgewertet: der Rand schimmert jetzt wie eine Aurora in der jeweiligen Box-Farbe
|
||
(derselbe Verlaufs-Trick wie beim Hero-Kopf oben auf der Seite, siehe .verwaltung-hero), jede
|
||
Box trägt ihr eigenes Icon zusätzlich riesig und ganz dezent als Wasserzeichen im Hintergrund
|
||
(per data-icon-Attribut, kein Bild nötig), und das Icon-Abzeichen sendet einen leisen
|
||
"Radar-Ping"-Ring aus — zusammen wirkt jede Kiste wie eine eigenständige kleine Instrumenten-
|
||
Kachel statt einer austauschbaren grauen Box. */
|
||
.verwaltung-box {
|
||
position: relative;
|
||
overflow: hidden;
|
||
border-radius: var(--radius-l);
|
||
border: 1.5px solid transparent;
|
||
background:
|
||
linear-gradient(155deg, color-mix(in srgb, var(--box-color, var(--c-accent)) 9%, var(--c-anthracite-light)), var(--c-anthracite)) padding-box,
|
||
linear-gradient(120deg, var(--box-color, var(--c-accent)), color-mix(in srgb, var(--box-color, var(--c-accent)) 35%, white), var(--box-color, var(--c-accent))) border-box;
|
||
background-size: 100% 100%, 300% 100%;
|
||
padding: 1.6rem 1.7rem;
|
||
margin: 1.4rem 0;
|
||
animation: verwaltung-box-border-shift 9s ease-in-out infinite, verwaltung-box-glow 3.4s ease-in-out infinite;
|
||
}
|
||
@keyframes verwaltung-box-border-shift {
|
||
0%, 100% { background-position: 0 0, 0% 50%; }
|
||
50% { background-position: 0 0, 100% 50%; }
|
||
}
|
||
@keyframes verwaltung-box-glow {
|
||
0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--box-color, var(--c-accent)) 22%, transparent); }
|
||
50% { box-shadow: 0 0 26px -6px color-mix(in srgb, var(--box-color, var(--c-accent)) 60%, transparent); }
|
||
}
|
||
.verwaltung-box::before {
|
||
content: "";
|
||
position: absolute;
|
||
top: -45%;
|
||
right: -15%;
|
||
width: 260px;
|
||
height: 260px;
|
||
background: radial-gradient(circle, color-mix(in srgb, var(--box-color, var(--c-accent)) 30%, transparent), transparent 70%);
|
||
pointer-events: none;
|
||
}
|
||
/* Riesiges, kaum sichtbares Icon-Wasserzeichen — nutzt dasselbe Icon wie das Abzeichen (über
|
||
data-icon), damit jede Kiste eine eigene "Textur" bekommt, ganz ohne zusätzliche Bilddateien. */
|
||
.verwaltung-box::after {
|
||
content: attr(data-icon);
|
||
position: absolute;
|
||
right: -1rem;
|
||
bottom: -2.2rem;
|
||
font-size: 8.5rem;
|
||
line-height: 1;
|
||
opacity: 0.06;
|
||
transform: rotate(-10deg);
|
||
filter: grayscale(0.4);
|
||
pointer-events: none;
|
||
z-index: 0;
|
||
}
|
||
.verwaltung-box-head {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.8rem;
|
||
margin-bottom: 1.1rem;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
.verwaltung-box-headtext { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
|
||
.verwaltung-box-kicker {
|
||
font-size: 0.72rem;
|
||
font-weight: 700;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
color: color-mix(in srgb, var(--box-color, var(--c-accent)) 80%, white);
|
||
opacity: 0.85;
|
||
}
|
||
.verwaltung-box-icon {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
width: 2.6rem;
|
||
height: 2.6rem;
|
||
border-radius: 50%;
|
||
font-size: 1.3rem;
|
||
background: color-mix(in srgb, var(--box-color, var(--c-accent)) 24%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--box-color, var(--c-accent)) 55%, transparent);
|
||
position: relative;
|
||
}
|
||
.verwaltung-box-icon::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: -6px;
|
||
border-radius: 50%;
|
||
border: 1.5px solid color-mix(in srgb, var(--box-color, var(--c-accent)) 65%, transparent);
|
||
animation: verwaltung-box-icon-ping 2.8s ease-out infinite;
|
||
pointer-events: none;
|
||
}
|
||
@keyframes verwaltung-box-icon-ping {
|
||
0% { transform: scale(0.75); opacity: 0.75; }
|
||
70%, 100% { transform: scale(1.4); opacity: 0; }
|
||
}
|
||
.verwaltung-box-head h2, .verwaltung-box-headtext h2 { margin: 0; font-size: 1.3rem; }
|
||
.verwaltung-box-body { position: relative; z-index: 1; }
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.verwaltung-box,
|
||
.verwaltung-box-icon::before { animation: none; }
|
||
}
|
||
|
||
/* Leerzustände innerhalb einer Kiste — großes Icon + kurzer, freundlicher Text statt nacktem
|
||
Fließtext, damit auch "noch nichts da" nicht trostlos wirkt. */
|
||
.verwaltung-box-empty {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
text-align: center;
|
||
gap: 0.4rem;
|
||
padding: 2.2rem 1rem;
|
||
color: var(--c-text-muted);
|
||
}
|
||
.verwaltung-box-empty-icon { font-size: 2.6rem; opacity: 0.75; }
|
||
.verwaltung-box-empty p { margin: 0; }
|
||
.verwaltung-box-empty p:first-of-type { color: var(--c-text); font-weight: 600; font-size: 1.02rem; }
|
||
|
||
/* Auswertungs-Kisten (Bestseller/Herkunft/Stammkundschaft) sind jetzt SELBST der Klick-Auslöser
|
||
für ihren eigenen Inhalt (Wunsch: "es sollten Kisten sein wo man drauf drückt und dann gehen
|
||
die anderen Sachen auf") — kein separater Knopf mehr davor. Jede startet eingeklappt (nur
|
||
Kopfzeile sichtbar) und lässt sich unabhängig von den anderen beiden öffnen/schließen. */
|
||
#verwaltung-auswertung-wrapper { margin-top: 1rem; }
|
||
.verwaltung-box-collapsible .verwaltung-box-body {
|
||
display: grid;
|
||
grid-template-rows: 1fr;
|
||
transition: grid-template-rows 0.25s var(--ease);
|
||
}
|
||
.verwaltung-box-collapsible .verwaltung-box-body-inner {
|
||
min-height: 0;
|
||
overflow: hidden;
|
||
opacity: 1;
|
||
transition: opacity 0.2s var(--ease);
|
||
}
|
||
.verwaltung-box-collapsible.is-collapsed .verwaltung-box-body { grid-template-rows: 0fr; }
|
||
.verwaltung-box-collapsible.is-collapsed .verwaltung-box-body-inner { opacity: 0; }
|
||
.verwaltung-box-collapsible.is-collapsed .verwaltung-box-head-btn { margin-bottom: 0; }
|
||
.verwaltung-box-head-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.8rem;
|
||
width: 100%;
|
||
background: transparent;
|
||
border: none;
|
||
padding: 0;
|
||
margin: 0 0 1.1rem;
|
||
font: inherit;
|
||
color: inherit;
|
||
text-align: left;
|
||
cursor: pointer;
|
||
}
|
||
.verwaltung-box-head-btn .verwaltung-box-headtext { flex: 1; }
|
||
.verwaltung-box-chevron {
|
||
flex-shrink: 0;
|
||
font-size: 1.1rem;
|
||
color: var(--c-text-muted);
|
||
transition: transform 0.25s var(--ease);
|
||
}
|
||
.verwaltung-box-collapsible.is-collapsed .verwaltung-box-chevron { transform: rotate(-90deg); }
|
||
.verwaltung-box-collapsible:not(.is-collapsed) .verwaltung-box-head-btn { color: var(--c-text); }
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.verwaltung-box-collapsible .verwaltung-box-body,
|
||
.verwaltung-box-chevron { transition: none; }
|
||
}
|
||
|
||
/* Hero-Kopf: dieselbe "besondere" Formsprache wie die anderen Premium-Karten der Seite
|
||
(wanderndes Verlaufslicht + pulsierender Rand + Funkeln), passend zu einer Seite, die "alles
|
||
übertrifft" — nur dezenter/edler gehalten, weil es ein Arbeits-Dashboard ist, kein Verkaufs-
|
||
Element. */
|
||
.verwaltung-hero {
|
||
position: relative;
|
||
overflow: hidden;
|
||
margin-top: 1.2rem;
|
||
padding: 1.8rem 2rem;
|
||
border-radius: var(--radius-l);
|
||
border: 1.5px solid transparent;
|
||
background:
|
||
linear-gradient(155deg, var(--c-anthracite-light), var(--c-anthracite)) padding-box,
|
||
linear-gradient(120deg, #5fd3ec, #9b7fd6, #e3b23c, #5fd3ec) border-box;
|
||
background-size: 100% 100%, 300% 100%;
|
||
animation: verwaltung-hero-shift 10s ease-in-out infinite;
|
||
}
|
||
@keyframes verwaltung-hero-shift {
|
||
0%, 100% { background-position: 0 0, 0% 50%; }
|
||
50% { background-position: 0 0, 100% 50%; }
|
||
}
|
||
.verwaltung-hero .eyebrow,
|
||
.verwaltung-hero h1,
|
||
.verwaltung-hero .lead { position: relative; z-index: 1; }
|
||
.verwaltung-hero h1 { margin: 0.3rem 0 0.6rem; }
|
||
.verwaltung-hero .lead { margin: 0; max-width: 62ch; }
|
||
.verwaltung-hero-sparkle { position: absolute; font-size: 1rem; pointer-events: none; z-index: 1; }
|
||
.verwaltung-hero-sparkle-1 { top: 1.4rem; right: 2.2rem; animation: account-nav-sparkle-twinkle 2.6s ease-in-out infinite; }
|
||
.verwaltung-hero-sparkle-2 { bottom: 1.6rem; right: 5rem; font-size: 0.7rem; animation: account-nav-sparkle-twinkle 3.4s ease-in-out infinite 0.6s; }
|
||
@media (prefers-reduced-motion: reduce) { .verwaltung-hero, .verwaltung-hero-sparkle { animation: none; } }
|
||
|
||
.verwaltung-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0.9rem; margin: 1.2rem 0; }
|
||
.verwaltung-stat-grid-secondary { margin-top: 0; }
|
||
.verwaltung-stat-tile-mini { padding: 0.8rem 1rem; }
|
||
.verwaltung-stat-tile-mini .verwaltung-stat-icon { font-size: 1.3rem; }
|
||
.verwaltung-stat-tile-mini .verwaltung-stat-value { font-size: 1.4rem; }
|
||
#stat-attention-tile { border-color: color-mix(in srgb, var(--c-sale) 50%, transparent); background: color-mix(in srgb, var(--c-sale) 10%, var(--c-anthracite-light)); animation: verwaltung-attention-pulse 2s ease-in-out infinite; }
|
||
#stat-attention-tile .verwaltung-stat-value { color: var(--c-sale); }
|
||
@keyframes verwaltung-attention-pulse {
|
||
0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--c-sale) 30%, transparent); }
|
||
50% { box-shadow: 0 0 16px -2px color-mix(in srgb, var(--c-sale) 55%, transparent); }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) { #stat-attention-tile { animation: none; } }
|
||
.verwaltung-stat-tile {
|
||
position: relative;
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: 0.3rem;
|
||
padding: 1.1rem 1.2rem;
|
||
text-align: left;
|
||
border: 1.5px solid rgba(244, 241, 247, 0.12);
|
||
cursor: pointer;
|
||
transition: transform 0.2s var(--ease), border-color 0.2s var(--ease);
|
||
font: inherit;
|
||
color: inherit;
|
||
}
|
||
.verwaltung-stat-tile:hover { transform: translateY(-3px); border-color: var(--c-accent); }
|
||
/* Kleiner Lichtstreif, der beim Hover einmal quer über die Kachel läuft — dezente "Premium"-
|
||
Mikro-Interaktion statt einer starren Karte. */
|
||
.verwaltung-stat-tile::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: 0;
|
||
left: -60%;
|
||
width: 40%;
|
||
height: 100%;
|
||
background: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.16), transparent);
|
||
transform: skewX(-20deg);
|
||
transition: left 0.6s var(--ease);
|
||
pointer-events: none;
|
||
}
|
||
.verwaltung-stat-tile:hover::after { left: 120%; }
|
||
@media (prefers-reduced-motion: reduce) { .verwaltung-stat-tile::after { transition: none; display: none; } }
|
||
.verwaltung-stat-tile-highlight { border-color: color-mix(in srgb, #e3b23c 45%, transparent); background: color-mix(in srgb, #e3b23c 10%, var(--c-anthracite-light)); cursor: default; }
|
||
.verwaltung-stat-tile-highlight:hover { transform: none; border-color: color-mix(in srgb, #e3b23c 45%, transparent); }
|
||
.verwaltung-stat-icon { font-size: 1.6rem; }
|
||
.verwaltung-stat-value { font-family: var(--font-head); font-size: 1.9rem; font-weight: 700; line-height: 1; }
|
||
.verwaltung-stat-label { font-size: 0.85rem; color: var(--c-text-muted); }
|
||
|
||
.verwaltung-filter { display: flex; gap: 0.6rem; flex-wrap: wrap; margin: 1.2rem 0; }
|
||
.verwaltung-filter-btn {
|
||
padding: 0.5em 1em;
|
||
border-radius: 999px;
|
||
border: 1.5px solid rgba(244, 241, 247, 0.16);
|
||
background: transparent;
|
||
color: var(--c-text-muted);
|
||
font-size: 0.88rem;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
transition: all 0.15s var(--ease);
|
||
}
|
||
.verwaltung-filter-btn:hover { border-color: var(--c-accent); color: var(--c-text); }
|
||
.verwaltung-filter-btn.is-active { background: var(--c-accent); border-color: var(--c-accent); color: var(--c-black); }
|
||
|
||
.verwaltung-auswertung-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1rem; margin-top: 1.2rem; }
|
||
.verwaltung-kat-card { display: flex; flex-direction: column; gap: 0.9rem; }
|
||
.verwaltung-kat-card h3 { margin: 0; }
|
||
|
||
/* Auswertungs-Kacheln (Bestseller je Kategorie / Herkunft / Stammkundschaft) — sehen jetzt
|
||
bewusst genauso aus wie die Bestellstatus-Kacheln oben (.verwaltung-stat-tile), auf Wunsch
|
||
("sollen aussehen wie auf screen2"), statt eigener Bar-Listen direkt in der Kiste. Klick auf
|
||
eine Kachel öffnet direkt darunter (".verwaltung-analyse-detail") die vollständige Liste. */
|
||
.verwaltung-analyse-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 0.9rem; margin: 1.2rem 0; }
|
||
.verwaltung-stat-tile.is-active {
|
||
border-color: color-mix(in srgb, var(--box-color, var(--c-accent)) 70%, transparent);
|
||
background: color-mix(in srgb, var(--box-color, var(--c-accent)) 14%, var(--c-anthracite-light));
|
||
}
|
||
.verwaltung-analyse-detail {
|
||
margin-top: 0.4rem;
|
||
padding: 1.2rem 1.3rem;
|
||
border-radius: var(--radius-m);
|
||
border: 1.5px solid color-mix(in srgb, var(--box-color, var(--c-accent)) 40%, transparent);
|
||
background: color-mix(in srgb, var(--box-color, var(--c-accent)) 6%, var(--c-anthracite));
|
||
animation: verwaltung-analyse-detail-in 0.2s var(--ease);
|
||
}
|
||
.verwaltung-analyse-detail[hidden] { display: none; }
|
||
@keyframes verwaltung-analyse-detail-in {
|
||
from { opacity: 0; transform: translateY(-6px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
.verwaltung-analyse-detail-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 0.9rem; }
|
||
.verwaltung-analyse-detail-head h3 { margin: 0; font-size: 1.05rem; }
|
||
.verwaltung-analyse-close {
|
||
flex-shrink: 0;
|
||
background: transparent;
|
||
border: none;
|
||
color: var(--c-text-muted);
|
||
font-size: 1.2rem;
|
||
line-height: 1;
|
||
padding: 0.2rem 0.4rem;
|
||
cursor: pointer;
|
||
transition: color 0.15s var(--ease);
|
||
}
|
||
.verwaltung-analyse-close:hover { color: var(--c-text); }
|
||
.verwaltung-analyse-order-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
gap: 1rem;
|
||
padding: 0.6rem 0;
|
||
border-bottom: 1px solid rgba(244, 241, 247, 0.08);
|
||
font-size: 0.9rem;
|
||
}
|
||
.verwaltung-analyse-order-row:last-child { border-bottom: none; }
|
||
@media (prefers-reduced-motion: reduce) { .verwaltung-analyse-detail { animation: none; } }
|
||
|
||
.verwaltung-bar-list { display: flex; flex-direction: column; gap: 0.8rem; }
|
||
.verwaltung-bar-head { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.9rem; margin-bottom: 0.3rem; }
|
||
.verwaltung-bar-track { height: 9px; border-radius: 999px; background: rgba(244, 241, 247, 0.08); overflow: hidden; }
|
||
.verwaltung-bar-fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--c-accent), #9b7fd6); transition: width 0.6s var(--ease); }
|
||
.verwaltung-bar-fill-land { background: linear-gradient(90deg, #e3b23c, #f6dda0); }
|
||
.verwaltung-bar-fill-kunden { background: linear-gradient(90deg, #e3b23c, #9b7fd6); }
|
||
|
||
/* Hinweis-Banner "neue Bestellungen im Hintergrund entdeckt" — soll auffallen, aber nicht die
|
||
Ansicht selbst verändern, solange man nicht aktiv auf "Aktualisieren" klickt. */
|
||
.verwaltung-new-banner {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 1rem;
|
||
flex-wrap: wrap;
|
||
margin: 1rem 0;
|
||
padding: 0.8rem 1.1rem;
|
||
border-radius: var(--radius-m);
|
||
background: color-mix(in srgb, var(--c-accent) 16%, var(--c-anthracite-light));
|
||
border: 1.5px solid color-mix(in srgb, var(--c-accent) 45%, transparent);
|
||
animation: verwaltung-new-banner-glow 2.2s ease-in-out infinite;
|
||
}
|
||
@keyframes verwaltung-new-banner-glow {
|
||
0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--c-accent) 30%, transparent); }
|
||
50% { box-shadow: 0 0 18px -2px color-mix(in srgb, var(--c-accent) 55%, transparent); }
|
||
}
|
||
@media (prefers-reduced-motion: reduce) { .verwaltung-new-banner { animation: none; } }
|
||
|
||
/* Werkzeugleiste über der Bestellliste: Suche, Zeitraum, Sortierung, CSV-Export. */
|
||
.verwaltung-toolbar { display: flex; gap: 0.7rem; flex-wrap: wrap; align-items: center; margin: 1rem 0; }
|
||
.verwaltung-input {
|
||
padding: 0.65em 0.9em;
|
||
border-radius: var(--radius-s);
|
||
border: 1px solid rgba(244, 241, 247, 0.15);
|
||
background: var(--c-anthracite);
|
||
color: var(--c-text);
|
||
font-family: var(--font-body);
|
||
font-size: 0.9rem;
|
||
}
|
||
.verwaltung-input:focus { outline: 2px solid var(--c-accent); outline-offset: 2px; }
|
||
#verwaltung-search { flex: 1 1 260px; min-width: 200px; }
|
||
.verwaltung-select { cursor: pointer; }
|
||
|
||
.btn-xs { padding: 0.35em 0.7em; font-size: 0.78rem; white-space: nowrap; }
|
||
|
||
/* Chips direkt neben der Bestellnummer — "neu"/"Stammkundin"/"braucht Aufmerksamkeit" auf einen
|
||
Blick, ohne erst die Karte lesen zu müssen. */
|
||
.verwaltung-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.3em;
|
||
padding: 0.15em 0.6em;
|
||
border-radius: 999px;
|
||
font-size: 0.72rem;
|
||
font-weight: 700;
|
||
margin-left: 0.5em;
|
||
vertical-align: middle;
|
||
}
|
||
.verwaltung-chip-new { background: color-mix(in srgb, var(--c-accent) 28%, transparent); border: 1px solid color-mix(in srgb, var(--c-accent) 55%, transparent); color: #d3f3fb; }
|
||
.verwaltung-chip-stamm { background: color-mix(in srgb, #9b7fd6 28%, transparent); border: 1px solid color-mix(in srgb, #9b7fd6 55%, transparent); color: #e4dbfa; }
|
||
.verwaltung-chip-attention { background: color-mix(in srgb, var(--c-sale) 28%, transparent); border: 1px solid color-mix(in srgb, var(--c-sale) 55%, transparent); color: #ffd7de; }
|
||
|
||
/* Bestellkarte, die "Aufmerksamkeit braucht" (offen + schon länger liegen geblieben) — warmer
|
||
Rand statt der neutralen Statusfarbe, damit sie in der Liste sofort auffällt. */
|
||
.order-card-attention { --status-color: var(--c-sale); }
|
||
|
||
/* Kopier-/PDF-Zeile: schnelle Aktionen fürs Verpacken/Versenden, ohne erst irgendwo hinklicken
|
||
zu müssen. */
|
||
.verwaltung-copy-row { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0.7rem 0; }
|
||
.verwaltung-copy-hint { color: #7ec8a0; font-weight: 600; }
|
||
|
||
.verwaltung-order-foot { flex-wrap: wrap; }
|
||
.verwaltung-tracking-edit { display: flex; align-items: center; gap: 0.4rem; }
|
||
.verwaltung-tracking-input { width: 160px; padding: 0.4em 0.6em; font-size: 0.82rem; }
|