world-game/src/views/Article.svelte

263 lines
5.3 KiB
Svelte
Raw Normal View History

<script>
/**
* Vue article — sous-composant de Blog.svelte.
* Reçoit les données article via props, pas via le slide system.
*/
let { data, onBack } = $props()
</script>
<article class="article">
<!-- Date + retour -->
<div class="article-topbar">
<time class="article-date">{data.date}</time>
<button class="article-back" onclick={onBack}> Retour</button>
</div>
<!-- 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>
<style>
.article {
max-width: 900px;
margin: 0 auto;
padding: 4rem 2rem 6rem;
}
/* --- 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 (max-width: 700px) {
.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 (min-width: 701px) and (max-width: 912px) {
.article-title {
font-size: var(--font-size-title-main-tablet);
}
.article-related-grid {
grid-template-columns: repeat(2, 1fr);
}
}
</style>