Files
livrets/docs/superpowers/plans/2026-08-31-politique-confidentialite.md

18 KiB
Raw Permalink Blame History

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 :

<!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 :

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
grep -o "À REMPLIR" privacy.html | wc -l

Attendu : 6 (éditeur ×2 FR/EN, email ×4 : section 7 FR/EN + footer FR/EN).

grep -o "\[DATE\]" privacy.html | wc -l

Attendu : 2 (section 1 FR/EN).

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
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