Migration vers architecture Svelte + Kirby inspirée de design-to-pack
- Mise en place de Svelte 4 avec Vite pour le frontend (SPA)
- Simplification des templates PHP (header/footer minimalistes)
- Création de templates JSON pour API (home, about, expertise, portfolio, jouer, game, blog, article, project)
- Ajout d'un controller de site pour définir genericData globalement
- Structure des stores Svelte (page, navigation, locale, site)
- Router avec navaid pour navigation SPA et interception des liens
- Composants layout (Header, Footer, Cursor) et vues de base
- Build Vite vers assets/dist/ (index.js/css)
- Header PHP détecte assets/dist pour basculer dev/prod
Architecture fonctionnelle de base établie, à améliorer et compléter.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 16:30:15 +01:00
|
|
|
<script>
|
Feat: pages Article + navigation blog/article interne
- Router: findSlideIndex() avec fallback parent path
(/blog/slug → /blog) pour sub-pages
- article.json.php: réécriture — date, intro, cover, body (blocks→HTML),
related articles (fallback siblings si vide)
- Article.svelte: sous-composant — topbar date+retour, titre Terminal,
intro, cover, body rich text (styles :global pour blocks Kirby),
related articles grid, responsive
- Blog.svelte: gère deux modes (liste + article) —
intercepte les clics article via stopPropagation (avant le router),
fetch article data, pushState pour URL, popstate pour back/forward,
direct navigation /blog/slug sur mount
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 16:55:34 +01:00
|
|
|
/**
|
|
|
|
|
* Vue article — sous-composant de Blog.svelte.
|
|
|
|
|
* Reçoit les données article via props, pas via le slide system.
|
|
|
|
|
*/
|
|
|
|
|
let { data, onBack } = $props()
|
Migration vers architecture Svelte + Kirby inspirée de design-to-pack
- Mise en place de Svelte 4 avec Vite pour le frontend (SPA)
- Simplification des templates PHP (header/footer minimalistes)
- Création de templates JSON pour API (home, about, expertise, portfolio, jouer, game, blog, article, project)
- Ajout d'un controller de site pour définir genericData globalement
- Structure des stores Svelte (page, navigation, locale, site)
- Router avec navaid pour navigation SPA et interception des liens
- Composants layout (Header, Footer, Cursor) et vues de base
- Build Vite vers assets/dist/ (index.js/css)
- Header PHP détecte assets/dist pour basculer dev/prod
Architecture fonctionnelle de base établie, à améliorer et compléter.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 16:30:15 +01:00
|
|
|
</script>
|
|
|
|
|
|
Feat: pages Article + navigation blog/article interne
- Router: findSlideIndex() avec fallback parent path
(/blog/slug → /blog) pour sub-pages
- article.json.php: réécriture — date, intro, cover, body (blocks→HTML),
related articles (fallback siblings si vide)
- Article.svelte: sous-composant — topbar date+retour, titre Terminal,
intro, cover, body rich text (styles :global pour blocks Kirby),
related articles grid, responsive
- Blog.svelte: gère deux modes (liste + article) —
intercepte les clics article via stopPropagation (avant le router),
fetch article data, pushState pour URL, popstate pour back/forward,
direct navigation /blog/slug sur mount
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 16:55:34 +01:00
|
|
|
<article class="article">
|
|
|
|
|
|
|
|
|
|
<!-- Date + retour -->
|
|
|
|
|
<div class="article-topbar">
|
|
|
|
|
<time class="article-date">{data.date}</time>
|
|
|
|
|
<button class="article-back" onclick={onBack}>← Retour</button>
|
Migration vers architecture Svelte + Kirby inspirée de design-to-pack
- Mise en place de Svelte 4 avec Vite pour le frontend (SPA)
- Simplification des templates PHP (header/footer minimalistes)
- Création de templates JSON pour API (home, about, expertise, portfolio, jouer, game, blog, article, project)
- Ajout d'un controller de site pour définir genericData globalement
- Structure des stores Svelte (page, navigation, locale, site)
- Router avec navaid pour navigation SPA et interception des liens
- Composants layout (Header, Footer, Cursor) et vues de base
- Build Vite vers assets/dist/ (index.js/css)
- Header PHP détecte assets/dist pour basculer dev/prod
Architecture fonctionnelle de base établie, à améliorer et compléter.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 16:30:15 +01:00
|
|
|
</div>
|
Feat: pages Article + navigation blog/article interne
- Router: findSlideIndex() avec fallback parent path
(/blog/slug → /blog) pour sub-pages
- article.json.php: réécriture — date, intro, cover, body (blocks→HTML),
related articles (fallback siblings si vide)
- Article.svelte: sous-composant — topbar date+retour, titre Terminal,
intro, cover, body rich text (styles :global pour blocks Kirby),
related articles grid, responsive
- Blog.svelte: gère deux modes (liste + article) —
intercepte les clics article via stopPropagation (avant le router),
fetch article data, pushState pour URL, popstate pour back/forward,
direct navigation /blog/slug sur mount
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 16:55:34 +01:00
|
|
|
|
|
|
|
|
<!-- Titre -->
|
|
|
|
|
<h1 class="article-title font-face-terminal">{data.title}</h1>
|
|
|
|
|
|
|
|
|
|
<!-- Intro -->
|
|
|
|
|
{#if data.intro}
|
|
|
|
|
<div class="article-intro">{@html data.intro}</div>
|
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
|
|
<!-- Cover -->
|
|
|
|
|
{#if data.cover}
|
|
|
|
|
<div class="article-cover">
|
|
|
|
|
<img src={data.cover} alt={data.title} />
|
|
|
|
|
</div>
|
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
|
|
<!-- Body (Kirby blocks → HTML) -->
|
|
|
|
|
{#if data.body}
|
|
|
|
|
<div class="article-body">{@html data.body}</div>
|
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
|
|
<!-- Articles recommandés -->
|
|
|
|
|
{#if data.related?.length}
|
|
|
|
|
<section class="article-related">
|
|
|
|
|
<h2>Nos recommandations</h2>
|
|
|
|
|
<div class="article-related-grid">
|
|
|
|
|
{#each data.related as rec}
|
|
|
|
|
<a href="/blog/{rec.slug}" class="article-related-card">
|
|
|
|
|
{#if rec.cover}
|
|
|
|
|
<img src={rec.cover} alt={rec.title} />
|
|
|
|
|
{/if}
|
|
|
|
|
<span class="article-related-title">{rec.title}</span>
|
|
|
|
|
</a>
|
|
|
|
|
{/each}
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
|
|
</article>
|
Migration vers architecture Svelte + Kirby inspirée de design-to-pack
- Mise en place de Svelte 4 avec Vite pour le frontend (SPA)
- Simplification des templates PHP (header/footer minimalistes)
- Création de templates JSON pour API (home, about, expertise, portfolio, jouer, game, blog, article, project)
- Ajout d'un controller de site pour définir genericData globalement
- Structure des stores Svelte (page, navigation, locale, site)
- Router avec navaid pour navigation SPA et interception des liens
- Composants layout (Header, Footer, Cursor) et vues de base
- Build Vite vers assets/dist/ (index.js/css)
- Header PHP détecte assets/dist pour basculer dev/prod
Architecture fonctionnelle de base établie, à améliorer et compléter.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 16:30:15 +01:00
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
.article {
|
Feat: pages Article + navigation blog/article interne
- Router: findSlideIndex() avec fallback parent path
(/blog/slug → /blog) pour sub-pages
- article.json.php: réécriture — date, intro, cover, body (blocks→HTML),
related articles (fallback siblings si vide)
- Article.svelte: sous-composant — topbar date+retour, titre Terminal,
intro, cover, body rich text (styles :global pour blocks Kirby),
related articles grid, responsive
- Blog.svelte: gère deux modes (liste + article) —
intercepte les clics article via stopPropagation (avant le router),
fetch article data, pushState pour URL, popstate pour back/forward,
direct navigation /blog/slug sur mount
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 16:55:34 +01:00
|
|
|
max-width: 900px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
padding: 4rem 2rem 6rem;
|
Migration vers architecture Svelte + Kirby inspirée de design-to-pack
- Mise en place de Svelte 4 avec Vite pour le frontend (SPA)
- Simplification des templates PHP (header/footer minimalistes)
- Création de templates JSON pour API (home, about, expertise, portfolio, jouer, game, blog, article, project)
- Ajout d'un controller de site pour définir genericData globalement
- Structure des stores Svelte (page, navigation, locale, site)
- Router avec navaid pour navigation SPA et interception des liens
- Composants layout (Header, Footer, Cursor) et vues de base
- Build Vite vers assets/dist/ (index.js/css)
- Header PHP détecte assets/dist pour basculer dev/prod
Architecture fonctionnelle de base établie, à améliorer et compléter.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 16:30:15 +01:00
|
|
|
}
|
|
|
|
|
|
Feat: pages Article + navigation blog/article interne
- Router: findSlideIndex() avec fallback parent path
(/blog/slug → /blog) pour sub-pages
- article.json.php: réécriture — date, intro, cover, body (blocks→HTML),
related articles (fallback siblings si vide)
- Article.svelte: sous-composant — topbar date+retour, titre Terminal,
intro, cover, body rich text (styles :global pour blocks Kirby),
related articles grid, responsive
- Blog.svelte: gère deux modes (liste + article) —
intercepte les clics article via stopPropagation (avant le router),
fetch article data, pushState pour URL, popstate pour back/forward,
direct navigation /blog/slug sur mount
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-10 16:55:34 +01:00
|
|
|
/* --- Topbar --- */
|
|
|
|
|
.article-topbar {
|
|
|
|
|
display: flex;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
align-items: center;
|
|
|
|
|
margin-bottom: 2rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-date {
|
|
|
|
|
color: rgba(255, 255, 255, 0.7);
|
|
|
|
|
font-size: var(--font-size-paragraph);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-back {
|
|
|
|
|
background: none;
|
|
|
|
|
color: var(--color-primary);
|
|
|
|
|
font-family: "Danzza Medium", sans-serif;
|
|
|
|
|
font-size: var(--font-size-paragraph-small);
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: opacity 0.2s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-back:hover {
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --- Titre --- */
|
|
|
|
|
.article-title {
|
|
|
|
|
font-size: var(--font-size-title-main);
|
|
|
|
|
text-align: center;
|
|
|
|
|
margin-bottom: 1.5rem;
|
|
|
|
|
line-height: 1.2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --- Intro --- */
|
|
|
|
|
.article-intro {
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: var(--font-size-subtitle);
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
color: rgba(255, 255, 255, 0.9);
|
|
|
|
|
margin-bottom: 2.5rem;
|
|
|
|
|
max-width: 700px;
|
|
|
|
|
margin-left: auto;
|
|
|
|
|
margin-right: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --- Cover --- */
|
|
|
|
|
.article-cover {
|
|
|
|
|
margin-bottom: 3rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-cover img {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: auto;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --- Body (rich text from Kirby blocks) --- */
|
|
|
|
|
.article-body {
|
|
|
|
|
line-height: 1.8;
|
|
|
|
|
margin-bottom: 4rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(h2),
|
|
|
|
|
.article-body :global(h3) {
|
|
|
|
|
font-family: "Danzza Bold", sans-serif;
|
|
|
|
|
margin: 2rem 0 1rem;
|
|
|
|
|
line-height: 1.3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(h2) {
|
|
|
|
|
font-size: 29px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(h3) {
|
|
|
|
|
font-size: 22px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(p) {
|
|
|
|
|
margin-bottom: 1.25rem;
|
|
|
|
|
font-size: var(--font-size-paragraph);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(a) {
|
|
|
|
|
color: var(--color-primary);
|
|
|
|
|
text-decoration: underline;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(ul),
|
|
|
|
|
.article-body :global(ol) {
|
|
|
|
|
margin: 1.25rem 0;
|
|
|
|
|
padding-left: 1.5rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(li) {
|
|
|
|
|
margin-bottom: 0.5rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(blockquote) {
|
|
|
|
|
border-left: 4px solid var(--color-primary);
|
|
|
|
|
padding: 1.25rem 1.25rem 1.25rem 2rem;
|
|
|
|
|
margin: 2rem 0;
|
|
|
|
|
background: rgba(4, 254, 160, 0.05);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(blockquote p) {
|
|
|
|
|
font-style: italic;
|
|
|
|
|
font-size: 19px;
|
|
|
|
|
margin-bottom: 0.5rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(figure) {
|
|
|
|
|
margin: 2rem 0;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(figure img) {
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
height: auto;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-body :global(figcaption) {
|
|
|
|
|
margin-top: 0.5rem;
|
|
|
|
|
font-style: italic;
|
|
|
|
|
color: rgba(255, 255, 255, 0.7);
|
|
|
|
|
font-size: var(--font-size-caption);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --- Recommandations --- */
|
|
|
|
|
.article-related {
|
|
|
|
|
border-top: 1px solid rgba(255, 255, 255, 0.15);
|
|
|
|
|
padding-top: 3rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-related h2 {
|
|
|
|
|
font-family: "Danzza Bold", sans-serif;
|
|
|
|
|
font-size: var(--font-size-title-section);
|
|
|
|
|
margin-bottom: 2rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-related-grid {
|
|
|
|
|
display: grid;
|
|
|
|
|
grid-template-columns: repeat(3, 1fr);
|
|
|
|
|
gap: 1.5rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-related-card {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 0.75rem;
|
|
|
|
|
transition: transform 0.3s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-related-card:hover {
|
|
|
|
|
transform: translateY(-5px);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-related-card img {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 180px;
|
|
|
|
|
object-fit: cover;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-related-title {
|
|
|
|
|
font-family: "Danzza Bold", sans-serif;
|
|
|
|
|
font-size: var(--font-size-paragraph);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --- Mobile --- */
|
|
|
|
|
@media (--mobile) {
|
|
|
|
|
.article {
|
|
|
|
|
padding: 3rem 1.25rem 4rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-title {
|
|
|
|
|
font-size: var(--font-size-title-section-mobile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-intro {
|
|
|
|
|
font-size: var(--font-size-paragraph-mobile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-related-grid {
|
|
|
|
|
grid-template-columns: 1fr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --- Tablet --- */
|
|
|
|
|
@media (--tablet-only) {
|
|
|
|
|
.article-title {
|
|
|
|
|
font-size: var(--font-size-title-main-tablet);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.article-related-grid {
|
|
|
|
|
grid-template-columns: repeat(2, 1fr);
|
|
|
|
|
}
|
Migration vers architecture Svelte + Kirby inspirée de design-to-pack
- Mise en place de Svelte 4 avec Vite pour le frontend (SPA)
- Simplification des templates PHP (header/footer minimalistes)
- Création de templates JSON pour API (home, about, expertise, portfolio, jouer, game, blog, article, project)
- Ajout d'un controller de site pour définir genericData globalement
- Structure des stores Svelte (page, navigation, locale, site)
- Router avec navaid pour navigation SPA et interception des liens
- Composants layout (Header, Footer, Cursor) et vues de base
- Build Vite vers assets/dist/ (index.js/css)
- Header PHP détecte assets/dist pour basculer dev/prod
Architecture fonctionnelle de base établie, à améliorer et compléter.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-06 16:30:15 +01:00
|
|
|
}
|
|
|
|
|
</style>
|