Fix: Carousel stays inside container for left alignment, breaks right only via negative margin-right. Fix contrast on mobile bottom nav (neutral-800, 10px).
This commit is contained in:
@@ -110,24 +110,17 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
|||||||
<div className="container relative z-10">
|
<div className="container relative z-10">
|
||||||
<div className="absolute right-0 top-0 bottom-0 w-16 bg-gradient-to-l from-neutral-dark to-transparent z-20 md:hidden pointer-events-none" />
|
<div className="absolute right-0 top-0 bottom-0 w-16 bg-gradient-to-l from-neutral-dark to-transparent z-20 md:hidden pointer-events-none" />
|
||||||
|
|
||||||
{/* Pure CSS Full-Bleed Alignment Container */}
|
{/* Carousel: stays inside container for left alignment, breaks right to viewport edge */}
|
||||||
<div style={{ '--offset': 'calc(50vw - 50%)' } as React.CSSProperties}>
|
<div
|
||||||
<div
|
ref={containerRef}
|
||||||
ref={containerRef}
|
onMouseDown={onMouseDown}
|
||||||
onMouseDown={onMouseDown}
|
onMouseLeave={onMouseLeave}
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseUp={onMouseUp}
|
||||||
onMouseUp={onMouseUp}
|
onMouseMove={onMouseMove}
|
||||||
onMouseMove={onMouseMove}
|
style={{ marginRight: 'calc(-50vw + 50%)' }}
|
||||||
style={{
|
className={`select-none flex gap-6 overflow-x-auto pb-8 pt-4 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden ${isDragging ? 'cursor-grabbing snap-none' : 'cursor-grab snap-x snap-mandatory'}`}
|
||||||
marginLeft: 'calc(-1 * var(--offset))',
|
>
|
||||||
marginRight: 'calc(-1 * var(--offset))',
|
{references.map((ref, i) => {
|
||||||
paddingLeft: 'var(--offset)',
|
|
||||||
paddingRight: 'var(--offset)',
|
|
||||||
scrollPaddingLeft: 'var(--offset)',
|
|
||||||
}}
|
|
||||||
className={`select-none flex overflow-x-auto pb-8 pt-4 [scrollbar-width:none] [-ms-overflow-style:none] [&::-webkit-scrollbar]:hidden ${isDragging ? 'cursor-grabbing snap-none' : 'cursor-grab snap-x snap-mandatory'}`}
|
|
||||||
>
|
|
||||||
{references.map((ref, i) => {
|
|
||||||
const imgSrc = ref.image
|
const imgSrc = ref.image
|
||||||
? (typeof ref.image === 'string' ? ref.image : ref.image.url)
|
? (typeof ref.image === 'string' ? ref.image : ref.image.url)
|
||||||
: fallbacks[i % fallbacks.length];
|
: fallbacks[i % fallbacks.length];
|
||||||
@@ -139,7 +132,7 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
|||||||
whileInView={{ opacity: 1, x: 0 }}
|
whileInView={{ opacity: 1, x: 0 }}
|
||||||
viewport={{ once: true, margin: "-50px" }}
|
viewport={{ once: true, margin: "-50px" }}
|
||||||
transition={{ delay: i * 0.1, duration: 1.0, ease: [0.16, 1, 0.3, 1] }}
|
transition={{ delay: i * 0.1, duration: 1.0, ease: [0.16, 1, 0.3, 1] }}
|
||||||
className="flex-shrink-0 w-[320px] md:w-[480px] snap-start group pointer-events-auto mr-6"
|
className="flex-shrink-0 w-[320px] md:w-[480px] snap-start group pointer-events-auto"
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
href={`/${locale}/referenzen#${ref.slug}`}
|
href={`/${locale}/referenzen#${ref.slug}`}
|
||||||
@@ -173,7 +166,8 @@ export function ReferencesSlider(props: ReferencesSliderProps) {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
{/* Right padding spacer so last card doesn't clip at viewport edge */}
|
||||||
|
<div className="flex-shrink-0 w-6" aria-hidden="true" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
<motion.span
|
<motion.span
|
||||||
animate={{ y: isActive ? 0 : 2 }}
|
animate={{ y: isActive ? 0 : 2 }}
|
||||||
className="text-[9px] font-bold mt-1 tracking-wide"
|
className="text-[10px] font-bold mt-1 tracking-wide"
|
||||||
>
|
>
|
||||||
{item.label}
|
{item.label}
|
||||||
</motion.span>
|
</motion.span>
|
||||||
@@ -144,7 +144,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
|||||||
key={item.label}
|
key={item.label}
|
||||||
onClick={() => setIsFlyoutOpen(!isFlyoutOpen)}
|
onClick={() => setIsFlyoutOpen(!isFlyoutOpen)}
|
||||||
className={`relative flex flex-col items-center justify-center flex-1 h-[62px] transition-colors duration-300 select-none w-full focus:outline-none ${
|
className={`relative flex flex-col items-center justify-center flex-1 h-[62px] transition-colors duration-300 select-none w-full focus:outline-none ${
|
||||||
isActive ? 'text-primary' : 'text-neutral-600 hover:text-neutral-900'
|
isActive ? 'text-primary' : 'text-neutral-800 hover:text-neutral-900'
|
||||||
}`}
|
}`}
|
||||||
style={{ WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation' }}
|
style={{ WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation' }}
|
||||||
>
|
>
|
||||||
@@ -159,7 +159,7 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
|||||||
href={mappedUrl}
|
href={mappedUrl}
|
||||||
onClick={() => setIsFlyoutOpen(false)}
|
onClick={() => setIsFlyoutOpen(false)}
|
||||||
className={`relative flex flex-col items-center justify-center flex-1 h-[62px] transition-colors duration-300 select-none ${
|
className={`relative flex flex-col items-center justify-center flex-1 h-[62px] transition-colors duration-300 select-none ${
|
||||||
isActive ? 'text-primary' : 'text-neutral-600 hover:text-neutral-900'
|
isActive ? 'text-primary' : 'text-neutral-800 hover:text-neutral-900'
|
||||||
}`}
|
}`}
|
||||||
style={{ WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation' }}
|
style={{ WebkitTapHighlightColor: 'transparent', touchAction: 'manipulation' }}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user