diff --git a/package-lock.json b/package-lock.json
index 7cac0e6c889314d51d8f8d6bbfd27ba626eed4f3..bb4b8f04650b1c14a9d5799ec57fb4bcdbe843fa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "leximpact-socio-fiscal-ui",
-  "version": "0.0.679",
+  "version": "0.0.681",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "leximpact-socio-fiscal-ui",
-      "version": "0.0.679",
+      "version": "0.0.681",
       "devDependencies": {
         "@auditors/core": "^0.7.0",
         "@fontsource/lato": "^5.0.5",
diff --git a/src/app.postcss b/src/app.postcss
index bddd107a24444d53e84abf6775d6f5f4ae56ba2b..34477717ae822379b3af53d7ccbb2e85bcf18378 100644
--- a/src/app.postcss
+++ b/src/app.postcss
@@ -57,7 +57,7 @@
   /* *******--- CARTES ---******* */
   /* CARTE : conteneur avec des coins arrondis, de l'ombre et des états au survol/clic */
   .lx-card {
-    @apply bg-white hover:bg-neutral-50 active:bg-neutral-100 rounded-lg border shadow-md hover:shadow-lg hover:scale-105 transition-all;
+    @apply bg-white hover:bg-gray-50 active:bg-gray-100 rounded-lg border shadow-md hover:shadow-lg hover:scale-105 transition-all;
   }
   /* carte avec une bordure inférieure le-jaune-dark */
   .lx-card-underline-le-vert {
@@ -65,7 +65,7 @@
   }
   /* carte grise avec une bordure inférieure le-jaune-dark */
   .lx-card-bg-gray-underline-le-vert {
-    @apply lx-card-underline-le-vert bg-neutral-100/70 hover:bg-neutral-200/50 active:bg-neutral-200/70;
+    @apply lx-card-underline-le-vert bg-gray-100/70 hover:bg-gray-200/50 active:bg-gray-200/70;
   }
   /* *******--- ANIMATION ---******* */
   .lx-opacity-0-unclickable {
diff --git a/src/lib/components/NavBar.svelte b/src/lib/components/NavBar.svelte
index a4bcd11dd637617705206f119c299912dff381b8..f2fe067a58a69ccbdff67baae716ba25e0739a8b 100644
--- a/src/lib/components/NavBar.svelte
+++ b/src/lib/components/NavBar.svelte
@@ -14,6 +14,7 @@
   import { goto } from "$app/navigation"
   import { page } from "$app/stores"
   import NavBarSearch from "$lib/components/search/NavBarSearch.svelte"
+  import { withLinkedVariableNames } from "$lib/decompositions"
   import type { DisplayMode } from "$lib/displays"
   import { trackSearchVariable } from "$lib/matomo"
   import type { NavbarConfig } from "$lib/navbar"
@@ -590,12 +591,17 @@
           {/if}
         </ul>
       {:else}
+        <span class="inline-flex items-center gap-1 px-3 pt-3 font-bold">
+          Recherchez parmi les {withLinkedVariableNames.length} dispositifs couverts
+          par le simulateur
+          <iconify-icon icon="ri-arrow-up-line" />
+        </span>
         <ul class="max-h-64 list-none overflow-y-auto py-2 md:max-h-[80vh]">
-          <li class="inline-block px-3 pb-2 text-gray-500">Suggestions</li>
+          <li class="inline-block px-3 py-2 text-gray-500">Suggestions</li>
           {#each dispositifsTypes as dispositif}
             <li>
               <button
-                class="w-full flex items-center gap-5 px-3 py-2 2xl:py-3 hover:bg-gray-200/70 active:bg-gray-200 transition"
+                class="w-full flex items-center gap-3 px-3 py-1 2xl:py-3 hover:bg-gray-200/70 active:bg-gray-200 transition"
                 on:click={() => {
                   $searchParameterName = dispositif.parametersVariableName
                   focused = false
@@ -606,11 +612,11 @@
                 on:touchend={() => (preventBlur = false)}
               >
                 <img
-                  class="max-h-8 md:max-h-10"
+                  class="max-h-6 md:max-h-8"
                   src={dispositif.icon}
                   alt="Icône {dispositif.title}"
                 />
-                <span class="font-bold text-start text-lg 2xl:text-xl">
+                <span class="text-start text-sm 2xl:text-base">
                   {dispositif.title}
                 </span>
               </button>
diff --git a/src/lib/components/SelectChip.svelte b/src/lib/components/SelectChip.svelte
new file mode 100644
index 0000000000000000000000000000000000000000..c0e745517c7aea027c4fc395951088cc9b8fa918
--- /dev/null
+++ b/src/lib/components/SelectChip.svelte
@@ -0,0 +1,66 @@
+<script lang="ts">
+  import { clickOutside } from "$lib/click_outside"
+
+  export let label: string
+  export let open: boolean = false
+  export let options: { label: string; shortLabel: string; value: string }[]
+  export let value: string | undefined = undefined
+  export let showCheckIcon: boolean = false
+
+  let chipButton: HTMLButtonElement
+
+  $: if (value === undefined && options.length > 0) {
+    value = options[0].value
+  }
+
+  $: optionByValue = Object.fromEntries(
+    options.map((option) => [option.value, option]),
+  )
+</script>
+
+<div class="relative {$$props.class ?? ''}">
+  <button
+    bind:this={chipButton}
+    class="relative flex items-center gap-1 px-3 py-1 bg-le-bleu-light rounded-full overflow-hidden transition after:absolute after:inset-0 after:rounded-full after:transition hover:after:bg-black/5 active:after:bg-black/10"
+    class:after:bg-black={open}
+    class:after:bg-opacity-5={open}
+    on:click={() => (open = !open)}
+  >
+    {#if showCheckIcon}
+      <iconify-icon class="text-lg" icon="ri-check-line" noobserver />
+    {/if}
+    {label}
+    {#if value !== undefined}
+      : {@html optionByValue[value].shortLabel}
+    {/if}
+    <iconify-icon class="text-lg" icon="ri-arrow-down-s-line" noobserver />
+  </button>
+
+  {#if open}
+    <ul
+      class="absolute -bottom-1 translate-y-full left-0 py-1.5 bg-white border shadow-md rounded-lg"
+      use:clickOutside={{
+        callback: () => (open = false),
+        excluded: [chipButton],
+      }}
+    >
+      {#each options as option}
+        {@const selected = option.value === value}
+        <li>
+          <button
+            class="w-full text-nowrap text-start px-3 py-1.5"
+            class:hover:bg-gray-100={!selected}
+            class:active:bg-gray-200={!selected}
+            class:bg-le-bleu-light={selected}
+            on:click={() => {
+              value = option.value
+              open = false
+            }}
+          >
+            {@html option.label}
+          </button>
+        </li>
+      {/each}
+    </ul>
+  {/if}
+</div>
diff --git a/src/lib/components/test_cases/TestCaseDixiemes.svelte b/src/lib/components/test_cases/TestCaseDixiemes.svelte
deleted file mode 100644
index 4186bc0b767fee6d3d0f491ae27391069bd8eb9f..0000000000000000000000000000000000000000
--- a/src/lib/components/test_cases/TestCaseDixiemes.svelte
+++ /dev/null
@@ -1,297 +0,0 @@
-<script lang="ts">
-  import { scaleByInstantFromBrackets } from "@openfisca/json-model"
-  import { createEventDispatcher, getContext } from "svelte"
-  import type { Writable } from "svelte/store"
-
-  import TestCasePictos from "$lib/components/test_cases/TestCasePictos.svelte"
-  import Tooltip from "$lib/components/Tooltip.svelte"
-  import VariableValueChange from "$lib/components/variables/VariableValueChange.svelte"
-  import {
-    decompositionCoreByName,
-    decompositionCoreByNameByReformName,
-    type EvaluationByName,
-  } from "$lib/decompositions"
-  import {
-    asScaleParameter,
-    getParameter,
-    rootParameter,
-    rootParameterByReformName,
-  } from "$lib/parameters"
-  import type { Situation } from "$lib/situations"
-  import { valueFormatter } from "$lib/values"
-  import {
-    variableSummaryByName,
-    variableSummaryByNameByReformName,
-  } from "$lib/variables"
-
-  export let testCases: Situation[]
-  export let variableName: string
-  export let year: number
-
-  const billName = getContext("billName") as Writable<string | undefined>
-  let descriptionsOpen = false
-  const dispatch = createEventDispatcher()
-  const evaluationByNameArray = getContext("evaluationByNameArray") as Writable<
-    EvaluationByName[]
-  >
-  const formatCurrency = valueFormatter(0, "currency-EUR", false)
-  const formatLongOrdinalSup = (n: number) => {
-    const rule = ordinalPluralRules.select(n)
-    const suffix = longOrdinalSuffixes.get(rule)
-    return `${n}<sup>${suffix}</sup>`
-  }
-  const longOrdinalSuffixes = new Map([
-    ["other", "ème"],
-    ["one", "er"],
-  ])
-  const ordinalPluralRules = new Intl.PluralRules("fr-FR", { type: "ordinal" })
-
-  let selectedDixieme = "1"
-
-  // Note: A reform decomposition is always more complete than a decomposition before reform.
-  // And the children of a reform decomposition always contain the children of the decomposition
-  // before reform.
-  // → Non reform decomposition is not needed.
-  $: latestDecompositionCoreByName =
-    decompositionCoreByNameByReformName[$billName] ?? decompositionCoreByName
-  $: latestDecompositionCore = latestDecompositionCoreByName[variableName]
-  $: decomposition =
-    latestDecompositionCore === undefined
-      ? undefined
-      : {
-          ...latestDecompositionCore,
-          variableName,
-        }
-
-  // Note: A reform variable is always more complete than a variable before reform.
-  // But it may contain different formulas, with different parameters & variables.
-  $: latestVariableSummaryByName =
-    variableSummaryByNameByReformName[$billName] ?? variableSummaryByName
-  $: variable = latestVariableSummaryByName[variableName]
-
-  $: if (decomposition === undefined && variable === undefined) {
-    console.error(`Variable "${variableName}" not found`)
-  }
-
-  $: shortLabel =
-    decomposition?.short_label ??
-    variable?.short_label ??
-    decomposition?.name ??
-    variable?.name
-
-  $: testCasesByDixieme = testCases.reduce(
-    (result: { [dixieme: string]: [Situation, number][] }, testCase, index) => {
-      if (testCase.dixieme !== undefined) {
-        const dixieme = `${testCase.dixieme}`
-        if (!Object.hasOwn(result, dixieme)) {
-          result[dixieme] = []
-        }
-        result[dixieme].push([testCase, index])
-      }
-      return result
-    },
-    {},
-  )
-
-  // Note: A reform parameters tree is always more complete than a parameters tree before reform.
-  // And the children of a reform node parameter always contain the children of the node parameter
-  // before reform (albeit with some different value parameters).
-  $: billRootParameter = rootParameterByReformName[$billName] ?? rootParameter
-
-  $: decilesNiveauDeVieParameter = asScaleParameter(
-    getParameter(billRootParameter, "deciles_niveau_de_vie"),
-  )
-
-  $: decilesNiveauDeVieScaleByInstant = scaleByInstantFromBrackets(
-    decilesNiveauDeVieParameter.brackets,
-  )
-
-  $: decilesNiveauDeVieInstantScaleCouplesArray = Object.entries(
-    decilesNiveauDeVieScaleByInstant,
-  ).sort(([instant1], [instant2]) => instant2.localeCompare(instant1))
-
-  $: decilesNiveauDeVieLatestInstantScaleCouple =
-    decilesNiveauDeVieInstantScaleCouplesArray[0]
-
-  $: decilesNiveauDeVieScaleAtInstant =
-    decilesNiveauDeVieLatestInstantScaleCouple[1]
-
-  $: console.log(decilesNiveauDeVieScaleAtInstant)
-</script>
-
-<span class="inline-block font-bold text-lg"
-  >Cas types distribués par niveau de vie :</span
->
-
-<div class="mt-2 hidden md:flex justify-between gap-1 px-2 overflow-x-scroll">
-  {#each Object.keys(testCasesByDixieme) as dixieme}
-    <button
-      class="flex flex-col justify-between items-center px-2 py-1 text-sm bg-neutral-100 border-y-4 border-transparent border-opacity-80 shadow"
-      class:shrink-0={dixieme === "1" || dixieme === "10"}
-      class:z-20={selectedDixieme === dixieme}
-      class:bg-white={selectedDixieme === dixieme}
-      class:border-t-neutral-500={selectedDixieme === dixieme}
-      class:hover:bg-neutral-50={selectedDixieme !== dixieme}
-      class:hover:border-t-neutral-300={selectedDixieme !== dixieme}
-      class:shadow={selectedDixieme !== dixieme}
-      on:click={() => (selectedDixieme = dixieme)}
-    >
-      <span class="font-semibold">
-        {#if dixieme !== "1"}
-          à partir de
-        {/if}
-        {formatCurrency(
-          decilesNiveauDeVieScaleAtInstant[Number(dixieme) - 2]?.threshold
-            ?.value ?? 0,
-        )}
-        {#if dixieme === "1"}
-          - {formatCurrency(
-            decilesNiveauDeVieScaleAtInstant[Number(dixieme) - 1]?.threshold
-              ?.value ?? ".",
-          )}
-        {/if}
-      </span>
-      <br />
-      <span>{@html formatLongOrdinalSup(Number(dixieme))} décile</span>
-    </button>
-  {/each}
-</div>
-<div
-  class="md:hidden w-full bg-neutral-100 active:bg-neutral-200 border-y-4 border-t-neutral-500 border-b-neutral-100 active:border-b-neutral-200 overflow-hidden shadow-md transition"
->
-  <select
-    bind:value={selectedDixieme}
-    class="w-full bg-transparent font-bold tracking-wide border-[12px] border-transparent outline-0"
-  >
-    {#each Object.keys(testCasesByDixieme) as dixieme}
-      <option value={dixieme}>
-        {@html formatLongOrdinalSup(Number(dixieme))} décile
-      </option>
-    {/each}
-  </select>
-</div>
-<div
-  class="relative z-10 grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-2 sm:gap-5 p-3 bg-white shadow-[0_-4px_6px_-1px_rgb(0,0,0,0.1),0_-2px_4px_-2px_rgb(0,0,0,0.1)]"
->
-  {#each testCasesByDixieme[selectedDixieme] as [situation, situationIndex]}
-    <div class="flex flex-col items-start">
-      <button
-        class="group flex-1 flex flex-col p-2 lx-card-bg-gray-underline-le-vert"
-        class:gap-2={variableName !== undefined}
-        on:click={() => dispatch("select", situationIndex)}
-      >
-        <div class="flex-1 flex items-center gap-3">
-          <div class="shrink-0 grid grid-cols-6">
-            <TestCasePictos
-              classes="[&>svg]:w-7 [&>svg]:h-7 col-span-3 last:odd:col-start-3 justify-center"
-              {situation}
-              {year}
-            />
-          </div>
-          <span class="flex-1 text-start text-sm">
-            {situation.title}
-          </span>
-        </div>
-        <div class="self-stretch flex justify-between">
-          <span class="text-sm text-gray-500">
-            {#if variableName !== undefined}
-              {shortLabel}&nbsp;:
-              <VariableValueChange
-                bold={true}
-                evaluationByName={$evaluationByNameArray[situationIndex]}
-                inline
-                name={variableName}
-              />
-            {/if}
-          </span>
-          <iconify-icon
-            class="text-le-vert-400 text-xl self-end group-hover:text-le-jaune-very-dark"
-            icon="ri-arrow-right-line"
-          />
-        </div>
-      </button>
-      <button
-        class="lx-link-text mt-1 text-sm text-gray-500"
-        on:click={() => (descriptionsOpen = !descriptionsOpen)}
-      >
-        <iconify-icon
-          class="text-xl align-[-0.25rem] transition-transform duration-300"
-          class:rotate-90={descriptionsOpen}
-          icon="ri-arrow-right-s-line"
-        />
-        Représentativité du cas type
-      </button>
-      {#if descriptionsOpen}
-        <span class="mt-1 pl-5 pr-1 text-sm">
-          {situation.description}
-        </span>
-      {/if}
-    </div>
-  {/each}
-</div>
-
-<div class="flex flex-col items-end mb-4">
-  <Tooltip arrowClass="bg-gray-100" widthClass="w-80" initialPlacement="bottom">
-    <span class="underline decoration-dotted hover:text-black"
-      >Qu'est-ce qu’un décile ?</span
-    >
-    <div
-      slot="tooltip"
-      class="overflow-hidden bg-white text-sm font-light rounded-lg border border-gray-200 shadow-md"
-    >
-      <div class="py-2 px-3 bg-gray-100 border-b border-gray-200">
-        <h3 class="font-semibold text-gray-900">
-          Qu'est-ce qu'un décile de niveau de vie ?
-        </h3>
-      </div>
-      <div class="py-2 px-3 font-normal text-black">
-        <p>
-          Chaque décile de niveau de vie représente 10% de la population
-          française agrégée par ménages classés par ordre croissant de niveau de
-          vie. Le 1er décile concerne donc les ménages les plus pauvres ; le
-          10ème décile, les ménages les plus aisés.
-        </p>
-        <p class="mt-2">
-          Le niveau de vie d'un ménage correspond à son revenu disponible après
-          tous les prélèvements et compléments de ressources, le tout divisé par
-          son nombre d'unité de consommation (peu ou prou le nombre de personnes
-          composant le foyer).
-        </p>
-      </div>
-    </div>
-  </Tooltip>
-
-  <Tooltip arrowClass="bg-gray-100" widthClass="w-80" initialPlacement="bottom">
-    <span class="underline decoration-dotted hover:text-black"
-      >Comment sont conçus ces cas types ?</span
-    >
-    <div
-      slot="tooltip"
-      class="overflow-hidden bg-white text-sm font-light rounded-lg border border-gray-200 shadow-md"
-    >
-      <div class="py-2 px-3 bg-gray-100 border-b border-gray-200">
-        <h3 class="font-semibold text-gray-900">
-          Comment sont conçus ces cas types ?
-        </h3>
-      </div>
-      <div class="py-2 px-3 font-normal text-black">
-        <p>
-          LexImpact s'est appuyé sur la base POTE 2021 des déclarations d'impôt
-          sur le revenu des foyers fiscaux distribuée par la DGFIP. À partir de
-          cette base représentative de la population française, LexImpact a
-          étudié chacun des déciles de niveau de vie pour en extraire les
-          caractéristiques les plus fréquentes :
-        </p>
-        <ul class="list-inside list-disc">
-          <li>composition familiale,</li>
-          <li>activité et revenus</li>
-          <li>lieu de vie et statut locataire ou propriétaire</li>
-        </ul>
-        <p class="mt-2">
-          La méthodologie appliquée est décrite pour chaque cas type en cliquant
-          sur le bouton "Représentativité du cas type".
-        </p>
-      </div>
-    </div>
-  </Tooltip>
-</div>
diff --git a/src/lib/components/test_cases/TestCaseFilters.svelte b/src/lib/components/test_cases/TestCaseFilters.svelte
index f888b421e7f7de993116bbc2dc060054624d3d88..29a9c7fbcd80753e55696b1a9e5580de555b4d50 100644
--- a/src/lib/components/test_cases/TestCaseFilters.svelte
+++ b/src/lib/components/test_cases/TestCaseFilters.svelte
@@ -4,8 +4,9 @@
   import type { Writable } from "svelte/store"
 
   import { page } from "$app/stores"
-  import { clickOutside } from "$lib/click_outside"
+  import SelectChip from "$lib/components/SelectChip.svelte"
   import TestCaseSummary from "$lib/components/test_cases/TestCaseSummary.svelte"
+  import Tooltip from "$lib/components/Tooltip.svelte"
   import VariableValueChange from "$lib/components/variables/VariableValueChange.svelte"
   import {
     decompositionCoreByName,
@@ -30,6 +31,7 @@
   } from "$lib/variables"
 
   export let displayMode: DisplayMode
+  export let showOnlyDeciles: boolean = false
   export let testCases: Situation[]
   export let variableName: string | undefined = undefined
   export let year: number
@@ -185,18 +187,12 @@
     },
   ]
 
+  let filterNiveauDeVieValue: string | undefined = undefined
+
   $: filterValueByName = Object.fromEntries(
     filters.map((filter) => [filter.name, filter.value]),
   )
 
-  const filterNiveauDeVie: {
-    open: boolean
-    value?: string
-    label?: string
-  } = {
-    open: false,
-  }
-
   $: selectDecilesNiveauDeVie = [
     {
       label: "Tous",
@@ -215,13 +211,18 @@
     })),
   ] as { label: string; shortLabel: string; value: string }[]
 
-  $: filteredTestCases = filterTestCases(filterValueByName, filterNiveauDeVie)
+  $: filteredTestCases = filterTestCases(
+    filterValueByName,
+    showOnlyDeciles,
+    filterNiveauDeVieValue,
+  )
 
   function filterTestCases(
     filterValueByName: {
       [filter: string]: boolean | string
     },
-    filterNiveauDeVie: { value?: string; label?: string },
+    showOnlyDeciles: boolean,
+    filterNiveauDeVie: string | undefined,
   ): [Situation, number][] {
     const filtered: [Situation, number][] = []
     for (const [index, situation] of testCases.entries()) {
@@ -341,12 +342,14 @@
           continue
         }
       }
-      if (filterNiveauDeVie.value !== undefined) {
-        if (filterNiveauDeVie.value === "tous") {
+      if (!showOnlyDeciles) {
+        filterNiveauDeVieValue = undefined
+      } else if (filterNiveauDeVie !== undefined) {
+        if (filterNiveauDeVie === "tous") {
           if (situation.dixieme === undefined) {
             continue
           }
-        } else if (`${situation.dixieme}` !== filterNiveauDeVie.value) {
+        } else if (`${situation.dixieme}` !== filterNiveauDeVie) {
           continue
         }
       }
@@ -381,74 +384,99 @@
 </div>
 
 <label class="mt-6 inline-flex items-center cursor-pointer">
-  <input
-    type="checkbox"
-    class="sr-only peer"
-    on:input={({ target }) => {
-      filterNiveauDeVie.value = target.checked
-        ? selectDecilesNiveauDeVie[0].value
-        : undefined
-      filterNiveauDeVie.label = target.checked
-        ? selectDecilesNiveauDeVie[0].shortLabel
-        : undefined
-    }}
-  />
+  <input bind:checked={showOnlyDeciles} class="sr-only peer" type="checkbox" />
   <div
     class="relative w-11 h-6 bg-gray-400 peer-focus:outline-none peer-focus:ring-4 rounded-full peer peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-400 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-le-bleu"
   />
   <span
     class="inline-flex items-center gap-1.5 ms-3 text-sm font-medium text-gray-900"
     >Afficher uniquement les cas types dont la représentativité a été définie
-    <!--    <div class="bg-le-bleu w-2 h-2" /><iconify-icon-->
-    <!--      class="text-[#b6b8ff] text-xl -ml-5"-->
-    <!--      icon="material-symbols:award-star-rounded"-->
-    <!--    />-->
   </span>
 </label>
 
-{#if filterNiveauDeVie.value}
+{#if showOnlyDeciles}
   <div class="mt-2 flex flex-wrap gap-x-2 gap-y-1">
-    <div
-      class="z-20 relative"
-      use:clickOutside={{
-        callback: () => (filterNiveauDeVie.open = false),
-      }}
+    <SelectChip
+      bind:value={filterNiveauDeVieValue}
+      class="z-20"
+      label="Niveau de vie"
+      options={selectDecilesNiveauDeVie}
+      showCheckIcon={true}
+    />
+  </div>
+
+  <div class="flex flex-col items-end">
+    <Tooltip
+      arrowClass="bg-gray-100"
+      widthClass="w-80"
+      initialPlacement="bottom"
     >
-      <button
-        class="relative flex items-center gap-1 px-3 py-1 bg-le-bleu-light rounded-full overflow-hidden transition after:absolute after:inset-0 after:rounded-full after:transition hover:after:bg-black/5 active:after:bg-black/10"
-        class:after:bg-black={filterNiveauDeVie.open}
-        class:after:bg-opacity-5={filterNiveauDeVie.open}
-        on:click={() => (filterNiveauDeVie.open = !filterNiveauDeVie.open)}
+      <span class="underline decoration-dotted hover:text-black"
+        >Qu'est-ce qu’un décile ?</span
       >
-        <iconify-icon class="text-lg" icon="ri-check-line" noobserver />
-        Niveau de vie : {@html filterNiveauDeVie.label}
-        <iconify-icon class="text-lg" icon="ri-arrow-down-s-line" noobserver />
-      </button>
-      {#if filterNiveauDeVie.open}
-        <ul
-          class="absolute -bottom-1 translate-y-full left-0 py-1.5 bg-white border shadow-md rounded-lg"
-        >
-          {#each selectDecilesNiveauDeVie as option}
-            {@const selected = option.value === filterNiveauDeVie.value}
-            <li>
-              <button
-                class="w-full text-nowrap text-start px-3 py-1.5"
-                class:hover:bg-gray-100={!selected}
-                class:active:bg-gray-200={!selected}
-                class:bg-le-bleu-light={selected}
-                on:click={() => {
-                  filterNiveauDeVie.value = option.value
-                  filterNiveauDeVie.label = option.shortLabel
-                  filterNiveauDeVie.open = false
-                }}
-              >
-                {@html option.label}
-              </button>
-            </li>
-          {/each}
-        </ul>
-      {/if}
-    </div>
+      <div
+        slot="tooltip"
+        class="overflow-hidden bg-white text-sm font-light rounded-lg border border-gray-200 shadow-md"
+      >
+        <div class="py-2 px-3 bg-gray-100 border-b border-gray-200">
+          <h3 class="font-semibold text-gray-900">
+            Qu'est-ce qu'un décile de niveau de vie ?
+          </h3>
+        </div>
+        <div class="py-2 px-3 font-normal text-black">
+          <p>
+            Chaque décile de niveau de vie représente 10% de la population
+            française agrégée par ménages classés par ordre croissant de niveau
+            de vie. Le 1er décile concerne donc les ménages les plus pauvres ;
+            le 10ème décile, les ménages les plus aisés.
+          </p>
+          <p class="mt-2">
+            Le niveau de vie d'un ménage correspond à son revenu disponible
+            après tous les prélèvements et compléments de ressources, le tout
+            divisé par son nombre d'unité de consommation (peu ou prou le nombre
+            de personnes composant le foyer).
+          </p>
+        </div>
+      </div>
+    </Tooltip>
+
+    <Tooltip
+      arrowClass="bg-gray-100"
+      widthClass="w-80"
+      initialPlacement="bottom"
+    >
+      <span class="underline decoration-dotted hover:text-black"
+        >Comment sont conçus ces cas types ?</span
+      >
+      <div
+        slot="tooltip"
+        class="overflow-hidden bg-white text-sm font-light rounded-lg border border-gray-200 shadow-md"
+      >
+        <div class="py-2 px-3 bg-gray-100 border-b border-gray-200">
+          <h3 class="font-semibold text-gray-900">
+            Comment sont conçus ces cas types ?
+          </h3>
+        </div>
+        <div class="py-2 px-3 font-normal text-black">
+          <p>
+            LexImpact s'est appuyé sur la base POTE 2021 des déclarations
+            d'impôt sur le revenu des foyers fiscaux distribuée par la DGFIP. À
+            partir de cette base représentative de la population française,
+            LexImpact a étudié chacun des déciles de niveau de vie pour en
+            extraire les caractéristiques les plus fréquentes :
+          </p>
+          <ul class="list-inside list-disc">
+            <li>composition familiale,</li>
+            <li>activité et revenus</li>
+            <li>lieu de vie et statut locataire ou propriétaire</li>
+          </ul>
+          <p class="mt-2">
+            La méthodologie appliquée est décrite pour chaque cas type en
+            cliquant sur le bouton "Représentativité du cas type".
+          </p>
+        </div>
+      </div>
+    </Tooltip>
   </div>
 {/if}
 
@@ -462,61 +490,73 @@
   >
     {#each filteredTestCases as [testCase, index]}
       <div>
-        <div class="relative lx-card">
+        <div class="relative lx-card-underline-le-vert">
           <button
-            class="group text-sm rounded-md overflow-hidden"
+            class="group w-full flex flex-col items-stretch text-sm rounded-md overflow-hidden"
             on:click={() => dispatch("select", index)}
             type="button"
           >
-            <div>
-              <div
-                class="bg-gray-100 p-4 pb-2 text-left"
-                id="situation_{index}_case_summary"
-              >
-                <TestCaseSummary
-                  {displayMode}
-                  mode="select"
-                  situation={testCase}
-                  situationIndex={index}
-                  valuesByCalculationNameByVariableName={$valuesByCalculationNameByVariableNameArray[
-                    index
-                  ]}
-                  {year}
-                />
-              </div>
+            <div
+              class="bg-gray-100 p-4 pb-2 text-left"
+              id="situation_{index}_case_summary"
+            >
+              <TestCaseSummary
+                {displayMode}
+                mode="select"
+                situation={testCase}
+                situationIndex={index}
+                valuesByCalculationNameByVariableName={$valuesByCalculationNameByVariableNameArray[
+                  index
+                ]}
+                {year}
+              />
+            </div>
+            <div
+              class="flex flex-col p-2"
+              class:bg-gray-100={variableName === undefined}
+              class:border-t={variableName !== undefined}
+            >
               {#if variableName !== undefined}
-                <div class="flex flex-col gap-2 bg-white p-3">
-                  <span class="text-start">{shortLabel}&nbsp;:</span>
-                  <div class="flex gap-5 text-3xl font-semibold">
-                    <VariableValueChange
-                      evaluationByName={$evaluationByNameArray[index]}
-                      legend
-                      name={variableName}
-                    />
-                  </div>
-                </div>
+                <p class="block px-1 text-start text-sm text-gray-500">
+                  {shortLabel}&nbsp;:
+                  <VariableValueChange
+                    bold={true}
+                    evaluationByName={$evaluationByNameArray[index]}
+                    inline
+                    name={variableName}
+                  />
+                </p>
               {/if}
+              <iconify-icon
+                class="block text-le-vert-400 text-xl self-end group-hover:text-le-jaune-very-dark"
+                icon="ri-arrow-right-line"
+              />
             </div>
-            <span class="block px-2 py-1 text-start border-t">
-              {testCase.title}
-            </span>
           </button>
           {#if testCase.dixieme !== undefined}
             <div
-              class="absolute -right-3 top-0 -translate-y-1/2 flex items-center"
+              class="absolute -right-7 top-0 -translate-y-1/2 flex items-center"
             >
               <div
-                class="flex items-center text-sm bg-le-bleu-light pl-2 -mr-5 rounded-full"
+                class="flex items-center text-sm bg-le-bleu-light pl-2 pr-4 rounded-l-full"
               >
                 {@html formatLongOrdinalSup(testCase.dixieme)} décile
-                <div class="ml-3 w-3 h-3 bg-le-bleu" />
               </div>
-              <iconify-icon
-                class=" text-[#b6b8ff]"
-                icon="material-symbols:award-star-rounded"
-                width="28"
-                height="28"
-              />
+              <svg
+                class="w-7 h-7 -translate-x-1/2"
+                xmlns="http://www.w3.org/2000/svg"
+                viewBox="0 0 24 24"
+                ><path
+                  class="text-[#b6b8ff]"
+                  fill="currentColor"
+                  d="M8.65 20H6q-.825 0-1.412-.587T4 18v-2.65L2.075 13.4q-.275-.3-.425-.662T1.5 12t.15-.737t.425-.663L4 8.65V6q0-.825.588-1.412T6 4h2.65l1.95-1.925q.3-.275.663-.425T12 1.5t.738.15t.662.425L15.35 4H18q.825 0 1.413.588T20 6v2.65l1.925 1.95q.275.3.425.663t.15.737t-.15.738t-.425.662L20 15.35V18q0 .825-.587 1.413T18 20h-2.65l-1.95 1.925q-.3.275-.662.425T12 22.5t-.737-.15t-.663-.425z"
+                />
+                <path
+                  class="text-le-bleu"
+                  fill="currentColor"
+                  d="m12 14.475l1.925 1.15q.275.175.538-.012t.187-.513l-.5-2.175l1.7-1.475q.25-.225.15-.537t-.45-.338l-2.225-.175l-.875-2.075q-.125-.3-.45-.3t-.45.3l-.875 2.075l-2.225.175q-.35.025-.45.338t.15.537l1.7 1.475l-.5 2.175q-.075.325.188.513t.537.012z"
+                />
+              </svg>
             </div>
           {/if}
         </div>
@@ -545,7 +585,7 @@
   <div
     class="mt-6 flex flex-col items-center gap-4 py-36 bg-gray-100 rounded-lg"
   >
-    Aucun cas type ne correspond à vos critères de filtre.
+    Aucun cas type ne correspond aux filtres sélectionnés.
     <button
       class="mb-8 flex items-center gap-1.5 py-1.5 px-3 bg-white hover:bg-neutral-200 active:bg-neutral-300 rounded-lg font-semibold text-le-gris-dispositif-dark hover:text-black text-sm tracking-wider uppercase transition-all duration-200 ease-out-back s-y_bCXRrkrYfP"
       on:click={() => {
diff --git a/src/lib/components/test_cases/TestCaseGraph.svelte b/src/lib/components/test_cases/TestCaseGraph.svelte
index 794d4dc197d52020ae921a4e159c58b8472433ed..72b573a829569b3ac4c0a0712ff68801e1cbf654 100644
--- a/src/lib/components/test_cases/TestCaseGraph.svelte
+++ b/src/lib/components/test_cases/TestCaseGraph.svelte
@@ -168,8 +168,6 @@
       niveauDeVieByCalculationName["revaluation"],
   )
 
-  $: console.log("deciles", deciles)
-
   $: childrenId = Object.values(familySituation).reduce(
     (children: string[], family) => [
       ...children,
diff --git a/src/lib/components/variables/VariableDetail.svelte b/src/lib/components/variables/VariableDetail.svelte
index d5449fe563b8b3dd67cad21f2ae0336b6b2420dc..e60445fec88574b39d98cbeefeb75422f5c3d0cf 100644
--- a/src/lib/components/variables/VariableDetail.svelte
+++ b/src/lib/components/variables/VariableDetail.svelte
@@ -14,7 +14,7 @@
   import Accordion from "$lib/components/accordion/Accordion.svelte"
   import AccordionItem from "$lib/components/accordion/AccordionItem.svelte"
   import PictoBudgetEtat from "$lib/components/pictos/PictoBudgetEtat.svelte"
-  import TestCaseDixiemes from "$lib/components/test_cases/TestCaseDixiemes.svelte"
+  import TestCaseFilters from "$lib/components/test_cases/TestCaseFilters.svelte"
   import TestCasePictos from "$lib/components/test_cases/TestCasePictos.svelte"
   import VariableDetailBudget from "$lib/components/variables/VariableDetailBudget.svelte"
   import VariableValueChange from "$lib/components/variables/VariableValueChange.svelte"
@@ -23,6 +23,7 @@
     decompositionCoreByNameByReformName,
     type EvaluationByName,
   } from "$lib/decompositions"
+  import type { DisplayMode } from "$lib/displays"
   import { memoUrlByName } from "$lib/memos"
   import type { Situation } from "$lib/situations"
   import { newSimulationUrl } from "$lib/urls"
@@ -32,12 +33,14 @@
     variableSummaryByNameByReformName,
   } from "$lib/variables"
 
+  export let displayMode: DisplayMode
   export let name: string
 
   const billName = getContext("billName") as Writable<string | undefined>
   const budgetSimulation = getContext("budgetSimulation") as Writable<
     BudgetSimulation | undefined
   >
+  let budgetSimulationOutdated = false
   const dateFormatter = new Intl.DateTimeFormat("fr-FR", {
     dateStyle: "medium",
   }).format
@@ -118,8 +121,12 @@
   )
 
   $: if (name) {
-    // Only called when the variable name changes
-    requestBudgetCalculations()
+    budgetSimulationOutdated = true
+    setTimeout(() => {
+      // Only called when the variable name changes
+      requestBudgetCalculations()
+      budgetSimulationOutdated = false
+    }, 500)
   }
 
   function requestBudgetCalculations() {
@@ -264,8 +271,11 @@
         title="Impacts budgétaires"
       >
         {#if budgetVariablesName.has(name)}
-          {#if $budgetSimulation === undefined}
-            Chargement des données budgétaires...
+          {#if budgetSimulationOutdated || $budgetSimulation === undefined}
+            <div class="flex flex-col gap-2 animate-pulse-2">
+              <div class="self-stretch h-6 mr-64 bg-neutral-300" />
+              <div class="self-stretch h-6 mr-48 bg-neutral-300" />
+            </div>
           {:else if $budgetSimulation.errors != null && $budgetSimulation.errors.length > 0}
             {#each $budgetSimulation.errors as error}
               <span>{error}</span>
@@ -351,31 +361,35 @@
                     </div>
                   {/if}
                   <span class="flex-1 text-start text-sm">
-                    {title}
+                    <span class="font-bold">{title.split("|")[0]}</span>
+                    {#if title.split("|")[1] !== undefined}
+                      {#if title.split("|")[0].length > 0}
+                        |
+                      {/if}
+                      {title.split("|")[1]}
+                    {/if}
                   </span>
                 </div>
-                <div class="flex justify-between">
-                  <span class="text-sm text-gray-500">
-                    {shortLabel}&nbsp;:
-                    <span class="inline-block">
-                      {#each indices as index, i}
-                        {#if i > 0}
-                          vs
-                        {/if}
-                        <VariableValueChange
-                          bold={true}
-                          evaluationByName={$evaluationByNameArray[index]}
-                          inline
-                          {name}
-                        />
-                      {/each}
-                    </span>
+                <span class="text-sm text-gray-500">
+                  {shortLabel}&nbsp;:
+                  <span class="inline-block">
+                    {#each indices as index, i}
+                      {#if i > 0}
+                        vs
+                      {/if}
+                      <VariableValueChange
+                        bold={true}
+                        evaluationByName={$evaluationByNameArray[index]}
+                        inline
+                        {name}
+                      />
+                    {/each}
                   </span>
-                  <iconify-icon
-                    class="text-le-vert-400 text-xl self-end group-hover:text-le-jaune-very-dark"
-                    icon="ri-arrow-right-line"
-                  />
-                </div>
+                </span>
+                <iconify-icon
+                  class="text-le-vert-400 text-xl self-end group-hover:text-le-jaune-very-dark"
+                  icon="ri-arrow-right-line"
+                />
               </a>
             {/each}
           </div>
@@ -385,15 +399,18 @@
             >&nbsp;{shortLabel}&nbsp;</span
           >» avec des cas types représentatifs :
         </span>
-        <TestCaseDixiemes
+        <TestCaseFilters
+          {displayMode}
           on:select={({ detail }) =>
             goto(
               newSimulationUrl({
+                ...displayMode,
                 parametersVariableName: name,
                 testCasesIndex: [detail],
                 tab: "dispositif",
               }),
             )}
+          showOnlyDeciles={true}
           testCases={$testCases}
           variableName={name}
           year={$year}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 532af997010d45d8d0a1f7077c161d9108641b5b..98b09e82f57ffcf5f19716b701c26ce085baf3c8 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1865,34 +1865,35 @@
                                     >{title.split("|")[0]}</span
                                   >
                                   {#if title.split("|")[1] !== undefined}
-                                    | {title.split("|")[1]}
+                                    {#if title.split("|")[0].length > 0}
+                                      |
+                                    {/if}
+                                    {title.split("|")[1]}
                                   {/if}
                                 </span>
                               </div>
-                              <div class="flex justify-between">
-                                <span class="text-sm text-gray-500">
-                                  {shortLabel}&nbsp;:
-                                  <span class="inline-block">
-                                    {#each indices as index, i}
-                                      {#if i > 0}
-                                        vs
-                                      {/if}
-                                      <VariableValueChange
-                                        bold={true}
-                                        evaluationByName={$evaluationByNameArray[
-                                          index
-                                        ]}
-                                        inline
-                                        name={displayMode.parametersVariableName}
-                                      />
-                                    {/each}
-                                  </span>
+                              <span class="text-sm text-gray-500">
+                                {shortLabel}&nbsp;:
+                                <span class="inline-block">
+                                  {#each indices as index, i}
+                                    {#if i > 0}
+                                      vs
+                                    {/if}
+                                    <VariableValueChange
+                                      bold={true}
+                                      evaluationByName={$evaluationByNameArray[
+                                        index
+                                      ]}
+                                      inline
+                                      name={displayMode.parametersVariableName}
+                                    />
+                                  {/each}
                                 </span>
-                                <iconify-icon
-                                  class="text-le-vert-400 text-xl self-end group-hover:text-le-jaune-very-dark"
-                                  icon="ri-arrow-right-line"
-                                />
-                              </div>
+                              </span>
+                              <iconify-icon
+                                class="text-le-vert-400 text-xl self-end group-hover:text-le-jaune-very-dark"
+                                icon="ri-arrow-right-line"
+                              />
                             </a>
                           {/each}
                         </div>
@@ -2127,6 +2128,7 @@
 
   {#if $variableModalOpen && displayMode.parametersVariableName !== undefined}
     <VariableDetail
+      {displayMode}
       name={displayMode.parametersVariableName}
       on:close={() => ($variableModalOpen = false)}
     />
diff --git a/src/routes/accueil/+page.svelte b/src/routes/accueil/+page.svelte
index bb2a8cbf16dc8dc2c98ac69d2889730805253c6a..ad2a04dc6141645e12069a1b460a51a1b5d02054 100644
--- a/src/routes/accueil/+page.svelte
+++ b/src/routes/accueil/+page.svelte
@@ -1108,6 +1108,7 @@
 
 {#if displayMode.parametersVariableName !== undefined}
   <VariableDetail
+    {displayMode}
     name={displayMode.parametersVariableName}
     on:close={() =>
       goto(