Compare commits

..

No commits in common. "0b19589288e4c635068832e6e014cebdc1011468" and "436a4371da29eb51b632c032f05b2580a6305a5a" have entirely different histories.

20 changed files with 37 additions and 69 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -84,30 +84,13 @@ return [
// Thumbs // Thumbs
'thumbs' => [ 'thumbs' => [
'quality' => 80,
'srcsets' => [ 'srcsets' => [
'default' => [ 'default' => [
'300w' => ['width' => 300],
'600w' => ['width' => 600],
'900w' => ['width' => 900],
'1200w' => ['width' => 1200],
],
// Galerie portfolio — desktop ~15vw, mobile ~33vw (3 colonnes)
// Widths couvrent 1x et 2x retina pour les deux breakpoints
'gallery' => [
'200w' => ['width' => 200],
'300w' => ['width' => 300], '300w' => ['width' => 300],
'400w' => ['width' => 400],
'600w' => ['width' => 600], '600w' => ['width' => 600],
'800w' => ['width' => 800], '900w' => ['width' => 900],
], '1200w' => ['width' => 1200]
'gallery-webp' => [ ]
'200w' => ['width' => 200, 'format' => 'webp'], ]
'300w' => ['width' => 300, 'format' => 'webp'],
'400w' => ['width' => 400, 'format' => 'webp'],
'600w' => ['width' => 600, 'format' => 'webp'],
'800w' => ['width' => 800, 'format' => 'webp'],
],
],
], ],
]; ];

View file

@ -8,11 +8,7 @@ $specificData = [
'catchphrase' => $project->catchphrase()->value(), 'catchphrase' => $project->catchphrase()->value(),
'description' => $project->description()->value(), 'description' => $project->description()->value(),
'thumbnail' => $project->thumbnail()->toFile()?->url(), 'thumbnail' => $project->thumbnail()->toFile()?->url(),
'images_gallery' => $project->images_gallery()->toFiles()->map(fn($f) => [ 'images_gallery' => $project->images_gallery()->toFiles()->map(fn($f) => $f->url())->values(),
'src' => $f->url(),
'srcset' => $f->srcset('gallery'),
'webp' => $f->srcset('gallery-webp'),
])->values(),
'mockup' => $project->mockup()->toFile()?->url(), 'mockup' => $project->mockup()->toFile()?->url(),
'keywords' => $project->keywords()->toStructure()->map(fn($i) => [ 'keywords' => $project->keywords()->toStructure()->map(fn($i) => [
'label' => $i->label()->value(), 'label' => $i->label()->value(),

View file

@ -1,8 +1,8 @@
<script> <script>
/** /**
* GalleryAnimation — animation CSS de galerie en 3 colonnes défilantes. * GalleryAnimation — animation CSS de galerie en 3 colonnes défilantes.
* @prop {Array<{src: string, srcset: string, webp: string}>} images * @prop {string[]} images — URLs des images
* @prop {number} secondsPerImage — durée par image (défaut: 8s) * @prop {number} secondsPerImage — durée par image (défaut: 8s)
*/ */
let { images = [], secondsPerImage = 8 } = $props() let { images = [], secondsPerImage = 8 } = $props()
@ -38,22 +38,11 @@
style="animation-delay: -{col.delay}s" style="animation-delay: -{col.delay}s"
> >
<!-- Images × 2 pour le défilement infini --> <!-- Images × 2 pour le défilement infini -->
{#each [col.images, col.images] as set} {#each col.images as src}
{#each set as img} <img class="gallery-animation__image" {src} alt="" aria-hidden="true" loading="lazy" />
<picture> {/each}
<source type="image/webp" srcset={img.webp} sizes="(max-width: 700px) 33vw, 15vw" /> {#each col.images as src}
<img <img class="gallery-animation__image" {src} alt="" aria-hidden="true" loading="lazy" />
class="gallery-animation__image"
src={img.src}
srcset={img.srcset}
sizes="(max-width: 700px) 33vw, 15vw"
alt=""
aria-hidden="true"
loading="lazy"
decoding="async"
/>
</picture>
{/each}
{/each} {/each}
</div> </div>
</div> </div>

View file

@ -9,21 +9,32 @@
@font-face { @font-face {
font-family: "Danzza"; font-family: "Danzza";
src: local("Danzza Regular"), src: local("Danzza Regular"),
url("/assets/fonts/Danzza%20Regular.otf") format("opentype"); url("/assets/fonts/Danzza-Regular.woff") format("woff"),
url("/assets/fonts/Danzza-Regular.otf") format("opentype");
font-display: swap;
}
@font-face {
font-family: "Danzza Light";
src: local("Danzza Light"),
url("/assets/fonts/Danzza-Light.woff") format("woff"),
url("/assets/fonts/Danzza-Light.otf") format("opentype");
font-display: swap; font-display: swap;
} }
@font-face { @font-face {
font-family: "Danzza Medium"; font-family: "Danzza Medium";
src: local("Danzza Medium"), src: local("Danzza Medium"),
url("/assets/fonts/Danzza%20Medium.otf") format("opentype"); url("/assets/fonts/Danzza-Medium.woff") format("woff"),
url("/assets/fonts/Danzza-Medium.otf") format("opentype");
font-display: swap; font-display: swap;
} }
@font-face { @font-face {
font-family: "Danzza Bold"; font-family: "Danzza Bold";
src: local("Danzza Bold"), src: local("Danzza Bold"),
url("/assets/fonts/Danzza%20Bold.otf") format("opentype"); url("/assets/fonts/Danzza-Bold.woff") format("woff"),
url("/assets/fonts/Danzza-Bold.otf") format("opentype");
font-display: swap; font-display: swap;
} }
@ -36,9 +47,8 @@
font-family: "Danzza"; font-family: "Danzza";
} }
/* Danzza Light n'existe pas — pointe vers Regular */
.font-face-danzza-light { .font-face-danzza-light {
font-family: "Danzza"; font-family: "Danzza Light";
} }
.font-face-danzza-medium { .font-face-danzza-medium {
@ -52,10 +62,3 @@
.green { .green {
color: var(--color-primary); color: var(--color-primary);
} }
.gradient-blue {
-webkit-text-fill-color: transparent;
background: linear-gradient(90deg, #2c85f3 0, #68e0cf 50%);
background-clip: text;
-webkit-background-clip: text;
}

View file

@ -105,7 +105,7 @@
<!-- Infos projet (droite) --> <!-- Infos projet (droite) -->
<div class="portfolio-text" aria-live="polite"> <div class="portfolio-text" aria-live="polite">
<h2>{currentProject.title}</h2> <h2>{currentProject.title}</h2>
<h3 class="portfolio-catchphrase gradient-blue">{@html currentProject.catchphrase}</h3> <h3 class="portfolio-catchphrase">{@html currentProject.catchphrase}</h3>
<div class="portfolio-description">{@html currentProject.description}</div> <div class="portfolio-description">{@html currentProject.description}</div>
<div class="portfolio-keywords"> <div class="portfolio-keywords">
{#each currentProject.keywords as kw} {#each currentProject.keywords as kw}
@ -128,8 +128,8 @@
class:active={i === currentIndex} class:active={i === currentIndex}
onclick={() => { currentIndex = i; setAnchor(i) }} onclick={() => { currentIndex = i; setAnchor(i) }}
> >
<img src={project.thumbnail} alt={project.title} />
<span class="portfolio-nav-number">{String(i + 1).padStart(2, '0')}</span> <span class="portfolio-nav-number">{String(i + 1).padStart(2, '0')}</span>
<img src={project.thumbnail} alt={project.title} />
</button> </button>
{/each} {/each}
</nav> </nav>
@ -170,7 +170,7 @@
} }
.portfolio-text { .portfolio-text {
grid-area: 7/11 / span 6 / span 5; grid-area: 7/11 / span 6 / span 6;
z-index: var(--z-content); z-index: var(--z-content);
text-align: left; text-align: left;
display: flex; display: flex;
@ -181,20 +181,18 @@
} }
.portfolio-text h2 { .portfolio-text h2 {
font-size: var(--font-size-title-main); font-size: var(--font-size-title-section);
text-transform: uppercase;
line-height: 1.1; line-height: 1.1;
} }
.portfolio-catchphrase { .portfolio-catchphrase {
font-family: "Danzza Medium", sans-serif;
font-size: var(--font-size-subtitle); font-size: var(--font-size-subtitle);
font-weight: 600;
color: var(--color-primary); color: var(--color-primary);
font-weight: normal;
} }
.portfolio-description { .portfolio-description {
font-size: var(--font-size-subtitle); font-size: var(--font-size-paragraph-small);
line-height: 1.5; line-height: 1.5;
opacity: 0.8; opacity: 0.8;
} }
@ -217,7 +215,6 @@
/* Sidebar navigation */ /* Sidebar navigation */
.portfolio-nav { .portfolio-nav {
grid-area: 4/17 / span 14 / span 4; grid-area: 4/17 / span 14 / span 4;
padding-right: 8rem;
z-index: var(--z-content); z-index: var(--z-content);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -228,7 +225,7 @@
.portfolio-nav-item { .portfolio-nav-item {
display: flex; display: flex;
align-items: flex-start; align-items: center;
gap: 0.5rem; gap: 0.5rem;
background: none; background: none;
border: none; border: none;
@ -239,13 +236,13 @@
} }
.portfolio-nav-item.active { .portfolio-nav-item.active {
transform: scale(1.5) translateX(-20%); transform: scale(1.25) translateX(-50%);
opacity: 1; opacity: 1;
} }
.portfolio-nav-number { .portfolio-nav-number {
color: var(--color-text); color: var(--color-text);
font-size: .5rem; font-size: var(--font-size-caption);
} }
.portfolio-nav-item img { .portfolio-nav-item img {

View file

@ -21,7 +21,7 @@ function keepFontsInPlace() {
if (chunk.type === 'asset' && chunk.fileName.endsWith('.css')) { if (chunk.type === 'asset' && chunk.fileName.endsWith('.css')) {
chunk.source = chunk.source.replace( chunk.source = chunk.source.replace(
/url\((['"]?)([^'")\s]*\.(woff2?|ttf|otf))\1\)/gi, /url\((['"]?)([^'")\s]*\.(woff2?|ttf|otf))\1\)/gi,
(_, _q, p) => `url("/assets/fonts/${decodeURIComponent(p.split('/').pop())}")` (_, _q, p) => `url("/assets/fonts/${p.split('/').pop()}")`
) )
} }
} }