Deuxième passe DA : direction "punchy, friendly, donne envie de fun"

Retour direct de Kévin après la 1ère passe (trop sage) : palette poussée
en saturation (corail vif en primaire, prune + doré en accents), formes
plus rondes (boutons pilule, rayons 20px), micro-animations avec du peps
(easing overshoot, coche qui se dessine + confettis CSS purs à l'envoi,
spinner animé). Police d'accent Fraunces ajoutée pour les titres (2
fichiers .woff2 auto-hébergés, ~44 Ko, SIL OFL, jamais de CDN).

Ton de voix retravaillé : micro-copies plus souriantes, nouvel état
"limite de photos atteinte" traité chaleureusement (pas comme une erreur).

Cohérence maintenue sur galerie admin, carton imprimable, et générateur
QR (sync légère, priorité basse). Testé en conditions réelles sur
photobooth.assistantaikev.eu.
This commit is contained in:
2026-09-16 15:48:29 +02:00
parent 66435b0705
commit 3afd475a55
10 changed files with 716 additions and 175 deletions
+77 -33
View File
@@ -12,6 +12,8 @@
lors du déploiement, hors scope de ce fichier front.
-->
<meta name="robots" content="noindex, nofollow">
<meta name="theme-color" content="#faf6f0">
<link rel="preload" href="/vendor/fonts/fraunces-latin-600-normal.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/e/style.css">
</head>
<body>
@@ -25,19 +27,43 @@
<span class="brand__name">photobooth</span>
</p>
<h1 id="event-name">Ajouter une photo</h1>
<p class="page__kicker">Une photo, un petit mot, et hop dans l'album&nbsp;!</p>
</header>
<section id="status-loading" class="state-block" role="status">
<section id="status-loading" class="state-block state-block--loading" role="status">
<span class="spinner" aria-hidden="true"></span>
<p>Chargement de l'événement…</p>
</section>
<section id="status-error" class="state-block state-block--error" hidden role="alert">
<div class="state-icon state-icon--error" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" focusable="false">
<circle cx="12" cy="12" r="9"/>
<path d="M12 8v5"/>
<path d="M12 16.2v.1"/>
</svg>
</div>
<div class="state-icon state-icon--limit" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" focusable="false">
<path d="M12 20.2s-7.5-4.6-7.5-10.1a4.4 4.4 0 0 1 7.5-3.1 4.4 4.4 0 0 1 7.5 3.1c0 5.5-7.5 10.1-7.5 10.1Z"/>
</svg>
</div>
<p id="status-error-message"></p>
<button type="button" id="retry-btn" hidden>Réessayer</button>
</section>
<section id="success-block" class="state-block state-block--success" hidden role="status">
<p>Merci&nbsp;! Ta photo est bien envoyée 🎉</p>
<div class="confetti" aria-hidden="true">
<span></span><span></span><span></span><span></span><span></span><span></span>
</div>
<div class="success-check" aria-hidden="true">
<svg viewBox="0 0 52 52" fill="none" focusable="false">
<circle class="success-check__circle" cx="26" cy="26" r="23" stroke-width="2.5"/>
<path class="success-check__mark" d="M15 27.5 22.5 35 38 18" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
<p class="success-title">C'est envoyé&nbsp;!</p>
<p class="success-text">Ta photo vient de rejoindre la fête. Merci d'avoir été là&nbsp;!</p>
<button type="button" id="add-another-btn">Ajouter une autre photo</button>
</section>
@@ -47,16 +73,20 @@
<!-- Deux entrées séparées : "photo-input" (capture="environment")
ouvre directement l'appareil photo, "photo-input-gallery" ouvre
le sélecteur de fichiers classique. Décision actée avec Kévin le
2026-09-16 : les deux doivent être accessibles en un tap. -->
2026-09-16 : les deux doivent être accessibles en un tap.
Hiérarchie visuelle ajoutée : "Prendre une photo" est l'action
attendue pour l'immense majorité des invités pendant l'événement
(capture sur le moment), donc traitée en primaire ; "Depuis la
galerie" reste secondaire mais tout aussi accessible. -->
<div class="photo-source-buttons">
<label for="photo-input" class="btn-secondary">
<label for="photo-input" class="btn-source btn-source--primary">
<svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M4 8h3l1.5-2h7L17 8h3a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1Z"/>
<circle cx="12" cy="13" r="3.5"/>
</svg>
<span>Prendre une photo</span>
</label>
<label for="photo-input-gallery" class="btn-secondary">
<label for="photo-input-gallery" class="btn-source btn-source--secondary">
<svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<rect x="3" y="4" width="18" height="16" rx="2.5"/>
<circle cx="8.5" cy="9.5" r="1.5"/>
@@ -87,42 +117,56 @@
<img id="preview" class="preview" alt="Aperçu de la photo choisie" hidden>
<div class="field">
<label for="nom-input">Ton prénom <span class="optional">(facultatif)</span></label>
<input
type="text"
id="nom-input"
name="nom"
maxlength="60"
autocomplete="given-name"
placeholder="Ex : Camille"
>
</div>
<div class="field-group">
<div class="field">
<label for="nom-input">Ton prénom <span class="optional">(facultatif)</span></label>
<input
type="text"
id="nom-input"
name="nom"
maxlength="60"
autocomplete="given-name"
placeholder="Ex : Camille"
>
</div>
<div class="field">
<label for="message-input">Un petit mot <span class="optional">(facultatif)</span></label>
<textarea
id="message-input"
name="message"
maxlength="300"
rows="3"
placeholder="Ton petit mot pour l'occasion…"
></textarea>
<div class="field">
<label for="message-input">Un petit mot <span class="optional">(facultatif)</span></label>
<textarea
id="message-input"
name="message"
maxlength="300"
rows="3"
placeholder="Ton petit mot pour l'occasion…"
></textarea>
</div>
</div>
<p class="legal-notice">
En déposant une photo, vous acceptez qu'elle soit stockée temporairement
dans le cadre de cet événement et mise à disposition de l'organisateur.
Vos photos sont automatiquement supprimées 7 jours après la date de
l'événement, sans action de votre part. Aucune photo n'est utilisée à
d'autres fins, ni transmise à des tiers. Vous pouvez demander la
suppression anticipée d'une photo en contactant l'organisateur de
l'événement.
<svg class="legal-notice__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<rect x="4.5" y="10.5" width="15" height="9.5" rx="2"/>
<path d="M8 10.5V7.5a4 4 0 0 1 8 0v3"/>
</svg>
<span>
En déposant une photo, vous acceptez qu'elle soit stockée temporairement
dans le cadre de cet événement et mise à disposition de l'organisateur.
Vos photos sont automatiquement supprimées 7 jours après la date de
l'événement, sans action de votre part. Aucune photo n'est utilisée à
d'autres fins, ni transmise à des tiers. Vous pouvez demander la
suppression anticipée d'une photo en contactant l'organisateur de
l'événement.
</span>
</p>
<p id="progress-text" class="progress-text" aria-live="polite"></p>
<button type="submit" id="submit-btn">Envoyer ma photo</button>
<button type="submit" id="submit-btn">
<svg class="btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M21 4 3 11.5l7 2.5"/>
<path d="M10 14l2.5 7L21 4"/>
</svg>
<span id="submit-btn-label">Envoyer ma photo</span>
</button>
</form>
</main>