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:
parent
d218bc47d7
commit
8481dc5f90
5 changed files with 615 additions and 0 deletions
20
site/blueprints/blocks/white-paper.yml
Normal file
20
site/blueprints/blocks/white-paper.yml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
name: Livre blanc
|
||||||
|
icon: download
|
||||||
|
|
||||||
|
fields:
|
||||||
|
whitePaper:
|
||||||
|
label: Livre blanc
|
||||||
|
type: pages
|
||||||
|
max: 1
|
||||||
|
query: site.find('livres-blancs').children
|
||||||
|
image:
|
||||||
|
cover: true
|
||||||
|
ratio: 4/3
|
||||||
|
bgColor:
|
||||||
|
label: Couleur de fond
|
||||||
|
type: color
|
||||||
|
default: "#ffffff"
|
||||||
|
textColor:
|
||||||
|
label: Couleur de texte
|
||||||
|
type: color
|
||||||
|
default: "#000000"
|
||||||
|
|
@ -72,6 +72,8 @@ tabs:
|
||||||
extends: blocks/video
|
extends: blocks/video
|
||||||
jeu:
|
jeu:
|
||||||
extends: blocks/jeu
|
extends: blocks/jeu
|
||||||
|
white-paper:
|
||||||
|
extends: blocks/white-paper
|
||||||
|
|
||||||
# Sidebar
|
# Sidebar
|
||||||
sidebar:
|
sidebar:
|
||||||
|
|
|
||||||
26
site/snippets/blocks/white-paper.php
Normal file
26
site/snippets/blocks/white-paper.php
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
/** @var \Kirby\Cms\Block $block */
|
||||||
|
|
||||||
|
$wp = $block->whitePaper()->toPage();
|
||||||
|
if (!$wp) return;
|
||||||
|
|
||||||
|
$cover = $wp->cover()->toFile()?->url();
|
||||||
|
$bgColor = $block->bgColor()->isNotEmpty() ? $block->bgColor()->value() : '#ffffff';
|
||||||
|
$textColor = $block->textColor()->isNotEmpty() ? $block->textColor()->value() : '#000000';
|
||||||
|
$style = 'background:' . htmlspecialchars($bgColor, ENT_QUOTES, 'UTF-8') . ';color:' . htmlspecialchars($textColor, ENT_QUOTES, 'UTF-8');
|
||||||
|
?>
|
||||||
|
<article class="wp-block" style="<?= $style ?>">
|
||||||
|
<div class="wp-block__content">
|
||||||
|
<p class="wp-block__label">Livre blanc</p>
|
||||||
|
<h3 class="wp-block__title"><?= html($wp->title()) ?></h3>
|
||||||
|
<?php if ($wp->intro()->isNotEmpty()): ?>
|
||||||
|
<p class="wp-block__intro"><?= strip_tags($wp->intro()->value()) ?></p>
|
||||||
|
<?php endif ?>
|
||||||
|
<button class="button with-icon download-icon wp-block__btn" type="button" data-uri="<?= htmlspecialchars($wp->uri(), ENT_QUOTES, 'UTF-8') ?>">
|
||||||
|
Téléchargement
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<?php if ($cover): ?>
|
||||||
|
<img class="wp-block__cover" src="<?= htmlspecialchars($cover, ENT_QUOTES, 'UTF-8') ?>" alt="<?= html($wp->title()) ?>" loading="lazy" />
|
||||||
|
<?php endif ?>
|
||||||
|
</article>
|
||||||
478
src/components/WhitePaperDialog.svelte
Normal file
478
src/components/WhitePaperDialog.svelte
Normal file
|
|
@ -0,0 +1,478 @@
|
||||||
|
<script>
|
||||||
|
import { locale } from '@state/locale.svelte'
|
||||||
|
import { t } from '@i18n'
|
||||||
|
|
||||||
|
let { uri = null, onClose } = $props()
|
||||||
|
|
||||||
|
let dialogEl = $state(null)
|
||||||
|
let firstFieldEl = $state(null)
|
||||||
|
|
||||||
|
let firstName = $state('')
|
||||||
|
let lastName = $state('')
|
||||||
|
let company = $state('')
|
||||||
|
let role = $state('')
|
||||||
|
let email = $state('')
|
||||||
|
let consent = $state(false)
|
||||||
|
let honeypot = $state('')
|
||||||
|
let submitting = $state(false)
|
||||||
|
let status = $state(null) // null | 'success' | 'error'
|
||||||
|
|
||||||
|
let isEmailValid = $derived.by(() => {
|
||||||
|
const re = /^[\w\-\.]+@([\w-]+\.)+[\w-]{2,}$/gm
|
||||||
|
return re.test(email)
|
||||||
|
})
|
||||||
|
|
||||||
|
let isDownloadable = $derived.by(() =>
|
||||||
|
firstName.length > 0 &&
|
||||||
|
lastName.length > 0 &&
|
||||||
|
company.length > 0 &&
|
||||||
|
role.length > 0 &&
|
||||||
|
email.length > 0 &&
|
||||||
|
isEmailValid &&
|
||||||
|
consent
|
||||||
|
)
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (!dialogEl) return
|
||||||
|
|
||||||
|
if (uri) {
|
||||||
|
dialogEl.showModal()
|
||||||
|
// Focus premier champ après ouverture
|
||||||
|
setTimeout(() => firstFieldEl?.focus(), 50)
|
||||||
|
} else if (dialogEl.open) {
|
||||||
|
dialogEl.close()
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function resetForm() {
|
||||||
|
firstName = ''
|
||||||
|
lastName = ''
|
||||||
|
company = ''
|
||||||
|
role = ''
|
||||||
|
email = ''
|
||||||
|
consent = false
|
||||||
|
honeypot = ''
|
||||||
|
submitting = false
|
||||||
|
status = null
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCancel() {
|
||||||
|
onClose?.()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSubmit(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
if (!consent || !uri) return
|
||||||
|
submitting = true
|
||||||
|
status = null
|
||||||
|
try {
|
||||||
|
const prefix = locale.current === 'en' ? '/en' : ''
|
||||||
|
const res = await fetch(`${prefix}/${uri}/download`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ firstName, lastName, company, role, email, _hp: honeypot })
|
||||||
|
})
|
||||||
|
const result = await res.json()
|
||||||
|
if (result.fileUrl) {
|
||||||
|
window.open(result.fileUrl, '_blank')
|
||||||
|
status = 'success'
|
||||||
|
} else {
|
||||||
|
status = 'error'
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
status = 'error'
|
||||||
|
} finally {
|
||||||
|
submitting = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- La dialog se ferme nativement avec Escape (événement cancel) -->
|
||||||
|
<dialog
|
||||||
|
bind:this={dialogEl}
|
||||||
|
class="wp-dialog"
|
||||||
|
aria-labelledby="wp-dialog-title"
|
||||||
|
aria-modal="true"
|
||||||
|
oncancel={handleCancel}
|
||||||
|
>
|
||||||
|
<div class="wp-dialog__inner" role="document">
|
||||||
|
<button
|
||||||
|
class="wp-dialog__close"
|
||||||
|
type="button"
|
||||||
|
aria-label="Fermer"
|
||||||
|
onclick={handleCancel}
|
||||||
|
>
|
||||||
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false">
|
||||||
|
<path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{#if status === 'success'}
|
||||||
|
<div class="wp-dialog__success">
|
||||||
|
<img src="/assets/img/smiley.svg" alt="" class="wp-dialog__smiley" aria-hidden="true" />
|
||||||
|
<p class="wp-dialog__success-heading">{t('wp_success_heading')}</p>
|
||||||
|
<p class="wp-dialog__success-sub">{t('wp_success_sub')}</p>
|
||||||
|
<button class="wp-dialog__done" type="button" onclick={handleCancel}>
|
||||||
|
Fermer
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div class="wp-dialog__form-wrap">
|
||||||
|
<p class="wp-dialog__intro" id="wp-dialog-title">{t('wp_form_intro')}</p>
|
||||||
|
|
||||||
|
<form class="wp-dialog__form" onsubmit={handleSubmit} novalidate>
|
||||||
|
<fieldset class="wp-dialog__fieldset">
|
||||||
|
<legend class="sr-only">Identité</legend>
|
||||||
|
<div class="wp-dialog__row">
|
||||||
|
<div class="wp-dialog__field">
|
||||||
|
<label class="sr-only" for="wp-firstname">{t('wp_firstname')}</label>
|
||||||
|
<input
|
||||||
|
id="wp-firstname"
|
||||||
|
class="wp-dialog__input"
|
||||||
|
type="text"
|
||||||
|
placeholder={t('wp_firstname')}
|
||||||
|
autocomplete="given-name"
|
||||||
|
required
|
||||||
|
aria-required="true"
|
||||||
|
bind:value={firstName}
|
||||||
|
bind:this={firstFieldEl}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="wp-dialog__field">
|
||||||
|
<label class="sr-only" for="wp-lastname">{t('wp_lastname')}</label>
|
||||||
|
<input
|
||||||
|
id="wp-lastname"
|
||||||
|
class="wp-dialog__input"
|
||||||
|
type="text"
|
||||||
|
placeholder={t('wp_lastname')}
|
||||||
|
autocomplete="family-name"
|
||||||
|
required
|
||||||
|
aria-required="true"
|
||||||
|
bind:value={lastName}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div class="wp-dialog__field">
|
||||||
|
<label class="sr-only" for="wp-company">{t('wp_company')}</label>
|
||||||
|
<input
|
||||||
|
id="wp-company"
|
||||||
|
class="wp-dialog__input"
|
||||||
|
type="text"
|
||||||
|
placeholder={t('wp_company')}
|
||||||
|
autocomplete="organization"
|
||||||
|
required
|
||||||
|
aria-required="true"
|
||||||
|
bind:value={company}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wp-dialog__field">
|
||||||
|
<label class="sr-only" for="wp-role">{t('wp_role')}</label>
|
||||||
|
<input
|
||||||
|
id="wp-role"
|
||||||
|
class="wp-dialog__input"
|
||||||
|
type="text"
|
||||||
|
placeholder={t('wp_role')}
|
||||||
|
autocomplete="organization-title"
|
||||||
|
required
|
||||||
|
aria-required="true"
|
||||||
|
bind:value={role}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="wp-dialog__field">
|
||||||
|
<label class="sr-only" for="wp-email">{t('wp_email')}</label>
|
||||||
|
<input
|
||||||
|
id="wp-email"
|
||||||
|
class="wp-dialog__input"
|
||||||
|
type="email"
|
||||||
|
placeholder={t('wp_email')}
|
||||||
|
autocomplete="email"
|
||||||
|
required
|
||||||
|
aria-required="true"
|
||||||
|
bind:value={email}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Honeypot anti-spam -->
|
||||||
|
<div aria-hidden="true" class="wp-dialog__hp">
|
||||||
|
<label for="wp-website">Website</label>
|
||||||
|
<input
|
||||||
|
id="wp-website"
|
||||||
|
type="text"
|
||||||
|
name="website"
|
||||||
|
tabindex="-1"
|
||||||
|
autocomplete="off"
|
||||||
|
bind:value={honeypot}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label class="wp-dialog__consent">
|
||||||
|
<input type="checkbox" bind:checked={consent} required aria-required="true" />
|
||||||
|
<span>{t('wp_consent')}</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
{#if status === 'error'}
|
||||||
|
<p class="wp-dialog__error" role="alert">{t('wp_error')}</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="wp-dialog__submit"
|
||||||
|
type="submit"
|
||||||
|
disabled={submitting || !isDownloadable}
|
||||||
|
aria-disabled={submitting || !isDownloadable}
|
||||||
|
>
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false">
|
||||||
|
<path d="M12 16L7 11H10V4H14V11H17L12 16Z" fill="currentColor"/>
|
||||||
|
<path d="M5 20H19V18H5V20Z" fill="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
{t('wp_download')}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.sr-only {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
padding: 0;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
margin: auto;
|
||||||
|
width: min(560px, 92vw);
|
||||||
|
max-height: 90vh;
|
||||||
|
background: #0d0e22;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog::backdrop {
|
||||||
|
background: rgba(0, 0, 0, 0.75);
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__inner {
|
||||||
|
position: relative;
|
||||||
|
padding: 2.5rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: 90vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__close {
|
||||||
|
position: absolute;
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.25rem;
|
||||||
|
line-height: 0;
|
||||||
|
transition: color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__close:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__intro {
|
||||||
|
font-family: "Danzza", sans-serif;
|
||||||
|
font-size: var(--font-size-paragraph);
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 1.75rem;
|
||||||
|
padding-right: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__fieldset {
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__field {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__input {
|
||||||
|
width: 100%;
|
||||||
|
background: rgba(255, 255, 255, 0.07);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0.65rem 0.9rem;
|
||||||
|
color: #fff;
|
||||||
|
font-family: "Danzza", sans-serif;
|
||||||
|
font-size: var(--font-size-paragraph);
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__input::placeholder {
|
||||||
|
color: rgba(255, 255, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__hp {
|
||||||
|
position: absolute;
|
||||||
|
left: -9999px;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__consent {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.75rem;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__consent input[type="checkbox"] {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
margin-top: 2px;
|
||||||
|
accent-color: var(--color-primary);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__consent span {
|
||||||
|
font-family: "Danzza", sans-serif;
|
||||||
|
font-size: var(--font-size-paragraph-small);
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__error {
|
||||||
|
font-family: "Danzza", sans-serif;
|
||||||
|
font-size: var(--font-size-paragraph-small);
|
||||||
|
color: #ff6b6b;
|
||||||
|
background: rgba(255, 107, 107, 0.1);
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__submit {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
padding: 0.75rem 2rem;
|
||||||
|
background: #04fea0;
|
||||||
|
color: #000;
|
||||||
|
border: 2px solid #04fea0;
|
||||||
|
border-radius: 0;
|
||||||
|
font-family: "Danzza", sans-serif;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s, border-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__submit:hover:not(:disabled) {
|
||||||
|
background: #03d98c;
|
||||||
|
border-color: #03d98c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__submit:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Écran de succès */
|
||||||
|
.wp-dialog__success {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.25rem;
|
||||||
|
padding: 1rem 0 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__smiley {
|
||||||
|
width: 72px;
|
||||||
|
height: 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__success-heading {
|
||||||
|
font-family: "Danzza bold", sans-serif;
|
||||||
|
font-size: var(--font-size-title-section);
|
||||||
|
color: var(--color-primary);
|
||||||
|
line-height: 1.2;
|
||||||
|
white-space: pre-line;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__success-sub {
|
||||||
|
font-family: "Danzza", sans-serif;
|
||||||
|
font-size: var(--font-size-paragraph);
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__done {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
padding: 0.6rem 2rem;
|
||||||
|
background: none;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: "Danzza", sans-serif;
|
||||||
|
font-size: var(--font-size-paragraph-small);
|
||||||
|
transition: border-color 0.2s, color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__done:hover {
|
||||||
|
border-color: #fff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile */
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
.wp-dialog__inner {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wp-dialog__row {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -7,9 +7,12 @@
|
||||||
import { t } from '@i18n'
|
import { t } from '@i18n'
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import Footer from '@components/layout/Footer.svelte'
|
import Footer from '@components/layout/Footer.svelte'
|
||||||
|
import WhitePaperDialog from '@components/WhitePaperDialog.svelte'
|
||||||
|
|
||||||
let { data, onBack } = $props()
|
let { data, onBack } = $props()
|
||||||
|
|
||||||
|
let activeWhitePaperUri = $state(null)
|
||||||
|
|
||||||
let copySuccess = $state(false)
|
let copySuccess = $state(false)
|
||||||
let copyTimer = null
|
let copyTimer = null
|
||||||
|
|
||||||
|
|
@ -18,6 +21,15 @@
|
||||||
if (!data.body) return
|
if (!data.body) return
|
||||||
|
|
||||||
const timer = setTimeout(() => {
|
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 => {
|
document.querySelectorAll('.iframe-game-container').forEach(container => {
|
||||||
if (container.dataset.initialized) return
|
if (container.dataset.initialized) return
|
||||||
container.dataset.initialized = 'true'
|
container.dataset.initialized = 'true'
|
||||||
|
|
@ -180,6 +192,8 @@
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<WhitePaperDialog uri={activeWhitePaperUri} onClose={() => activeWhitePaperUri = null} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.article-wrapper {
|
.article-wrapper {
|
||||||
grid-area: 6 / 1 / span 15 / span 20;
|
grid-area: 6 / 1 / span 15 / span 20;
|
||||||
|
|
@ -546,6 +560,81 @@
|
||||||
font-size: var(--font-size-paragraph);
|
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 --- */
|
/* --- Mobile --- */
|
||||||
@media (max-width: 700px) {
|
@media (max-width: 700px) {
|
||||||
.article {
|
.article {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue