diff --git a/tests/test_palier16.py b/tests/test_palier16.py
new file mode 100644
index 0000000..d57699a
--- /dev/null
+++ b/tests/test_palier16.py
@@ -0,0 +1,36 @@
+"""Palier 16 (0.20.0) — refonte professionnelle de l'entête Projets.
+
+Fini le « Bonjour 👋 » et les rangées éparses : titre sobre,
+bande KPI unifiée, et une seule barre d'outils (onglets
+segmentés, filtre, tri, regroupement, vue). Les crochets
+fonctionnels (ids, liaisons Alpine) sont inchangés.
+"""
+
+
+def test_dashboard_professional_header(client):
+ r = client.get("/")
+ assert r.status_code == 200
+ # Titre sobre + sous-titre, plus de formule familière.
+ assert "
Projets
" in r.text
+ assert "Bonjour" not in r.text
+ # Bande KPI unifiée : valeurs + libellés.
+ assert "kpi-strip" in r.text
+ assert "Projets actifs" in r.text
+ assert "Issues fermées · 30 j" in r.text
+ assert "Temps de cycle moyen" in r.text
+ # Les KPI journal mènent à l'activité.
+ assert 'href="/activity"' in r.text
+
+
+def test_dashboard_single_toolbar_keeps_its_hooks(client):
+ r = client.get("/")
+ assert "dash-toolbar" in r.text
+ # Onglets segmentés avec compteurs, mêmes liaisons Alpine.
+ assert "seg-tabs" in r.text
+ assert "seg-count" in r.text
+ assert "tab = 'inactive'" in r.text
+ # Filtre, tri, regroupement et vue : ids préservés pour
+ # dashboard.js et l'état Alpine.
+ for hook in ('id="project-search"', 'id="dash-sort"',
+ 'id="dash-group"', "setView('list')"):
+ assert hook in r.text, hook
diff --git a/tests/test_palier2.py b/tests/test_palier2.py
index 54539d5..d13a7d1 100644
--- a/tests/test_palier2.py
+++ b/tests/test_palier2.py
@@ -198,5 +198,7 @@ def test_dashboard_uses_new_design_system(client):
r = client.get("/")
assert "app-header" in r.text
assert "nav-pill" in r.text
- assert "stat-tile" in r.text
+ # En-tête refondu en 0.20.0 : bande KPI unifiée (les stat-tile
+ # ne servent plus qu'au briefing).
+ assert "kpi-strip" in r.text
assert "live.js" in r.text