1125 lines
25 KiB
CSS
1125 lines
25 KiB
CSS
/**
|
||
* @file productpage.css
|
||
* @brief Stylesheet für die Produktdetailseite
|
||
* @details Diese Datei enthält alle CSS-Regeln für die Darstellung der Produktdetails, der Shop-Angebote sowie der Bewertungsbereiche.
|
||
* Es werden moderne CSS-Features wie Flexbox, Grid, CSS-Variablen und Keyframe-Animationen verwendet.
|
||
* @version 1.0
|
||
*/
|
||
|
||
/**
|
||
* ==========================================================
|
||
* @section PRODUCT PAGE – Animated Detail View & Shop Offers
|
||
* @brief Hauptbereich der Produktseite, der das Bild und die Details umschließt.
|
||
* ==========================================================
|
||
*/
|
||
|
||
/**
|
||
* @class .product-wrapper
|
||
* @brief Haupt-Container für die Produktpräsentation.
|
||
* @details Setzt eine maximale Breite, zentriert den Inhalt und ordnet die linke und rechte Spalte nebeneinander an.
|
||
* Nutzt eine Fade-In-Animation beim Laden.
|
||
*/
|
||
.product-wrapper {
|
||
max-width: 1200px;
|
||
margin: 3rem auto;
|
||
padding: 0 1.5rem;
|
||
display: flex;
|
||
gap: 3.5rem;
|
||
animation: fadeInUp 0.6s ease both;
|
||
}
|
||
|
||
/**
|
||
* ─── Left Column (Image) ───
|
||
*/
|
||
|
||
/**
|
||
* @class .product-left
|
||
* @brief Linke Spalte, die das Produktbild enthält.
|
||
* @details Nimmt 1 Teil des Flex-Containers ein und wird mit einer leichten Verzögerung eingeblendet.
|
||
*/
|
||
.product-left {
|
||
flex: 1;
|
||
animation: fadeInUp 0.5s ease 0.1s both;
|
||
}
|
||
|
||
/**
|
||
* @class .product-image-box
|
||
* @brief Box-Container für das eigentliche Produktbild.
|
||
* @details Beinhaltet Hintergrund, Schatten, Abrundungen und positioniert pseudo-Elemente für Hover-Effekte.
|
||
*/
|
||
.product-image-box {
|
||
background: #ffffff;
|
||
padding: 40px;
|
||
border-radius: 14px;
|
||
box-shadow: 0 8px 25px rgba(0,0,0,0.08);
|
||
text-align: center;
|
||
transition: all var(--transition-smooth);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/**
|
||
* @pseudo .product-image-box::before
|
||
* @brief Animierter Gradient-Rahmen beim Hover.
|
||
* @details Nutzt Maskierungen (-webkit-mask), um einen leuchtenden Rahmen über den bestehenden Border zu zeichnen, der weich eingeblendet wird.
|
||
*/
|
||
.product-image-box::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: -1px;
|
||
border-radius: var(--radius-xl);
|
||
padding: 1px;
|
||
background: linear-gradient(135deg, rgba(37, 99, 235, 0.3), rgba(74, 222, 128, 0.2), transparent);
|
||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||
-webkit-mask-composite: xor;
|
||
mask-composite: exclude;
|
||
opacity: 0;
|
||
transition: opacity var(--transition-smooth);
|
||
}
|
||
|
||
/**
|
||
* @state .product-image-box:hover
|
||
* @brief Hover-Zustand für die Bild-Box.
|
||
* @details Verstärkt den Schatten und hebt das Element leicht an (TranslateY).
|
||
*/
|
||
.product-image-box:hover {
|
||
box-shadow: var(--shadow-lg), var(--shadow-glow-blue);
|
||
transform: translateY(-4px);
|
||
}
|
||
|
||
/**
|
||
* @state .product-image-box:hover::before
|
||
* @brief Macht den Gradient-Rahmen beim Hover sichtbar.
|
||
*/
|
||
.product-image-box:hover::before {
|
||
opacity: 1;
|
||
}
|
||
|
||
/**
|
||
* @element .product-image-box img
|
||
* @brief Das Produktbild selbst.
|
||
* @details Skaliert sich weich beim Hovern.
|
||
*/
|
||
.product-image-box img {
|
||
max-width: 100%;
|
||
height: auto;
|
||
object-fit: contain;
|
||
transition: transform var(--transition-smooth);
|
||
}
|
||
|
||
/**
|
||
* @state .product-image-box:hover img
|
||
* @brief Vergrößert das Bild beim Hover leicht (Scale).
|
||
*/
|
||
.product-image-box:hover img {
|
||
transform: scale(1.03);
|
||
}
|
||
|
||
/**
|
||
* ─── Right Column (Details) ───
|
||
*/
|
||
|
||
/**
|
||
* @class .product-right
|
||
* @brief Rechte Spalte für die Produktdetails (Titel, Beschreibung, Spezifikationen).
|
||
* @details Nimmt 1.2 Teile des Flex-Platzes ein, etwas mehr als das Bild. Besitzt ebenfalls eine Fade-In Animation.
|
||
*/
|
||
.product-right {
|
||
flex: 1.2;
|
||
animation: fadeInUp 0.5s ease 0.2s both;
|
||
}
|
||
|
||
/**
|
||
* @class .product-title
|
||
* @brief Titel des Produkts.
|
||
* @details Große weiße Schrift mit einer Trennlinie nach unten.
|
||
*/
|
||
.product-title {
|
||
font-size: 32px;
|
||
color: white;
|
||
font-weight: 600;
|
||
margin-bottom: 30px;
|
||
border-bottom: 2px solid #eaeaea;
|
||
padding-bottom: 15px;
|
||
}
|
||
|
||
/**
|
||
* @class .product-desc
|
||
* @brief Kurze Beschreibungstexte zum Produkt.
|
||
*/
|
||
.product-desc {
|
||
font-size: 23px;
|
||
line-height: 1.7;
|
||
color: #ffffff;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
/**
|
||
* @class .product-specs
|
||
* @brief Container für die Haupt-Spezifikationen.
|
||
* @details Richtet Elemente vertikal aus (Flex-Column) mit entsprechendem Abstand (Gap).
|
||
*/
|
||
.product-specs {
|
||
display: flex;
|
||
color: #ffffff;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
}
|
||
|
||
/**
|
||
* @element .product-specs p
|
||
* @brief Einzelner Spec-Absatz.
|
||
* @details Halbtransparenter Hintergrund mit Blur-Effekt, um Tiefe zu simulieren.
|
||
*/
|
||
.product-specs p {
|
||
padding: 0.7rem 1rem;
|
||
background: rgba(27, 34, 48, 0.65);
|
||
backdrop-filter: blur(8px);
|
||
border: 1px solid var(--border-subtle);
|
||
border-radius: var(--radius-md);
|
||
font-size: 0.9rem;
|
||
transition: all var(--transition-normal);
|
||
}
|
||
|
||
/**
|
||
* @state .product-specs p:hover
|
||
* @brief Hover-Effekt für Specs.
|
||
* @details Der Hintergrund wird deckender und der Text rückt leicht nach rechts ein.
|
||
*/
|
||
.product-specs p:hover {
|
||
background: rgba(27, 34, 48, 0.9);
|
||
border-color: var(--border-default);
|
||
transform: translateX(4px);
|
||
}
|
||
|
||
/**
|
||
* @element .product-specs p strong
|
||
* @brief Hervorhebung des Spec-Labels innerhalb eines Absatzes.
|
||
*/
|
||
.product-specs p strong {
|
||
color: var(--text-muted);
|
||
font-weight: 500;
|
||
margin-right: 0.5rem;
|
||
}
|
||
|
||
/**
|
||
* ─── Spec Rows ───
|
||
*/
|
||
|
||
/**
|
||
* @class .spec-row
|
||
* @brief Zeilenbasierte Darstellung einer einzelnen Spezifikation.
|
||
* @details Nutzt Flexbox zur Verteilung von Label und Wert an die äußeren Ränder.
|
||
*/
|
||
.spec-row {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 0.75rem 1rem;
|
||
background: var(--bg-surface);
|
||
border: 1px solid var(--border-subtle);
|
||
border-radius: var(--radius-md);
|
||
transition: all var(--transition-normal);
|
||
}
|
||
|
||
/**
|
||
* @state .spec-row:hover
|
||
* @brief Hover-Verhalten einer Spec-Row.
|
||
* @details Ähnlich wie bei .product-specs p, leichtes Verschieben nach rechts.
|
||
*/
|
||
.spec-row:hover {
|
||
background: rgba(27, 34, 48, 0.9);
|
||
transform: translateX(4px);
|
||
}
|
||
|
||
/**
|
||
* @class .spec-name
|
||
* @brief Der Name bzw. die Bezeichnung der Spezifikation in der Zeile.
|
||
*/
|
||
.spec-name {
|
||
font-weight: 500;
|
||
color: var(--text-secondary);
|
||
}
|
||
|
||
/**
|
||
* @class .spec-value
|
||
* @brief Der tatsächliche Wert der Spezifikation, fett hervorgehoben.
|
||
*/
|
||
.spec-value {
|
||
font-weight: 600;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
/**
|
||
* ─── Responsive Product Page ───
|
||
* @details Media-Queries für Tablets und Smartphones im Produkt-Bereich.
|
||
*/
|
||
@media (max-width: 900px) {
|
||
.product-wrapper {
|
||
flex-direction: column;
|
||
gap: 2rem;
|
||
margin: 1.5rem auto;
|
||
padding: 0 1rem;
|
||
}
|
||
|
||
.product-image-box {
|
||
padding: 1.5rem;
|
||
}
|
||
|
||
.product-title {
|
||
font-size: 1.4rem;
|
||
margin-bottom: 1rem;
|
||
padding-bottom: 0.75rem;
|
||
}
|
||
|
||
.product-desc {
|
||
font-size: 0.92rem;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 600px) {
|
||
.product-wrapper {
|
||
gap: 1.25rem;
|
||
margin: 1rem auto;
|
||
padding: 0 0.75rem;
|
||
}
|
||
|
||
.product-image-box {
|
||
padding: 1rem;
|
||
border-radius: var(--radius-lg);
|
||
}
|
||
|
||
.product-title {
|
||
font-size: 1.2rem;
|
||
}
|
||
|
||
.product-desc {
|
||
font-size: 0.88rem;
|
||
line-height: 1.6;
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
.product-specs p {
|
||
padding: 0.6rem 0.8rem;
|
||
font-size: 0.85rem;
|
||
}
|
||
|
||
.product-specs p:hover {
|
||
transform: none;
|
||
}
|
||
|
||
/* Wishlist button under image on mobile */
|
||
.product-left .auth__actions {
|
||
margin-top: 0.75rem;
|
||
}
|
||
|
||
.product-left .auth__submit {
|
||
font-size: 0.88rem;
|
||
min-height: 46px;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* ==========================================================
|
||
* @section SHOP OFFERS – Animated List
|
||
* @brief Bereich für die Anzeige verfügbarer Angebote verschiedener Shops.
|
||
* ==========================================================
|
||
*/
|
||
|
||
/**
|
||
* @class .shop-offers
|
||
* @brief Container, der alle Shop-Angebote umschließt.
|
||
* @details Vertikales Flexbox-Layout mit Animation.
|
||
*/
|
||
.shop-offers {
|
||
max-width: 1200px;
|
||
margin: 0 auto 4rem;
|
||
padding: 0 1.5rem;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 0.65rem;
|
||
animation: fadeInUp 0.6s ease 0.3s both;
|
||
}
|
||
|
||
/**
|
||
* @class .shop-line
|
||
* @brief Eine einzelne Zeile für ein Shop-Angebot.
|
||
* @details Nutzt ein CSS Grid mit 3 Spalten (Bild, Details, Preis/Button).
|
||
*/
|
||
.shop-line {
|
||
display: grid;
|
||
grid-template-columns: 250px 1fr auto;
|
||
align-items: center;
|
||
gap: 1.5rem;
|
||
background: #1f2a3a;
|
||
border: 1px solid #2f3c52;
|
||
border-radius: 12px;
|
||
padding: 1rem 1.5rem;
|
||
transition: all var(--transition-smooth);
|
||
animation: fadeInUp 0.4s ease both;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/**
|
||
* @pseudo .shop-line::before
|
||
* @brief Dekorationslinie (Gradient), die links auftaucht, wenn man über das Angebot fährt.
|
||
*/
|
||
.shop-line::before {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
bottom: 0;
|
||
width: 3px;
|
||
background: linear-gradient(180deg, var(--color-primary), var(--color-accent));
|
||
border-radius: var(--radius-full);
|
||
opacity: 0;
|
||
transition: opacity var(--transition-smooth);
|
||
}
|
||
|
||
/**
|
||
* @state .shop-line:hover
|
||
* @brief Interaktion mit einem Shop-Angebot.
|
||
* @details Ändert die Hintergrundfarbe, erzeugt Schatten und animiert nach oben.
|
||
*/
|
||
.shop-line:hover {
|
||
background: #243248;
|
||
transform: translateY(-3px);
|
||
box-shadow: 0 8px 20px rgba(0,0,0,0.25);
|
||
}
|
||
|
||
/**
|
||
* @state .shop-line:hover::before
|
||
* @brief Blendet die linke Dekorationslinie beim Hovern ein.
|
||
*/
|
||
.shop-line:hover::before {
|
||
opacity: 1;
|
||
}
|
||
|
||
/**
|
||
* @brief Staggered Animations
|
||
* @details Verzögert das Einblenden der Listenelemente sukzessive für einen Wasserfall-Effekt.
|
||
*/
|
||
.shop-line:nth-child(1) { animation-delay: 0.35s; }
|
||
.shop-line:nth-child(2) { animation-delay: 0.42s; }
|
||
.shop-line:nth-child(3) { animation-delay: 0.49s; }
|
||
.shop-line:nth-child(4) { animation-delay: 0.56s; }
|
||
.shop-line:nth-child(5) { animation-delay: 0.63s; }
|
||
|
||
/**
|
||
* @class .shop-left
|
||
* @brief Linker Abschnitt in einem Shop-Angebot (Logo).
|
||
*/
|
||
.shop-left {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 1rem;
|
||
}
|
||
|
||
/**
|
||
* @class .shop-logo
|
||
* @brief Container für das Shop-Logo.
|
||
*/
|
||
.shop-logo {
|
||
display: flex;
|
||
align-items: center;
|
||
height: 40px;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/**
|
||
* @element .shop-logo img
|
||
* @brief Das Bild des Shop-Logos.
|
||
*/
|
||
.shop-logo img {
|
||
max-height: 36px;
|
||
max-width: 90px;
|
||
object-fit: contain;
|
||
border-radius: var(--radius-sm);
|
||
transition: transform var(--transition-normal);
|
||
}
|
||
|
||
/**
|
||
* @state .shop-line:hover .shop-logo img
|
||
* @brief Skaliert das Logo beim Hovern über die Zeile.
|
||
*/
|
||
.shop-line:hover .shop-logo img {
|
||
transform: scale(1.08);
|
||
}
|
||
|
||
/**
|
||
* @class .shop-name
|
||
* @brief Textanzeige des Shop-Namens.
|
||
*/
|
||
.shop-name {
|
||
color: white;
|
||
font-weight: 600;
|
||
font-size: 16px;
|
||
}
|
||
|
||
/**
|
||
* @element .shop-name a
|
||
* @brief Link auf den Shop, falls der Name geklickt wird.
|
||
*/
|
||
.shop-name a {
|
||
color: white;
|
||
text-decoration: none;
|
||
}
|
||
|
||
/**
|
||
* @state .shop-name a:hover
|
||
* @brief Unterstreichung beim Hover über den Shop-Namen.
|
||
*/
|
||
.shop-name a:hover {
|
||
text-decoration: underline;
|
||
}
|
||
|
||
/**
|
||
* @class .shop-middle
|
||
* @brief Mittlerer Abschnitt mit Zusatzinfos (Versand, Bestand).
|
||
*/
|
||
.shop-middle {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 2rem;
|
||
font-size: 14px;
|
||
color: #cbd5e1;
|
||
}
|
||
|
||
/**
|
||
* @class .shop-shipping
|
||
* @brief Bereich für Versandinformationen.
|
||
*/
|
||
.shop-shipping {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
/**
|
||
* @class .shop-stock
|
||
* @brief Lagerbestands-Anzeige.
|
||
*/
|
||
.shop-stock {
|
||
font-weight: 500;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
}
|
||
|
||
/**
|
||
* @state .shop-stock.in-stock::before
|
||
* @brief Prefix-Icon für vorrätige Artikel (grünes Häkchen).
|
||
*/
|
||
.shop-stock.in-stock::before {
|
||
content: "✔";
|
||
color: #22c55e;
|
||
}
|
||
|
||
/**
|
||
* @state .shop-stock.out-stock::before
|
||
* @brief Prefix-Icon für nicht vorrätige Artikel (rotes X).
|
||
*/
|
||
.shop-stock.out-stock::before {
|
||
content: "✖";
|
||
color: #ef4444;
|
||
}
|
||
|
||
/**
|
||
* @class .shop-price
|
||
* @brief Preis-Hervorhebung ganz rechts in der Shop-Zeile.
|
||
*/
|
||
.shop-price {
|
||
margin-left: auto;
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #4ade80;
|
||
}
|
||
|
||
/**
|
||
* @state .shop-line:hover .shop-price
|
||
* @brief Skaliert den Preis leicht bei Interaktion.
|
||
*/
|
||
.shop-line:hover .shop-price {
|
||
transform: scale(1.05);
|
||
}
|
||
|
||
/**
|
||
* @class .no-shop
|
||
* @brief Fallback-Ansicht, wenn kein Angebot vorhanden ist.
|
||
*/
|
||
.no-shop {
|
||
background: #1f2a3a;
|
||
padding: 20px;
|
||
border-radius: 12px;
|
||
color: #cbd5e1;
|
||
text-align: center;
|
||
}
|
||
|
||
/**
|
||
* ─── Responsive Shop Offers ───
|
||
* @details Umbrüche für Shop-Zeilen bei kleineren Screens.
|
||
*/
|
||
@media (max-width: 900px) {
|
||
.shop-line {
|
||
grid-template-columns: 1fr;
|
||
gap: 0.75rem;
|
||
padding: 1rem;
|
||
}
|
||
|
||
.shop-middle {
|
||
flex-wrap: wrap;
|
||
gap: 0.75rem;
|
||
}
|
||
|
||
.shop-price {
|
||
font-size: 1.2rem;
|
||
}
|
||
|
||
.shop-offers {
|
||
padding: 0 1rem;
|
||
margin-bottom: 3rem;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 600px) {
|
||
.shop-line {
|
||
gap: 0.5rem;
|
||
padding: 0.85rem;
|
||
border-radius: var(--radius-md);
|
||
}
|
||
|
||
.shop-line:hover {
|
||
padding-left: 0.85rem;
|
||
transform: none;
|
||
}
|
||
|
||
.shop-left {
|
||
gap: 0.75rem;
|
||
}
|
||
|
||
.shop-logo img {
|
||
max-height: 28px;
|
||
max-width: 70px;
|
||
}
|
||
|
||
.shop-name {
|
||
font-size: 0.88rem;
|
||
}
|
||
|
||
.shop-middle {
|
||
gap: 0.5rem;
|
||
font-size: 0.8rem;
|
||
}
|
||
|
||
.shop-stock {
|
||
font-size: 0.72rem;
|
||
padding: 0.2rem 0.6rem;
|
||
}
|
||
|
||
.shop-price {
|
||
font-size: 1.1rem;
|
||
}
|
||
|
||
.shop-offers {
|
||
padding: 0 0.75rem;
|
||
gap: 0.5rem;
|
||
}
|
||
|
||
.no-shop {
|
||
padding: 1.5rem;
|
||
font-size: 0.88rem;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* ==========================================================
|
||
* @section PRODUCT REVIEWS
|
||
* @brief Anzeige und Strukturierung der Produktbewertungen.
|
||
* ==========================================================
|
||
*/
|
||
|
||
/**
|
||
* @class .reviews
|
||
* @brief Wrapper für alle Bewertungen, inklusive Überschrift.
|
||
*/
|
||
.reviews {
|
||
max-width: 1200px;
|
||
margin: 3rem auto 5rem;
|
||
padding: 0 1.5rem;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 1rem;
|
||
animation: fadeInUp 0.6s ease 0.4s both;
|
||
}
|
||
|
||
/**
|
||
* @class .reviews-title
|
||
* @brief Titel der Bewertungs-Sektion.
|
||
*/
|
||
.reviews-title {
|
||
color: white;
|
||
font-size: 22px;
|
||
font-weight: 600;
|
||
margin-bottom: 0.5rem;
|
||
}
|
||
|
||
/**
|
||
* @class .review-card
|
||
* @brief Einzelne Karte für eine Bewertung von einem User.
|
||
* @details Beinhaltet Hintergrund, Ränder und relative Positionierung für den Border-Effekt.
|
||
*/
|
||
.review-card {
|
||
background: #1c2533; /* leicht dunkler als shop */
|
||
border: 1px solid #2a374a;
|
||
border-radius: 14px;
|
||
padding: 1.2rem 1.5rem;
|
||
transition: all var(--transition-smooth);
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/**
|
||
* @pseudo .review-card::after
|
||
* @brief Gradient-Rahmenkante auf der rechten Seite, die beim Hover erscheint.
|
||
*/
|
||
.review-card::after {
|
||
content: "";
|
||
position: absolute;
|
||
right: 0;
|
||
top: 0;
|
||
bottom: 0;
|
||
width: 3px;
|
||
background: linear-gradient(180deg, var(--color-accent), var(--color-primary));
|
||
opacity: 0;
|
||
transition: opacity var(--transition-smooth);
|
||
}
|
||
|
||
/**
|
||
* @state .review-card:hover
|
||
* @brief Hover-State der Bewertung, hellt Hintergrund leicht auf.
|
||
*/
|
||
.review-card:hover {
|
||
background: #223047;
|
||
transform: translateY(-3px);
|
||
box-shadow: 0 8px 18px rgba(0,0,0,0.25);
|
||
}
|
||
|
||
/**
|
||
* @state .review-card:hover::after
|
||
* @brief Blendet den farbigen Rand rechts ein.
|
||
*/
|
||
.review-card:hover::after {
|
||
opacity: 1;
|
||
}
|
||
|
||
/**
|
||
* @class .review-header
|
||
* @brief Kopfzeile einer Bewertung (User links, Sterne/Datum z.B. rechts).
|
||
*/
|
||
.review-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 0.6rem;
|
||
}
|
||
|
||
/**
|
||
* @class .review-user-info
|
||
* @brief Container für Avatar, Name und ggf. Datum.
|
||
*/
|
||
.review-user-info {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.75rem;
|
||
min-width: 0; /* erlaubt Text-Ellipsis/Umbruch in flex */
|
||
}
|
||
|
||
/**
|
||
* @class .review-avatar
|
||
* @brief Profilbild in kleinen Abmessungen innerhalb der Review.
|
||
*/
|
||
.review-avatar {
|
||
width: clamp(28px, 3.2vw, 34px);
|
||
height: clamp(28px, 3.2vw, 34px);
|
||
flex: 0 0 auto;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
object-position: center;
|
||
display: block;
|
||
border: 1px solid rgba(148, 163, 184, 0.35);
|
||
background: #0f172a; /* falls Bild transparent/fehlend */
|
||
}
|
||
|
||
/**
|
||
* @class .review-user
|
||
* @brief Benutzername des Reviewers, wird abgeschnitten (ellipsis), wenn zu lang.
|
||
*/
|
||
.review-user {
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.review-user {
|
||
font-weight: 600;
|
||
color: white;
|
||
font-size: 15px;
|
||
}
|
||
|
||
/**
|
||
* @class .review-rating
|
||
* @brief Container für die Sterne-Bewertung.
|
||
*/
|
||
.review-rating {
|
||
display: flex;
|
||
gap: 4px;
|
||
}
|
||
|
||
/**
|
||
* @class .star
|
||
* @brief Ein einzelnes Stern-Symbol.
|
||
*/
|
||
.star {
|
||
font-size: 16px;
|
||
color: #475569;
|
||
transition: transform 0.2s ease;
|
||
}
|
||
|
||
/**
|
||
* @state .star.filled
|
||
* @brief Aktiver, goldener Stern.
|
||
*/
|
||
.star.filled {
|
||
color: #fbbf24;
|
||
}
|
||
|
||
/**
|
||
* @state .review-card:hover .star.filled
|
||
* @brief Skaliert goldene Sterne innerhalb einer Karte beim Hovern.
|
||
*/
|
||
.review-card:hover .star.filled {
|
||
transform: scale(1.15);
|
||
}
|
||
|
||
/**
|
||
* @class .review-comment
|
||
* @brief Textinhalt einer Bewertung.
|
||
*/
|
||
.review-comment {
|
||
color: #cbd5e1;
|
||
font-size: 14px;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
/**
|
||
* @class .no-review
|
||
* @brief Fallback-Text, falls noch keine Bewertungen existieren.
|
||
*/
|
||
.no-review {
|
||
background: #1f2a3a;
|
||
border: 1px solid #2f3c52;
|
||
border-radius: 12px;
|
||
padding: 1rem 1.5rem;
|
||
color: #94a3b8;
|
||
}
|
||
|
||
|
||
/**
|
||
* ==========================================================
|
||
* @section REVIEW OVERVIEW BOX (Linke Spalte) - Kompakte Version
|
||
* @brief Zusammenfassung aller Bewertungen (Durchschnittsnote und Sterne-Verteilung).
|
||
* ==========================================================
|
||
*/
|
||
|
||
/**
|
||
* @class .review-overview-box
|
||
* @brief Sidebar-Box zur Übersicht der Gesamtbewertung.
|
||
*/
|
||
.review-overview-box {
|
||
background: #1c2533;
|
||
border: 1px solid #2a374a;
|
||
border-radius: var(--radius-lg);
|
||
/* Padding von 1.5rem auf 1rem reduziert für eine kleinere Box */
|
||
padding: 1rem;
|
||
margin-top: 1.5rem;
|
||
color: #cbd5e1;
|
||
animation: fadeInUp 0.5s ease 0.3s both;
|
||
}
|
||
|
||
/**
|
||
* @class .overview-header
|
||
* @brief Headerbereich der Übersicht (Zentriert, Rand unten).
|
||
*/
|
||
.overview-header {
|
||
text-align: center;
|
||
/* Abstände verringert */
|
||
margin-bottom: 0.8rem;
|
||
padding-bottom: 0.8rem;
|
||
border-bottom: 1px solid #2a374a;
|
||
}
|
||
|
||
/**
|
||
* @class .overview-avg
|
||
* @brief Die durchschnittliche Bewertung als große Zahl.
|
||
*/
|
||
.overview-avg {
|
||
/* Schriftgröße der Durchschnittsnote von 2.5rem auf 2rem verkleinert */
|
||
font-size: 2rem;
|
||
font-weight: 700;
|
||
color: white;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 0.4rem;
|
||
}
|
||
|
||
/**
|
||
* @element .overview-avg .star
|
||
* @brief Der Stern-Icon neben der Durchschnittsbewertung.
|
||
*/
|
||
.overview-avg .star {
|
||
/* Stern etwas verkleinert */
|
||
font-size: 1.5rem;
|
||
}
|
||
|
||
/**
|
||
* @class .overview-count
|
||
* @brief Anzahl der Gesamtbewertungen in kleinem Text.
|
||
*/
|
||
.overview-count {
|
||
/* Textgröße leicht verkleinert */
|
||
font-size: 0.8rem;
|
||
color: #94a3b8;
|
||
margin-top: 0.2rem;
|
||
}
|
||
|
||
/**
|
||
* @class .overview-breakdown
|
||
* @brief Container für die Verteilung (Progress-Bars) der einzelnen Sterne (5,4,3,2,1).
|
||
*/
|
||
.overview-breakdown {
|
||
display: flex;
|
||
flex-direction: column;
|
||
/* Abstand zwischen den Balken verringert */
|
||
gap: 0.4rem;
|
||
}
|
||
|
||
/**
|
||
* @class .breakdown-row
|
||
* @brief Einzelne Zeile der Verteilung (Stellt z.B. 5 Sterne und deren Balken dar).
|
||
*/
|
||
.breakdown-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.5rem;
|
||
/* Text bei den Balken etwas kleiner */
|
||
font-size: 0.8rem;
|
||
}
|
||
|
||
/**
|
||
* @class .breakdown-stars
|
||
* @brief Beschriftung am Start des Balkens ("5 Sterne").
|
||
*/
|
||
.breakdown-stars {
|
||
width: 50px;
|
||
white-space: nowrap;
|
||
text-align: right;
|
||
color: #cbd5e1;
|
||
}
|
||
|
||
/**
|
||
* @class .breakdown-bar-bg
|
||
* @brief Dunkler Hintergrund des Fortschrittsbalkens.
|
||
*/
|
||
.breakdown-bar-bg {
|
||
flex: 1;
|
||
/* Höhe der Balken von 8px auf 6px reduziert */
|
||
height: 6px;
|
||
background: #2a374a;
|
||
border-radius: 3px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/**
|
||
* @class .breakdown-bar-fill
|
||
* @brief Goldene Füllung des Balkens, je nach prozentualer Verteilung.
|
||
* @details Nutzt CSS-Transitions für einen aufbauenden Lade-Effekt.
|
||
*/
|
||
.breakdown-bar-fill {
|
||
height: 100%;
|
||
background: #fbbf24;
|
||
border-radius: 3px;
|
||
transition: width 0.8s ease-out;
|
||
}
|
||
|
||
/**
|
||
* @class .breakdown-num
|
||
* @brief Absolute Anzahl der Bewertungen für diese Stern-Reihe.
|
||
*/
|
||
.breakdown-num {
|
||
width: 20px;
|
||
text-align: right;
|
||
color: #94a3b8;
|
||
}
|
||
|
||
/**
|
||
* @class .overview-empty
|
||
* @brief Nachricht in der Übersicht, wenn keine Daten vorliegen.
|
||
*/
|
||
.overview-empty {
|
||
text-align: center;
|
||
color: #94a3b8;
|
||
padding: 0.5rem 0;
|
||
font-size: 0.85rem;
|
||
}
|
||
|
||
/**
|
||
* ==========================================================
|
||
* @section REVIEW HINZUFÜGEN (Formular)
|
||
* @brief Bereich zum Schreiben einer eigenen Bewertung.
|
||
* ==========================================================
|
||
*/
|
||
|
||
/**
|
||
* @class .review-add
|
||
* @brief Wrapper für das Eingabeformular.
|
||
*/
|
||
.review-add {
|
||
max-width: 1200px;
|
||
margin: 0 auto 2rem;
|
||
padding: 0 1.5rem;
|
||
animation: fadeInUp 0.5s ease 0.4s both;
|
||
}
|
||
|
||
/**
|
||
* @class .review-input-form
|
||
* @brief Das eigentliche Formular-Layout (vertikal).
|
||
*/
|
||
.review-input-form {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 1.2rem;
|
||
}
|
||
|
||
/**
|
||
* --- Sterne-Auswahl (Radio-Button Trick) ---
|
||
* @class .rating-input
|
||
* @brief Behälter für die Radio-Buttons zur Sternbewertung.
|
||
* @details Nutzt `flex-direction: row-reverse;`, um CSS-basiertes Highlighten vorheriger Sterne durch Geschwister-Selektoren zu ermöglichen.
|
||
*/
|
||
.rating-input {
|
||
display: flex;
|
||
/* Dreht die Reihenfolge um für den Hover-Effekt */
|
||
flex-direction: row-reverse;
|
||
justify-content: flex-end;
|
||
gap: 0.3rem;
|
||
}
|
||
|
||
/**
|
||
* @element .rating-input input[type="radio"]
|
||
* @brief Die eigentlichen HTML-Radio-Elemente werden versteckt.
|
||
*/
|
||
.rating-input input[type="radio"] {
|
||
display: none;
|
||
}
|
||
|
||
/**
|
||
* @element .rating-input label
|
||
* @brief Das angezeigte Label, das visuell als auswählbarer Stern fungiert.
|
||
*/
|
||
.rating-input label {
|
||
font-size: 2.2rem;
|
||
color: #475569; /* Dunkelgrau für leere Sterne */
|
||
cursor: pointer;
|
||
transition: color 0.2s ease, transform 0.2s ease;
|
||
}
|
||
|
||
/**
|
||
* @state .rating-input label:hover, ...
|
||
* @brief Hover- und Auswahl-Mechanik für die interaktiven Sterne.
|
||
* @details Wenn ein Stern gehovert oder angewählt (checked) wird, färben sich dieser und alle in der row-reverse-Reihenfolge nachfolgenden Sterne golden.
|
||
*/
|
||
.rating-input label:hover,
|
||
.rating-input label:hover ~ label,
|
||
.rating-input input[type="radio"]:checked ~ label {
|
||
color: #fbbf24; /* Das gleiche Gelb wie bei deinen bestehenden Sternen */
|
||
}
|
||
|
||
/**
|
||
* @state .rating-input label:hover
|
||
* @brief Kleiner Skalierungseffekt beim drüberfahren.
|
||
*/
|
||
.rating-input label:hover {
|
||
transform: scale(1.15);
|
||
}
|
||
|
||
/**
|
||
* --- Textarea ---
|
||
* @class .review-comment-input
|
||
* @brief Das Mahrzeilen-Textfeld für den eigentlichen Kommentar.
|
||
*/
|
||
.review-comment-input {
|
||
width: 100%;
|
||
background: #1f2a3a;
|
||
border: 1px solid #2f3c52;
|
||
border-radius: 8px;
|
||
padding: 1rem;
|
||
color: #cbd5e1;
|
||
font-family: inherit;
|
||
font-size: 1rem;
|
||
resize: vertical; /* Nuter kann das Feld nach unten größer ziehen */
|
||
transition: all var(--transition-smooth);
|
||
}
|
||
|
||
/**
|
||
* @state .review-comment-input:focus
|
||
* @brief Klick/Fokus-Status für das Textfeld, zeigt grünen Rahmen.
|
||
*/
|
||
.review-comment-input:focus {
|
||
outline: none;
|
||
border-color: #4ade80; /* Passt zu deinem grünen Button-Stil */
|
||
background: #243248;
|
||
box-shadow: 0 0 0 3px rgba(74, 222, 128, 0.1);
|
||
}
|
||
|
||
/**
|
||
* --- Button Positionierung ---
|
||
* @element .review-input-form .auth__submit
|
||
* @brief Stilisierung des Absende-Buttons innerhalb der Reviews.
|
||
*/
|
||
.review-input-form .auth__submit {
|
||
align-self: flex-start; /* Button bleibt linksbündig und wird nicht über die ganze Breite gestreckt */
|
||
padding: 0.8rem 2.5rem;
|
||
}
|
||
|
||
/**
|
||
* @class .reviews-all
|
||
* @brief Container für die Auflistung aller existierenden Bewertungen (ohne das Eingabeformular).
|
||
*/
|
||
.reviews-all {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 1.8rem; /* Hier kannst du den Abstand zwischen den Karten anpassen */
|
||
margin-bottom: 3rem; /* Etwas Luft nach unten zum "Hinzufügen"-Formular */
|
||
}
|
||
|
||
/**
|
||
* @class .review-comment
|
||
* @brief (Wiederholung/Erweiterung) Anpassung des Kommentar-Texts für Wortumbrüche.
|
||
* @details Zwingt den Browser bei überlangen Wörtern rechtzeitig umzubrechen, damit das Layout nicht explodiert.
|
||
*/
|
||
.review-comment {
|
||
color: #cbd5e1;
|
||
font-size: 14px;
|
||
line-height: 1.6;
|
||
|
||
/* NEU: Zwingt zu lange Wörter in die nächste Zeile */
|
||
overflow-wrap: break-word;
|
||
word-break: break-word;
|
||
hyphens: auto; /* Setzt automatisch Bindestriche, wenn möglich */
|
||
}
|
||
|