diff --git a/.env.example b/.env.example
index 226c914..80d08de 100644
--- a/.env.example
+++ b/.env.example
@@ -7,7 +7,7 @@
# reachable from the internet — port 80 is what the ACME challenge uses.
SITE_ADDRESS=pardis.example.com
-# Notified by Let's Encrypt before a certificate expires. Optional but advised.
+# Required contact address for Let's Encrypt certificate management.
ACME_EMAIL=you@example.com
# Adresse locale d’écoute ; laisser 0.0.0.0 pour toutes les interfaces.
diff --git a/PRODUCTION.md b/PRODUCTION.md
index 2962911..2ba98bd 100644
--- a/PRODUCTION.md
+++ b/PRODUCTION.md
@@ -54,8 +54,12 @@ Commandes : `npx playwright install chromium` puis `npm run validate:all`.
Un navigateur installé peut être choisi avec `PARDIS_CHROME_PATH`.
La CI installe Chromium avec ses dépendances et lance les mêmes parcours.
`docker compose config --quiet` a été validé avec des variables d’exemple.
-Le build et le lancement de l’image Docker n’ont pas été exécutés ici (accès au
-socket Docker indisponible dans le bac à sable).
+Cette sandbox ne pouvait pas lancer les conteneurs (socket Docker indisponible),
+mais l'opérateur confirme que le déploiement Docker de production et son job
+CI/CD fonctionnent et sont en service depuis plusieurs commits. La VM qui héberge
+l'instance reçoit une sauvegarde quotidienne. Celle-ci protège l'hébergement et
+le service de synchronisation, mais pas les données locales conservées dans les
+navigateurs des utilisateurs.
## Vérifications sur appareils réels à terminer avant publication
diff --git a/README.md b/README.md
index 5f8b7f0..1e338ae 100644
--- a/README.md
+++ b/README.md
@@ -263,6 +263,7 @@ docker compose up -d --build
Requirements:
- `SITE_ADDRESS` must already resolve to the server.
+- `ACME_EMAIL` is required and must be a valid contact address.
- Ports **80 and 443** must be reachable from the internet. Port 80 is not optional —
it is what the ACME challenge uses to prove domain ownership.
diff --git a/docker/Caddyfile b/docker/Caddyfile
index cac7bdc..f03af1a 100644
--- a/docker/Caddyfile
+++ b/docker/Caddyfile
@@ -62,6 +62,8 @@ http://{$SITE_ADDRESS} {
header {
Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self'"
+ # Apply HSTS to this site address only; deliberately omit includeSubDomains.
+ Strict-Transport-Security "max-age=31536000"
X-Content-Type-Options nosniff
X-Frame-Options DENY
Referrer-Policy strict-origin-when-cross-origin
diff --git a/src/App.svelte b/src/App.svelte
index d91b9d6..6660308 100644
--- a/src/App.svelte
+++ b/src/App.svelte
@@ -14,6 +14,7 @@
import Stats from './routes/Stats.svelte';
import DataSettings from './routes/DataSettings.svelte';
import SyncSettings from './routes/SyncSettings.svelte';
+ import About from './routes/About.svelte';
import { liveQuery } from 'dexie';
import { loadSyncStatus, synchronize, takeAutomationRole } from './lib/sync/client.js';
import { syncState } from './lib/sync/state.svelte.js';
@@ -120,6 +121,8 @@
{:else if view === 'sync'}
+ {:else if view === 'about'}
+
{:else if ['settings', 'automations', 'non-working'].includes(view)}
{:else if view === 'today'}
diff --git a/src/app.css b/src/app.css
index 957d395..9112bd4 100644
--- a/src/app.css
+++ b/src/app.css
@@ -8,6 +8,27 @@
* - Nothing tappable is under 64px; primary actions are 88px.
*/
+/*
+ * When the font files are ready, add their @font-face declarations here and
+ * place them under public/fonts/ (for example, /fonts/pardis-text.woff2).
+ * Keeping these declarations commented avoids requests for files not yet shipped.
+ *
+ * @font-face {
+ * font-family: 'Pardis Text';
+ * src: url('/fonts/pardis-text.woff2') format('woff2');
+ * font-style: normal;
+ * font-weight: 400;
+ * font-display: swap;
+ * }
+ * @font-face {
+ * font-family: 'Pardis Headings';
+ * src: url('/fonts/pardis-headings.woff2') format('woff2');
+ * font-style: normal;
+ * font-weight: 400;
+ * font-display: swap;
+ * }
+ */
+
:root {
--bg: #ffffff;
--fg: #000000;
@@ -31,9 +52,10 @@
--radius: 10px;
--border: 3px;
- --sans: system-ui, 'Segoe UI', Roboto, sans-serif;
+ --font-body: 'Pardis Text', system-ui, 'Segoe UI', Roboto, sans-serif;
+ --font-heading: 'Pardis Headings', system-ui, 'Segoe UI', Roboto, sans-serif;
- font-family: var(--sans);
+ font-family: var(--font-body);
font-size: 20px;
line-height: 1.35;
color: var(--fg);
@@ -44,12 +66,12 @@
:root[data-theme='nuit'] {
--bg: #000000;
- --fg: #ffffff;
- --fg-dim: #cccccc;
+ --fg: #e2bfbf;
+ --fg-dim: #dba7a7;
--surface: #1a1a1a;
- --line: #ffffff;
+ --line: #774a4a;
- --accent: #ffb000; /* amber reads well at night and preserves dark adaptation */
+ --accent: #e63100; /* amber reads well at night and preserves dark adaptation */
--accent-fg: #000000;
--accent-soft: #3a2a00;
@@ -89,6 +111,7 @@ body {
h1,
h2,
h3 {
+ font-family: var(--font-heading);
margin: 0;
font-weight: 800;
letter-spacing: -0.01em;
diff --git a/src/components/AboutLink.svelte b/src/components/AboutLink.svelte
new file mode 100644
index 0000000..c2bf3c2
--- /dev/null
+++ b/src/components/AboutLink.svelte
@@ -0,0 +1,19 @@
+
+
+
diff --git a/src/lib/router.svelte.js b/src/lib/router.svelte.js
index 22b0dd2..6a15241 100644
--- a/src/lib/router.svelte.js
+++ b/src/lib/router.svelte.js
@@ -6,7 +6,7 @@
* worker should land on.
*/
-const ROUTES = ['resume', 'today', 'settings', 'stats', 'details', 'automations', 'non-working', 'data', 'sync'];
+const ROUTES = ['resume', 'today', 'settings', 'stats', 'details', 'automations', 'non-working', 'data', 'sync', 'about'];
function fromHash() {
const [path, query = ''] = location.hash.replace(/^#\/?/, '').split('?');
diff --git a/src/routes/About.svelte b/src/routes/About.svelte
new file mode 100644
index 0000000..e28c864
--- /dev/null
+++ b/src/routes/About.svelte
@@ -0,0 +1,83 @@
+
+
+
+
+
À propos de Pardis
+
+ Pardis est une application hors ligne de suivi des heures de chantier. Elle
+ enregistre les journées, les tâches, les clients, les repas et les pauses,
+ puis prépare un récapitulatif à consulter ou à copier.
+
+
+
+
Fonctionnement
+
+ Les données sont enregistrées dans le stockage du navigateur sur cet
+ appareil. L’application fonctionne hors ligne après son premier chargement.
+ Elle n’exécute pas les automatismes lorsque le navigateur ou la PWA est
+ fermé ou suspendu ; elle rattrape les étapes prévues à la prochaine
+ ouverture.
+
+
+ Les horaires automatiques sont des estimations. Vérifiez les journées
+ entièrement déduites avant de vous servir de leur récapitulatif.
+
+
+
+
+
Données et confidentialité
+
+ Pardis ne demande ni compte, ni adresse e-mail, ni mot de passe. Aucun
+ service d’analyse ou de suivi publicitaire n’est chargé. Les statistiques
+ sont calculées sur l’appareil.
+
+
+ L’historique local reste dans le navigateur jusqu’à sa suppression par
+ l’utilisateur ou à l’effacement du stockage du site. Le réglage de
+ conservation détermine quelles journées peuvent être purgées ; la purge
+ est manuelle. Le stockage du navigateur n’est pas chiffré par Pardis et
+ reste accessible à cette origine sur un navigateur déverrouillé. Un export
+ peut être conservé ailleurs, mais il n’est pas chiffré.
+
+
+ La synchronisation entre appareils est facultative. Lorsqu’elle est
+ activée, le contenu des journées et des réglages synchronisés est chiffré
+ de bout en bout. Le serveur ne peut pas lire cet historique, mais reçoit
+ des métadonnées nécessaires au service : adresse IP, identifiants et clés
+ publiques des appareils, liens entre révisions, tailles et dates de
+ connexion. Ces données sont conservées un an, conformément à la loi.
+
+
+ Supprimer une journée de l’historique synchronisé ne supprime pas ses
+ anciennes révisions chiffrées du coffre. Elles y restent jusqu’à la
+ suppression du coffre. Les sauvegardes de l’hébergement peuvent aussi
+ conserver des données supprimées jusqu’à l’expiration de leur rétention.
+
+
+
+
+
Opérateur de cette instance
+
+ Le service de synchronisation de cette instance est hébergé sur un serveur
+ sauvegardé quotidiennement. Les sauvegardes de ce serveur
+ protègent le service en ligne ; elles ne sauvegardent pas les données
+ conservées uniquement dans le navigateur de chaque utilisateur.
+
+
+ L'application est développée par Adrien Weiskopff.
+ L'application et son serveur de production sont hébergés en France par
+ clawd.fr (EI Adrien Weiskopff).
+ Pour plus d'informations rendez-vous sur le site https://clawd.fr ou écrivez
+ à l'adresse pardis@clawd.fr.
+
+
+
+
+
diff --git a/src/routes/Automations.svelte b/src/routes/Automations.svelte
index 8df5944..468f296 100644
--- a/src/routes/Automations.svelte
+++ b/src/routes/Automations.svelte
@@ -5,10 +5,10 @@
import { go } from '../lib/router.svelte.js';