docs: plan d'implémentation de la politique de confidentialité
This commit is contained in:
1 file changed
+393
@@ -0,0 +1,393 @@
|
||||
# Politique de confidentialité — plan d'implémentation
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal :** livrer `privacy.html` — page autonome bilingue FR/EN (toggle) à héberger pour le formulaire Google Play.
|
||||
|
||||
**Architecture :** un seul fichier HTML statique, tout le contenu en double (`data-lang="fr"` / `data-lang="en"`), bascule par classes sur `<html>` + script inline (~15 lignes) gérant hash `#fr`/`#en` et `localStorage`. Tailwind via CDN configuré avec la palette du logo ; mode sombre automatique via `prefers-color-scheme`.
|
||||
|
||||
**Tech stack :** HTML5 + Tailwind CDN + JS inline. Aucun build, aucune dépendance Gradle.
|
||||
|
||||
**Spec :** `docs/superpowers/specs/2026-08-31-politique-confidentialite-design.md`
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Un seul fichier livrable : `privacy.html`, à la racine du dépôt.
|
||||
- Français par défaut ; bascule EN via bouton, hash `#en`/`#fr`, persistance `localStorage` (`livrets-lang`).
|
||||
- Palette du logo, valeurs exactes : `#1D3557` (navy/encre), `#A8DADC` (mist), `#E63946` (coral), `#F1FAEE` (paper), `#457B9D` (accent).
|
||||
- Mode sombre uniquement via `prefers-color-scheme` (`darkMode: 'media'`), pas de toggle manuel.
|
||||
- Placeholders visibles : `[ÉDITEUR — À REMPLIR]`, `[EMAIL — À REMPLIR]`, `[DATE]` (style pointillé coral), à remplacer avant publication.
|
||||
- Pas d'analytique, pas de police externe, pas d'image externe ; seul appel réseau autorisé : le script CDN Tailwind.
|
||||
- Commits en conventional commits français.
|
||||
- Page hors build Gradle : vérification par tests manuels navigateur (pas de `:sharedUI:jvmTest` concerné).
|
||||
|
||||
---
|
||||
|
||||
### Task 1 : Créer `privacy.html` bilingue
|
||||
|
||||
**Files:**
|
||||
- Create: `privacy.html`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes : logo `docs/branding/logo.svg` (contenu inline reproduit tel quel ci-dessous, sans `<title>` ni attributs `role`/`aria-labelledby` — l'en-tête de page porte déjà le nom).
|
||||
- Produces : fichier autonome déployable tel quel ; l'URL finale sera saisie dans Play Console (hors périmètre de ce plan).
|
||||
|
||||
- [ ] **Step 1 : Créer le fichier complet**
|
||||
|
||||
Créer `privacy.html` avec exactement ce contenu :
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr" class="fr">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Politique de confidentialité — Livrets</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Politique de confidentialité du jeu Livrets : vos données restent sur votre appareil. Privacy policy for the Livrets game: your data stays on your device."
|
||||
/>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
darkMode: 'media',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
navy: '#1D3557',
|
||||
accent: '#457B9D',
|
||||
mist: '#A8DADC',
|
||||
paper: '#F1FAEE',
|
||||
coral: '#E63946',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
html.fr [data-lang='en'] { display: none !important; }
|
||||
html.en [data-lang='fr'] { display: none !important; }
|
||||
.placeholder {
|
||||
border: 1px dashed #e63946;
|
||||
color: #e63946;
|
||||
border-radius: 0.375rem;
|
||||
padding: 0 0.375rem;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-screen bg-paper text-navy antialiased dark:bg-navy dark:text-paper">
|
||||
<div class="mx-auto max-w-2xl px-6 py-10">
|
||||
<header class="flex items-center justify-between gap-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<svg width="48" height="48" viewBox="0 0 128 128" aria-hidden="true" class="shrink-0">
|
||||
<rect x="4" y="4" width="120" height="120" rx="28" fill="#1D3557"/>
|
||||
<rect x="18" y="18" width="42" height="42" rx="12" fill="#A8DADC"/>
|
||||
<rect x="68" y="18" width="42" height="42" rx="12" fill="#E63946"/>
|
||||
<rect x="18" y="68" width="42" height="42" rx="12" fill="#F1FAEE"/>
|
||||
<rect x="68" y="68" width="42" height="42" rx="12" fill="#457B9D"/>
|
||||
<path d="M29,28 L49,28 L36,50" fill="none" stroke="#1D3557" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M81,31 L97,47 M97,31 L81,47" fill="none" stroke="#F1FAEE" stroke-width="6.5" stroke-linecap="round"/>
|
||||
<circle cx="39" cy="82.75" r="5.5" fill="#1D3557"/>
|
||||
<circle cx="39" cy="93.25" r="7.5" fill="#1D3557"/>
|
||||
<path d="M81,81 C81,73 97,73 97,81 C97,86.5 89,86.5 89,93 L89,95.5" fill="none" stroke="#F1FAEE" stroke-width="6" stroke-linecap="round"/>
|
||||
<circle cx="89" cy="102.5" r="3.4" fill="#F1FAEE"/>
|
||||
</svg>
|
||||
<div>
|
||||
<p class="text-sm font-medium text-accent">Livrets</p>
|
||||
<h1 class="text-2xl font-bold" data-lang="fr">Politique de confidentialité</h1>
|
||||
<h1 class="text-2xl font-bold" data-lang="en">Privacy Policy</h1>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
id="lang-toggle"
|
||||
type="button"
|
||||
aria-label="Switch to English"
|
||||
class="shrink-0 rounded-lg border border-navy/20 px-3 py-1.5 text-sm font-semibold hover:bg-mist/50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-accent dark:border-paper/30 dark:hover:bg-paper/10"
|
||||
>
|
||||
English
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<p class="mt-8 rounded-xl bg-mist/40 p-4 text-sm dark:bg-paper/10" data-lang="fr">
|
||||
<strong>En résumé : vos données restent sur votre appareil.</strong> Le jeu ne contient
|
||||
ni publicité ni analytique, et rien n'est envoyé à des serveurs, sauf si vous activez
|
||||
volontairement Google Play Jeux sur Android.
|
||||
</p>
|
||||
<p class="mt-8 rounded-xl bg-mist/40 p-4 text-sm dark:bg-paper/10" data-lang="en">
|
||||
<strong>In short: your data stays on your device.</strong> The game contains no ads and
|
||||
no analytics, and nothing is sent to servers unless you voluntarily sign in to
|
||||
Google Play Games on Android.
|
||||
</p>
|
||||
|
||||
<main class="mt-10 space-y-10 text-base leading-relaxed text-navy/85 dark:text-paper/85">
|
||||
<section>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="fr">1. Éditeur</h2>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="en">1. Publisher</h2>
|
||||
<p data-lang="fr">
|
||||
Cette politique de confidentialité décrit la manière dont Livrets (« le jeu »),
|
||||
édité par <span class="placeholder">[ÉDITEUR — À REMPLIR]</span>, traite les données.
|
||||
Dernière mise à jour : <span class="placeholder">[DATE]</span>.
|
||||
</p>
|
||||
<p data-lang="en">
|
||||
This privacy policy describes how Livrets (“the game”), published by
|
||||
<span class="placeholder">[ÉDITEUR — À REMPLIR]</span>, handles data.
|
||||
Last updated: <span class="placeholder">[DATE]</span>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="fr">
|
||||
2. Données stockées localement
|
||||
</h2>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="en">
|
||||
2. Data stored locally
|
||||
</h2>
|
||||
<p data-lang="fr">
|
||||
Le jeu enregistre sur votre appareil — et uniquement sur votre appareil :
|
||||
l'historique des parties (score, date, réponses) et le taux de réussite cumulé
|
||||
par table. Ces données ne sont jamais transmises à des serveurs : elles restent
|
||||
dans le stockage local de l'application (<code>~/.livrets/</code> sur desktop,
|
||||
stockage privé de l'app sur Android et iOS). Désinstaller l'application
|
||||
les supprime définitivement.
|
||||
</p>
|
||||
<p data-lang="en">
|
||||
The game saves the following data on your device — and only on your device:
|
||||
game history (score, date, answers) and cumulative success rate per table.
|
||||
This data is never transmitted to servers: it stays in the app's local storage
|
||||
(<code>~/.livrets/</code> on desktop, private app storage on Android and iOS).
|
||||
Uninstalling the app permanently deletes it.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="fr">
|
||||
3. Google Play Jeux (Android, optionnel)
|
||||
</h2>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="en">
|
||||
3. Google Play Games (Android, optional)
|
||||
</h2>
|
||||
<p data-lang="fr">
|
||||
Sur Android, si vous choisissez de vous connecter à Google Play Jeux, le jeu envoie
|
||||
vos scores aux classements. Google traite alors votre identifiant joueur et votre
|
||||
pseudonyme Play Jeux conformément à
|
||||
<a
|
||||
href="https://policies.google.com/privacy"
|
||||
class="font-medium text-accent underline underline-offset-2"
|
||||
>sa propre politique de confidentialité</a
|
||||
>. La connexion est optionnelle : sans elle, le jeu reste pleinement jouable et
|
||||
aucune donnée ne quitte votre appareil.
|
||||
</p>
|
||||
<p data-lang="en">
|
||||
On Android, if you choose to sign in to Google Play Games, the game submits your
|
||||
scores to leaderboards. Google then processes your Play Games player ID and
|
||||
nickname under
|
||||
<a
|
||||
href="https://policies.google.com/privacy"
|
||||
class="font-medium text-accent underline underline-offset-2"
|
||||
>its own privacy policy</a
|
||||
>. Signing in is optional: without it, the game remains fully playable and no data
|
||||
leaves your device.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="fr">
|
||||
4. Ce que le jeu ne fait pas
|
||||
</h2>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="en">
|
||||
4. What the game does not do
|
||||
</h2>
|
||||
<ul class="list-disc space-y-1 pl-5" data-lang="fr">
|
||||
<li>pas de publicité ;</li>
|
||||
<li>pas d'analytique ni de mesure d'audience ;</li>
|
||||
<li>pas de création de compte par nos soins ;</li>
|
||||
<li>pas d'accès à votre position ;</li>
|
||||
<li>pas d'accès à vos contacts, photos ou fichiers ;</li>
|
||||
<li>aucune donnée vendue ni partagée à des tiers.</li>
|
||||
</ul>
|
||||
<ul class="list-disc space-y-1 pl-5" data-lang="en">
|
||||
<li>no advertising;</li>
|
||||
<li>no analytics or audience measurement;</li>
|
||||
<li>no account creation on our side;</li>
|
||||
<li>no access to your location;</li>
|
||||
<li>no access to your contacts, photos or files;</li>
|
||||
<li>no data sold or shared with third parties.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="fr">5. Mineurs</h2>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="en">5. Minors</h2>
|
||||
<p data-lang="fr">
|
||||
Livrets est un jeu éducatif destiné à l'apprentissage des tables de multiplication.
|
||||
Le jeu ne collecte délibérément aucune donnée personnelle d'enfant. Les seules
|
||||
données susceptibles de transiter le sont via Google Play Jeux, sous la
|
||||
responsabilité de Google.
|
||||
</p>
|
||||
<p data-lang="en">
|
||||
Livrets is an educational game for learning multiplication tables. The game does not
|
||||
knowingly collect any personal data from children. The only data that may transit
|
||||
does so via Google Play Games, under Google's responsibility.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="fr">
|
||||
6. Conservation des données
|
||||
</h2>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="en">
|
||||
6. Data retention
|
||||
</h2>
|
||||
<p data-lang="fr">
|
||||
Les données locales sont conservées tant que l'application est installée sur votre
|
||||
appareil ; vous pouvez les effacer à tout moment en désinstallant l'application.
|
||||
Les scores envoyés aux classements Play Jeux sont conservés par Google selon ses
|
||||
propres règles.
|
||||
</p>
|
||||
<p data-lang="en">
|
||||
Local data is kept as long as the app is installed on your device; you can erase it
|
||||
at any time by uninstalling the app. Scores submitted to Play Games leaderboards are
|
||||
retained by Google under its own rules.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="fr">
|
||||
7. Vos droits
|
||||
</h2>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="en">
|
||||
7. Your rights
|
||||
</h2>
|
||||
<p data-lang="fr">
|
||||
Conformément au RGPD, vous disposez de droits d'accès, de rectification et de
|
||||
suppression. Comme l'essentiel des données reste sur votre appareil, l'exercice de
|
||||
ces droits passe par la désinstallation de l'application. Pour toute autre demande :
|
||||
<span class="placeholder">[EMAIL — À REMPLIR]</span>.
|
||||
</p>
|
||||
<p data-lang="en">
|
||||
Under the GDPR, you have rights of access, rectification and erasure. Since most
|
||||
data stays on your device, exercising these rights is done by uninstalling the app.
|
||||
For any other request:
|
||||
<span class="placeholder">[EMAIL — À REMPLIR]</span>.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="fr">
|
||||
8. iOS et desktop
|
||||
</h2>
|
||||
<h2 class="mb-2 text-lg font-semibold text-navy dark:text-mist" data-lang="en">
|
||||
8. iOS and desktop
|
||||
</h2>
|
||||
<p data-lang="fr">
|
||||
Sur iOS et macOS, le jeu n'a aucune fonctionnalité en ligne : toutes les données
|
||||
restent sur votre appareil.
|
||||
</p>
|
||||
<p data-lang="en">
|
||||
On iOS and macOS, the game has no online features: all data stays on your device.
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="mt-12 border-t border-navy/10 pt-6 text-sm text-navy/70 dark:border-paper/20 dark:text-paper/70">
|
||||
<p data-lang="fr">
|
||||
Contact : <span class="placeholder">[EMAIL — À REMPLIR]</span>
|
||||
</p>
|
||||
<p data-lang="en">
|
||||
Contact: <span class="placeholder">[EMAIL — À REMPLIR]</span>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var root = document.documentElement;
|
||||
var btn = document.getElementById('lang-toggle');
|
||||
function set(lang) {
|
||||
root.classList.remove('fr', 'en');
|
||||
root.classList.add(lang);
|
||||
root.lang = lang;
|
||||
btn.textContent = lang === 'fr' ? 'English' : 'Français';
|
||||
btn.setAttribute('aria-label', lang === 'fr' ? 'Switch to English' : 'Passer en français');
|
||||
try {
|
||||
localStorage.setItem('livrets-lang', lang);
|
||||
} catch (e) {}
|
||||
}
|
||||
var saved = null;
|
||||
try {
|
||||
saved = localStorage.getItem('livrets-lang');
|
||||
} catch (e) {}
|
||||
var initial =
|
||||
location.hash === '#en' ? 'en' : location.hash === '#fr' ? 'fr' : saved === 'en' ? 'en' : 'fr';
|
||||
set(initial);
|
||||
btn.addEventListener('click', function () {
|
||||
set(root.classList.contains('fr') ? 'en' : 'fr');
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
- [ ] **Step 2 : Vérification manuelle navigateur**
|
||||
|
||||
Ouvrir la page :
|
||||
|
||||
```bash
|
||||
open privacy.html
|
||||
```
|
||||
|
||||
Checklist attendue :
|
||||
1. **Défaut FR** : tout le texte visible est en français ; aucun bloc EN visible ; le bouton affiche « English ».
|
||||
2. **Toggle** : cliquer « English » → tout le contenu bascule en anglais, le bouton affiche « Français », `<html lang="en">` (vérifier dans l'inspecteur).
|
||||
3. **Persistance** : recharger la page → reste en anglais ; recharger une fenêtre privée → français.
|
||||
4. **Hash** : ouvrir `privacy.html#en` dans une fenêtre privée → anglais dès le chargement.
|
||||
5. **Sombre** : basculer l'apparence du système (macOS Réglages → Apparence) → fond navy `#1D3557`, texte clair, aucun contraste cassé (badges placeholder restent lisibles).
|
||||
6. **Mobile** : réduire la fenêtre à ~360px de large → pas de débordement horizontal, bouton et logo sur une ligne.
|
||||
7. **Logo** : rendu identique à l'icône de l'app (4 tuiles colorées sur fond navy).
|
||||
|
||||
- [ ] **Step 3 : Vérifier les placeholders et l'autonomie du fichier**
|
||||
|
||||
```bash
|
||||
grep -o "À REMPLIR" privacy.html | wc -l
|
||||
```
|
||||
|
||||
Attendu : `6` (éditeur ×2 FR/EN, email ×4 : section 7 FR/EN + footer FR/EN).
|
||||
|
||||
```bash
|
||||
grep -o "\[DATE\]" privacy.html | wc -l
|
||||
```
|
||||
|
||||
Attendu : `2` (section 1 FR/EN).
|
||||
|
||||
```bash
|
||||
grep -Eo 'src="[^"]*"|href="[^"]*"' privacy.html | sort -u
|
||||
```
|
||||
|
||||
Attendu uniquement : `https://cdn.tailwindcss.com` (src) et `https://policies.google.com/privacy` (href). Aucune autre ressource externe.
|
||||
|
||||
- [ ] **Step 4 : Commit**
|
||||
|
||||
```bash
|
||||
git add privacy.html
|
||||
git commit -m "feat: ajouter la page de politique de confidentialité bilingue"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2 : Checklist de publication (hors dépôt)
|
||||
|
||||
**Files:**
|
||||
- Aucun fichier modifié. Étapes à réaliser par le propriétaire avant/après déploiement.
|
||||
|
||||
- [ ] **Step 1 : Remplacer les placeholders**
|
||||
|
||||
Dans `privacy.html` : `[ÉDITEUR — À REMPLIR]` → nom/pseudo de l'éditeur ; `[EMAIL — À REMPLIR]` (3 occurrences) → email de contact ; `[DATE]` (1 occurrence) → date de publication.
|
||||
|
||||
- [ ] **Step 2 : Déployer et saisir l'URL dans Play Console**
|
||||
|
||||
Héberger le fichier publiquement (GitHub Pages : committer `privacy.html` sur la branche publiée, ou dossier `docs/` d'un dépôt dédié). Vérifier que l'URL répond en HTTPS. Coller l'URL dans Play Console → Contenu de l'app → Politique de confidentialité.
|
||||
|
||||
- [ ] **Step 3 : Re-vérifier les 7 points de la Step 2 du Task 1 sur l'URL déployée**
|
||||
Reference in new issue
Block a user