:root{--bg:#f5f7fb;--card:#fff;--text:#1c2533;--muted:#6b7482;--line:#e3e8ef;--primary:#2458d3;--primary2:#173f9d;--accent:#eef4ff;--ok:#177245;--warn:#a86600;--error:#b32929;--shadow:0 10px 30px rgba(29,45,75,.06)}*{box-sizing:border-box}html{font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:var(--text);background:var(--bg)}body{margin:0}.container{max-width:1480px;margin:0 auto;padding:32px}.topbar{height:68px;background:#fff;border-bottom:1px solid var(--line);display:flex;align-items:center;padding:0 28px;position:sticky;top:0;z-index:10}.brand{font-weight:800;display:flex;align-items:center;gap:10px;margin-right:35px}.brand-mark,.login-logo{display:inline-grid;place-items:center;background:var(--primary);color:#fff;border-radius:10px;width:34px;height:34px}.topbar nav{display:flex;gap:6px}.topbar nav a{color:var(--muted);text-decoration:none;padding:10px 13px;border-radius:9px;font-weight:600}.topbar nav a:hover,.topbar nav a.active{background:var(--accent);color:var(--primary)}.logout-form{margin-left:auto}.button{appearance:none;border:1px solid var(--line);background:#fff;color:var(--text);padding:10px 14px;border-radius:9px;font-weight:700;text-decoration:none;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:6px}.button:hover{border-color:#b7c4d8}.button.primary{background:var(--primary);color:#fff;border-color:var(--primary)}.button.primary:hover{background:var(--primary2)}.button.ghost{background:transparent}.button.full{width:100%}.card{background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);padding:20px}.page-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;margin-bottom:22px}.page-heading h1{margin:0 0 4px;font-size:29px}.muted{color:var(--muted)}p{margin-top:0}.metrics-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:14px;margin-bottom:18px}.metric{min-height:126px;display:flex;flex-direction:column}.metric span{color:var(--muted);font-weight:650;font-size:13px}.metric strong{font-size:28px;margin:13px 0 4px}.metric small{color:var(--muted)}.metric.accent{background:var(--accent);border-color:#d8e5ff}.card-heading{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:14px}.card-heading h2,.card h2{margin:0 0 5px;font-size:18px}.chart-card{margin-bottom:18px}.chart{min-height:250px}.chart svg{width:100%;height:260px}.chart-axis{stroke:#d7dce5;stroke-width:1}.chart-line{stroke:var(--primary);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}.chart-label{font-size:12px;fill:#737d8c}.empty-chart{display:grid;place-items:center;height:240px;color:var(--muted)}.table-wrap{overflow:auto;padding:0}.table-wrap .card-heading{padding:20px 20px 0}table{width:100%;border-collapse:collapse;min-width:780px}th,td{text-align:left;padding:13px 14px;border-bottom:1px solid var(--line);vertical-align:top}th{font-size:12px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);background:#fafbfc;position:sticky;top:0}td{font-size:14px}td small{display:block;color:var(--muted);margin-top:3px}.clickable{cursor:pointer}.clickable:hover td{background:#f8faff}.empty{text-align:center;color:var(--muted);padding:30px}.filters-grid{display:grid;grid-template-columns:repeat(5,minmax(150px,1fr));gap:13px;margin-bottom:18px}.filters-grid label,.stack label{display:flex;flex-direction:column;gap:7px;color:var(--muted);font-size:13px;font-weight:650}input,select{width:100%;border:1px solid #cfd7e3;border-radius:8px;padding:10px 11px;font:inherit;color:var(--text);background:#fff}input:focus{outline:2px solid #cbdcff;border-color:var(--primary)}.filter-actions{display:flex;align-items:end;gap:8px}.pagination{display:flex;align-items:center;justify-content:center;gap:18px;margin-top:18px}.pill{display:inline-block;border:1px solid #d9e0e9;border-radius:999px;padding:4px 8px;background:#f6f8fb;font-size:12px;color:#566071}.pill.warn{background:#fff6e8;border-color:#f0d59f;color:var(--warn)}.ok-pill{background:#edf8f2;border-color:#bfe3cf;color:var(--ok)}.error-pill{background:#fff0f0;border-color:#efc1c1;color:var(--error)}.detail-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin-bottom:18px}.details{display:grid;grid-template-columns:180px 1fr;gap:0;margin:10px 0 0}.details dt,.details dd{padding:11px 0;border-bottom:1px solid var(--line);margin:0}.details dt{color:var(--muted);font-weight:650}.source-pre{white-space:pre-wrap;word-break:break-word;background:#f7f9fc;border:1px solid var(--line);border-radius:10px;padding:15px;max-height:420px;overflow:auto}.email-body{max-height:650px}.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.break{word-break:break-all}.back{display:inline-block;margin-bottom:9px;color:var(--primary);text-decoration:none;font-weight:700}.inline-actions{display:flex;gap:10px;flex-wrap:wrap}.admin-metrics{grid-template-columns:repeat(4,minmax(0,1fr))}.status-text{font-size:21px!important}.ok{color:var(--ok)}.warn-text{color:var(--warn)}.login-container{min-height:100vh;display:grid;place-items:center;padding:30px}.login-card{width:min(420px,100%);padding:34px}.login-logo{width:48px;height:48px;font-weight:800;margin-bottom:18px}.login-card h1{margin:0 0 5px}.stack{display:grid;gap:16px;margin-top:24px}.alert{padding:11px 13px;border-radius:9px;margin-top:15px}.alert.error{background:#fff0f0;color:var(--error);border:1px solid #efc1c1}@media(max-width:1100px){.metrics-grid{grid-template-columns:repeat(3,1fr)}.filters-grid{grid-template-columns:repeat(3,1fr)}}@media(max-width:760px){.container{padding:18px}.topbar{padding:0 13px}.brand span:last-child{display:none}.topbar nav a{padding:8px}.metrics-grid,.admin-metrics,.filters-grid,.detail-grid{grid-template-columns:1fr}.page-heading{flex-direction:column}.details{grid-template-columns:1fr}.details dt{border-bottom:0;padding-bottom:0}.details dd{padding-top:4px}.logout-form .button{padding:8px}}
.chart-point{fill:#fff;stroke:var(--primary);stroke-width:3;cursor:help}.chart-point:hover{r:6}

/* Dashboard periods */
.dashboard-period{margin-bottom:22px}.period-heading{display:flex;align-items:flex-end;justify-content:space-between;margin:0 0 10px}.period-heading h2{margin:0 0 3px;font-size:18px}.period-heading p{margin:0;font-size:13px}

/* Database-backed filter comboboxes */
.filter-field{display:flex;flex-direction:column;gap:7px;color:var(--muted);font-size:13px;font-weight:650;min-width:0}.db-combobox{position:relative}.db-combobox-control{position:relative}.db-combobox-search{padding-right:36px}.db-combobox-clear{position:absolute;right:5px;top:50%;transform:translateY(-50%);width:28px;height:28px;border:0;background:transparent;border-radius:7px;color:#7a8492;font-size:20px;line-height:1;cursor:pointer}.db-combobox-clear:hover{background:#eef2f8;color:var(--text)}.db-combobox-results{position:absolute;left:0;right:0;top:calc(100% + 5px);z-index:30;max-height:290px;overflow:auto;background:#fff;border:1px solid #cfd7e3;border-radius:10px;box-shadow:0 16px 35px rgba(29,45,75,.16);padding:5px}.db-combobox-results button{display:block;width:100%;border:0;background:#fff;color:var(--text);text-align:left;padding:9px 10px;border-radius:7px;cursor:pointer;font:inherit;font-weight:500}.db-combobox-results button:hover,.db-combobox-results button.active{background:var(--accent);color:var(--primary)}.db-combobox-empty{padding:12px;color:var(--muted);font-weight:500}.db-combobox-search:invalid{border-color:var(--error);outline-color:#f3b8b8}

/* Interactive daily chart */
.chart{overflow-x:auto;min-height:335px}.chart-shell{position:relative;min-width:1000px}.chart svg{width:100%;height:335px;display:block;touch-action:none}.chart-axis,.chart-tick{stroke:#d7dce5;stroke-width:1}.chart-line{stroke:var(--primary);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}.chart-label{font-size:12px;fill:#737d8c}.chart-date-label{font-size:10px;fill:#737d8c}.chart-point{fill:#fff;stroke:var(--primary);stroke-width:3}.chart-hover-line{stroke:#8493ad;stroke-width:1;stroke-dasharray:4 4;pointer-events:none}.chart-hover-dot{fill:#fff;stroke:#111827;stroke-width:3;pointer-events:none}.chart-tooltip{position:absolute;z-index:5;display:flex;flex-direction:column;gap:4px;min-width:190px;padding:10px 12px;border-radius:9px;background:#111827;color:#fff;box-shadow:0 10px 30px rgba(0,0,0,.2);font-size:12px;pointer-events:none}.chart-tooltip strong{font-size:13px}.chart-tooltip span{white-space:nowrap}.chart-tooltip[hidden]{display:none}.chart-hover-line[hidden],.chart-hover-dot[hidden]{display:none}

@media(max-width:760px){.chart-shell{min-width:920px}.period-heading{align-items:flex-start}.dashboard-period{margin-bottom:18px}}

/* Dashboard remanié — une seule période à la fois, médiane en tête.
   Le bleu porte le marché, l'ocre nos propres lots : couple vérifié pour les
   déficiences de la vision des couleurs (ΔE 28,7 en protanopie), et doublé
   d'une légende plus d'une valeur écrite au bout de chaque barre, pour que
   l'identité ne repose jamais sur la seule couleur. */
:root{--nous:#b45309}
.entete-actions{display:flex;gap:10px;align-items:center}
.segment{display:inline-flex;background:#eaeef6;border-radius:10px;padding:3px}
.segment a{text-decoration:none;font-weight:700;font-size:13px;padding:8px 15px;border-radius:8px;color:var(--muted)}
.segment a:hover{color:var(--text)}
.segment a.actif{background:#fff;color:var(--primary);box-shadow:0 1px 3px rgba(29,45,75,.14)}
.metrics-grid.quatre{grid-template-columns:repeat(4,minmax(0,1fr))}
.metrics-grid.quatre .metric{min-height:118px}
.metrics-grid.quatre .metric small{line-height:1.45}
.duo{display:grid;grid-template-columns:1.05fr .95fr;gap:18px;margin-bottom:18px;align-items:start}
.hero{display:flex;align-items:baseline;gap:12px;margin:2px 0 14px}
.hero b{font-size:38px;letter-spacing:-1px;color:var(--nous)}
.hero em{font-style:normal;color:var(--muted);font-size:13px;line-height:1.45}
.legende{display:flex;flex-wrap:wrap;gap:16px;align-items:center;font-size:12.5px;color:var(--muted);margin:0 0 14px}
.puce{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:6px;vertical-align:-1px}
.puce.marche{background:var(--primary)}
.puce.nous{background:var(--nous)}
.bande{margin-bottom:11px}
.bande-titre{font-size:12.5px;font-weight:650;color:var(--muted);margin-bottom:5px}
.bande-barres{display:flex;flex-direction:column;gap:2px}
.barre-ligne{display:flex;align-items:center;gap:9px;min-height:15px}
.barre{height:11px;border-radius:0 4px 4px 0;min-width:3px}
.barre.marche{background:var(--primary)}
.barre.nous{background:var(--nous)}
.barre-val{font-size:12px;font-weight:700;white-space:nowrap}
.barre-n{font-size:11px;color:var(--muted);white-space:nowrap}
.barre-absent{font-size:11.5px;color:#9aa3b0;font-style:italic}
.reserve{font-size:11.5px;color:var(--muted);line-height:1.6;margin:12px 0 0;border-top:1px solid var(--line);padding-top:11px}
table.compacte{min-width:0}
table.compacte th{padding:8px 10px;background:transparent;position:static}
table.compacte td{padding:9px 10px;font-size:13px;border-bottom:1px solid #f0f3f7}
td.num,th.num{text-align:right;font-variant-numeric:tabular-nums}
td.forte{font-weight:700}
.fleche{color:#a9b3c2}
details summary{cursor:pointer;font-weight:700;font-size:13.5px;color:var(--primary);padding:12px 0}
details summary:hover{color:var(--primary2)}
.detail-deplie h3{font-size:14px;margin:18px 0 6px}
/* Le graphique tient désormais dans la largeur : les dates ne sont plus
   inclinées ni affichées toutes, donc plus de défilement horizontal imposé. */
.chart{overflow-x:visible;min-height:0}
.chart-shell{min-width:0}
.chart svg{height:300px}
@media(max-width:1100px){.metrics-grid.quatre{grid-template-columns:repeat(2,1fr)}.duo{grid-template-columns:1fr}}
@media(max-width:760px){.metrics-grid.quatre{grid-template-columns:1fr}.chart-shell{min-width:640px}.chart{overflow-x:auto}.page-heading .entete-actions{width:100%}}
/* Correctifs de mise en page relevés au contrôle visuel du 14/08.
   1. Une piste de grille vaut par défaut « auto » en largeur minimale : le
      tableau des axes imposait donc sa largeur intrinsèque à la colonne, et
      poussait toute la page en débordement horizontal. min-width:0 rend la
      piste compressible et laisse le tableau se replier.
   2. Une hauteur fixe sur un SVG à viewBox le centre au lieu de l'étirer
      (preserveAspectRatio par défaut) : le graphique laissait une centaine de
      pixels morts de chaque côté. Hauteur automatique = mise à l'échelle sur
      la largeur disponible. */
.duo>*{min-width:0}
.chart svg{width:100%;height:auto}
table.compacte{width:100%;table-layout:auto}
table.compacte th,table.compacte td{white-space:normal}
/* Chevron des filtres à menu. Sans lui, un champ de recherche adossé à la base
   de données ne se distingue pas d'une saisie libre : l'utilisateur tape au
   jugé au lieu de choisir dans la liste. */
.db-combobox-search{padding-right:58px}
.db-combobox-clear{right:27px}
.db-combobox-toggle{position:absolute;right:4px;top:50%;transform:translateY(-50%);width:24px;height:28px;border:0;background:transparent;border-radius:7px;color:#7a8492;font-size:13px;line-height:1;cursor:pointer;display:grid;place-items:center}
.db-combobox-toggle:hover{background:#eef2f8;color:var(--text)}
/* Liens du Dashboard vers le détail des offres. Le chiffre reste un chiffre :
   il ne prend la couleur du lien qu'au survol, pour ne pas transformer le
   tableau de bord en page de liens bleus. */
.lien-detail{color:inherit;text-decoration:none;border-bottom:1px dashed transparent}
.lien-detail:hover{color:var(--primary);border-bottom-color:var(--primary)}
.lien-detail.discret{color:var(--muted)}
.barre-ligne.cliquable{text-decoration:none;color:inherit;border-radius:6px}
.barre-ligne.cliquable:hover{background:#f4f7fd}
.barre-ligne.cliquable:hover .barre-val{color:var(--primary)}
.barre{display:inline-block}
/* Bandeau rappelant d'où vient la restriction en cours. */
.bandeau-filtres{display:flex;flex-wrap:wrap;align-items:center;gap:9px;margin-bottom:14px;padding:14px 18px}
.bandeau-titre{font-size:13px;font-weight:700;color:var(--muted)}
.jeton{display:inline-flex;align-items:center;gap:7px;background:var(--accent);border:1px solid #d8e5ff;color:var(--primary);border-radius:999px;padding:5px 11px;font-size:12.5px;font-weight:650;text-decoration:none}
.jeton:hover{background:#e0ebff}
.jeton b{font-weight:800;opacity:.65}
/* Cinquième tuile (charge moyenne) et double indicateur du comparatif. */
.metrics-grid.cinq{grid-template-columns:repeat(5,minmax(0,1fr))}
.metrics-grid.cinq .metric{min-height:118px}
.metrics-grid.cinq .metric small{line-height:1.45}
.paire-indicateurs{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:0 0 10px}
.paire-indicateurs>div{background:#fafbfd;border:1px solid var(--line);border-radius:11px;padding:10px 12px}
.paire-indicateurs span{display:block;font-size:12px;font-weight:650;color:var(--muted);margin-bottom:5px}
.paire-indicateurs b{font-size:19px;letter-spacing:-.3px}
.paire-indicateurs b.nous{color:var(--nous);margin-left:10px}
.paire-indicateurs em{font-style:normal;font-size:11px;color:var(--muted);margin-left:3px}
.rappel{font-size:11.5px;margin:0 0 12px}
@media(max-width:1250px){.metrics-grid.cinq{grid-template-columns:repeat(3,1fr)}}
@media(max-width:760px){.metrics-grid.cinq{grid-template-columns:1fr}.paire-indicateurs{grid-template-columns:1fr}}
/* Comparatif en matrice d'écart, pleine largeur (sorti de la demi-colonne .duo
   qui le forçait à monter en hauteur pendant que la droite restait vide). Une
   grille : lignes = bandes de distance, groupes de colonnes = les trois
   grandeurs. L'écart est porté par une pastille : vert « nous payons moins »,
   rouge « plus » ; la charge reste neutre (grise), car un écart de charge est
   une taille de lot, pas un prix. La couleur double toujours un nombre signé,
   jamais seule. « Nos lots » garde l'ocre habituel (var(--nous)). */
.comparatif-card .hero{margin-bottom:14px}
.matrice-wrap{overflow-x:auto}
table.matrice{width:100%;border-collapse:collapse;min-width:760px}
table.matrice th.grp{text-align:center;font-size:11.5px;color:var(--text);border-bottom:1px solid var(--line);padding:6px 10px;text-transform:none;letter-spacing:0}
table.matrice th.sub{font-size:10px;font-weight:600;color:var(--muted);text-transform:none;letter-spacing:0;padding:5px 10px}
table.matrice td{border-top:1px solid #f0f3f7;padding:10px;vertical-align:middle;font-size:13px}
table.matrice td.libelle{font-weight:600;white-space:nowrap}
table.matrice td.libelle .n{display:block;font-weight:600;color:var(--muted);font-size:10.5px}
.duo-val{display:inline-flex;gap:6px;align-items:baseline;justify-content:flex-end;font-variant-numeric:tabular-nums}
.duo-val a.m,.duo-val .m{color:var(--muted);font-weight:600}
.duo-val .fl{color:#b6bfcd}
.badge{display:inline-block;padding:2px 9px;border-radius:999px;font-size:11.5px;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.badge.bas{background:#e9f6ef;border:1px solid #bfe3cf;color:var(--ok)}
.badge.haut{background:#fdecec;border:1px solid #f0c9c9;color:var(--error)}
.badge.neutre{background:#f1f4f8;border:1px solid #dfe5ee;color:var(--muted)}
.badge.vide{color:#aeb6c2;font-weight:600;font-size:11px}
.comparatif-legende{font-size:11.5px;color:var(--muted);margin:12px 0 0;display:flex;gap:16px;flex-wrap:wrap}
.comparatif-legende i{display:inline-block;width:11px;height:11px;border-radius:4px;vertical-align:-1px;margin-right:5px;border:1px solid}
.comparatif-legende i.bas{background:#e9f6ef;border-color:#bfe3cf}
.comparatif-legende i.haut{background:#fdecec;border-color:#f0c9c9}
.comparatif-legende i.neutre{background:#f1f4f8;border-color:#dfe5ee}
.lien-detail.nous{color:var(--nous)}
.lien-detail.nous:hover{color:var(--nous);border-bottom-color:var(--nous)}
/* Matrice €/km à conditions égales : petits effectifs sous chaque valeur. */
table.matrice-km td small{display:block;color:var(--muted);font-size:10.5px;font-weight:600;margin-top:1px}
table.matrice-km .nous{color:var(--nous);font-weight:650}
/* Carte de France des départs, à côté du tableau des axes : rééquilibre la
   ligne (le tableau seul laissait la droite vide). Choroplèthe des offres
   uniques par région de départ — intensité = fill-opacity sur le bleu du
   marché, calculée en log côté serveur (volumes très déséquilibrés). Une
   région sans départ reste grise, jamais bleu pâle « faible » : absence ≠ peu.
   Chaque région est un lien vers ses offres ; le survol l'entoure d'un liseré. */
.carte-france{display:flex;justify-content:center;padding:4px 0}
.carte-france svg{width:100%;max-width:340px;height:auto}
.carte-region{fill:var(--primary);stroke:#fff;stroke-width:.7;transition:stroke-width .1s}
.carte-region.vide{fill:#e9edf3}
.carte-france a{cursor:pointer}
.carte-france a:hover .carte-region{stroke:var(--text);stroke-width:1.2}
.carte-france a:focus{outline:none}
.carte-kpi{list-style:none;margin:14px 0 0;padding:0;display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.carte-kpi li{background:#fafbfd;border:1px solid var(--line);border-radius:11px;padding:10px 11px}
.carte-kpi span{display:block;font-size:11px;color:var(--muted);font-weight:650}
.carte-kpi b{display:block;font-size:15px;letter-spacing:-.2px;margin:4px 0 2px}
.carte-kpi em{font-style:normal;font-size:10.5px;color:var(--muted);line-height:1.35;display:block}
@media(max-width:760px){.carte-kpi{grid-template-columns:1fr}}
/* Gestion des comptes : identité + rôle dans la barre du haut, page de gestion.
   Le rôle est doublé d'une pastille (ocre pour admin) pour qu'on sache d'un
   coup d'œil avec quel niveau on est connecté. */
.topbar-right{margin-left:auto;display:flex;align-items:center;gap:14px}
.topbar-right .logout-form{margin-left:0}
.user-chip{display:flex;align-items:center;gap:8px}
.user-nom{font-weight:700;font-size:13px}
/* Sélecteur de langue (FR/EN/DE) : trois petits liens, l'actif souligné en teal. */
.lang-switch{display:flex;gap:2px;border:1px solid var(--line);border-radius:7px;overflow:hidden}
.lang-switch a{padding:3px 8px;font-size:11.5px;font-weight:700;letter-spacing:.03em;color:var(--muted);text-decoration:none}
.lang-switch a:hover{background:var(--accent);color:var(--primary)}
.lang-switch a.active{background:var(--primary);color:#fff}
.alert.ok-alert{background:#edf8f2;border:1px solid #bfe3cf;color:var(--ok)}
.button.danger{color:var(--error);border-color:#efc1c1}
.button.danger:hover{background:#fff0f0;border-color:#e29a9a}
.note-amorcage{font-size:12px;margin-top:14px;border-top:1px solid var(--line);padding-top:10px}
.note-amorcage code,.empty code{background:#f1f4f8;border-radius:4px;padding:1px 5px;font-size:12px}
.table-scroll{overflow-x:auto}
.col-actions{min-width:270px}
details.menu-reset{position:relative}
details.menu-reset>summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;padding:10px 14px;border:1px solid var(--line);border-radius:9px;background:#fff;font-weight:700;font-size:13px}
details.menu-reset>summary::-webkit-details-marker{display:none}
details.menu-reset>summary:hover{border-color:#b7c4d8}
.reset-form{position:absolute;z-index:20;top:calc(100% + 5px);left:0;display:flex;gap:6px;background:#fff;border:1px solid #cfd7e3;border-radius:10px;box-shadow:0 16px 35px rgba(29,45,75,.16);padding:8px;width:max-content}
.reset-form input{width:200px}
/* Points du graphique cliquables : chaque point mène aux offres uniques de son
   jour (même jeu que la médiane tracée). Le curseur et l'agrandissement au
   survol signalent qu'on peut cliquer ; l'infobulle le dit aussi. */
.chart-point{cursor:pointer}
.chart-point-lien:hover .chart-point{r:6;stroke-width:4}
.chart-tooltip-hint{color:#9fb4e6;font-size:11px;margin-top:2px}
/* En-têtes triables de la liste des offres : la colonne devient un lien, la
   flèche indique le sens (▲/▼ actif, ↕ neutre). Le libellé garde le style des
   th ; seule la flèche et la couleur au survol signalent l'interactivité. */
.th-tri{padding:0}
.th-tri a{display:flex;align-items:center;gap:6px;justify-content:space-between;padding:13px 14px;color:var(--muted);text-decoration:none;font:inherit;text-transform:uppercase;letter-spacing:.04em;font-size:12px;font-weight:700}
.th-tri a:hover{color:var(--text);background:#f2f5f9}
.th-tri.actif a{color:var(--primary)}
.tri-fleche{font-size:10px;opacity:.55}
.th-tri.actif .tri-fleche{opacity:1}
.th-tri a:hover .tri-fleche{opacity:.9}
