add white-paper block type for articles

- Kirby block blueprint with page reference + editable bg/text colors
- PHP snippet renders the card with accessible markup (article, h3, button)
- WhitePaperDialog.svelte: native dialog with download form (a11y: labels, fieldset, autocomplete, focus management)
- Article.svelte: click detection on .wp-block__btn + dialog mount

refs #49

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-03-30 19:51:21 +02:00
parent d218bc47d7
commit 8481dc5f90
5 changed files with 615 additions and 0 deletions

View file

@ -7,9 +7,12 @@
import { t } from '@i18n'
import { onMount } from 'svelte'
import Footer from '@components/layout/Footer.svelte'
import WhitePaperDialog from '@components/WhitePaperDialog.svelte'
let { data, onBack } = $props()
let activeWhitePaperUri = $state(null)
let copySuccess = $state(false)
let copyTimer = null
@ -18,6 +21,15 @@
if (!data.body) return
const timer = setTimeout(() => {
// Boutons livre-blanc → ouvre la dialog
document.querySelectorAll('.wp-block__btn').forEach(btn => {
if (btn.dataset.initialized) return
btn.dataset.initialized = 'true'
btn.addEventListener('click', () => {
activeWhitePaperUri = btn.dataset.uri
})
})
document.querySelectorAll('.iframe-game-container').forEach(container => {
if (container.dataset.initialized) return
container.dataset.initialized = 'true'
@ -180,6 +192,8 @@
<Footer />
</div>
<WhitePaperDialog uri={activeWhitePaperUri} onClose={() => activeWhitePaperUri = null} />
<style>
.article-wrapper {
grid-area: 6 / 1 / span 15 / span 20;
@ -546,6 +560,81 @@
font-size: var(--font-size-paragraph);
}
/* --- Bloc livre blanc --- */
.article-body :global(.wp-block) {
position: relative;
display: flex;
align-items: center;
gap: 2rem;
border-radius: 16px;
padding: 2.5rem 4rem;
margin: 2.5rem 0;
width: 170%;
margin-left: -35%;
}
.article-body :global(.wp-block__content) {
width: 50%;
z-index: 1;
}
.article-body :global(.wp-block__label) {
font-family: "Terminal", sans-serif;
font-size: var(--font-size-paragraph);
color: var(--color-primary);
text-transform: uppercase;
margin: 0;
}
.article-body :global(.wp-block__title) {
font-size: var(--font-size-title-section);
font-weight: 700;
font-family: "Danzza", sans-serif;
text-transform: uppercase;
line-height: 1.1;
margin: 0;
}
.article-body :global(.wp-block__intro) {
font-family: "Danzza", sans-serif;
font-size: var(--font-size-paragraph);
line-height: 1.5;
opacity: 0.5;
margin: 0;
}
.article-body :global(.wp-block__btn) {
margin-top: 1rem;
}
.article-body :global(.wp-block__btn:hover) {
background: #03d98c;
border-color: #03d98c;
}
.article-body :global(.wp-block__cover) {
position: absolute;
width: 50vw;
right: -18rem;
top: -5vw;
}
@media (max-width: 700px) {
.article-body :global(.wp-block) {
flex-direction: column;
padding: 1.75rem 1.25rem;
}
.article-body :global(.wp-block__cover) {
width: 60%;
max-width: none;
}
.article-body :global(.wp-block__title) {
font-size: var(--font-size-title-section-mobile);
}
}
/* --- Mobile --- */
@media (max-width: 700px) {
.article {