diff --git a/css/style.css b/css/style.css
index c6f1b0f..89b49ce 100644
--- a/css/style.css
+++ b/css/style.css
@@ -140,6 +140,101 @@ button[aria-pressed="true"] {
color: #fff;
}
+/* --- barre de filtres ----------------------------------------------------- */
+
+.filtres {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 7px 16px;
+ background: var(--surface);
+ border-bottom: 1px solid var(--bordure);
+ flex-shrink: 0;
+}
+
+.filtres__titre {
+ font-size: 12px;
+ font-weight: 500;
+ color: var(--texte-doux);
+ white-space: nowrap;
+}
+
+.filtres button:not(.tag) {
+ font-size: 12px;
+ padding: 3px 9px;
+ margin-left: auto;
+ white-space: nowrap;
+}
+
+/* --- tags ----------------------------------------------------------------- */
+
+/* Chaque pastille porte sa teinte dans `--teinte-tag`, calculée par hachage du
+ nom du tag (model.js). La saturation et la clarté restent fixes, elles : ce
+ sont elles qui garantissent le contraste, quelle que soit la teinte tirée. */
+.tags {
+ display: flex;
+ gap: 4px;
+ min-width: 0;
+ overflow: hidden;
+}
+
+.tags--filtres,
+.tags--suggestions {
+ flex-wrap: wrap;
+ overflow: visible;
+}
+
+.tag {
+ font: inherit;
+ font-size: 10px;
+ font-weight: 500;
+ line-height: 1.6;
+ padding: 0 6px;
+ max-width: 84px;
+ border: 1px solid transparent;
+ border-radius: 9px;
+ cursor: pointer;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ background: hsl(var(--teinte-tag) 62% 92%);
+ color: hsl(var(--teinte-tag) 55% 27%);
+}
+
+.tags--filtres .tag,
+.tags--suggestions .tag {
+ font-size: 11px;
+ padding: 1px 9px;
+ max-width: none;
+ border-radius: 11px;
+}
+
+.tag:hover {
+ border-color: hsl(var(--teinte-tag) 45% 55%);
+}
+
+/* Un tag actif s'inverse : le fond prend la teinte pleine. Il faut donc
+ neutraliser la règle générale `button[aria-pressed="true"]`, qui repeindrait
+ toutes les pastilles de la même couleur d'accent. */
+.tag[aria-pressed="true"] {
+ background: hsl(var(--teinte-tag) 52% 38%);
+ border-color: hsl(var(--teinte-tag) 52% 38%);
+ color: #fff;
+}
+
+@media (prefers-color-scheme: dark) {
+ .tag {
+ background: hsl(var(--teinte-tag) 34% 24%);
+ color: hsl(var(--teinte-tag) 62% 76%);
+ }
+
+ .tag[aria-pressed="true"] {
+ background: hsl(var(--teinte-tag) 58% 62%);
+ border-color: hsl(var(--teinte-tag) 58% 62%);
+ color: #0f172a;
+ }
+}
+
/* --- structure de la frise ------------------------------------------------ */
/* Un seul conteneur défilant, sur les deux axes. L'en-tête et la colonne des
@@ -286,12 +381,22 @@ button[aria-pressed="true"] {
.libelle-projet__nom {
flex: 1;
+ /* Le nom cède la place aux pastilles, mais jamais entièrement : sous quatre
+ caractères il ne resterait qu'un « … » qui n'identifie plus rien. */
+ min-width: 4em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
}
+/* Les pastilles rognent le nom, pas l'inverse — mais elles s'effacent à leur
+ tour plutôt que de repousser l'œil et le menu hors de la colonne. */
+.libelle-projet .tags {
+ flex: 0 1 auto;
+ max-width: 45%;
+}
+
.libelle-projet__derive {
font-size: 11px;
font-weight: 500;
diff --git a/index.html b/index.html
index 89f5779..7491d7f 100644
--- a/index.html
+++ b/index.html
@@ -24,6 +24,16 @@
+
+
+
Filtrer
+
+
+
+