diff --git a/package-lock.json b/package-lock.json
index 7c0141ed6c652fcad328eac314329cb11f39802b..0f63b3ba500a2e8e536d5cbfb02d15548e4833d9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -40,8 +40,6 @@
         "eslint": "^8.0.0",
         "eslint-config-prettier": "^8.1.0",
         "eslint-plugin-svelte3": "^4.0.0",
-        "flowbite": "^1.5.5",
-        "flowbite-svelte": "^0.40.1",
         "fs-extra": "^11.1.0",
         "iconify-icon": "^1.0.2",
         "intro.js": "^7.0.1",
@@ -2674,34 +2672,6 @@
       "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
       "dev": true
     },
-    "node_modules/flowbite": {
-      "version": "1.7.0",
-      "resolved": "https://registry.npmjs.org/flowbite/-/flowbite-1.7.0.tgz",
-      "integrity": "sha512-OTTmnhRgv85Rs+mcMaVU7zB6EvRQs7BaQziyMUsZLRjW9aUpeQyqKjLmxsVMMCdr8isYPCLd6UL7X1IaSVI0WQ==",
-      "dev": true,
-      "dependencies": {
-        "@popperjs/core": "^2.9.3",
-        "mini-svg-data-uri": "^1.4.3"
-      }
-    },
-    "node_modules/flowbite-svelte": {
-      "version": "0.40.1",
-      "resolved": "https://registry.npmjs.org/flowbite-svelte/-/flowbite-svelte-0.40.1.tgz",
-      "integrity": "sha512-NtAfgMKfh/UyrE7hM4uVqai4xAn8gjmLvK5ekv4GHHhgOgypsLlYiPmqz+zLHRIwNbBw9SJwzK6BclCie1Apfw==",
-      "dev": true,
-      "dependencies": {
-        "@floating-ui/dom": "^1.4.5",
-        "flowbite": "^1.7.0",
-        "tailwind-merge": "^1.13.2"
-      },
-      "engines": {
-        "node": ">=16.0.0",
-        "npm": ">=7.0.0"
-      },
-      "peerDependencies": {
-        "svelte": "^3.55.1 || ^4.0.0"
-      }
-    },
     "node_modules/for-each": {
       "version": "0.3.3",
       "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -3710,15 +3680,6 @@
         "node": ">=4"
       }
     },
-    "node_modules/mini-svg-data-uri": {
-      "version": "1.4.4",
-      "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz",
-      "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
-      "dev": true,
-      "bin": {
-        "mini-svg-data-uri": "cli.js"
-      }
-    },
     "node_modules/minimatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -5120,16 +5081,6 @@
         }
       }
     },
-    "node_modules/tailwind-merge": {
-      "version": "1.14.0",
-      "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-1.14.0.tgz",
-      "integrity": "sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==",
-      "dev": true,
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/dcastil"
-      }
-    },
     "node_modules/tailwindcss": {
       "version": "3.3.3",
       "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz",
diff --git a/package.json b/package.json
index d286a4e54e7555fd1b24c458773f6790567327be..834cb144c0031b87deb240e8b086f36dba64c1b1 100644
--- a/package.json
+++ b/package.json
@@ -44,8 +44,6 @@
     "eslint": "^8.0.0",
     "eslint-config-prettier": "^8.1.0",
     "eslint-plugin-svelte3": "^4.0.0",
-    "flowbite": "^1.5.5",
-    "flowbite-svelte": "^0.40.1",
     "fs-extra": "^11.1.0",
     "iconify-icon": "^1.0.2",
     "intro.js": "^7.0.1",
diff --git a/src/lib/components/ReplaceTestCaseModal.svelte b/src/lib/components/ReplaceTestCaseModal.svelte
new file mode 100644
index 0000000000000000000000000000000000000000..52107d997d80326d6230e55c92126d46de7e3c18
--- /dev/null
+++ b/src/lib/components/ReplaceTestCaseModal.svelte
@@ -0,0 +1,105 @@
+<script lang="ts">
+  import {
+    Dialog,
+    DialogDescription,
+    DialogOverlay,
+    DialogTitle,
+    Transition,
+    TransitionChild,
+  } from "@rgossiaux/svelte-headlessui"
+  import { createEventDispatcher } from "svelte"
+
+  export let isOpen = false
+
+  const dispatch = createEventDispatcher()
+
+  function onChange() {
+    isOpen = false
+    dispatch("positive")
+  }
+
+  function onClose() {
+    isOpen = false
+    dispatch("close")
+  }
+</script>
+
+<Transition appear show={isOpen}>
+  <Dialog
+    as="div"
+    class="fixed inset-0 z-40 overflow-y-auto"
+    on:close={onClose}
+  >
+    <div class="min-h-screen px-4 text-center">
+      <TransitionChild
+        enter="ease-out duration-300"
+        enterFrom="opacity-0"
+        enterTo="opacity-100"
+        leave="ease-in duration-200"
+        leaveFrom="opacity-100"
+        leaveTo="opacity-0"
+      >
+        <DialogOverlay
+          class="fixed inset-0 bg-gray-500 opacity-50 transition-opacity"
+        />
+      </TransitionChild>
+
+      <!-- This element is to trick the browser into centering the modal contents. -->
+      <span class="inline-block h-screen align-middle" aria-hidden="true">
+        &#8203;
+      </span>
+
+      <TransitionChild
+        class="inline-block align-middle my-8"
+        enter="ease-out duration-300"
+        enterFrom="opacity-0 scale-95"
+        enterTo="opacity-100 scale-100"
+        leave="ease-in duration-200"
+        leaveFrom="opacity-100 scale-100"
+        leaveTo="opacity-0 scale-95"
+      >
+        <div
+          class="divide-y divide-gray-200 w-full max-w-2xl transform overflow-hidden rounded-md bg-white text-left shadow-xl transition-all"
+        >
+          <div class="px-6 py-4 flex items-center justify-between">
+            <DialogTitle as="h3" class="text-xl font-semibold text-gray-900">
+              Changer de cas type
+            </DialogTitle>
+
+            <button
+              type="button"
+              class="focus:outline-none whitespace-normal m-0.5 rounded-lg focus:ring-2 p-1.5 focus:ring-gray-400 hover:bg-gray-100 active:bg-gray-200 ml-auto"
+              aria-label="Close modal"
+              on:click={onClose}
+              ><span class="sr-only">Close modal</span>
+              <iconify-icon class="block text-2xl" icon="ri-close-line" />
+            </button>
+          </div>
+          <DialogDescription as="div" class="p-6 space-y-6">
+            <div class="flex flex-col gap-3">
+              <p class="text-lg font-bold text-black">
+                Êtes-vous sûr de vouloir remplacer le cas type ?
+              </p>
+              <p class="text-black">
+                En validant, vous remplacez le cas type sur lequel vous
+                travaillez. Vous pouvez toujours le retrouver en cliquant sur
+                "plus de cas types".
+              </p>
+            </div>
+
+            <div class="flex justify-between">
+              <button
+                class="rounded-md border border-le-vert-700 bg-white px-5 py-2 text-sm uppercase text-le-vert-800 hover:bg-le-vert-100 active:bg-le-vert-200 s-y_bCXRrkrYfP"
+                on:click={onClose}>Annuler</button
+              >
+              <button
+                class="rounded-md bg-le-vert-600 px-5 py-2 text-sm uppercase text-white shadow-md hover:bg-le-vert-800 active:bg-le-vert-900 s-y_bCXRrkrYfP"
+                on:click={onChange}>Remplacer</button
+              >
+            </div>
+          </DialogDescription>
+        </div>
+      </TransitionChild>
+    </div>
+  </Dialog>
+</Transition>
diff --git a/src/lib/components/test_cases/TestCaseRelatedCarousel.svelte b/src/lib/components/test_cases/TestCaseRelatedCarousel.svelte
index 27d86a078d516094ca2bdabcea5093f92c3b7ac8..0b9b3a936305d9c9ec0c439eafb53f9d8ccb699b 100644
--- a/src/lib/components/test_cases/TestCaseRelatedCarousel.svelte
+++ b/src/lib/components/test_cases/TestCaseRelatedCarousel.svelte
@@ -17,7 +17,6 @@
   export let displayMode: DisplayMode
   export let year: number
   export let variable: string
-  export let replacementValidationModalTestCaseIndex: number
 
   const billName = getContext("billName") as Writable<string | undefined>
   const testCases = getContext("testCases") as Writable<Situation[]>
@@ -106,8 +105,9 @@
         <button
           class="group w-full self-start text-start"
           on:click={() => {
-            if (!isTestCaseSelected)
-              replacementValidationModalTestCaseIndex = situationIndex
+            if (!isTestCaseSelected) {
+              dispatch("changeTestCase", situationIndex)
+            }
           }}
           type="button"
         >
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index ae28051821df46f1c51120dfc46b0a0df5561c03..4e1c31b3c237c8a31eec266eadd2143847f0a0a8 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -12,7 +12,6 @@
     auditOptions,
   } from "@auditors/core"
   import type { PopulationWithoutId, Waterfall } from "@openfisca/json-model"
-  import { Modal } from "flowbite-svelte"
   import introJs from "intro.js"
   import { getContext, setContext } from "svelte"
   import type { Writable } from "svelte/store"
@@ -28,11 +27,14 @@
     requestAllTestCasesCalculations,
     type RequestedCalculations,
   } from "$lib/calculations"
+  import CopyClipboard from "$lib/components/CopyClipboard.svelte"
   import CsgBudgetView from "$lib/components/CsgBudgetView.svelte"
+  import CsgGagnantsPerdantsView from "$lib/components/CsgGagnantsPerdantsView.svelte"
   import IrBudgetView from "$lib/components/IrBudgetView.svelte"
   import IrGagnantsPerdantsView from "$lib/components/IrGagnantsPerdantsView.svelte"
-  import CsgGagnantsPerdantsView from "$lib/components/CsgGagnantsPerdantsView.svelte"
+  import PersistentPopover from "$lib/components/PersistentPopover.svelte"
   import ReformsChanges from "$lib/components/ReformsChanges.svelte"
+  import ReplaceTestCaseModal from "$lib/components/ReplaceTestCaseModal.svelte"
   import Spinner from "$lib/components/Spinner.svelte"
   import TestCaseSelectModal from "$lib/components/test_cases/TestCaseSelectModal.svelte"
   import TestCaseExamplesSelectBar from "$lib/components/test_cases/TestCaseExamplesSelectBar.svelte"
@@ -41,6 +43,7 @@
   import TestCaseRelatedCarousel from "$lib/components/test_cases/TestCaseRelatedCarousel.svelte"
   import TestCasesStackRepresentation from "$lib/components/test_cases/TestCasesStackRepresentation.svelte"
   import TestCaseView from "$lib/components/test_cases/TestCaseView.svelte"
+  import Tooltip from "$lib/components/Tooltip.svelte"
   import NonVariableReferredParameter from "$lib/components/variables/NonVariableReferredParameter.svelte"
   import VariableReferredInputsPane from "$lib/components/variables/VariableReferredInputsPane.svelte"
   import VariableReferredParameters from "$lib/components/variables/VariableReferredParameters.svelte"
@@ -69,9 +72,6 @@
   } from "$lib/variables"
 
   import type { PageData } from "./$types"
-  import CopyClipboard from "$lib/components/CopyClipboard.svelte"
-  import PersistentPopover from "$lib/components/PersistentPopover.svelte"
-  import Tooltip from "$lib/components/Tooltip.svelte"
 
   export let data: PageData
 
@@ -756,21 +756,7 @@
 
   let testCasesBtnHeight = 0
 
-  let replacementValidationModalTestCaseIndex: number | undefined
-  let isReplacementValidationModalOpen: boolean
-  $: isReplacementValidationModalOpen =
-    replacementValidationModalTestCaseIndex !== undefined &&
-    replacementValidationModalTestCaseIndex !== false
-
-  function changeTestCaseIndex(value: number) {
-    goto(
-      newSimulationUrl({
-        ...displayMode,
-        testCasesIndex: [value],
-      }),
-      { noScroll: true },
-    )
-  }
+  let changeTestCaseIndex: number | undefined
 
   let clipboardElement: HTMLElement
   async function onCopyParameterLink(parameterName: string) {
@@ -1510,7 +1496,8 @@
                   variable={displayMode.parametersVariableName}
                   on:openTestCaseSelectModal={() =>
                     (isTestCaseSelectModalOpen = true)}
-                  bind:replacementValidationModalTestCaseIndex
+                  on:changeTestCase={({ detail }) =>
+                    (changeTestCaseIndex = detail)}
                 />
               {/if}
             {/if}
@@ -1637,35 +1624,18 @@
     </button>
   {/if}
 
-  <Modal
-    title="Changer de cas type"
-    bind:open={isReplacementValidationModalOpen}
-    autoclose
-    on:hide={() => (replacementValidationModalTestCaseIndex = undefined)}
-  >
-    <div class="flex flex-col gap-3">
-      <p class="text-lg font-bold text-black">
-        Êtes-vous sûr de vouloir remplacer le cas type ?
-      </p>
-      <p class="text-black">
-        En validant, vous remplacez le cas type sur lequel vous travaillez. Vous
-        pouvez toujours le retrouver en cliquant sur "plus de cas types".
-      </p>
-    </div>
-    <div class="flex justify-between">
-      <button
-        class="rounded-md border border-le-vert-700 bg-white px-5 py-2 text-sm uppercase text-le-vert-800 hover:bg-le-vert-100 active:bg-le-vert-200"
-        >Annuler
-      </button>
-      <button
-        class="rounded-md bg-le-vert-600 px-5 py-2 text-sm uppercase text-white shadow-md hover:bg-le-vert-800 active:bg-le-vert-900"
-        on:click={() =>
-          changeTestCaseIndex(replacementValidationModalTestCaseIndex)}
-      >
-        Remplacer
-      </button>
-    </div>
-  </Modal>
+  <ReplaceTestCaseModal
+    isOpen={changeTestCaseIndex !== undefined}
+    on:close={() => (changeTestCaseIndex = undefined)}
+    on:positive={() =>
+      goto(
+        newSimulationUrl({
+          ...displayMode,
+          testCasesIndex: [changeTestCaseIndex],
+        }),
+        { noScroll: true },
+      )}
+  />
 </main>
 
 <style>
diff --git a/tailwind.config.cjs b/tailwind.config.cjs
index 39af68818f18e5931ab4a049a8166a217fbda7bd..e6e90904742150e5c07e373db570741a00d80358 100644
--- a/tailwind.config.cjs
+++ b/tailwind.config.cjs
@@ -1,14 +1,9 @@
-const flowbytePlugin = require("flowbite/plugin")
 const typography = require("@tailwindcss/typography")
 const colors = require("tailwindcss/colors")
 
 const config = {
-  content: [
-    "./src/**/*.{html,js,svelte,ts}",
-    "./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}",
-  ],
+  content: ["./src/**/*.{html,js,svelte,ts}"],
   plugins: [
-    flowbytePlugin,
     typography,
     function ({ addUtilities }) {
       const extendLineThrough = {