---
suivi: 1658
date: 2026-09-22
sujet: Barre KPI liseré — fond blanc, filet latéral, plus de repli, Enregistrer sur les ancres
chantier: Foncier / Faisabilité
type: feature
statut: poussé
hash: 14a6ecd2
fichiers:
  - resources/js/Components/Foncier/ScenarioKpiBar.vue
  - resources/js/Pages/Foncier/Scenarios/Show.vue
  - resources/js/utils/seuilsIndicateursEtudeFi.js
  - tests/Unit/ScenarioKpiBarLisere1658SourceTest.php
  - tests/Unit/ScenarioKpiBar1634SourceTest.php
  - tests/Unit/ScenarioBarreKpiEtUnites1640SourceTest.php
  - tests/Unit/ScenarioSeuilsCouleurBarreKpi1654SourceTest.php
  - tests/Unit/ScenarioSeuilsTotauxPiedAide1656SourceTest.php
  - database/data/journal_mises_a_jour_post_2026_06_12.php
  - public/build/
  - docs/suivi/SUIVI_1658_barre_kpi_lisere.md
---

# SUIVI #1658 — barre KPI liseré

## PROMPT ENVOYÉ

Lot PUREMENT VISUEL. Barre collante du scénario : fond blanc + ombre,
filet latéral 3 px par indicateur, libellés courts, plus de bouton
« Indicateurs » ni de repli sessionStorage, sous-menu séparé et
souligné, Enregistrer à droite des ancres. Aucun calcul.

## FICHES LUES

- **#1654 LEÇON** — une seule source `seuilsIndicateursEtudeFi.js` ;
  0 → palier null (fond neutre) ; sans `peut_prix` aucune couleur.
  Conservé : `classeSeuilAffiche` inchangée, `CLASSES_PALIER_SEUIL`
  inchangé (étude Fi + tableau dossier #1655). Ajouté :
  `CLASSES_PALIER_LISERE` (mêmes clés de palier, présentation filet).
- **#1656 LEÇON** — 3ᵉ barème = `% consolidé / CA HT`. Les deux
  « / CA HT » se distinguent par le **premier mot** (Bénéfice vs
  Consolidé). Libellés courts demandés par Robin, mot distinctif
  en tête.
- **#1640** — Teleport `#scenario-kpi-bar-host`, pas d'`overflow-x-hidden`.
  Conservé. Abandonné : fond `bg-blue-50`, repli sessionStorage.
- **#1641** — une seule zone collante, IntersectionObserver des ancres.
  Conservé tel quel. Hauteur avant #1641 = 85 px (deux rangées KPI +
  ancres). Après #1654 (une rangée KPI) ≈ 79 px.
- **#1648 / #1649** — enregistrement unique, libellé dynamique, série,
  arrêt sur échec. Comportement INTOUCHÉ ; seul le **emplacement** du
  bouton change (rangée des ancres, à droite).
- **#1652** — estompage `calculsEnAttente ? 'opacity-50'` conservé sur
  la valeur 22 px.
- **#1657** — diagnostic TVA, hors sujet. AppShell NON touché.

Anti-collision : dernier numéro = **#1657**. **#1658 est libre.**
`Show.vue` en série (zones communes). Rebase `origin/main` avant Vite.

## SYNTHÈSE

### Composition de la zone collante

1. Rangée indicateurs — fond `bg-white`, ombre
   `shadow-[0_2px_6px_rgba(27,43,75,0.08)]` (déjà #1640), filet
   `border-b border-[#E5E7EB]`.
2. Rangée sous-menu — `border-t-2 border-[#D1D5DB] bg-[#F9FAFB]`
   (thead fiche foncière). Ancres soulignées `border-b-2`. Enregistrer
   + badge dirty + « Recalcul… » à droite.

### Filet latéral (piste Liseré)

Filet `w-[3px] rounded-full`. Valeur `text-[22px] font-bold tabular-nums`.
Libellé `text-[10px] uppercase tracking-wide text-[#6B7280]`, une ligne
(`whitespace-nowrap`).

| Indicateur | Filet | Valeur | Fond |
|---|---|---|---|
| Résultat consolidé | `bg-[#1B2B4B]` | `text-[#1B2B4B]` | aucun |
| Bénéfice brut | `bg-[#64748B]` | `text-[#475569]` | aucun |
| 3 à seuil, palier connu | `CLASSES_PALIER_LISERE[palier].filet` | `.texte` | `.fond` (*50) |
| 3 à seuil, 0 / absent | `bg-[#D1D5DB]` | `text-[#374151]` | aucun |

Séparateur vertical `w-px bg-[#D1D5DB]` entre le 2ᵉ et le 3ᵉ
(`min-[1100px]:block`).

Aucun pavé `bg-emerald-600 text-white` sur la barre : `vert_fonce` du
tableau reste inchangé ; le liseré utilise `bg-emerald-50` +
`text-emerald-800` + filet `bg-emerald-600`.

### Libellés — choix retenu

« Résultat consolidé » · « Bénéfice brut » · « Consolidé / lot » ·
« Bénéfice / CA HT » · « Consolidé / CA HT ».

Les deux « / CA HT » partagent le dénominateur (#1656) : le mot
distinctif (Bénéfice / Consolidé) est **en premier**, donc lisible
avant le suffixe commun. Titres au survol conservent la formulation
longue (« Étude financière — % consolidé / CA HT »).

### Supprimé

- Bouton « Indicateurs », `replie`, `basculerRepli`, `onMounted`,
  `sessionStorage`, prop `storageKey`, `:storage-key` dans Show.vue.
- Onglets pleins `rounded-t` / `border-b-white`.
- Fond `bg-blue-50`.

### Hauteurs (modèle de boîte, pas de navigateur local)

| | Décomposition | Total |
|---|---|---|
| Avant (#1654, 1 rangée KPI + ancres collées) | py-1.5 12 + carte 10+18+py-1.5 42 + mt-1 4 + onglet 24 + border-b-2 2 − mb 2 | **≈ 82 px** |
| Après (#1658) | rangée KPI py-1 8 + 10+22+py-0.5 36 → 44 ; filet 2 + rangée ancres py-1 8 + bouton 27 + border-b 1 | **≈ 82 px** |

Comparable. Le chiffre plus grand (+4 px) est compensé par le retrait
du bouton Repli et le passage du Save sur la rangée plus basse.

### Garde-fous tenus

- AppShell.vue non modifié. Un seul Teleport.
- Barèmes `SEUILS_INDICATEURS_ETUDE_FI` inchangés. `CLASSES_PALIER_SEUIL`
  inchangé (étude Fi + dossier).
- Recalcul live : opacity-50 sur la valeur. IntersectionObserver intact.
- `enregistrerDepuisBarre` intact. `overflow-x-hidden` absent.
- Closures PHP : **aucune ajoutée**.

## DÉPLOIEMENT-TEST

```
php artisan optimize:clear
php artisan view:clear
php artisan journal:sync
```

Aucune migration. Pas de route.

1. V1 : 100 583,31 € · 59 207,31 € · 25 145,83 € VERT · 18,01 % VERT FONCÉ · 30,6 % VERT FONCÉ.
2. Fond blanc, filet latéral, aucun pavé plein.
3. Plus de bouton Indicateurs, barre toujours visible.
4. Sous-menu séparé, ancres soulignées.
5. Enregistrer à droite des ancres, libellé dynamique.
6. Trois sections → « 3 sections », les trois partent.
7. Clic sans modification : message, aucun PUT.
8. Défilement : section active soulignée.
9. Recalcul live : palier + couleur sans enregistrer.
10. Sans `peut_prix` : ni montants ni couleurs.
11. Gelé : bouton inactif.
12. 1366 / 1920 : pas d'ascenseur horizontal.

## LEÇON

Un fond teinté concurrence les couleurs de seuil dès qu'il y a plus
de deux indicateurs colorés : le liseré porte la couleur, le fond de
barre reste blanc. `CLASSES_PALIER_SEUIL` (pavé du tableau) et
`CLASSES_PALIER_LISERE` (filet de la barre) sont deux présentations
du **même** palier — ne pas recopier les bornes. Un bouton de repli
mémorisé en sessionStorage se retrouve orphelin dès que la barre
tient en hauteur : le retirer partout (prop, tests, journal) sinon
l'entrée journal continue de promettre un geste qui n'existe plus.
