diff --git a/site/config/config.php b/site/config/config.php
index cbb056b..c556463 100644
--- a/site/config/config.php
+++ b/site/config/config.php
@@ -1,113 +1,14 @@
true,
-
- // Panel configuration
- 'panel' => [
- 'css' => 'assets/css/custom-panel.css',
- 'theme' => 'dark',
- // Menu personnalisé du panel
- 'menu' => [
- 'site' => [
- 'label' => 'Données partagées',
- 'icon' => 'cog',
- 'current' => function (string $current): bool {
- $path = Kirby\Cms\App::instance()->path();
- return Str::contains($path, '/site');
- }
- ],
- '-', // Séparateur
- 'home' => [
- 'label' => 'Accueil',
- 'icon' => 'home',
- 'link' => 'pages/home',
- 'current' => function (string $current): bool {
- $path = Kirby\Cms\App::instance()->path();
- return Str::contains($path, 'pages/home');
- }
- ],
- 'expertise' => [
- 'label' => 'Expertise',
- 'icon' => 'wand',
- 'link' => 'pages/expertise',
- 'current' => function (string $current): bool {
- $path = Kirby\Cms\App::instance()->path();
- return Str::contains($path, 'pages/expertise');
- }
- ],
- 'portfolio' => [
- 'label' => 'Portfolio',
- 'icon' => 'images',
- 'link' => 'pages/portfolio',
- 'current' => function (string $current): bool {
- $path = Kirby\Cms\App::instance()->path();
- return Str::contains($path, 'pages/portfolio');
- }
- ],
- 'jouer' => [
- 'label' => 'Jouer',
- 'icon' => 'play',
- 'link' => 'pages/jouer',
- 'current' => function (string $current): bool {
- $path = Kirby\Cms\App::instance()->path();
- return Str::contains($path, 'pages/jouer');
- }
- ],
- 'a-propos' => [
- 'label' => 'À propos',
- 'icon' => 'users',
- 'link' => 'pages/a-propos',
- 'current' => function (string $current): bool {
- $path = Kirby\Cms\App::instance()->path();
- return Str::contains($path, 'pages/a-propos');
- }
- ],
- 'blog' => [
- 'label' => 'Blog',
- 'icon' => 'text',
- 'link' => 'pages/blog',
- 'current' => function (string $current): bool {
- $path = Kirby\Cms\App::instance()->path();
- return Str::contains($path, 'pages/blog');
- }
- ],
- '-', // Séparateur
- 'users',
- 'system'
- ]
- ],
-
- // Langues
+ 'debug' => true,
'languages' => true,
- // Thumbs
- 'thumbs' => [
- 'quality' => 80,
- 'srcsets' => [
- '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],
- '400w' => ['width' => 400],
- '600w' => ['width' => 600],
- '800w' => ['width' => 800],
- ],
- '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'],
- ],
- ],
+ 'panel' => [
+ 'css' => 'assets/css/custom-panel.css',
+ 'theme' => 'dark',
+ 'menu' => require __DIR__ . '/menu.php',
],
-];
\ No newline at end of file
+
+ 'thumbs' => require __DIR__ . '/thumbs.php',
+];
diff --git a/site/config/menu.php b/site/config/menu.php
new file mode 100644
index 0000000..ab988d0
--- /dev/null
+++ b/site/config/menu.php
@@ -0,0 +1,36 @@
+ $label,
+ 'icon' => $icon,
+ 'link' => $link,
+ 'current' => function () use ($link): bool {
+ return Str::contains(Kirby\Cms\App::instance()->path(), $link);
+ },
+ ];
+}
+
+return [
+ 'site' => [
+ 'label' => 'Données partagées',
+ 'icon' => 'cog',
+ 'current' => function (): bool {
+ return Str::contains(Kirby\Cms\App::instance()->path(), '/site');
+ },
+ ],
+ '-',
+ 'home' => menuItem('home', 'Accueil', 'home', 'pages/home'),
+ 'expertise' => menuItem('expertise', 'Expertise','wand', 'pages/expertise'),
+ 'portfolio' => menuItem('portfolio', 'Portfolio','images', 'pages/portfolio'),
+ 'jouer' => menuItem('jouer', 'Jouer', 'play', 'pages/jouer'),
+ 'a-propos' => menuItem('a-propos', 'À propos', 'users', 'pages/a-propos'),
+ 'blog' => menuItem('blog', 'Blog', 'text', 'pages/blog'),
+ '-',
+ 'users',
+ 'system',
+];
diff --git a/site/config/thumbs.php b/site/config/thumbs.php
new file mode 100644
index 0000000..8d0c22a
--- /dev/null
+++ b/site/config/thumbs.php
@@ -0,0 +1,54 @@
+ largeur_px].
+ * Applique le multiplicateur et optionnellement un format (ex: 'webp').
+ */
+function srcsetPreset(array $widths, float $mult, ?string $format = null): array
+{
+ $preset = [];
+ foreach ($widths as $label => $px) {
+ $entry = ['width' => (int) round($px * $mult)];
+ if ($format !== null) {
+ $entry['format'] = $format;
+ }
+ $preset[$label] = $entry;
+ }
+ return $preset;
+}
+
+/**
+ * Génère une paire de presets (original + webp) depuis un tableau de widths.
+ * Retourne ['name' => [...], 'name-webp' => [...]].
+ */
+function srcsetPair(string $name, array $widths, float $mult): array
+{
+ return [
+ $name => srcsetPreset($widths, $mult),
+ $name . '-webp' => srcsetPreset($widths, $mult, 'webp'),
+ ];
+}
+
+// Multiplicateur global (ex: 1.5 pour avoir de la marge sur les écrans Retina)
+$m = 1.5;
+
+// Définition des widths par usage (une seule fois)
+$widths = [
+ 'default' => ['300w' => 300, '600w' => 600, '900w' => 900, '1200w' => 1200],
+ // Galerie portfolio — desktop ~15vw, mobile ~33vw (3 colonnes)
+ 'gallery' => ['200w' => 200, '300w' => 300, '400w' => 400, '600w' => 600, '800w' => 800],
+ // Mockup portfolio — desktop ~25vw, mobile ~90vw
+ 'mockup' => ['350w' => 350, '480w' => 480, '700w' => 700, '960w' => 960],
+ // Vignettes jeux — active: clamp(170px, 18.41vw, 355px)
+ 'thumbnail' => ['170w' => 170, '255w' => 255, '355w' => 355, '510w' => 510, '710w' => 710],
+];
+
+return [
+ 'quality' => 80,
+ 'srcsets' => array_merge(
+ ['default' => srcsetPreset($widths['default'], $m)],
+ srcsetPair('gallery', $widths['gallery'], $m),
+ srcsetPair('mockup', $widths['mockup'], $m),
+ srcsetPair('thumbnail', $widths['thumbnail'], $m),
+ ),
+];
diff --git a/site/templates/play.json.php b/site/templates/play.json.php
index feeb766..3cf86ec 100644
--- a/site/templates/play.json.php
+++ b/site/templates/play.json.php
@@ -8,6 +8,8 @@ $specificData = [
'lettering' => $game->lettering()->toFile()?->url(),
'description' => $game->description()->value(),
'thumbnail' => $game->thumbnail()->toFile()?->url(),
+ 'thumbnailSrcset' => $game->thumbnail()->toFile()?->srcset('thumbnail'),
+ 'thumbnailWebp' => $game->thumbnail()->toFile()?->srcset('thumbnail-webp'),
'backgroundColor' => $game->backgroundColor()->value() ?: null,
'preview' => $game->preview()->toFile()?->url(),
'playLink' => $game->playLink()->value() ?: null,
diff --git a/site/templates/portfolio.json.php b/site/templates/portfolio.json.php
index e2fc5f7..825bfd4 100644
--- a/site/templates/portfolio.json.php
+++ b/site/templates/portfolio.json.php
@@ -15,6 +15,8 @@ $specificData = [
'webp' => $f->srcset('gallery-webp'),
])->values(),
'mockup' => $project->mockup()->toFile()?->url(),
+ 'mockupSrcset' => $project->mockup()->toFile()?->srcset('mockup'),
+ 'mockupWebp' => $project->mockup()->toFile()?->srcset('mockup-webp'),
'galleryBackgroundColor' => $project->galleryBackgroundColor()->value(),
'keywords' => $project->keywords()->toStructure()->map(fn($i) => [
'label' => $i->label()->value(),
diff --git a/src/components/ui/ResponsivePicture.svelte b/src/components/ui/ResponsivePicture.svelte
new file mode 100644
index 0000000..74f6b04
--- /dev/null
+++ b/src/components/ui/ResponsivePicture.svelte
@@ -0,0 +1,28 @@
+
+
+
+ {#if webp}
+
+ {/if}
+
+
diff --git a/src/views/Play.svelte b/src/views/Play.svelte
index 3700179..8c25c97 100644
--- a/src/views/Play.svelte
+++ b/src/views/Play.svelte
@@ -1,6 +1,7 @@