feat(parvagues): Comprehensive UI/UX enhancements for ParVagues subsite

This commit implements a series of improvements to the ParVagues subsite, addressing issues related to layout, interactivity, and content presentation.

Key changes include:

1.  **Header Redesign:**
    *   Implemented a thinner, single-row fixed header.
    *   Logo positioned top-left, navigation links centered, and "Book" button top-right.
    *   Dynamic title now appears next to the logo on scroll or non-home pages.

2.  **Interactive Section ("Potentiel/Composition/Performance"):**
    *   Added a pointer cursor for section selection.
    *   The active section is now clearly highlighted.
    *   Implemented auto-toggling between sections every 5 seconds, with timer reset on manual click.

3.  **Album Link Sorting:**
    *   Platform links for albums in the "Sorties" section are now consistently ordered: YouTube > Deezer > Spotify > Apple Music > Tidal > Amazon.

4.  **Upcoming Events ("Prochains Événements"):**
    *   Events are now sorted by increasing date (soonest first).
    *   Card styling was reviewed and confirmed to be appropriate.

5.  **Event Page Restructure:**
    *   Improved typography: Event title is H1, countdown timer is a prominent H2, and location is H3.
    *   Enhanced above-the-fold visibility of key event information and teasers.
    *   Revamped image gallery:
        *   Displays all images as fixed-size cards in a masonry layout.
        *   Images open in a modal view on click, with a close button and Esc key dismissal.
        *   Transparent images (PNGs) now have a light background for better visibility in cards and modal.

6.  **Footer Fix:**
    *   Resolved issue where footer content (especially links) could be hidden.
    *   Removed `overflow: hidden` from the footer and adjusted its internal layout (logo size, column structure) to ensure all content is visible.
    *   Confirmed main page flexbox structure correctly pushes the footer to the bottom of the viewport.

These changes collectively improve the visual appeal, usability, and information hierarchy of the ParVagues subsite.
parent 998a6768
// next/components/ImageGallery.js
import { useState } from 'react';
import { useState, useEffect } from 'react'; // Added useEffect
import Image from 'next/image';
import Masonry from 'react-masonry-css';
import styles from '@/styles/parvagues.module.css'; // Import css modules
export default function ImageGallery({ images, slug }) {
const [selectedImage, setSelectedImage] = useState(null);
// Close modal on Escape key press
useEffect(() => {
const handleEsc = (event) => {
if (event.key === 'Escape') {
setSelectedImage(null);
}
};
if (selectedImage) {
window.addEventListener('keydown', handleEsc);
}
return () => {
window.removeEventListener('keydown', handleEsc);
};
}, [selectedImage]);
const breakpointColumns = {
default: 3,
default: 4, // Changed to 4 for a denser grid
1024: 3,
768: 2,
480: 1
480: 1,
};
const isPng = (src) => typeof src === 'string' && src.toLowerCase().endsWith('.png');
return (
<>
<div className="mt-8">
<h3 className="text-xl font-semibold mb-4 text-purple-400">Galerie</h3>
<h3 className="text-2xl font-bold mb-6 text-purple-300 text-center">Galerie Photos</h3>
<Masonry
breakpointCols={breakpointColumns}
className="masonry-grid" // Ensure this class or its child provides relative positioning for 'fill'
columnClassName="masonry-grid_column"
className={styles.galleryGrid} // Use CSS module for masonry grid
columnClassName={styles.galleryGridColumn}
>
{images.map((imageSrc, i) => (
<div
key={i}
className="mb-4 cursor-pointer hover:opacity-75 transition-opacity"
className={`${styles.galleryCard} mb-4 cursor-pointer group`}
onClick={() => setSelectedImage(imageSrc)}
>
{/* Ensure this div is the relatively positioned parent for fill */}
<div className="relative aspect-square rounded-lg overflow-hidden"> {/* Tailwind's aspect-square utility */}
<div className={`relative aspect-square rounded-lg overflow-hidden shadow-lg group-hover:shadow-xl transition-shadow duration-300 ${isPng(imageSrc) ? styles.pngBackground : 'bg-gray-800'}`}>
<Image
src={imageSrc}
alt={`${slug} image ${i + 1}`}
fill
className="object-cover" // object-cover will fill the square, cropping if necessary
className={`object-cover group-hover:scale-105 transition-transform duration-300`}
/>
</div>
</div>
......@@ -41,28 +59,28 @@ export default function ImageGallery({ images, slug }) {
</Masonry>
</div>
{/* Lightbox */}
{/* Modal */}
{selectedImage && (
<div
className="fixed inset-0 z-50 bg-black/90 flex items-center justify-center cursor-zoom-out"
className={styles.modalOverlay}
onClick={() => setSelectedImage(null)}
>
<div className="relative max-w-[90vw] max-h-[90vh]">
<div
className={`${styles.modalContent} ${isPng(selectedImage) ? styles.pngBackgroundModal : 'bg-gray-900'}`}
onClick={(e) => e.stopPropagation()} // Prevent click inside modal from closing it
>
<Image
src={selectedImage}
alt="Selected image"
width={1200} // These are for the lightbox, not the gallery thumbs
height={800} // These define the max dimensions and aspect ratio for the lightbox image
className="max-w-full max-h-full object-contain" // object-contain is good for lightbox
width={1600}
height={1200}
className="max-w-full max-h-full object-contain rounded-lg"
/>
<button
className="absolute top-4 right-4 text-white text-2xl hover:text-purple-400 transition-colors"
onClick={(e) => {
e.stopPropagation();
setSelectedImage(null);
}}
className={styles.modalCloseButton}
onClick={() => setSelectedImage(null)}
>
×
&times; {/* Using HTML entity for '×' for better rendering */}
</button>
</div>
</div>
......
......@@ -17,67 +17,71 @@ export default function ParVaguesFooter() {
const year = new Date().getFullYear();
return (
<footer className="bg-black border-t border-[#d900ff]/20 py-8 relative overflow-hidden">
<footer className="bg-black border-t border-[#d900ff]/20 py-8 relative"> {/* Removed overflow-hidden */}
<div className={styles.neonGradient}></div>
<div className="max-w-6xl mx-auto px-4 relative z-10">
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 items-start"> {/* Changed to md:grid-cols-3 and items-start */}
{/* About Column */}
<div>
<div className="md:col-span-1"> {/* Explicit column span */}
<p className="text-gray-400 text-sm mb-4">
Livecoding de musique libre<br />
Performances algorithmiques en direct.
</p>
<p className="text-xs text-gray-500">
&copy; {year} ParVagues. Tous droits réservés.
</p>
</div>
{/* Social Column */}
<div className="flex flex-col items-center md:items-end">
<div className="flex justify-center w-full">
<div className="relative">
{/* Logo Column (New) */}
<div className="md:col-span-1 flex flex-col items-center justify-center"> {/* Centering logo */}
<div className="relative mb-4">
<Image
src="/images/parvagues/logo.png"
alt="ParVagues Logo"
width={240}
height={240}
className="mx-auto mb-4"
width={100} // Reduced logo size
height={100} // Reduced logo size
/>
</div>
</div>
<div className="flex flex-wrap gap-4 justify-center md:justify-end">
{/* Social Column */}
<div className="md:col-span-1 flex flex-col items-center md:items-end"> {/* Explicit column span */}
<p className="text-gray-400 text-sm mb-3 text-center md:text-right">Restons connectés :</p>
<div className="flex flex-wrap gap-3 justify-center md:justify-end"> {/* Reduced gap */}
{socialLinks.map((link, index) => (
<a
key={index}
href={link.url}
target="_blank"
rel="noopener noreferrer"
className="bg-gray-800 hover:bg-[#8900b3]/60 text-white p-3 rounded-full transition-colors shadow-md hover:shadow-[#d900ff]/40"
className="bg-gray-800 hover:bg-purple-700/70 text-white p-2.5 rounded-full transition-colors shadow-md hover:shadow-purple-500/40" // Slightly smaller padding
aria-label={link.label}
>
{link.icon}
{React.cloneElement(link.icon, { size: '1.1em' })} {/* Slightly smaller icons */}
</a>
))}
</div>
</div>
</div>
{/* Navigation Links - more compact */}
<div className="w-full bg-black py-4">
<div className="flex justify-center items-center space-x-8 text-xs tracking-widest uppercase flex-wrap">
<Link href="/parvagues#music" className="text-gray-300 hover:text-[#ff3d7b] transition-colors tracking-wider px-3">
MUSIQUE
{/* Navigation Links - more compact and centered */}
<div className="w-full mt-8 pt-6 border-t border-purple-500/10"> {/* Added top margin, padding and border */}
<div className="flex justify-center items-center space-x-6 text-xs tracking-wider uppercase flex-wrap gap-y-2"> {/* Reduced space-x, added gap-y */}
<Link href="/parvagues#music" className="text-gray-400 hover:text-purple-400 transition-colors px-2">
Musique
</Link>
<Link href="/parvagues#performances" className="text-gray-300 hover:text-[#ff3d7b] transition-colors tracking-wider px-3">
PERFORMANCES
<Link href="/parvagues#performances" className="text-gray-400 hover:text-purple-400 transition-colors px-2">
Performances
</Link>
<Link href="/parvagues#about" className="text-gray-300 hover:text-[#ff3d7b] transition-colors tracking-wider px-3">
À PROPOS
<Link href="/parvagues#about" className="text-gray-400 hover:text-purple-400 transition-colors px-2">
À Propos
</Link>
<a
href="mailto:parvagues@nech.pl?subject=Booking Request"
className="text-gray-300 hover:text-[#ff3d7b] transition-colors tracking-wider px-3"
className="text-gray-400 hover:text-purple-400 transition-colors px-2"
>
RÉSERVER
Réserver
</a>
</div>
</div>
......
......@@ -27,30 +27,28 @@ function useScrolledPast(threshold = 100) {
export default function ParVaguesHeader({ eventName = null, title = null }) {
const router = useRouter();
const isHome = router.pathname === '/parvagues';
const showInHeader = useScrolledPast(300);
const showInHeader = useScrolledPast(300); // Threshold for showing title on scroll
const headerTitle = title || eventName || 'ParVagues';
return (
<header className="sticky top-0 left-0 w-full z-50 bg-black/80 backdrop-blur-md border-b border-[#d900ff]/20">
<header className={`sticky top-0 left-0 w-full z-50 bg-black/80 backdrop-blur-md border-b border-[#d900ff]/20 ${styles.headerContainer}`}>
<div className={`${styles.neonGradient} opacity-5 absolute inset-0`}></div>
<div className="max-w-6xl mx-auto px-4 py-3 flex items-center justify-between">
{/* Logo and Title with Navigation */}
<div className="flex items-center justify-between w-full">
<div className="max-w-full mx-auto px-4 flex items-center justify-between h-16"> {/* Reduced height here, e.g. h-16 for 4rem */}
{/* Logo and Title */}
<Link href="/parvagues" className="flex items-center group">
<div className="h-10 w-10 relative flex-shrink-0">
<div className="h-10 w-10 relative flex-shrink-0"> {/* Ensure logo size is controlled */}
<Image
src="/images/parvagues/logo.png"
alt="ParVagues Logo"
width={48}
height={48}
width={40} // Adjusted size
height={40} // Adjusted size
className="object-contain transition-all duration-300 group-hover:filter group-hover:drop-shadow-[0_0_8px_rgba(217,0,255,0.7)]"
/>
</div>
<div className="overflow-hidden ml-2">
<div className="overflow-hidden ml-3"> {/* Increased margin slightly */}
<span
className={`text-white font-bold transition-all duration-500 ${
showInHeader || !isHome ? 'opacity-100 translate-y-0' : 'opacity-0 -translate-y-8'
showInHeader || !isHome ? 'opacity-100 translate-y-0' : 'opacity-0 -translate-y-full' // Adjusted animation
}`}
style={{
textShadow: '0 0 5px rgba(217, 0, 255, 0.7), 0 0 10px rgba(217, 0, 255, 0.5)',
......@@ -62,17 +60,15 @@ export default function ParVaguesHeader({ eventName = null, title = null }) {
</div>
</Link>
{/* Navigation and CTA */}
<div className="flex items-center space-x-6">
{/* Navigation Links */}
<nav className="flex items-center space-x-6 text-sm tracking-wider">
<Link href="/parvagues#music" className="text-gray-300 hover:text-[#ff3d7b] transition-colors">
<nav className="flex-grow flex justify-center items-center space-x-6 text-sm tracking-wider">
<Link href="/parvagues#music" className={`${styles.navLink} text-gray-300 hover:text-[#ff3d7b] transition-colors`}>
Music
</Link>
<Link href="/parvagues#performances" className="text-gray-300 hover:text-[#ff3d7b] transition-colors">
<Link href="/parvagues#performances" className={`${styles.navLink} text-gray-300 hover:text-[#ff3d7b] transition-colors`}>
Performances
</Link>
<Link href="/parvagues#about" className="text-gray-300 hover:text-[#ff3d7b] transition-colors">
<Link href="/parvagues#about" className={`${styles.navLink} text-gray-300 hover:text-[#ff3d7b] transition-colors`}>
About
</Link>
</nav>
......@@ -80,14 +76,12 @@ export default function ParVaguesHeader({ eventName = null, title = null }) {
{/* CTA button */}
<Link
href="/book"
className={`${styles.outlineButton} py-2 px-4 text-sm flex items-center whitespace-nowrap`}
className={`${styles.outlineButton} ${styles.bookButton} py-2 px-4 text-sm flex items-center whitespace-nowrap`} // Added custom class for specific styling if needed
>
<FaEnvelope className="mr-2 flex-shrink-0" />
<span>Book</span>
</Link>
</div>
</div>
</div>
</header>
);
}
......@@ -67,10 +67,10 @@ export default function ParVagues({ lives }) {
const backgroundRef = useRef(null);
const audioRef = useRef(null);
// Filter future events
// Filter future events and sort them by date in ascending order
const futureEvents = lives.filter(live => {
return new Date(live.date) > new Date();
});
}).sort((a, b) => new Date(a.date) - new Date(b.date));
// Define section content
const sections = {
......@@ -120,6 +120,20 @@ d4 $ note ("<e3 fs3 <gs3 d4> <a3 df4>>" - 12)
}
}, [selectedSection]);
// Auto-toggling for sections (Potentiel, Composition, Performance)
const sectionOrder = ['potentiel', 'composition', 'performance'];
useEffect(() => {
const intervalId = setInterval(() => {
setSelectedSection(currentSection => {
const currentIndex = sectionOrder.indexOf(currentSection);
const nextIndex = (currentIndex + 1) % sectionOrder.length;
return sectionOrder[nextIndex];
});
}, 5000); // 5 seconds
return () => clearInterval(intervalId); // Cleanup on component unmount or when selectedSection changes
}, [selectedSection]); // Re-run effect (and reset timer) when selectedSection changes
// Auto-advance carousel for section images
useEffect(() => {
if (sections[selectedSection]?.images?.length > 1) {
......@@ -176,7 +190,10 @@ d4 $ note ("<e3 fs3 <gs3 d4> <a3 df4>>" - 12)
}
};
const albums = [
// Define the desired order of platforms
const platformOrder = ['YouTube', 'Deezer', 'Spotify', 'Apple', 'Tidal', 'Amazon'];
const albumsData = [
{
id: '2024_opal',
title: 'Livecoding (Opal Festival 2024)',
......@@ -204,6 +221,19 @@ d4 $ note ("<e3 fs3 <gs3 d4> <a3 df4>>" - 12)
}
];
// Sort the links for each album
const albums = albumsData.map(album => ({
...album,
links: album.links.sort((a, b) => {
const indexA = platformOrder.indexOf(a.platform);
const indexB = platformOrder.indexOf(b.platform);
// If a platform is not in platformOrder, keep its relative order towards the end
if (indexA === -1) return 1;
if (indexB === -1) return -1;
return indexA - indexB;
})
}));
const renderSectionContent = () => {
const sectionContent = sections[selectedSection];
if (!sectionContent) return null;
......@@ -344,36 +374,36 @@ d4 $ note ("<e3 fs3 <gs3 d4> <a3 df4>>" - 12)
<div className={styles.splitSection}>
<div>
<div
className={`cursor-pointer transition-all duration-300 hover:bg-purple-500/10 rounded-lg p-2 ${selectedSection === 'potentiel' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : ''}`}
className={`cursor-pointer transition-all duration-300 hover:bg-purple-500/10 rounded-lg p-2 ${selectedSection === 'potentiel' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : 'text-gray-400 border-l-2 border-transparent'}`}
onClick={() => setSelectedSection('potentiel')}
>
<h3 className={`${styles.bulletPoint} text-xl font-semibold text-purple-400 mb-2 group relative inline-block`} style={{ margin: '1em 0', textDecorationLine: 'underline', textDecorationColor: 'darkviolet', textDecorationThickness: '3px' }}>
<h3 className={`${styles.bulletPoint} text-xl font-semibold mb-2 group relative inline-block ${selectedSection === 'potentiel' ? 'text-purple-400' : 'text-gray-400'}`} style={{ margin: '1em 0', textDecorationLine: 'underline', textDecorationColor: 'darkviolet', textDecorationThickness: '3px' }}>
Potentiel
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-purple-400 to-pink-500 group-hover:w-full transition-all duration-300"></span>
</h3>
<p className="text-gray-300">Samples glanés et synthés SuperCollider</p>
<p className={`${selectedSection === 'potentiel' ? 'text-gray-300' : 'text-gray-500'}`}>Samples glanés et synthés SuperCollider</p>
</div>
<div
className={`cursor-pointer transition-all duration-300 hover:bg-purple-500/10 rounded-lg p-2 ${selectedSection === 'composition' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : ''}`}
className={`cursor-pointer transition-all duration-300 hover:bg-purple-500/10 rounded-lg p-2 ${selectedSection === 'composition' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : 'text-gray-400 border-l-2 border-transparent'}`}
onClick={() => setSelectedSection('composition')}
>
<h3 className={`${styles.bulletPoint} text-xl font-semibold text-purple-400 mb-2 group relative inline-block`} style={{ margin: '1em 0', textDecorationLine: 'underline', textDecorationColor: 'darkviolet', textDecorationThickness: '3px' }}>
<h3 className={`${styles.bulletPoint} text-xl font-semibold mb-2 group relative inline-block ${selectedSection === 'composition' ? 'text-purple-400' : 'text-gray-400'}`} style={{ margin: '1em 0', textDecorationLine: 'underline', textDecorationColor: 'darkviolet', textDecorationThickness: '3px' }}>
Composition
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-purple-400 to-pink-500 group-hover:w-full transition-all duration-300"></span>
</h3>
<p className="text-gray-300">Code Haskell TidalCycles + input MIDI</p>
<p className={`${selectedSection === 'composition' ? 'text-gray-300' : 'text-gray-500'}`}>Code Haskell TidalCycles + input MIDI</p>
</div>
<div
className={`cursor-pointer transition-all duration-300 hover:bg-purple-500/10 rounded-lg p-2 ${selectedSection === 'performance' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : ''}`}
className={`cursor-pointer transition-all duration-300 hover:bg-purple-500/10 rounded-lg p-2 ${selectedSection === 'performance' ? 'text-purple-400 border-l-2 border-purple-400 pl-4' : 'text-gray-400 border-l-2 border-transparent'}`}
onClick={() => setSelectedSection('performance')}
>
<h3 className={`${styles.bulletPoint} text-xl font-semibold text-purple-400 mb-2 group relative inline-block`} style={{ margin: '1em 0', textDecorationLine: 'underline', textDecorationColor: 'darkviolet', textDecorationThickness: '3px' }}>
<h3 className={`${styles.bulletPoint} text-xl font-semibold mb-2 group relative inline-block ${selectedSection === 'performance' ? 'text-purple-400' : 'text-gray-400'}`} style={{ margin: '1em 0', textDecorationLine: 'underline', textDecorationColor: 'darkviolet', textDecorationThickness: '3px' }}>
Performance
<span className="absolute bottom-0 left-0 w-0 h-0.5 bg-gradient-to-r from-purple-400 to-pink-500 group-hover:w-full transition-all duration-300"></span>
</h3>
<p className="text-gray-300">Performance live avec improvisation au contrôleur MIDI</p>
<p className={`${selectedSection === 'performance' ? 'text-gray-300' : 'text-gray-500'}`}>Performance live avec improvisation au contrôleur MIDI</p>
</div>
</div>
......
......@@ -258,45 +258,39 @@ export default function Live({ data, slug, images }) {
<div className="grid md:grid-cols-2 gap-6 items-center">
{/* Left Side: Event Info */}
<div>
<h1 className="text-4xl md:text-5xl font-bold mb-2 text-white">{data.frontmatter.title}</h1>
<h1 className="text-4xl md:text-6xl font-bold mb-3 text-white">{data.frontmatter.title}</h1>
{pastEvent ? (
<div className="inline-block bg-gray-800 text-white text-sm px-3 py-1 rounded-full mb-4">
{!pastEvent && (
<h2 className="text-2xl md:text-4xl font-semibold mb-3 text-purple-300">
{timeToEvent === 0 ? "Aujourd'hui !" : `Dans ${timeString}`}
</h2>
)}
{pastEvent && (
<h2 className="text-xl md:text-2xl font-semibold mb-3 text-gray-500">
Événement passé
</div>
) : (
<div className="inline-block bg-purple-800 text-white text-sm px-3 py-1 rounded-full mb-4">
{timeToEvent === 0 ? "Aujourd'hui" : `Dans ${timeString}`}
</div>
</h2>
)}
<div className="flex flex-col space-y-2 mb-4">
<div className="flex items-center">
<span className="text-purple-400 w-24">Date:</span>
<span>{formatEventDate(data.frontmatter.date)}</span>
</div>
<div className="flex items-center">
<span className="text-purple-400 w-24">Lieu:</span>
<span>{data.frontmatter.venue || 'À annoncer'}</span>
</div>
<h3 className="text-lg md:text-xl text-gray-400 mb-4">
{data.frontmatter.venue || 'Lieu à annoncer'}
{data.frontmatter.city && `, ${data.frontmatter.city}`}
</h3>
{data.frontmatter.city && (
<div className="flex flex-col space-y-1 mb-6 text-sm"> {/* Reduced space-y and mb */}
<div className="flex items-center">
<span className="text-purple-400 w-24">Ville:</span>
<span>{data.frontmatter.city}</span>
<span className="text-purple-400 w-20">Date:</span> {/* Reduced width */}
<span>{formatEventDate(data.frontmatter.date)}</span>
</div>
)}
</div>
{/* Action Buttons */}
<div className="flex flex-wrap gap-2 mt-4">
<div className="flex flex-wrap gap-3 mt-6"> {/* Increased gap and mt */}
{data.frontmatter.ticketLink && !pastEvent && (
<a
href={data.frontmatter.ticketLink}
target="_blank"
rel="noopener noreferrer"
className="bg-gradient-to-r from-purple-600 to-pink-600 px-4 py-2 rounded-md text-white font-medium hover:from-purple-700 hover:to-pink-700 transition-all shadow-lg"
className="bg-gradient-to-r from-purple-600 to-pink-600 px-6 py-3 rounded-lg text-white font-semibold hover:from-purple-700 hover:to-pink-700 transition-all shadow-lg hover:shadow-xl text-base" // Increased padding, font-size, rounded
>
Billets
</a>
......@@ -307,32 +301,32 @@ export default function Live({ data, slug, images }) {
href={data.frontmatter.eventLink}
target="_blank"
rel="noopener noreferrer"
className="bg-gray-800 hover:bg-gray-700 px-4 py-2 rounded-md text-white font-medium transition-all"
className="bg-gray-700 hover:bg-gray-600 px-5 py-3 rounded-lg text-white font-medium transition-all shadow-md hover:shadow-lg text-base" // Increased padding, font-size, adjusted colors
>
Info Event
Plus d'Infos
</a>
)}
<a
href="#details-section"
onClick={scrollToSection}
className="bg-transparent border border-purple-500 hover:bg-purple-900/30 px-4 py-2 rounded-md text-white font-medium transition-all"
className="bg-transparent border-2 border-purple-500 hover:bg-purple-500/20 px-5 py-3 rounded-lg text-purple-300 hover:text-white font-medium transition-all text-base" // Increased padding, font-size, border
>
Détails
Voir les Détails
</a>
</div>
</div>
{/* Right Side: Upcoming Drops or Latest Teasing */}
<div>
<div className="mt-6 md:mt-0"> {/* Added margin top for small screens */}
{!pastEvent && upcomingDrops.length > 0 ? (
<div className="bg-black/60 backdrop-blur p-4 rounded-lg border border-purple-500/30">
<h3 className="text-lg font-semibold text-purple-400 mb-3">Prochains drops</h3>
<ul className="space-y-2">
<div className="bg-black/70 backdrop-blur-md p-6 rounded-xl border border-purple-500/40 shadow-xl"> {/* Enhanced styling */}
<h3 className="text-xl font-bold text-purple-300 mb-4">Prochains Drops</h3> {/* Enhanced styling */}
<ul className="space-y-3">
{upcomingDrops.map((drop, i) => (
<li key={i} className="flex items-center justify-between bg-black/50 p-2 rounded">
<span className="text-sm">{drop.name}</span>
<span className="text-xs bg-purple-900/60 px-2 py-1 rounded">
<li key={i} className="flex items-center justify-between bg-gray-800/70 p-3 rounded-md shadow"> {/* Enhanced styling */}
<span className="text-sm font-medium text-gray-200">{drop.name}</span>
<span className="text-xs bg-purple-700/80 text-white px-3 py-1 rounded-full font-semibold"> {/* Enhanced styling */}
{getTimeDifferenceString(drop.date)}
</span>
</li>
......@@ -340,13 +334,17 @@ export default function Live({ data, slug, images }) {
</ul>
</div>
) : teasingsToShow.length > 0 ? (
<div className="bg-black/60 backdrop-blur p-4 rounded-lg border border-purple-500/30">
<h3 className="text-lg font-semibold text-purple-400 mb-2">
{pastEvent ? "Highlights" : "Teasing"}
<div className="bg-black/70 backdrop-blur-md p-6 rounded-xl border border-purple-500/40 shadow-xl"> {/* Enhanced styling */}
<h3 className="text-xl font-bold text-purple-300 mb-3"> {/* Enhanced styling */}
{pastEvent ? "Highlights" : "Dernier Teasing"}
</h3>
<div dangerouslySetInnerHTML={renderMarkdown(teasingsToShow[0])} className="prose prose-sm prose-invert max-w-none" />
<div dangerouslySetInnerHTML={renderMarkdown(teasingsToShow[0])} className="prose prose-base prose-invert max-w-none leading-relaxed" /> {/* Increased prose size, leading */}
</div>
) : (
<div className="bg-black/70 backdrop-blur-md p-6 rounded-xl border border-purple-500/40 shadow-xl text-gray-400">
<p>Plus de détails à venir prochainement...</p>
</div>
) : null}
)}
</div>
</div>
</div>
......@@ -418,44 +416,13 @@ export default function Live({ data, slug, images }) {
/>
</div>
)}
{/* Mini Gallery - Limited to 3 images */}
{images && images.length > 0 && (
<div className="bg-gray-900/40 rounded-lg p-4">
<h3 className="text-lg font-semibold text-purple-400 mb-2">Photos</h3>
<div className="grid grid-cols-3 gap-2">
{images.slice(0, 3).map((image, i) => (
<div key={i} className="relative aspect-square rounded overflow-hidden">
<img
src={image}
alt={`${data.frontmatter.title} - image ${i+1}`}
fill
className="live-gallery-image object-cover hover:scale-110 transition-transform duration-300 max-w-sm"
/>
</div>
))}
</div>
{images.length > 3 && (
<div className="mt-2 text-center">
<button
onClick={() => {
const gallery = document.getElementById('full-gallery');
gallery?.scrollIntoView({ behavior: 'smooth' });
}}
className="text-xs text-purple-400 hover:text-purple-300"
>
Voir les {images.length} photos →
</button>
</div>
)}
</div>
)}
{/* Artists / Other sidebar content can go here if needed */}
</div>
</div>
{/* Full Gallery - only if more than 3 images */}
{images && images.length > 3 && (
<div id="full-gallery" className="max-w-5xl mx-auto mt-8">
{/* Full Image Gallery - Render if images exist */}
{images && images.length > 0 && (
<div id="full-gallery" className="max-w-6xl mx-auto mt-12 pt-8 border-t border-purple-500/20"> {/* Increased max-width and added top margin/padding/border */}
<ImageGallery images={images} slug={slug} />
</div>
)}
......
......@@ -562,5 +562,100 @@ AS MODULE CSS FORBIDS ROOT VARIABLES
}
img.live-gallery-image {
max-width: 1em;
width: 100%;
height: 100%;
object-fit: cover;
}
/* Image Gallery Styles */
.galleryGrid {
display: flex;
margin-left: -1rem; /* gutter size offset */
width: auto;
}
.galleryGridColumn {
padding-left: 1rem; /* gutter size */
background-clip: padding-box;
}
.galleryCard {
/* Base card styling if needed beyond Tailwind */
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.galleryCard:hover {
transform: translateY(-5px);
}
.pngBackground {
background-color: #e9e9e9; /* Light gray background for PNG cards */
}
.pngBackgroundModal {
background-color: #cccccc; /* Slightly darker gray for modal PNG background for contrast */
}
.modalOverlay {
position: fixed;
inset: 0;
background-color: rgba(0, 0, 0, 0.85);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000; /* High z-index */
padding: 1rem;
}
.modalContent {
position: relative;
padding: 1rem; /* Padding around the image in modal */
border-radius: 0.5rem; /* Rounded corners for the modal content box */
max-width: 95vw;
max-height: 95vh;
display: flex; /* Allow image to determine size up to max */
align-items: center;
justify-content: center;
}
.modalCloseButton {
position: absolute;
top: -10px; /* Position outside the content padding */
right: -5px;
background: rgba(30, 30, 30, 0.8);
color: white;
border: none;
border-radius: 50%;
width: 30px;
height: 30px;
font-size: 1.5rem;
line-height: 28px; /* Vertically center times symbol */
text-align: center;
cursor: pointer;
transition: background-color 0.2s ease, color 0.2s ease;
box-shadow: 0 2px 10px rgba(0,0,0,0.5);
}
.modalCloseButton:hover {
background-color: var(--neon-high); /* Use theme color */
color: black;
}
/* Styles for the updated ParVaguesHeader */
.headerContainer {
/* Ensuring vertical alignment for items if needed, though Tailwind's `items-center` on the child div should handle this. */
/* Example: display: flex; align-items: center; */
/* Height is controlled by Tailwind's h-16 class in the component */
}
.navLink {
/* Individual styling for nav links if required beyond Tailwind classes */
/* Example: padding: 0.5rem 1rem; */
/* The space-x-6 on the parent nav element in JSX handles spacing between links */
}
.bookButton {
/* Specific adjustments for the book button if necessary */
/* Example: ensure it aligns well with the new header height */
/* padding-top: 0.5rem; padding-bottom: 0.5rem; /* Adjust if default py-2 is too large */
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment