diff --git a/privat/CV/andreknie.de/src/components/TestimonialSlider.css b/privat/CV/andreknie.de/src/components/TestimonialSlider.css index ab53c04..f804e7e 100644 --- a/privat/CV/andreknie.de/src/components/TestimonialSlider.css +++ b/privat/CV/andreknie.de/src/components/TestimonialSlider.css @@ -2,17 +2,59 @@ padding: var(--section-padding) 20px; } +.testimonial-scroll-container { + display: flex; + overflow-x: auto; + scroll-snap-type: x mandatory; + scroll-behavior: smooth; + gap: 24px; + padding-bottom: 32px; /* Space for scrollbar and shadow */ + + /* Hide scrollbar for cleaner look, or keep it subtle */ + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE/Edge */ +} +.testimonial-scroll-container::-webkit-scrollbar { + display: none; /* Chrome/Safari */ +} + .testimonial-card { - max-width: 800px; - margin: 0 auto; - padding: 60px 48px; + /* On mobile, show ~85% width so the next card peeks in */ + flex: 0 0 calc(88% - 24px); + scroll-snap-align: start; + + /* Equal heights trick: cards stretch to the tallest sibling */ + display: flex; + flex-direction: column; + + margin: 0; + padding: 40px 32px; text-align: center; position: relative; } +@media (min-width: 768px) { + .testimonial-card { + /* On tablet, show ~60% width */ + flex: 0 0 calc(60% - 24px); + } +} + +@media (min-width: 1024px) { + .testimonial-card { + /* On desktop, show ~45% width */ + flex: 0 0 calc(45% - 24px); + } +} + .testimonial-quote { position: relative; margin-bottom: 32px; + /* Push author block to the bottom of the card */ + flex-grow: 1; + display: flex; + flex-direction: column; + justify-content: center; } .quote-mark { @@ -27,11 +69,13 @@ } .testimonial-quote p { - font-size: 1.2rem; - line-height: 1.7; + font-size: 1.1rem; + line-height: 1.6; color: var(--text-primary); font-style: italic; margin: 0; + position: relative; + z-index: 1; } .testimonial-author { @@ -39,6 +83,7 @@ align-items: center; justify-content: center; gap: 12px; + margin-top: auto; /* Force to bottom */ } .author-photo { @@ -58,27 +103,3 @@ color: var(--text-secondary); font-size: 0.85rem; } - -.testimonial-dots { - display: flex; - justify-content: center; - gap: 8px; - margin-top: 24px; -} - -.dot { - width: 8px; - height: 8px; - border-radius: 50%; - background: var(--glass-border); - border: none; - cursor: pointer; - transition: all var(--transition-fast); - padding: 0; -} - -.dot.active { - background: var(--accent-color); - box-shadow: 0 0 8px var(--accent-color); - transform: scale(1.3); -} diff --git a/privat/CV/andreknie.de/src/components/TestimonialSlider.jsx b/privat/CV/andreknie.de/src/components/TestimonialSlider.jsx index c596ed7..6d056ec 100644 --- a/privat/CV/andreknie.de/src/components/TestimonialSlider.jsx +++ b/privat/CV/andreknie.de/src/components/TestimonialSlider.jsx @@ -1,51 +1,31 @@ -import React, { useState, useEffect } from 'react' +import React from 'react' import './TestimonialSlider.css' /** - * Auto-rotating testimonial slider with quotes. - * Testimonials are passed as props (from content/meta/testimonials.yaml later). + * Manual testimonial slider (carousel). + * Equal heights, horizontal scroll, no autoplay. */ export default function TestimonialSlider({ testimonials = [] }) { - const [activeIndex, setActiveIndex] = useState(0) - - useEffect(() => { - if (testimonials.length <= 1) return - const interval = setInterval(() => { - setActiveIndex(prev => (prev + 1) % testimonials.length) - }, 6000) - return () => clearInterval(interval) - }, [testimonials.length]) - if (testimonials.length === 0) return null - const current = testimonials[activeIndex] - return (
-
-
- " -

{current.quote}

-
-
- {current.photo && {current.name}} -
- {current.name} - {current.role} +
+ {testimonials.map((current, i) => ( +
+
+ " +

{current.quote}

+
+
+ {current.photo && {current.name}} +
+ {current.name} + {current.role} +
+
-
- {testimonials.length > 1 && ( -
- {testimonials.map((_, i) => ( -
- )} + ))}
)