From 600f7b29e3f1a33765bab5cdab63ca607c593655 Mon Sep 17 00:00:00 2001
From: Dennis Collaris <d.a.c.collaris@uu.nl>
Date: Fri, 7 Feb 2025 16:50:12 +0000
Subject: [PATCH] feat: tooltip, popover, and context menu style improvements

---
 .storybook/main.ts                            |   8 +-
 .storybook/preview.tsx                        |  14 +-
 public/fonts/inter/inter.css                  | 514 +++++++++++++-----
 public/site.webmanifest                       |   2 +-
 src/app/navbar/navbar.tsx                     |  14 +-
 src/config/styles.css                         |   4 +-
 src/config/styling/fonts.css                  |  10 +-
 .../VisualizationTooltip.tsx                  |  23 -
 .../components/VisualizationTooltip/index.tsx |   1 -
 src/lib/components/charts/barplot/index.tsx   |   2 +-
 src/lib/components/charts/heatmap1D/index.tsx |   2 +-
 .../charts/indicatorGraph/index.tsx           |   2 +-
 src/lib/components/color-mode/index.tsx       |   2 +-
 src/lib/components/dropdowns/index.tsx        |   6 +-
 src/lib/components/forms/index.tsx            |  66 +--
 src/lib/components/index.ts                   |   2 +
 src/lib/components/inputs/DropdownInput.tsx   |   8 +-
 src/lib/components/inputs/NumberInput.tsx     |  10 +-
 src/lib/components/inputs/TextInput.tsx       |  10 +-
 .../NodeDetails.stories.tsx}                  |  23 +-
 .../components/nodeDetails/NodeDetails.tsx    |  21 +
 src/lib/components/nodeDetails/index.tsx      |   1 +
 src/lib/components/popover/Popover.tsx        | 331 +++++++++++
 .../components/popover/PopoverProvider.tsx    |  77 +++
 src/lib/components/popover/index.tsx          |   2 +
 .../components/popover/popover.stories.tsx    | 174 ++++++
 src/lib/components/tabs/Tab.tsx               |  23 +-
 src/lib/components/tooltip/Overview.mdx       |  99 +++-
 src/lib/components/tooltip/Tooltip.tsx        | 101 ++--
 src/lib/components/tooltip/index.tsx          |  21 -
 .../components/tooltip/tooltip.stories.tsx    |  93 +++-
 .../data-access/store/visualizationSlice.ts   |  11 +-
 src/lib/management/database/Databases.tsx     |   4 +-
 .../querybuilder/panel/ManualQueryDialog.tsx  |   2 +-
 src/lib/querybuilder/panel/QueryBuilder.tsx   |   4 +-
 ...xtMenu.tsx => QueryBuilderContextMenu.tsx} |  14 +-
 .../querybuilder/panel/QueryBuilderNav.tsx    |  42 +-
 .../QueryBuilderLogicPillsPanel.tsx           |   4 +-
 .../panel/querysidepanel/QueryMLDialog.tsx    | 136 ++---
 .../panel/querysidepanel/QuerySettings.tsx    |   4 +-
 .../pillattributes/PillAttributesItem.tsx     |   2 +-
 src/lib/schema/model/reactflow.tsx            |   4 +-
 .../iconsLayout/GridIcon.tsx                  |  18 +-
 src/lib/schema/panel/Schema.tsx               | 158 +++---
 src/lib/schema/panel/SchemaList.tsx           |  14 +-
 src/lib/schema/panel/SchemaSettings.tsx       |   6 +-
 .../pills/nodes/SchemaPopUp/SchemaPopUp.tsx   |  39 +-
 .../pills/nodes/entity/SchemaEntityPill.tsx   |  52 +-
 .../nodes/entity/SchemaListEntityPill.tsx     |  52 +-
 .../node-quality-relation-popup.stories.tsx   |   2 -
 .../node-quality-entity-popup.stories.tsx     |   2 -
 .../nodes/relation/SchemaListRelationPill.tsx |  62 +--
 .../nodes/relation/SchemaRelationPill.tsx     |  62 +--
 src/lib/sidebar/index.tsx                     |   2 +-
 src/lib/sidebar/search/SearchBar.tsx          |   4 +-
 src/lib/vis/components/VisualizationPanel.tsx |   5 +-
 .../vis/components/VisualizationTabBar.tsx    |  38 +-
 .../config/VisualizationSettings.tsx          |   2 +-
 .../arcplotvis/arcplotvis.stories.tsx         |   3 +-
 .../{MapTooltip.tsx => MapDataInspector.tsx}  |  19 +-
 .../visualizations/mapvis/components/index.ts |   2 +-
 .../visualizations/mapvis/mapvis.stories.tsx  |   3 +-
 src/lib/vis/visualizations/mapvis/mapvis.tsx  |  40 +-
 .../matrixvis/matrix.stories.tsx              |   3 +-
 .../nodelinkvis/components/NLPixi.tsx         |  36 +-
 .../nodelinkvis/components/NLPopup.tsx        |   2 +-
 .../nodelinkvis/nodelinkvis.stories.tsx       |   3 +-
 .../paohvis/components/HyperRangeBlock.tsx    |   2 +-
 .../paohvis/components/RowLabels.tsx          |   2 +-
 .../paohvis/paohvis.stories.tsx               |   3 +-
 .../vis1D/components/CustomChartPlotly.tsx    |  11 +-
 71 files changed, 1734 insertions(+), 806 deletions(-)
 delete mode 100644 src/lib/components/VisualizationTooltip/VisualizationTooltip.tsx
 delete mode 100644 src/lib/components/VisualizationTooltip/index.tsx
 rename src/lib/components/{VisualizationTooltip/VisualizationTooltip.stories.tsx => nodeDetails/NodeDetails.stories.tsx} (80%)
 create mode 100644 src/lib/components/nodeDetails/NodeDetails.tsx
 create mode 100644 src/lib/components/nodeDetails/index.tsx
 create mode 100644 src/lib/components/popover/Popover.tsx
 create mode 100644 src/lib/components/popover/PopoverProvider.tsx
 create mode 100644 src/lib/components/popover/index.tsx
 create mode 100644 src/lib/components/popover/popover.stories.tsx
 rename src/lib/querybuilder/panel/{ContextMenu.tsx => QueryBuilderContextMenu.tsx} (93%)
 rename src/lib/vis/visualizations/mapvis/components/{MapTooltip.tsx => MapDataInspector.tsx} (87%)

diff --git a/.storybook/main.ts b/.storybook/main.ts
index d82729eb3..c341d8154 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -3,13 +3,7 @@ import type { StorybookConfig } from '@storybook/react-vite';
 
 const config: StorybookConfig = {
   stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
-  addons: [
-    '@storybook/addon-onboarding',
-    // '@chromatic-com/storybook',
-    '@storybook/addon-essentials',
-    '@storybook/addon-interactions',
-    '@storybook/addon-links',
-  ],
+  addons: ['@storybook/addon-onboarding', '@storybook/addon-essentials', '@storybook/addon-interactions', '@storybook/addon-links'],
   framework: {
     name: '@storybook/react-vite',
     options: {},
diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
index 71958ab8f..a6b7249b0 100644
--- a/.storybook/preview.tsx
+++ b/.storybook/preview.tsx
@@ -1,12 +1,12 @@
-import React from 'react';
 import type { Preview } from '@storybook/react';
 import '../src/main.css';
 
 const preview: Preview = {
   decorators: [
     (Story, context) => {
-      if (document?.body?.className !== undefined) document.body.className += ' ' + 'light-mode';
-
+      if (document?.body?.className !== undefined) {
+        document.body.className += ' light-mode';
+      }
       return <Story />;
     },
   ],
@@ -17,13 +17,9 @@ const preview: Preview = {
         date: /Date$/i,
       },
     },
+    actions: {},
+    docs: {},
   },
 };
 
-export const decorators = [];
-
-export const parameters = {
-  actions: {},
-};
-
 export default preview;
diff --git a/public/fonts/inter/inter.css b/public/fonts/inter/inter.css
index 614406530..95a861662 100644
--- a/public/fonts/inter/inter.css
+++ b/public/fonts/inter/inter.css
@@ -8,141 +8,411 @@
   font-style: normal;
   font-weight: 100 900;
   font-display: swap;
-  src: url("InterVariable.woff2") format("woff2");
+  src: url('InterVariable.woff2') format('woff2');
 }
 @font-face {
   font-family: InterVariable;
   font-style: italic;
   font-weight: 100 900;
   font-display: swap;
-  src: url("InterVariable-Italic.woff2") format("woff2");
+  src: url('InterVariable-Italic.woff2') format('woff2');
 }
 
 /* static fonts */
-@font-face { font-family: "Inter"; font-style: normal; font-weight: 100; font-display: swap; src: url("Inter-Thin.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: italic; font-weight: 100; font-display: swap; src: url("Inter-ThinItalic.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: normal; font-weight: 200; font-display: swap; src: url("Inter-ExtraLight.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: italic; font-weight: 200; font-display: swap; src: url("Inter-ExtraLightItalic.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: normal; font-weight: 300; font-display: swap; src: url("Inter-Light.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: italic; font-weight: 300; font-display: swap; src: url("Inter-LightItalic.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap; src: url("Inter-Regular.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: italic; font-weight: 400; font-display: swap; src: url("Inter-Italic.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: normal; font-weight: 500; font-display: swap; src: url("Inter-Medium.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: italic; font-weight: 500; font-display: swap; src: url("Inter-MediumItalic.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap; src: url("Inter-SemiBold.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: italic; font-weight: 600; font-display: swap; src: url("Inter-SemiBoldItalic.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap; src: url("Inter-Bold.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: italic; font-weight: 700; font-display: swap; src: url("Inter-BoldItalic.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: normal; font-weight: 800; font-display: swap; src: url("Inter-ExtraBold.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: italic; font-weight: 800; font-display: swap; src: url("Inter-ExtraBoldItalic.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: normal; font-weight: 900; font-display: swap; src: url("Inter-Black.woff2") format("woff2"); }
-@font-face { font-family: "Inter"; font-style: italic; font-weight: 900; font-display: swap; src: url("Inter-BlackItalic.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 100; font-display: swap; src: url("InterDisplay-Thin.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 100; font-display: swap; src: url("InterDisplay-ThinItalic.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 200; font-display: swap; src: url("InterDisplay-ExtraLight.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 200; font-display: swap; src: url("InterDisplay-ExtraLightItalic.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 300; font-display: swap; src: url("InterDisplay-Light.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 300; font-display: swap; src: url("InterDisplay-LightItalic.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 400; font-display: swap; src: url("InterDisplay-Regular.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 400; font-display: swap; src: url("InterDisplay-Italic.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 500; font-display: swap; src: url("InterDisplay-Medium.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 500; font-display: swap; src: url("InterDisplay-MediumItalic.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 600; font-display: swap; src: url("InterDisplay-SemiBold.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 600; font-display: swap; src: url("InterDisplay-SemiBoldItalic.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 700; font-display: swap; src: url("InterDisplay-Bold.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 700; font-display: swap; src: url("InterDisplay-BoldItalic.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 800; font-display: swap; src: url("InterDisplay-ExtraBold.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 800; font-display: swap; src: url("InterDisplay-ExtraBoldItalic.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: normal; font-weight: 900; font-display: swap; src: url("InterDisplay-Black.woff2") format("woff2"); }
-@font-face { font-family: "InterDisplay"; font-style: italic; font-weight: 900; font-display: swap; src: url("InterDisplay-BlackItalic.woff2") format("woff2"); }
+@font-face {
+  font-family: 'Inter';
+  font-style: normal;
+  font-weight: 100;
+  font-display: swap;
+  src: url('Inter-Thin.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: italic;
+  font-weight: 100;
+  font-display: swap;
+  src: url('Inter-ThinItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: normal;
+  font-weight: 200;
+  font-display: swap;
+  src: url('Inter-ExtraLight.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: italic;
+  font-weight: 200;
+  font-display: swap;
+  src: url('Inter-ExtraLightItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: normal;
+  font-weight: 300;
+  font-display: swap;
+  src: url('Inter-Light.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: italic;
+  font-weight: 300;
+  font-display: swap;
+  src: url('Inter-LightItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: normal;
+  font-weight: 400;
+  font-display: swap;
+  src: url('Inter-Regular.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: italic;
+  font-weight: 400;
+  font-display: swap;
+  src: url('Inter-Italic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: normal;
+  font-weight: 500;
+  font-display: swap;
+  src: url('Inter-Medium.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: italic;
+  font-weight: 500;
+  font-display: swap;
+  src: url('Inter-MediumItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: normal;
+  font-weight: 600;
+  font-display: swap;
+  src: url('Inter-SemiBold.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: italic;
+  font-weight: 600;
+  font-display: swap;
+  src: url('Inter-SemiBoldItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: normal;
+  font-weight: 700;
+  font-display: swap;
+  src: url('Inter-Bold.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: italic;
+  font-weight: 700;
+  font-display: swap;
+  src: url('Inter-BoldItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: normal;
+  font-weight: 800;
+  font-display: swap;
+  src: url('Inter-ExtraBold.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: italic;
+  font-weight: 800;
+  font-display: swap;
+  src: url('Inter-ExtraBoldItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: normal;
+  font-weight: 900;
+  font-display: swap;
+  src: url('Inter-Black.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'Inter';
+  font-style: italic;
+  font-weight: 900;
+  font-display: swap;
+  src: url('Inter-BlackItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: normal;
+  font-weight: 100;
+  font-display: swap;
+  src: url('InterDisplay-Thin.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: italic;
+  font-weight: 100;
+  font-display: swap;
+  src: url('InterDisplay-ThinItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: normal;
+  font-weight: 200;
+  font-display: swap;
+  src: url('InterDisplay-ExtraLight.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: italic;
+  font-weight: 200;
+  font-display: swap;
+  src: url('InterDisplay-ExtraLightItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: normal;
+  font-weight: 300;
+  font-display: swap;
+  src: url('InterDisplay-Light.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: italic;
+  font-weight: 300;
+  font-display: swap;
+  src: url('InterDisplay-LightItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: normal;
+  font-weight: 400;
+  font-display: swap;
+  src: url('InterDisplay-Regular.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: italic;
+  font-weight: 400;
+  font-display: swap;
+  src: url('InterDisplay-Italic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: normal;
+  font-weight: 500;
+  font-display: swap;
+  src: url('InterDisplay-Medium.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: italic;
+  font-weight: 500;
+  font-display: swap;
+  src: url('InterDisplay-MediumItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: normal;
+  font-weight: 600;
+  font-display: swap;
+  src: url('InterDisplay-SemiBold.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: italic;
+  font-weight: 600;
+  font-display: swap;
+  src: url('InterDisplay-SemiBoldItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: normal;
+  font-weight: 700;
+  font-display: swap;
+  src: url('InterDisplay-Bold.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: italic;
+  font-weight: 700;
+  font-display: swap;
+  src: url('InterDisplay-BoldItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: normal;
+  font-weight: 800;
+  font-display: swap;
+  src: url('InterDisplay-ExtraBold.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: italic;
+  font-weight: 800;
+  font-display: swap;
+  src: url('InterDisplay-ExtraBoldItalic.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: normal;
+  font-weight: 900;
+  font-display: swap;
+  src: url('InterDisplay-Black.woff2') format('woff2');
+}
+@font-face {
+  font-family: 'InterDisplay';
+  font-style: italic;
+  font-weight: 900;
+  font-display: swap;
+  src: url('InterDisplay-BlackItalic.woff2') format('woff2');
+}
 
 @font-feature-values InterVariable {
-    @character-variant {
-        cv01: 1; cv02: 2; cv03: 3; cv04: 4; cv05: 5; cv06: 6; cv07: 7; cv08: 8;
-        cv09: 9; cv10: 10; cv11: 11; cv12: 12; cv13: 13;
-        alt-1:            1; /* Alternate one */
-        alt-3:            9; /* Flat-top three */
-        open-4:           2; /* Open four */
-        open-6:           3; /* Open six */
-        open-9:           4; /* Open nine */
-        lc-l-with-tail:   5; /* Lower-case L with tail */
-        simplified-u:     6; /* Simplified u */
-        alt-double-s:     7; /* Alternate German double s */
-        uc-i-with-serif:  8; /* Upper-case i with serif */
-        uc-g-with-spur:  10; /* Capital G with spur */
-        single-story-a:  11; /* Single-story a */
-        compact-lc-f:    12; /* Compact f */
-        compact-lc-t:    13; /* Compact t */
-    }
-    @styleset {
-        ss01: 1; ss02: 2; ss03: 3; ss04: 4; ss05: 5; ss06: 6; ss07: 7; ss08: 8;
-        open-digits: 1;                /* Open digits */
-        disambiguation: 2;             /* Disambiguation (with zero) */
-        disambiguation-except-zero: 4; /* Disambiguation (no zero) */
-        round-quotes-and-commas: 3;    /* Round quotes &amp; commas */
-        square-punctuation: 7;         /* Square punctuation */
-        square-quotes: 8;              /* Square quotes */
-        circled-characters: 5;         /* Circled characters */
-        squared-characters: 6;         /* Squared characters */
-    }
+  @character-variant {
+    cv01: 1;
+    cv02: 2;
+    cv03: 3;
+    cv04: 4;
+    cv05: 5;
+    cv06: 6;
+    cv07: 7;
+    cv08: 8;
+    cv09: 9;
+    cv10: 10;
+    cv11: 11;
+    cv12: 12;
+    cv13: 13;
+    alt-1: 1; /* Alternate one */
+    alt-3: 9; /* Flat-top three */
+    open-4: 2; /* Open four */
+    open-6: 3; /* Open six */
+    open-9: 4; /* Open nine */
+    lc-l-with-tail: 5; /* Lower-case L with tail */
+    simplified-u: 6; /* Simplified u */
+    alt-double-s: 7; /* Alternate German double s */
+    uc-i-with-serif: 8; /* Upper-case i with serif */
+    uc-g-with-spur: 10; /* Capital G with spur */
+    single-story-a: 11; /* Single-story a */
+    compact-lc-f: 12; /* Compact f */
+    compact-lc-t: 13; /* Compact t */
+  }
+  @styleset {
+    ss01: 1;
+    ss02: 2;
+    ss03: 3;
+    ss04: 4;
+    ss05: 5;
+    ss06: 6;
+    ss07: 7;
+    ss08: 8;
+    open-digits: 1; /* Open digits */
+    disambiguation: 2; /* Disambiguation (with zero) */
+    disambiguation-except-zero: 4; /* Disambiguation (no zero) */
+    round-quotes-and-commas: 3; /* Round quotes &amp; commas */
+    square-punctuation: 7; /* Square punctuation */
+    square-quotes: 8; /* Square quotes */
+    circled-characters: 5; /* Circled characters */
+    squared-characters: 6; /* Squared characters */
+  }
 }
 @font-feature-values Inter {
-    @character-variant {
-        cv01: 1; cv02: 2; cv03: 3; cv04: 4; cv05: 5; cv06: 6; cv07: 7; cv08: 8;
-        cv09: 9; cv10: 10; cv11: 11; cv12: 12; cv13: 13;
-        alt-1:            1; /* Alternate one */
-        alt-3:            9; /* Flat-top three */
-        open-4:           2; /* Open four */
-        open-6:           3; /* Open six */
-        open-9:           4; /* Open nine */
-        lc-l-with-tail:   5; /* Lower-case L with tail */
-        simplified-u:     6; /* Simplified u */
-        alt-double-s:     7; /* Alternate German double s */
-        uc-i-with-serif:  8; /* Upper-case i with serif */
-        uc-g-with-spur:  10; /* Capital G with spur */
-        single-story-a:  11; /* Single-story a */
-        compact-lc-f:    12; /* Compact f */
-        compact-lc-t:    13; /* Compact t */
-    }
-    @styleset {
-        ss01: 1; ss02: 2; ss03: 3; ss04: 4; ss05: 5; ss06: 6; ss07: 7; ss08: 8;
-        open-digits: 1;                /* Open digits */
-        disambiguation: 2;             /* Disambiguation (with zero) */
-        disambiguation-except-zero: 4; /* Disambiguation (no zero) */
-        round-quotes-and-commas: 3;    /* Round quotes &amp; commas */
-        square-punctuation: 7;         /* Square punctuation */
-        square-quotes: 8;              /* Square quotes */
-        circled-characters: 5;         /* Circled characters */
-        squared-characters: 6;         /* Squared characters */
-    }
+  @character-variant {
+    cv01: 1;
+    cv02: 2;
+    cv03: 3;
+    cv04: 4;
+    cv05: 5;
+    cv06: 6;
+    cv07: 7;
+    cv08: 8;
+    cv09: 9;
+    cv10: 10;
+    cv11: 11;
+    cv12: 12;
+    cv13: 13;
+    alt-1: 1; /* Alternate one */
+    alt-3: 9; /* Flat-top three */
+    open-4: 2; /* Open four */
+    open-6: 3; /* Open six */
+    open-9: 4; /* Open nine */
+    lc-l-with-tail: 5; /* Lower-case L with tail */
+    simplified-u: 6; /* Simplified u */
+    alt-double-s: 7; /* Alternate German double s */
+    uc-i-with-serif: 8; /* Upper-case i with serif */
+    uc-g-with-spur: 10; /* Capital G with spur */
+    single-story-a: 11; /* Single-story a */
+    compact-lc-f: 12; /* Compact f */
+    compact-lc-t: 13; /* Compact t */
+  }
+  @styleset {
+    ss01: 1;
+    ss02: 2;
+    ss03: 3;
+    ss04: 4;
+    ss05: 5;
+    ss06: 6;
+    ss07: 7;
+    ss08: 8;
+    open-digits: 1; /* Open digits */
+    disambiguation: 2; /* Disambiguation (with zero) */
+    disambiguation-except-zero: 4; /* Disambiguation (no zero) */
+    round-quotes-and-commas: 3; /* Round quotes &amp; commas */
+    square-punctuation: 7; /* Square punctuation */
+    square-quotes: 8; /* Square quotes */
+    circled-characters: 5; /* Circled characters */
+    squared-characters: 6; /* Squared characters */
+  }
 }
 @font-feature-values InterDisplay {
-    @character-variant {
-        cv01: 1; cv02: 2; cv03: 3; cv04: 4; cv05: 5; cv06: 6; cv07: 7; cv08: 8;
-        cv09: 9; cv10: 10; cv11: 11; cv12: 12; cv13: 13;
-        alt-1:            1; /* Alternate one */
-        alt-3:            9; /* Flat-top three */
-        open-4:           2; /* Open four */
-        open-6:           3; /* Open six */
-        open-9:           4; /* Open nine */
-        lc-l-with-tail:   5; /* Lower-case L with tail */
-        simplified-u:     6; /* Simplified u */
-        alt-double-s:     7; /* Alternate German double s */
-        uc-i-with-serif:  8; /* Upper-case i with serif */
-        uc-g-with-spur:  10; /* Capital G with spur */
-        single-story-a:  11; /* Single-story a */
-        compact-lc-f:    12; /* Compact f */
-        compact-lc-t:    13; /* Compact t */
-    }
-    @styleset {
-        ss01: 1; ss02: 2; ss03: 3; ss04: 4; ss05: 5; ss06: 6; ss07: 7; ss08: 8;
-        open-digits: 1;                /* Open digits */
-        disambiguation: 2;             /* Disambiguation (with zero) */
-        disambiguation-except-zero: 4; /* Disambiguation (no zero) */
-        round-quotes-and-commas: 3;    /* Round quotes &amp; commas */
-        square-punctuation: 7;         /* Square punctuation */
-        square-quotes: 8;              /* Square quotes */
-        circled-characters: 5;         /* Circled characters */
-        squared-characters: 6;         /* Squared characters */
-    }
+  @character-variant {
+    cv01: 1;
+    cv02: 2;
+    cv03: 3;
+    cv04: 4;
+    cv05: 5;
+    cv06: 6;
+    cv07: 7;
+    cv08: 8;
+    cv09: 9;
+    cv10: 10;
+    cv11: 11;
+    cv12: 12;
+    cv13: 13;
+    alt-1: 1; /* Alternate one */
+    alt-3: 9; /* Flat-top three */
+    open-4: 2; /* Open four */
+    open-6: 3; /* Open six */
+    open-9: 4; /* Open nine */
+    lc-l-with-tail: 5; /* Lower-case L with tail */
+    simplified-u: 6; /* Simplified u */
+    alt-double-s: 7; /* Alternate German double s */
+    uc-i-with-serif: 8; /* Upper-case i with serif */
+    uc-g-with-spur: 10; /* Capital G with spur */
+    single-story-a: 11; /* Single-story a */
+    compact-lc-f: 12; /* Compact f */
+    compact-lc-t: 13; /* Compact t */
+  }
+  @styleset {
+    ss01: 1;
+    ss02: 2;
+    ss03: 3;
+    ss04: 4;
+    ss05: 5;
+    ss06: 6;
+    ss07: 7;
+    ss08: 8;
+    open-digits: 1; /* Open digits */
+    disambiguation: 2; /* Disambiguation (with zero) */
+    disambiguation-except-zero: 4; /* Disambiguation (no zero) */
+    round-quotes-and-commas: 3; /* Round quotes &amp; commas */
+    square-punctuation: 7; /* Square punctuation */
+    square-quotes: 8; /* Square quotes */
+    circled-characters: 5; /* Circled characters */
+    squared-characters: 6; /* Squared characters */
+  }
 }
diff --git a/public/site.webmanifest b/public/site.webmanifest
index adb99843f..8eb18780a 100644
--- a/public/site.webmanifest
+++ b/public/site.webmanifest
@@ -18,4 +18,4 @@
   "theme_color": "#ffffff",
   "background_color": "#ffffff",
   "display": "standalone"
-}
\ No newline at end of file
+}
diff --git a/src/app/navbar/navbar.tsx b/src/app/navbar/navbar.tsx
index cae161513..34a184c70 100644
--- a/src/app/navbar/navbar.tsx
+++ b/src/app/navbar/navbar.tsx
@@ -15,7 +15,7 @@ import GpLogo from './gp-logo';
 import { getEnvVariable } from '@/config';
 import { useAuthentication, useAuthCache, useActiveSaveStateAuthorization, Button, DropdownItem, useAppDispatch } from '@/lib';
 import { FeatureEnabled } from '@/lib/components/featureFlags';
-import { Popover, PopoverTrigger, PopoverContent } from '@/lib/components/layout/Popover';
+import { Popover, PopoverTrigger, PopoverContent } from '@/lib/components/popover';
 import { ManagementViews, ManagementTrigger } from '@/lib/management';
 import { addError } from '@/lib/data-access/store/configSlice';
 
@@ -73,14 +73,14 @@ export const Navbar = () => {
               </div>
             </PopoverTrigger>
 
-            <PopoverContent className="w-56 z-30 bg-light rounded-sm border-[1px] outline-none">
-              <div className="p-2 text-sm border-b">
+            <PopoverContent className="w-56 z-30 bg-light divide-y divide-secondary-200">
+              <div className="text-sm p-2">
                 <h2 className="font-bold">user: {authCache.authentication?.username}</h2>
                 <h3 className="text-xs break-words">session: {authCache?.sessionID}</h3>
                 <h3 className="text-xs break-words">license: Creator</h3>
               </div>
               {authCache.authentication?.authenticated ? (
-                <>
+                <div className="p-2">
                   <FeatureEnabled featureFlag="SHARABLE_EXPLORATION">
                     <DropdownItem
                       value={sharing ? 'Creating Share Link' : 'Share'}
@@ -126,7 +126,7 @@ export const Navbar = () => {
                       }}
                     />
                   )}
-                </>
+                </div>
               ) : (
                 <>
                   <DropdownItem value="Login" onClick={() => {}} />
@@ -134,11 +134,11 @@ export const Navbar = () => {
               )}
 
               {authCache.authentication?.roomID && (
-                <div className="p-2 border-b">
+                <div className="p-2">
                   <h3 className="text-xs break-words">Share ID: {authCache.authentication?.roomID}</h3>
                 </div>
               )}
-              <div className="p-2 border-t">
+              <div className="p-2">
                 <h3 className="text-xs">Version: {buildInfo}</h3>
               </div>
             </PopoverContent>
diff --git a/src/config/styles.css b/src/config/styles.css
index 80973a5c1..3cf72f933 100644
--- a/src/config/styles.css
+++ b/src/config/styles.css
@@ -13,7 +13,7 @@
   }
   /* Hide scrollbar for IE, Edge and Firefox */
   .no-scrollbar {
-    -ms-overflow-style: none;  /* IE and Edge */
-    scrollbar-width: none;  /* Firefox */
+    -ms-overflow-style: none; /* IE and Edge */
+    scrollbar-width: none; /* Firefox */
   }
 }
diff --git a/src/config/styling/fonts.css b/src/config/styling/fonts.css
index b8edb246c..37724fd45 100644
--- a/src/config/styling/fonts.css
+++ b/src/config/styling/fonts.css
@@ -1,17 +1,19 @@
 :root {
-  font-family: "Inter", sans-serif;
+  font-family: 'Inter', sans-serif;
 }
 
 @supports (font-variation-settings: normal) {
   :root {
-    font-family: "InterVariable", sans-serif;
+    font-family: 'InterVariable', sans-serif;
     font-optical-sizing: auto;
   }
 }
 
 .font-data {
-  font-family: "InterVariable", "Inter", sans-serif;
+  font-family: 'InterVariable', 'Inter', sans-serif;
   font-optical-sizing: auto;
   font-variant-numeric: tabular-nums slashed-zero;
-  font-feature-settings: "tnum" 1, "zero" 1;
+  font-feature-settings:
+    'tnum' 1,
+    'zero' 1;
 }
diff --git a/src/lib/components/VisualizationTooltip/VisualizationTooltip.tsx b/src/lib/components/VisualizationTooltip/VisualizationTooltip.tsx
deleted file mode 100644
index b718ed68d..000000000
--- a/src/lib/components/VisualizationTooltip/VisualizationTooltip.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import React, { ReactNode } from 'react';
-
-export type VisualizationTooltipProps = {
-  name: string;
-  colorHeader: string;
-  children: ReactNode;
-};
-
-export const VisualizationTooltip: React.FC<VisualizationTooltipProps> = ({ name, colorHeader, children }) => {
-  return (
-    <div className="border-1 border-sec-200 bg-light w-[12rem] -mx-2 -my-2">
-      <div className="flex m-0 justify-start items-stretch border-b border-sec-200 relative">
-        <div className="left-0 top-0 h-auto w-1.5" style={{ backgroundColor: colorHeader }}></div>
-        <div className="px-2.5 py-1 truncate flex">
-          <div className={'flex max-w-full'}>
-            <span className="text-base font-semibold line-clamp-1">{name}</span>
-          </div>
-        </div>
-      </div>
-      {children}
-    </div>
-  );
-};
diff --git a/src/lib/components/VisualizationTooltip/index.tsx b/src/lib/components/VisualizationTooltip/index.tsx
deleted file mode 100644
index 868ce59de..000000000
--- a/src/lib/components/VisualizationTooltip/index.tsx
+++ /dev/null
@@ -1 +0,0 @@
-export * from './VisualizationTooltip';
diff --git a/src/lib/components/charts/barplot/index.tsx b/src/lib/components/charts/barplot/index.tsx
index 5f703dfae..6b846816d 100644
--- a/src/lib/components/charts/barplot/index.tsx
+++ b/src/lib/components/charts/barplot/index.tsx
@@ -156,7 +156,7 @@ export const BarPlot = ({ typeBarPlot, numBins, data, marginPercentage, classNam
   }, [data, dimensions, marginPercentage, numBins, typeBarPlot, axis, name]);
 
   return (
-    <TooltipProvider delayDuration={300}>
+    <TooltipProvider delay={300}>
       <div className={className || ''}>
         <svg ref={svgRef} width="100%" height="100%">
           <g ref={groupMarginRef}>
diff --git a/src/lib/components/charts/heatmap1D/index.tsx b/src/lib/components/charts/heatmap1D/index.tsx
index 7e6eb999c..3b85046b8 100644
--- a/src/lib/components/charts/heatmap1D/index.tsx
+++ b/src/lib/components/charts/heatmap1D/index.tsx
@@ -110,7 +110,7 @@ export const Heatmap1D = ({ numBins, maxValue, data, marginPercentage, className
   }, [data, dimensions, marginPercentage, numBins, axis, name]);
 
   return (
-    <TooltipProvider delayDuration={300}>
+    <TooltipProvider delay={300}>
       <div className={className || ''}>
         <svg ref={svgRef} width="100%" height="100%">
           <g ref={groupMarginRef}>
diff --git a/src/lib/components/charts/indicatorGraph/index.tsx b/src/lib/components/charts/indicatorGraph/index.tsx
index f6d0f80c2..8f01f43d6 100644
--- a/src/lib/components/charts/indicatorGraph/index.tsx
+++ b/src/lib/components/charts/indicatorGraph/index.tsx
@@ -79,7 +79,7 @@ export const IndicatorGraph = ({ maxValue, data, marginPercentage, className, ax
   }, [data, dimensions, marginPercentage, axis, name]);
 
   return (
-    <TooltipProvider delayDuration={300}>
+    <TooltipProvider delay={300}>
       <div className={className || ''}>
         <svg ref={svgRef} width="100%" height="100%">
           <g ref={groupMarginRef}>
diff --git a/src/lib/components/color-mode/index.tsx b/src/lib/components/color-mode/index.tsx
index 1a104d8b5..4895b2627 100644
--- a/src/lib/components/color-mode/index.tsx
+++ b/src/lib/components/color-mode/index.tsx
@@ -35,7 +35,7 @@ const ColorMode = () => {
         : 'icon-[ic--baseline-auto-mode]';
 
   return (
-    <TooltipProvider delayDuration={0}>
+    <TooltipProvider delay={0}>
       <Tooltip placement={'right'}>
         <TooltipTrigger asChild>
           <Button variant="ghost" size="sm" iconComponent={iconComponent} onClick={toggleTheme} />
diff --git a/src/lib/components/dropdowns/index.tsx b/src/lib/components/dropdowns/index.tsx
index 56f9d478f..06bc3fe63 100644
--- a/src/lib/components/dropdowns/index.tsx
+++ b/src/lib/components/dropdowns/index.tsx
@@ -1,6 +1,6 @@
 import React, { useState, useRef, ReactNode } from 'react';
 import { Icon } from '../icon';
-import { PopoverContent, PopoverTrigger, Popover, PopoverOptions } from '../layout/Popover';
+import { PopoverContent, PopoverTrigger, Popover, PopoverOptions } from '@/lib/components/popover';
 
 export const DropdownContainer = ({ children, ...props }: { children: React.ReactNode } & PopoverOptions) => {
   return (
@@ -127,8 +127,8 @@ export function DropdownItem({ value, label, disabled, className, onClick, subme
     <li
       ref={itemRef}
       style={{ border: 0, listStyleType: 'none' }}
-      className={`flex w-full grow cursor-pointer divide-y origin-top-right whitespace-nowrap 
-        rounded-sm items-center justify-between text-sm px-2 pe-1 py-1 hover:bg-secondary-200 ${
+      className={`flex w-full grow cursor-pointer divide-y origin-top-right whitespace-nowrap
+        rounded items-center justify-between text-sm gap-1.5 px-1.5 py-1 hover:bg-secondary-100 ${
           className && className
         } ${selected ? 'bg-secondary-400 text-white hover:text-black' : ''}`}
       onClick={() => {
diff --git a/src/lib/components/forms/index.tsx b/src/lib/components/forms/index.tsx
index 149e485f0..78ab61026 100644
--- a/src/lib/components/forms/index.tsx
+++ b/src/lib/components/forms/index.tsx
@@ -69,58 +69,60 @@ export const FormDiv = React.forwardRef<HTMLDivElement, PropsWithChildren<{ clas
   },
 );
 export const FormCard = (props: PropsWithChildren<{ className?: string }>) => (
-  <div className={'card card-bordered bg-light rounded-none ' + (props.className ? props.className : '')}>{props.children}</div>
+  <div className={'border border-secondary-200 bg-light rounded-none p-2' + (props.className ? props.className : '')}>{props.children}</div>
 );
 export const FormBody = ({
   children,
   ...props
 }: PropsWithChildren<React.DetailedHTMLProps<React.FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>>) => (
-  <form className="px-0 w-72 py-2" {...props}>
-    {children}
-  </form>
+  <form {...props}>{children}</form>
 );
-export const FormTitle = ({ children, title, onClose }: PropsWithChildren<{ title: string; onClose?: () => void }>) => {
+export const FormTitle = ({
+  children,
+  title,
+  onClose,
+  className = '',
+  ...props
+}: PropsWithChildren<{
+  title: string;
+  onClose?: () => void;
+  className?: string;
+}>) => {
   return (
-    <div className="font-semibold p-5 py-0 flex w-full">
-      <h2 className="w-full">{title}</h2>
-      {onClose && <Button rounded variant="ghost" iconComponent="icon-[ic--baseline-close]" onClick={() => onClose()} />}
+    <div className={`font-semibold font-sm flex flex-row justify-between w-full p-2 ${className}`} {...props}>
+      <h2>{title}</h2>
+      {onClose && <Button rounded variant="ghost" iconComponent="icon-[ic--baseline-close]" onClick={onClose} />}
     </div>
   );
 };
-export const FormHBar = () => <div className="divider m-0"></div>;
-export const FormControl = ({ children }: PropsWithChildren) => <div className="form-control px-5">{children}</div>;
-export const FormActions = (props: { onClose?: () => void; onApply?: () => void }) => (
+export const FormHBar = () => <hr className="border-px w-full my-1"></hr>;
+export const FormControl = ({ children }: PropsWithChildren) => <div className="form-control">{children}</div>;
+export const FormActions = ({
+  onClose,
+  onApply,
+  size = 'md',
+}: {
+  onClose?: () => void;
+  onApply?: () => void;
+  size?: 'sm' | 'md' | 'lg';
+}) => (
   <>
-    {props.onClose && (
-      <div className="grid grid-cols-2 px-5 gap-2 mb-2">
+    {onClose ? (
+      <div className="grid grid-cols-2 gap-2">
         <Button
           variantType="secondary"
           variant="outline"
           label="Cancel"
+          size={size}
           onClick={e => {
             e.preventDefault();
-            if (props.onClose) props.onClose();
+            onClose();
           }}
         />
-        <Button
-          variantType="primary"
-          label="Apply"
-          onClick={() => {
-            if (props.onApply) props.onApply();
-          }}
-          className="flex-grow"
-        />
+        <Button variantType="primary" label="Apply" size={size} onClick={onApply} className="flex-grow" />
       </div>
-    )}
-    {!props.onClose && (
-      <Button
-        variantType="primary"
-        label="Apply"
-        onClick={() => {
-          if (props.onApply) props.onApply();
-        }}
-        className="w-full"
-      />
+    ) : (
+      <Button variantType="primary" label="Apply" size={size} onClick={onApply} className="w-full" />
     )}
   </>
 );
diff --git a/src/lib/components/index.ts b/src/lib/components/index.ts
index b5769a607..ed9def1ff 100644
--- a/src/lib/components/index.ts
+++ b/src/lib/components/index.ts
@@ -12,7 +12,9 @@ export * from './pagination';
 export * from './tooltip';
 export * from './Legend';
 export * from './LoadingSpinner';
+export * from './nodeDetails';
 export * from './Popup';
+export * from './popover';
 export * from './layout';
 export * from './pills';
 export * from './tabs';
diff --git a/src/lib/components/inputs/DropdownInput.tsx b/src/lib/components/inputs/DropdownInput.tsx
index f85718699..83c913676 100644
--- a/src/lib/components/inputs/DropdownInput.tsx
+++ b/src/lib/components/inputs/DropdownInput.tsx
@@ -76,7 +76,7 @@ export const DropdownInput = ({
   const [filteredOptions, setFilteredOptions] = React.useState<(string | number | { [key: string]: string })[]>(options);
 
   useEffect(() => {
-      setFilteredOptions(options);
+    setFilteredOptions(options);
   }, [options]);
 
   const handleInputChange = (e: string) => {
@@ -94,11 +94,11 @@ export const DropdownInput = ({
 
   return (
     <Tooltip>
-      <TooltipTrigger className={'w-full' + (inline ? ' grid grid-cols-2 items-center gap-0.5' : '') + ' ' + className}>
+      <TooltipTrigger className={'w-full' + (inline ? ' flex flex-row items-center gap-0.5 justify-between' : '') + ' ' + className}>
         {label && (
-          <label className="label p-0">
+          <label className="label p-0 flex-1 min-w-0">
             <span
-              className={`text-${size} text-left truncate font-medium text-secondary-700 ${required && "after:content-['*'] after:ml-0.5 after:text-danger-500"}`}
+              className={`text-${size} text-left font-medium text-secondary-700 line-clamp-2 leading-snug ${required && "after:content-['*'] after:ml-0.5 after:text-danger-500"}`}
             >
               {label}
             </span>
diff --git a/src/lib/components/inputs/NumberInput.tsx b/src/lib/components/inputs/NumberInput.tsx
index 996dfddfc..4ce219f79 100644
--- a/src/lib/components/inputs/NumberInput.tsx
+++ b/src/lib/components/inputs/NumberInput.tsx
@@ -38,13 +38,15 @@ export const NumberInput = ({
   if (!tooltip && inline && label) tooltip = label;
   return (
     <div className={styles['input'] + `${containerClassName ? ` ${containerClassName}` : ''}`}>
-      <TooltipProvider delayDuration={50}>
+      <TooltipProvider delay={50}>
         <Tooltip>
-          <TooltipTrigger className={'form-control w-full' + (inline && label ? ' grid grid-cols-2 items-center gap-0.5' : '')}>
+          <TooltipTrigger
+            className={'form-control w-full' + (inline && label ? ' flex flex-row items-center gap-0.5 justify-between' : '')}
+          >
             {label && (
-              <label className="label p-0">
+              <label className="label p-0 flex-1 min-w-0">
                 <span
-                  className={`text-sm text-left truncate font-medium text-secondary-700 ${required && "after:content-['*'] after:ml-0.5 after:text-danger-500"}`}
+                  className={`text-${size} text-left font-medium text-secondary-700 line-clamp-2 leading-snug ${required && "after:content-['*'] after:ml-0.5 after:text-danger-500"}`}
                 >
                   {label}
                 </span>
diff --git a/src/lib/components/inputs/TextInput.tsx b/src/lib/components/inputs/TextInput.tsx
index a773c6c45..32e073369 100644
--- a/src/lib/components/inputs/TextInput.tsx
+++ b/src/lib/components/inputs/TextInput.tsx
@@ -37,11 +37,13 @@ export const TextInput = ({
   if (!tooltip && inline) tooltip = label;
   return (
     <Tooltip>
-      <TooltipTrigger className={styles['input'] + ' form-control w-full' + (inline ? ' grid grid-cols-2 items-center gap-0.5' : '')}>
+      <TooltipTrigger
+        className={styles['input'] + ' form-control w-full' + (inline ? ' flex flex-row items-center gap-0.5 justify-between' : '')}
+      >
         {label && (
-          <label className="label p-0">
+          <label className="label p-0 flex-1 min-w-0">
             <span
-              className={`text-sm font-medium text-secondary-700 ${required && "after:content-['*'] after:ml-0.5 after:text-danger-500"}`}
+              className={`text-${size} font-medium text-secondary-700 line-clamp-2 leading-snug ${required && "after:content-['*'] after:ml-0.5 after:text-danger-500"}`}
             >
               {label}
             </span>
@@ -53,7 +55,7 @@ export const TextInput = ({
           type={visible ? 'text' : 'password'}
           placeholder={placeholder}
           className={
-            `${size} bg-light border border-secondary-200 placeholder-secondary-400 focus:outline-none block w-full focus:ring-1 ${
+            `${size} bg-light border border-secondary-200 placeholder-secondary-400 w-auto min-w-6 max-w-[65%] shrink-0 grow-1 focus:outline-none block focus:ring-1 ${
               isValid ? '' : 'input-error'
             }` + (className ? ` ${className}` : '')
           }
diff --git a/src/lib/components/VisualizationTooltip/VisualizationTooltip.stories.tsx b/src/lib/components/nodeDetails/NodeDetails.stories.tsx
similarity index 80%
rename from src/lib/components/VisualizationTooltip/VisualizationTooltip.stories.tsx
rename to src/lib/components/nodeDetails/NodeDetails.stories.tsx
index cd2b769f2..9ebc14c60 100644
--- a/src/lib/components/VisualizationTooltip/VisualizationTooltip.stories.tsx
+++ b/src/lib/components/nodeDetails/NodeDetails.stories.tsx
@@ -1,17 +1,16 @@
-import React from 'react';
 import type { Meta, StoryObj } from '@storybook/react';
-import { VisualizationTooltip, VisualizationTooltipProps } from '@/lib/components/VisualizationTooltip';
+import { NodeDetails, NodeDetailsProps } from '@/lib/components/nodeDetails';
 import { SchemaPopUp, SchemaPopUpProps } from '@/lib/schema/pills/nodes/SchemaPopUp/SchemaPopUp';
 import { NLPopUp, NLPopUpProps } from '@/lib/vis/visualizations/nodelinkvis/components/NLPopup';
 
-const meta: Meta<typeof VisualizationTooltip> = {
-  component: VisualizationTooltip,
-  title: 'Components/VisualizationTooltip',
+const meta: Meta<typeof NodeDetails> = {
+  component: NodeDetails,
+  title: 'Components/NodeDetails',
 };
 
 export default meta;
 
-type CombinedProps = VisualizationTooltipProps & SchemaPopUpProps & NLPopUpProps & { attributes: { name: string; type: string }[] };
+type CombinedProps = NodeDetailsProps & SchemaPopUpProps & NLPopUpProps & { attributes: { name: string; type: string }[] };
 
 type Story = StoryObj<CombinedProps>;
 
@@ -30,9 +29,9 @@ export const SchemaNode: Story = {
 
     return (
       <div className="w-1/4 my-10 m-auto flex items-center justify-center">
-        <VisualizationTooltip name={name} colorHeader={colorHeader}>
+        <NodeDetails name={name} colorHeader={colorHeader}>
           <SchemaPopUp data={data} numberOfElements={numberOfElements} />
-        </VisualizationTooltip>
+        </NodeDetails>
       </div>
     );
   },
@@ -66,9 +65,9 @@ export const SchemaRelationship: Story = {
 
     return (
       <div className="w-1/4 my-10 m-auto flex items-center justify-center">
-        <VisualizationTooltip name={name} colorHeader={colorHeader}>
+        <NodeDetails name={name} colorHeader={colorHeader}>
           <SchemaPopUp data={data} numberOfElements={numberOfElements} connections={connections} />
-        </VisualizationTooltip>
+        </NodeDetails>
       </div>
     );
   },
@@ -92,9 +91,9 @@ export const NodeLinkPopUp: Story = {
     const { name, data, colorHeader } = args;
     return (
       <div className="w-1/4 my-10 m-auto flex items-center justify-center">
-        <VisualizationTooltip name={name} colorHeader={colorHeader}>
+        <NodeDetails name={name} colorHeader={colorHeader}>
           <NLPopUp data={data} />
-        </VisualizationTooltip>
+        </NodeDetails>
       </div>
     );
   },
diff --git a/src/lib/components/nodeDetails/NodeDetails.tsx b/src/lib/components/nodeDetails/NodeDetails.tsx
new file mode 100644
index 000000000..ec98753ac
--- /dev/null
+++ b/src/lib/components/nodeDetails/NodeDetails.tsx
@@ -0,0 +1,21 @@
+import React, { ReactNode } from 'react';
+
+export type NodeDetailsProps = {
+  name: string;
+  colorHeader: string;
+  children: ReactNode;
+};
+
+export const NodeDetails: React.FC<NodeDetailsProps> = ({ name, colorHeader, children }) => {
+  return (
+    <div className="w-[12rem] divide-y divider-secondary-200">
+      <div className="px-2 relative w-full">
+        <div className="left-0 top-0 h-full w-1 shrink-0 absolute" style={{ backgroundColor: colorHeader }}></div>
+        <div className="px-1 py-1">
+          <div className="text-sm font-semibold truncate overflow-hidden whitespace-nowrap">{name}</div>
+        </div>
+      </div>
+      {children && <div className="text-xs p-1">{children}</div>}
+    </div>
+  );
+};
diff --git a/src/lib/components/nodeDetails/index.tsx b/src/lib/components/nodeDetails/index.tsx
new file mode 100644
index 000000000..ace73d287
--- /dev/null
+++ b/src/lib/components/nodeDetails/index.tsx
@@ -0,0 +1 @@
+export * from './NodeDetails';
diff --git a/src/lib/components/popover/Popover.tsx b/src/lib/components/popover/Popover.tsx
new file mode 100644
index 000000000..099b7d828
--- /dev/null
+++ b/src/lib/components/popover/Popover.tsx
@@ -0,0 +1,331 @@
+import React, { useEffect } from 'react';
+import {
+  useFloating,
+  autoUpdate,
+  offset,
+  flip,
+  shift,
+  hide,
+  arrow,
+  useClick,
+  useHover,
+  useFocus,
+  useDismiss,
+  useRole,
+  useInteractions,
+  useMergeRefs,
+  FloatingPortal,
+  FloatingArrow,
+} from '@floating-ui/react';
+import type { Placement, Alignment } from '@floating-ui/react';
+import { Button } from '@/lib';
+import { v4 as uuidv4 } from 'uuid';
+import { usePopoverGlobalContext } from '@/lib';
+
+export interface PopoverOptions {
+  id?: string;
+  initialOpen?: boolean;
+  placement?: Placement;
+  alignment?: Alignment;
+  autoAlignment?: boolean;
+  open?: boolean;
+  onOpenChange?: (open: boolean) => void;
+  boundaryElement?: React.RefObject<HTMLElement> | HTMLElement | null;
+  showArrow?: boolean;
+  interactive?: boolean;
+  delay?: number | { open?: number; close?: number };
+  activation?: 'click' | 'hover' | 'focus';
+  showCloseButton?: boolean;
+}
+
+interface PopoverInstanceContextProps {
+  open: boolean;
+  setOpen: (state: boolean) => void;
+  closePopover: () => void;
+  interactions: ReturnType<typeof useInteractions>;
+  data: ReturnType<typeof useFloating>;
+  interactive: boolean;
+  showCloseButton?: boolean;
+}
+const globalOpenPopovers = new Set<string>();
+
+const PopoverInstanceContext = React.createContext<PopoverInstanceContextProps | null>(null);
+
+// Custom hook to access the instance Popover context
+export const usePopoverInstanceContext = (): PopoverInstanceContextProps => {
+  const context = React.useContext(PopoverInstanceContext);
+  if (!context) {
+    throw new Error('Popover components must be wrapped in <Popover>.');
+  }
+  return context;
+};
+
+// Hook to handle popover state
+export function usePopover({
+  id = uuidv4(),
+  initialOpen = false,
+  placement = 'top',
+  alignment,
+  autoAlignment = true,
+  open: controlledOpen,
+  onOpenChange,
+  boundaryElement = null,
+  showArrow = true,
+  interactive = true,
+  delay,
+  activation = 'click',
+}: PopoverOptions = {}) {
+  // Access the global Popover context if available
+  const popoverGlobal = usePopoverGlobalContext();
+  const [uncontrolledOpen, setUncontrolledOpen] = React.useState(initialOpen);
+
+  const hasInitialized = React.useRef(false);
+  // Sync initialOpen when component mounts
+  useEffect(() => {
+    if (initialOpen && !hasInitialized.current) {
+      hasInitialized.current = true;
+      setUncontrolledOpen(true);
+      if (popoverGlobal) {
+        popoverGlobal.openPopover(id);
+      } else {
+        globalOpenPopovers.add(id);
+      }
+    }
+  }, [initialOpen, popoverGlobal, id]);
+
+  const isManaged = popoverGlobal !== null;
+  const open = controlledOpen ?? uncontrolledOpen ?? (isManaged ? popoverGlobal.isOpen(id) : false);
+
+  const setOpen = (state: boolean) => {
+    if (isManaged && popoverGlobal) {
+      // Popover zit in een provider
+      if (state) {
+        popoverGlobal.openPopover(id);
+      } else {
+        popoverGlobal.closePopover(id);
+      }
+    } else {
+      if (state) {
+        globalOpenPopovers.clear();
+        globalOpenPopovers.add(id);
+      } else {
+        globalOpenPopovers.delete(id);
+      }
+    }
+
+    setUncontrolledOpen(state);
+    onOpenChange?.(state);
+  };
+
+  const arrowRef = React.useRef<SVGSVGElement | null>(null);
+  const middleware = [
+    offset(5),
+    shift({ padding: 5 }),
+    flip({
+      crossAxis: placement.includes('-'),
+      flipAlignment: autoAlignment === false ? false : !!alignment,
+      padding: 5,
+    }),
+  ];
+
+  if (boundaryElement) {
+    const boundary = boundaryElement instanceof HTMLElement ? boundaryElement : (boundaryElement?.current ?? undefined);
+    if (boundary) {
+      middleware.push(hide({ boundary }));
+    }
+  }
+
+  if (showArrow) middleware.push(arrow({ element: arrowRef }));
+
+  const adjustedPlacement = alignment ? (`${placement}-${alignment}` as Placement) : placement;
+
+  const data = useFloating({
+    placement: adjustedPlacement,
+    open,
+    onOpenChange: setOpen,
+    whileElementsMounted: autoUpdate,
+    middleware,
+  });
+
+  // Attach the arrow ref
+  (data.refs as any).arrow = arrowRef;
+
+  const click = useClick(data.context, { enabled: activation === 'click' });
+  const hover = useHover(data.context, { enabled: activation === 'hover', delay, move: true, restMs: 50 });
+  const focus = useFocus(data.context, { enabled: activation === 'focus' });
+  const dismiss = useDismiss(data.context, {
+    enabled: activation === 'click',
+
+    outsidePress: (event: MouseEvent) => {
+      if (isManaged && popoverGlobal) {
+        return !(popoverGlobal.isMultiselect() && event.shiftKey);
+      }
+      return true;
+    },
+  });
+
+  const role = useRole(data.context, { role: 'dialog' });
+
+  const interactions = useInteractions([click, hover, focus, dismiss, role]);
+
+  return React.useMemo(
+    () => ({
+      open,
+      setOpen,
+      closePopover: () => setOpen(false),
+      interactions,
+      data,
+      interactive,
+    }),
+    [open, setOpen, interactions, data, interactive],
+  );
+}
+
+/**
+ * The `Popover` component displays contextual information or actions in a floating container.
+ * It supports various configurations like placement, alignment, activation method, and options to show an arrow or close button.
+ */
+export function Popover({
+  children,
+  autoAlignment = true,
+  showCloseButton = false,
+  initialOpen = false,
+  ...options
+}: {
+  children: React.ReactNode;
+  showCloseButton?: boolean;
+} & PopoverOptions) {
+  const popover = usePopover({ ...options, initialOpen });
+
+  return (
+    <PopoverInstanceContext.Provider
+      value={{
+        ...popover,
+        showCloseButton,
+      }}
+    >
+      {children}
+    </PopoverInstanceContext.Provider>
+  );
+}
+
+// PopoverTrigger component
+export const PopoverTrigger = React.forwardRef<HTMLElement, React.HTMLProps<HTMLElement> & { asChild?: boolean; x?: number; y?: number }>(
+  function PopoverTrigger({ children, asChild = false, x = null, y = null, ...props }, propRef) {
+    const context = usePopoverInstanceContext();
+    const ref = useMergeRefs([context.data.refs.setReference, propRef]);
+
+    React.useEffect(() => {
+      if (x !== null && y !== null && context.data.refs.reference.current != null) {
+        const element = context.data.refs.reference.current as HTMLElement;
+        element.style.position = 'absolute';
+        const { x: offsetX, y: offsetY } = element.getBoundingClientRect();
+        element.getBoundingClientRect = () => {
+          return {
+            width: 0,
+            height: 0,
+            x: offsetX,
+            y: offsetY,
+            top: y + offsetY,
+            left: x + offsetX,
+            right: x + offsetX,
+            bottom: y + offsetY,
+          } as DOMRect;
+        };
+        context.data.update();
+      }
+    }, [x, y, context.data.refs.reference, context.data.update]);
+
+    // `asChild` allows the user to pass any element as the anchor
+    if (asChild && React.isValidElement(children)) {
+      return React.cloneElement(
+        children,
+        context.interactions.getReferenceProps({
+          ref,
+          ...props,
+          ...(children as any).props,
+          'data-state': context.open ? 'open' : 'closed',
+          onClick: (e: React.MouseEvent) => {
+            e.stopPropagation();
+            context.setOpen(!context.open);
+          },
+          // Accessibility attributes
+          'aria-expanded': context.open,
+          'aria-haspopup': 'dialog',
+        }),
+      );
+    }
+
+    return (
+      <div
+        ref={ref}
+        data-state={context.open ? 'open' : 'closed'}
+        {...context.interactions.getReferenceProps({
+          ...props,
+          onClick: (e: React.MouseEvent) => {
+            e.stopPropagation();
+            context.setOpen(!context.open);
+          },
+          // Accessibility attributes
+          'aria-expanded': context.open,
+          'aria-haspopup': 'dialog',
+        })}
+      >
+        {children}
+      </div>
+    );
+  },
+);
+
+// PopoverContent component
+export const PopoverContent = React.forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement>>(function PopoverContent(
+  { style, className, ...props },
+  propRef,
+) {
+  const context = usePopoverInstanceContext();
+  const ref = useMergeRefs([context.data.refs.setFloating, propRef]);
+
+  React.useEffect(() => {
+    if (context.open) {
+      context.data.update();
+    }
+  }, [context.open, context.data]);
+
+  if (!context.open) return null;
+
+  return (
+    <FloatingPortal>
+      <div
+        ref={ref}
+        className={`max-w-72 sm:max-w-lg rounded bg-light border border-secondary-200 shadow-lg animate-in fade-in-0 zoom-in-95
+            ${className ? ` ${className}` : ''}`}
+        style={{
+          ...context.data.floatingStyles,
+          ...style,
+          display: context.data.middlewareData.hide?.referenceHidden ? 'none' : 'block',
+          pointerEvents: context.interactive ? 'auto' : 'none',
+        }}
+        {...context.interactions.getFloatingProps(props)}
+      >
+        {context.showCloseButton && (
+          <Button
+            onClick={() => context.setOpen(false)}
+            variantType="secondary"
+            rounded
+            className="float-right z-10 m-1"
+            variant="ghost"
+            size="xs"
+            iconComponent="icon-[ic--baseline-close]"
+            aria-label="Close popover"
+          />
+        )}
+
+        {props.children}
+
+        {context.data.middlewareData.arrow ? (
+          <FloatingArrow ref={(context.data.refs as any).arrow} context={context.data.context} className="fill-secondary-300" />
+        ) : null}
+      </div>
+    </FloatingPortal>
+  );
+});
diff --git a/src/lib/components/popover/PopoverProvider.tsx b/src/lib/components/popover/PopoverProvider.tsx
new file mode 100644
index 000000000..b20952dd7
--- /dev/null
+++ b/src/lib/components/popover/PopoverProvider.tsx
@@ -0,0 +1,77 @@
+import React, { useState, useEffect } from 'react';
+
+interface PopoverGlobalContextProps {
+  openPopover: (id: string) => void;
+  closePopover: (id: string) => void;
+  isOpen: (id: string) => boolean;
+  isMultiselect: () => boolean;
+}
+
+const PopoverGlobalContext = React.createContext<PopoverGlobalContextProps | null>(null);
+
+// Custom hook to access the global Popover context
+export const usePopoverGlobalContext = (): PopoverGlobalContextProps | null => {
+  return React.useContext(PopoverGlobalContext);
+};
+
+// PopoverProvider component
+interface PopoverProviderProps {
+  children: React.ReactNode;
+  multiselect?: boolean;
+  multiselectKey?: 'Shift' | 'Alt' | 'Control';
+}
+
+export function PopoverProvider({ children, multiselect = false, multiselectKey = 'Shift' }: PopoverProviderProps) {
+  const [openPopoverIds, setOpenPopoverIds] = useState<Set<string>>(new Set());
+  const [isModifierPressed, setIsModifierPressed] = useState(false);
+
+  useEffect(() => {
+    const handleKeyDown = (event: KeyboardEvent) => {
+      if (event.key === multiselectKey) {
+        setIsModifierPressed(true);
+      }
+    };
+    const handleKeyUp = (event: KeyboardEvent) => {
+      if (event.key === multiselectKey) {
+        setIsModifierPressed(false);
+      }
+    };
+
+    window.addEventListener('keydown', handleKeyDown);
+    window.addEventListener('keyup', handleKeyUp);
+    return () => {
+      window.removeEventListener('keydown', handleKeyDown);
+      window.removeEventListener('keyup', handleKeyUp);
+    };
+  }, [multiselectKey]);
+
+  const openPopover = (id: string) => {
+    setOpenPopoverIds(prev => {
+      const newSet = new Set(prev);
+
+      if (multiselect && isModifierPressed) {
+        newSet.add(id); // Voeg popover toe zonder anderen te sluiten
+      } else {
+        prev.forEach(openId => newSet.delete(openId)); // Sluit alle popovers in deze provider
+        newSet.add(id);
+      }
+
+      return newSet;
+    });
+  };
+
+  const closePopover = (id: string) => {
+    setOpenPopoverIds(prev => {
+      const newSet = new Set(prev);
+      newSet.delete(id);
+      return newSet;
+    });
+  };
+
+  const isOpen = (id: string) => openPopoverIds.has(id);
+  const isMultiselect = () => multiselect;
+
+  return (
+    <PopoverGlobalContext.Provider value={{ openPopover, closePopover, isOpen, isMultiselect }}>{children}</PopoverGlobalContext.Provider>
+  );
+}
diff --git a/src/lib/components/popover/index.tsx b/src/lib/components/popover/index.tsx
new file mode 100644
index 000000000..45477db8e
--- /dev/null
+++ b/src/lib/components/popover/index.tsx
@@ -0,0 +1,2 @@
+export * from './Popover';
+export * from './PopoverProvider';
diff --git a/src/lib/components/popover/popover.stories.tsx b/src/lib/components/popover/popover.stories.tsx
new file mode 100644
index 000000000..3309a6bd1
--- /dev/null
+++ b/src/lib/components/popover/popover.stories.tsx
@@ -0,0 +1,174 @@
+// Popover.stories.tsx
+import { Meta, StoryObj } from '@storybook/react';
+import { Popover, PopoverTrigger, PopoverContent, PopoverProvider } from '@/lib';
+
+export default {
+  title: 'Components/Popover',
+  component: Popover,
+  tags: ['autodocs'],
+  decorators: [Story => <div className="p-10">{Story()}</div>],
+  argTypes: {
+    placement: {
+      control: 'inline-radio',
+      options: ['top', 'bottom', 'left', 'right'],
+      description: 'Popover placement relative to the trigger',
+    },
+    alignment: {
+      control: 'inline-radio',
+      options: [undefined, 'start', 'end'],
+      description: 'Popover alignment relative to the trigger',
+    },
+    activation: {
+      control: 'inline-radio',
+      options: ['click', 'hover', 'focus'],
+      description: 'Defines how the popover is triggered',
+    },
+    showArrow: {
+      control: 'boolean',
+      description: 'Show an arrow on the popover',
+    },
+    showCloseButton: {
+      control: 'boolean',
+      description: 'Show a close button on the popover',
+    },
+    delayOpen: {
+      control: 'number',
+      description: 'Delay (hover/focus trigger only) before the popover opens (ms)',
+    },
+    delayClose: {
+      control: 'number',
+      description: 'Delay (hover/focus trigger only) before the popover closes (ms)',
+    },
+    id: {
+      control: { disable: true },
+      description: 'Unique identifier to manage multiple popovers, can be set manually else auto-generated',
+    },
+    boundaryElement: {
+      control: { disable: true },
+      description: 'Element to which the popover is constrained',
+    },
+    autoAlignment: {
+      control: { disable: true },
+      description: 'Automatically align the popover based on the available space',
+    },
+    initialOpen: {
+      control: 'boolean',
+      description: 'Initial state of the popover',
+    },
+    children: { table: { disable: true } },
+    boundaryElement: { table: { disable: true } },
+    interactive: { table: { disable: true } },
+    delay: { table: { disable: true } },
+    onOpenChange: { table: { disable: true } },
+    open: { table: { disable: true } },
+    initialOpen: { table: { disable: true } },
+  },
+} as Meta<typeof Popover>;
+
+type Story = StoryObj<typeof Popover>;
+
+// Template Function (Independent Popovers)
+const DefaultTemplate = (args: any) => (
+  <div className="min-h-52 flex flex-col gap-1 items-center justify-center">
+    <PopoverInstance {...args} />
+  </div>
+);
+
+// PopoverInstance Component for Independent Story
+const PopoverInstance = ({ placement, alignment, activation, showArrow, delayOpen, delayClose, showCloseButton, initialOpen }: any) => (
+  <Popover
+    placement={placement}
+    activation={activation}
+    alignment={alignment}
+    showArrow={showArrow}
+    showCloseButton={showCloseButton}
+    initialOpen={initialOpen}
+    {...(activation === 'hover' && { delay: { open: delayOpen, close: delayClose } })}
+  >
+    <PopoverTrigger>
+      <button className="border px-3 py-2 hover:text-primary rounded">
+        {activation === 'click' ? 'Click me' : activation === 'hover' ? 'Hover me' : 'Focus me'}
+      </button>
+    </PopoverTrigger>
+    <PopoverContent>
+      <h3 className={'p-2 border-b border-secondary-200'}>Popover at {placement}</h3>
+      <p className="text-xs text-secondary-500 p-2">
+        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec dui id nunc lacinia eleifend. Cras vestibulum.
+      </p>
+    </PopoverContent>
+  </Popover>
+);
+
+// Default Story: Independent Popovers
+/**
+ * The `Popover` component displays contextual information or actions in a floating container.
+ * It supports configurations like placement, alignment, activation method, and options to show an arrow or close button.
+ */
+export const Default: Story = {
+  render: DefaultTemplate,
+  args: {
+    placement: 'top',
+    alignment: undefined,
+    activation: 'click',
+    showArrow: true,
+    showCloseButton: false,
+    delayOpen: 500,
+    delayClose: 150,
+    initialOpen: false,
+  },
+};
+
+// Template for Managed Story (multiselect)
+const ManagedTemplate = (args: any) => {
+  return (
+    <div>
+      <PopoverProvider multiselect>
+        <div className="min-h-52 flex flex-col gap-4 items-center justify-center">
+          <div className="flex space-x-4">
+            <PopoverInstanceManaged {...args} id="popover-1" />
+            <PopoverInstanceManaged {...args} id="popover-2" />
+          </div>
+        </div>
+      </PopoverProvider>
+    </div>
+  );
+};
+
+// Managed PopoverInstance Component
+const PopoverInstanceManaged = ({ id, placement, alignment, activation, showArrow, delayOpen, delayClose, showCloseButton }: any) => (
+  <Popover
+    id={id}
+    placement={placement}
+    activation={activation}
+    alignment={alignment}
+    showArrow={showArrow}
+    showCloseButton={showCloseButton}
+    {...(activation === 'hover' && { delay: { open: delayOpen, close: delayClose } })}
+  >
+    <PopoverTrigger>
+      <button className="border px-3 py-2 hover:text-primary rounded">{`Open Popover ${id.split('-')[1]}`}</button>
+    </PopoverTrigger>
+    <PopoverContent>
+      <h3 className={'p-2 border-b border-secondary-200'}>
+        Popover {id.split('-')[1]} at {placement}
+      </h3>
+      <p className="text-xs text-secondary-500 p-2">
+        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla nec dui id nunc lacinia eleifend. Cras vestibulum.
+      </p>
+    </PopoverContent>
+  </Popover>
+);
+
+/** Managed Popovers, a `<PopoverProvider multiselect>` will have options like hold shift to select multiple  */
+export const Managed: StoryObj<typeof Popover> = {
+  render: ManagedTemplate,
+  name: 'Managed Popovers',
+  args: {
+    placement: 'top',
+    alignment: undefined,
+    activation: 'click',
+    showArrow: true,
+    showCloseButton: false,
+    delay: { open: 500, close: 150 },
+  },
+};
diff --git a/src/lib/components/tabs/Tab.tsx b/src/lib/components/tabs/Tab.tsx
index c61d4cd1d..cd2b537ee 100644
--- a/src/lib/components/tabs/Tab.tsx
+++ b/src/lib/components/tabs/Tab.tsx
@@ -10,11 +10,14 @@ const TabContext = React.createContext<ContextType>({
   tabType: 'inline',
 });
 
-export const Tabs = forwardRef<HTMLDivElement, {
-  children: React.ReactNode;
-  tabType?: TabTypes;
-  className?: string;
-}>((props, ref) => {
+export const Tabs = forwardRef<
+  HTMLDivElement,
+  {
+    children: React.ReactNode;
+    tabType?: TabTypes;
+    className?: string;
+  }
+>((props, ref) => {
   const { children, tabType = 'inline', className = '' } = props;
   let baseClass = '';
   if (tabType === 'inline') {
@@ -26,7 +29,7 @@ export const Tabs = forwardRef<HTMLDivElement, {
   }
   const combinedClass = `${baseClass} ${className}`.trim();
   return (
-    <TabContext.Provider value={{ tabType : tabType}}>
+    <TabContext.Provider value={{ tabType: tabType }}>
       <div ref={ref} className={combinedClass}>
         {children}
       </div>
@@ -53,16 +56,14 @@ export const Tab = ({
   if (context.tabType === 'inline') {
     className += ` px-2 gap-1 relative h-full max-w-64 flex-nowrap before:content-['']
     before:absolute before:left-0 before:bottom-0 before:h-[2px] before:w-full
-    ${activeTab
+    ${
+      activeTab
         ? 'before:bg-primary-500 text-dark'
         : ' text-secondary-600 hover:text-dark hover:bg-secondary-200 hover:bg-opacity-50 before:bg-transparent hover:before:bg-secondary-300'
     }`;
   } else if (context.tabType === 'rounded') {
     className += ` py-1.5 px-3 -mb-px text-sm flex-nowrap text-center border border-secondary-200 rounded-t
-    ${activeTab
-        ? 'active z-[2] text-dark bg-light'
-        : 'bg-secondary-100 hover:text-dark border-secondary-100 text-secondary-600'
-    }`;
+    ${activeTab ? 'active z-[2] text-dark bg-light' : 'bg-secondary-100 hover:text-dark border-secondary-100 text-secondary-600'}`;
   } else if (context.tabType === 'simple') {
     className += ` px-2 py-1 gap-1 ${activeTab ? 'active text-dark' : 'text-secondary-500 hover:text-dark'}`;
   }
diff --git a/src/lib/components/tooltip/Overview.mdx b/src/lib/components/tooltip/Overview.mdx
index 369f13159..b64d3ff58 100644
--- a/src/lib/components/tooltip/Overview.mdx
+++ b/src/lib/components/tooltip/Overview.mdx
@@ -1,36 +1,85 @@
 import { Canvas, Meta, Story } from '@storybook/blocks';
-
 import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from './index';
 
 <Meta title="Components/Tooltip" component={Tooltip} />
 
 ## Usage
 
-<div>
-  <TooltipProvider delayDuration={0}>
-    <div className="flex justify-center items-center py-16">
-      <Tooltip>
-        <TooltipTrigger>
-          <div className="mx-auto">Hover over me</div>
-        </TooltipTrigger>
-        <TooltipContent side={'bottom'}>
-          <p>This is a tooltip</p>
-        </TooltipContent>
-      </Tooltip>
-    </div>
-  </TooltipProvider>
+### ✨ Single Tooltip (With Delay)
+
+The **Tooltip** component provides contextual information when users hover over an element. It supports the following options:
+
+- **`placement`**: Position of the tooltip (`top`, `bottom`, `left`, `right`).
+- **`showArrow`**: Whether to display an arrow pointing to the trigger.
+- **`interactive`**: Allows interaction with the tooltip content.
+- **`delay`**: Controls the tooltip's open/close delay (in milliseconds).
+- **`boundaryElement`**: Prevents clipping by specifying a boundary element.
+
+This example shows a **single Tooltip** with a custom delay.
+  <div className="flex flex-row gap-2">
+    <Tooltip delay={{ open: 500, close: 100 }}>
+      <TooltipTrigger>
+        <div className="border px-3 py-2 hover:text-primary rounded">Hover over me</div>
+      </TooltipTrigger>
+      <TooltipContent side="bottom">
+        <p>This is a tooltip</p>
+      </TooltipContent>
+    </Tooltip>
+  </div>
+
+```jsx
+<Tooltip delay={{ open: 500, close: 100 }}>
+  <TooltipTrigger>
+    <div className="border px-3 py-2 hover:text-primary rounded">Hover over me</div>
+  </TooltipTrigger>
+  <TooltipContent side={"bottom"}>
+    <p>This is a tooltip</p>
+  </TooltipContent>
+</Tooltip>
+```
+
+### ✨ Multiple Tooltips (with group delay)
+For grouped tooltips, use **`TooltipProvider`** to apply a shared delay across multiple tooltips.
+
+This example shows **multiple Tooltips** with a group delay.
+<div className="flex flex-row gap-2">
+<TooltipProvider delay={{ open: 500, close: 100 }}>
+  <Tooltip>
+    <TooltipTrigger>
+      <div className="border px-3 py-2 hover:text-primary rounded">Hover over me</div>
+    </TooltipTrigger>
+    <TooltipContent side="bottom">
+      <p>This is a tooltip</p>
+    </TooltipContent>
+  </Tooltip>
+  <Tooltip>
+    <TooltipTrigger>
+      <div className="border px-3 py-2 hover:text-primary rounded">Hover over me</div>
+    </TooltipTrigger>
+    <TooltipContent side="bottom">
+      <p>This is a tooltip</p>
+    </TooltipContent>
+  </Tooltip>
+</TooltipProvider>
 </div>
 
 ```jsx
-    <div className="flex justify-center items-center py-16">
-      <Tooltip>
-        <TooltipTrigger>
-          <div className="mx-auto">Hover over me</div>
-        </TooltipTrigger>
-        <TooltipContent side={"bottom"}>
-          <p>This is a tooltip</p>
-        </TooltipContent>
-      </Tooltip>
-    </div>
-  </TooltipProvider>
+<TooltipProvider delay={{ open: 500, close: 100 }}>
+  <Tooltip>
+    <TooltipTrigger>
+      <div className="border px-3 py-2 hover:text-primary rounded">Hover over me</div>
+    </TooltipTrigger>
+    <TooltipContent side={"bottom"}>
+      <p>This is a tooltip</p>
+    </TooltipContent>
+  </Tooltip>
+  <Tooltip>
+    <TooltipTrigger>
+      <div className="border px-3 py-2 hover:text-primary rounded">Hover over me</div>
+    </TooltipTrigger>
+    <TooltipContent side={"bottom"}>
+      <p>This is a tooltip</p>
+    </TooltipContent>
+  </Tooltip>
+</TooltipProvider>
 ```
diff --git a/src/lib/components/tooltip/Tooltip.tsx b/src/lib/components/tooltip/Tooltip.tsx
index 2a2287989..6c512a6d0 100644
--- a/src/lib/components/tooltip/Tooltip.tsx
+++ b/src/lib/components/tooltip/Tooltip.tsx
@@ -17,7 +17,7 @@ import {
   FloatingArrow,
 } from '@floating-ui/react';
 import type { Placement } from '@floating-ui/react';
-import { FloatingDelayGroup } from '@floating-ui/react';
+import { useDelayGroup, FloatingDelayGroup } from '@floating-ui/react';
 
 interface TooltipOptions {
   initialOpen?: boolean;
@@ -27,6 +27,7 @@ interface TooltipOptions {
   boundaryElement?: React.RefObject<HTMLElement> | HTMLElement | null | React.RefObject<HTMLDivElement | null>;
   showArrow?: boolean;
   interactive?: boolean;
+  delay?: number | { open?: number; close?: number };
 }
 
 export function useTooltip({
@@ -37,6 +38,7 @@ export function useTooltip({
   boundaryElement = null,
   showArrow = false,
   interactive = true,
+  delay,
 }: TooltipOptions = {}): {
   open: boolean;
   setOpen: (open: boolean) => void;
@@ -50,45 +52,58 @@ export function useTooltip({
   const setOpen = setControlledOpen ?? setUncontrolledOpen;
   const arrowRef = React.useRef<SVGSVGElement | null>(null);
 
-  const config = {
-    placement,
-    open,
-    onOpenChange: setOpen,
-    whileElementsMounted: autoUpdate,
-    middleware: [
-      offset(5),
-      flip({
-        crossAxis: placement.includes('-'),
-        fallbackAxisSideDirection: 'start',
-        padding: 5,
-      }),
-      shift({ padding: 5 }),
-    ],
-  };
-
-  if (boundaryElement != null) {
-    const boundary = boundaryElement instanceof HTMLElement ? (boundaryElement ?? undefined) : (boundaryElement?.current ?? undefined);
-    config.middleware.find(x => x.name == 'flip')!.options[0].boundary = boundary;
-    config.middleware.find(x => x.name == 'shift')!.options[0].boundary = boundary;
-    config.middleware.push(hide({ boundary }));
+  const middleware = [
+    offset(5),
+    flip({
+      crossAxis: placement.includes('-'),
+      fallbackAxisSideDirection: 'start',
+      padding: 5,
+    }),
+    shift({ padding: 5 }),
+  ];
+
+  if (boundaryElement) {
+    const boundary = boundaryElement instanceof HTMLElement ? boundaryElement : (boundaryElement?.current ?? undefined);
+
+    if (boundary) {
+      const flipMiddleware = middleware.find(m => m.name === 'flip');
+      const shiftMiddleware = middleware.find(m => m.name === 'shift');
+
+      if (flipMiddleware) {
+        (flipMiddleware as any).options.boundary = boundary;
+      }
+      if (shiftMiddleware) {
+        (shiftMiddleware as any).options.boundary = boundary;
+      }
+      middleware.push(hide({ boundary }));
+    }
   }
 
   if (showArrow) {
-    config.middleware.push(arrow({ element: arrowRef }));
+    middleware.push(arrow({ element: arrowRef }));
   }
 
-  const data = useFloating(config);
+  const data = useFloating({
+    placement,
+    open,
+    onOpenChange: setOpen,
+    whileElementsMounted: autoUpdate,
+    middleware,
+  });
+
   (data.refs as any).arrow = arrowRef;
 
   const context = data.context;
 
+  const { delay: groupDelay } = useDelayGroup(context);
+
   const hover = useHover(context, {
     move: false,
     enabled: controlledOpen == null,
+    delay: delay ?? groupDelay ?? undefined,
   });
-  const focus = useFocus(context, {
-    enabled: controlledOpen == null,
-  });
+
+  const focus = useFocus(context, { enabled: controlledOpen == null });
   const dismiss = useDismiss(context);
   const role = useRole(context, { role: 'tooltip' });
 
@@ -98,9 +113,9 @@ export function useTooltip({
     () => ({
       open,
       setOpen,
-      interactions: interactions,
-      data: data,
-      interactive: interactive,
+      interactions,
+      data,
+      interactive,
     }),
     [open, setOpen, interactions, data, interactive],
   );
@@ -131,15 +146,7 @@ export function Tooltip({ children, ...options }: { children: React.ReactNode }
 export const TooltipTrigger = React.forwardRef<HTMLElement, React.HTMLProps<HTMLElement> & { asChild?: boolean; x?: number; y?: number }>(
   function TooltipTrigger({ children, asChild = false, x = null, y = null, ...props }, propRef) {
     const context = useTooltipContext();
-    const childrenRef = React.useMemo(() => {
-      if (children == null) {
-        return null;
-      } else {
-        return (children as any).ref;
-      }
-    }, [children]);
-
-    const ref = useMergeRefs([context.data.refs.setReference, propRef, childrenRef]);
+    const ref = useMergeRefs([context.data.refs.setReference, propRef]);
 
     React.useEffect(() => {
       if (x && y && context.data.refs.reference.current != null) {
@@ -203,8 +210,8 @@ export const TooltipContent = React.forwardRef<
     <FloatingPortal>
       <div
         ref={ref}
-        className={`max-w-64 rounded bg-light px-2 py-2 shadow text-xs border border-secondary-200
-          text-dark animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0
+        className={`max-w-64 rounded bg-secondary-900 px-2 py-1 shadow text-xs
+          text-secondary-100 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0
           data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2
           data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2${className ? ` ${className}` : ''}`}
         style={{
@@ -217,13 +224,19 @@ export const TooltipContent = React.forwardRef<
       >
         {props.children}
         {context.data.middlewareData.arrow ? (
-          <FloatingArrow ref={(context.data.refs as any).arrow} context={context.data.context} style={{ fill: 'white' }} />
+          <FloatingArrow ref={(context.data.refs as any).arrow} context={context.data.context} className={'fill-secondary-900'} />
         ) : null}
       </div>
     </FloatingPortal>
   );
 });
 
-export const TooltipProvider = (props: { delayDuration: number; children: React.ReactNode }) => {
-  return <FloatingDelayGroup delay={props.delayDuration}>{props.children}</FloatingDelayGroup>;
+export const TooltipProvider = ({
+  delay = { open: 500, close: 100 },
+  children,
+}: {
+  delay?: number | { open?: number; close?: number };
+  children: React.ReactNode;
+}) => {
+  return <FloatingDelayGroup delay={delay}>{children}</FloatingDelayGroup>;
 };
diff --git a/src/lib/components/tooltip/index.tsx b/src/lib/components/tooltip/index.tsx
index 0e13947ed..7594a8f06 100644
--- a/src/lib/components/tooltip/index.tsx
+++ b/src/lib/components/tooltip/index.tsx
@@ -1,22 +1 @@
-// https://www.radix-ui.com/primitives/docs/components/tooltip
-
 export * from './Tooltip';
-
-/*
-export interface BarTooltipProps {
-  x: number;
-  y: number;
-  children: React.ReactNode;
-}
-
-export const BarPlotTooltip = ({ x, y, children }: BarTooltipProps) => {
-  return (
-    <div
-      className="absolute bg-light border border-secondary text-secondary p-2 pointer-events-none"
-      style={{ left: `${x}px`, top: `${y}px` }}
-    >
-      {children}
-    </div>
-  );
-};
-*/
diff --git a/src/lib/components/tooltip/tooltip.stories.tsx b/src/lib/components/tooltip/tooltip.stories.tsx
index 5c6822de2..046981d4e 100644
--- a/src/lib/components/tooltip/tooltip.stories.tsx
+++ b/src/lib/components/tooltip/tooltip.stories.tsx
@@ -1,20 +1,87 @@
-import React from 'react';
-import { Meta } from '@storybook/react';
-import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from './index';
+import { Meta, StoryObj } from '@storybook/react';
+import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from '@/lib';
 
 export default {
   title: 'Components/Tooltip',
   component: Tooltip,
-  decorators: [Story => <div className="m-5">{Story()}</div>],
+  decorators: [
+    Story => (
+      <div className="p-10">
+        <Story />
+      </div>
+    ),
+  ],
+
+  argTypes: {
+    placement: {
+      control: 'inline-radio',
+      options: ['top', 'bottom', 'left', 'right'],
+      description: 'Tooltip placement relative to the trigger',
+    },
+    groupDelay: {
+      control: 'boolean',
+      description: 'Wrap the tooltip in a TooltipProvider to apply group delay',
+    },
+    delayOpen: {
+      control: 'number',
+      description: 'Delay before the tooltip opens (ms)',
+    },
+    delayClose: {
+      control: 'number',
+      description: 'Delay before the tooltip closes (ms)',
+    },
+    showArrow: {
+      control: 'boolean',
+      description: 'Show an arrow on the tooltip',
+    },
+
+    children: { table: { disable: true } },
+    boundaryElement: { table: { disable: true } },
+    interactive: { table: { disable: true } },
+    delay: { table: { disable: true } },
+    onOpenChange: { table: { disable: true } },
+    open: { table: { disable: true } },
+    initialOpen: { table: { disable: true } },
+  },
 } as Meta;
 
-export const Default = () => (
-  <TooltipProvider delayDuration={0}>
-    <Tooltip>
-      <TooltipTrigger>
-        <button>Hover me</button>
-      </TooltipTrigger>
-      <TooltipContent>Tooltip content</TooltipContent>
-    </Tooltip>
-  </TooltipProvider>
+const Template = (args: any) => {
+  return (
+    <div className="p-10 flex flex-col gap-1 items-center justify-center">
+      {/* ✅ Conditionally wrap in TooltipProvider */}
+      {args.groupDelay ? (
+        <TooltipProvider delay={{ open: args.delayOpen, close: args.delayClose }}>
+          <TooltipInstance {...args} />
+          <TooltipInstance {...args} />
+          <TooltipInstance {...args} />
+        </TooltipProvider>
+      ) : (
+        <TooltipInstance {...args} />
+      )}
+    </div>
+  );
+};
+
+const TooltipInstance = ({ placement, showArrow, delayOpen, delayClose, groupDelay }: any) => (
+  <Tooltip
+    placement={placement}
+    showArrow={showArrow}
+    {...(!groupDelay && { delay: { open: delayOpen, close: delayClose } })} // ✅ Remove delay if groupDelay is true
+  >
+    <TooltipTrigger>
+      <button className="border px-3 py-2 hover:text-primary rounded">Hover me</button>
+    </TooltipTrigger>
+    <TooltipContent>Tooltip at {placement}</TooltipContent>
+  </Tooltip>
 );
+
+export const Default: StoryObj = {
+  render: Template,
+  args: {
+    placement: 'top',
+    showArrow: false,
+    delayOpen: 500,
+    delayClose: 150,
+    groupDelay: false,
+  },
+};
diff --git a/src/lib/data-access/store/visualizationSlice.ts b/src/lib/data-access/store/visualizationSlice.ts
index 9a1fa4eb0..ed1138497 100644
--- a/src/lib/data-access/store/visualizationSlice.ts
+++ b/src/lib/data-access/store/visualizationSlice.ts
@@ -15,13 +15,12 @@ export const initialState: VisState = {
   openVisualizationArray: [],
 };
 function generateUUID(): string {
-  if (typeof crypto?.randomUUID === "function") {
+  if (typeof crypto?.randomUUID === 'function') {
     return crypto.randomUUID();
   }
   return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
 }
 
-
 export const visualizationSlice = createSlice({
   name: 'visualization',
   initialState,
@@ -51,12 +50,10 @@ export const visualizationSlice = createSlice({
     setVisualizationState: (state, action: PayloadAction<VisState>) => {
       if (action.payload.activeVisualizationIndex !== undefined && !isEqual(action.payload, state)) {
         state.openVisualizationArray = (action.payload.openVisualizationArray || []).map(item => ({
-          ...item, uuid: item.uuid || generateUUID(),
+          ...item,
+          uuid: item.uuid || generateUUID(),
         }));
-        state.activeVisualizationIndex = Math.min(
-          action.payload.activeVisualizationIndex,
-          state.openVisualizationArray.length - 1
-        );
+        state.activeVisualizationIndex = Math.min(action.payload.activeVisualizationIndex, state.openVisualizationArray.length - 1);
       }
     },
     updateVisualization: (state, action: PayloadAction<{ id: number; settings: VisualizationSettingsType }>) => {
diff --git a/src/lib/management/database/Databases.tsx b/src/lib/management/database/Databases.tsx
index 2c9c94e4f..0e01b3a32 100644
--- a/src/lib/management/database/Databases.tsx
+++ b/src/lib/management/database/Databases.tsx
@@ -13,7 +13,7 @@ import {
 } from '../..';
 import { clearQB, deleteSaveState, selectSaveState } from '../../data-access/store/sessionSlice';
 import { clearSchema } from '../../data-access/store/schemaSlice';
-import { Popover, PopoverContent, PopoverTrigger } from '../../components/layout/Popover';
+import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
 import { useHandleDatabase } from './useHandleDatabase';
 import { SaveState } from 'ts-common';
 
@@ -272,7 +272,7 @@ export function Databases({ onClose, saveStates, changeActive, setSelectedSaveSt
                   <PopoverTrigger>
                     <Button iconComponent="icon-[mi--options-vertical]" variant="ghost" />
                   </PopoverTrigger>
-                  <PopoverContent className="w-56 z-50 bg-light rounded-sm border-[1px] outline-none">
+                  <PopoverContent className="p-1 min-w-24">
                     <DropdownItem
                       value="Open"
                       onClick={() => {
diff --git a/src/lib/querybuilder/panel/ManualQueryDialog.tsx b/src/lib/querybuilder/panel/ManualQueryDialog.tsx
index 0b0c16ef5..8467e08f0 100644
--- a/src/lib/querybuilder/panel/ManualQueryDialog.tsx
+++ b/src/lib/querybuilder/panel/ManualQueryDialog.tsx
@@ -16,7 +16,7 @@ export const ManualQueryDialog = ({ onSubmit }: ManualQueryDialogProps) => {
   };
 
   return (
-    <div className="flex flex-col w-full gap-2 px-4 py-2">
+    <div className="flex flex-col w-full gap-2 p-2">
       <label className="text-xs font-bold">Manual Query</label>
       <textarea
         value={query}
diff --git a/src/lib/querybuilder/panel/QueryBuilder.tsx b/src/lib/querybuilder/panel/QueryBuilder.tsx
index 0a806685e..8867c776b 100644
--- a/src/lib/querybuilder/panel/QueryBuilder.tsx
+++ b/src/lib/querybuilder/panel/QueryBuilder.tsx
@@ -38,7 +38,7 @@ import { ConnectingNodeDataI } from './utils/connectorDrop';
 import { QueryBuilderDispatcherContext } from './QueryBuilderDispatcher';
 import { QueryBuilderNav, QueryBuilderToggleSettings } from './QueryBuilderNav';
 import html2canvas from 'html2canvas';
-import { ContextMenu } from './ContextMenu';
+import { QueryBuilderContextMenu } from './QueryBuilderContextMenu';
 import { QueryElementTypes, AllLogicMap, isLogicHandle, defaultGraph } from 'ts-common';
 import { setQuerybuilderGraphology, toQuerybuilderGraphology } from '@/lib/data-access/store/sessionSlice';
 
@@ -550,7 +550,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => {
         },
       }}
     >
-      <ContextMenu
+      <QueryBuilderContextMenu
         open={contextMenuOpen.open}
         node={contextMenuOpen.node}
         position={contextMenuOpen.position}
diff --git a/src/lib/querybuilder/panel/ContextMenu.tsx b/src/lib/querybuilder/panel/QueryBuilderContextMenu.tsx
similarity index 93%
rename from src/lib/querybuilder/panel/ContextMenu.tsx
rename to src/lib/querybuilder/panel/QueryBuilderContextMenu.tsx
index 27df0fb08..5af7cc5df 100644
--- a/src/lib/querybuilder/panel/ContextMenu.tsx
+++ b/src/lib/querybuilder/panel/QueryBuilderContextMenu.tsx
@@ -1,5 +1,5 @@
 import { useMemo, useState } from 'react';
-import { Tooltip, TooltipTrigger, TooltipContent, DropdownItem, Icon, Input } from '../../components';
+import { Popover, PopoverTrigger, PopoverContent, DropdownItem, Input, Icon } from '@/lib/components';
 import { ReactFlowInstance, Node } from 'reactflow';
 import { useActiveQuery, useActiveSaveState, useAppDispatch, useQuerybuilderHash } from '../..';
 import { isEqual } from 'lodash-es';
@@ -12,7 +12,7 @@ import {
   toQuerybuilderGraphology,
 } from '@/lib/data-access/store/sessionSlice';
 
-export const ContextMenu = (props: {
+export const QueryBuilderContextMenu = (props: {
   open: boolean;
   position?: { x: number; y: number };
   node?: Node;
@@ -83,9 +83,9 @@ export const ContextMenu = (props: {
   }
 
   return (
-    <Tooltip open={props.open && state !== undefined} interactive={true} showArrow={false} placement="bottom-start">
-      <TooltipTrigger x={state ? state.x : 0} y={state ? state.y : 0} />
-      <TooltipContent>
+    <Popover open={props.open && state !== undefined} interactive={true} showArrow={false} placement="bottom-start">
+      <PopoverTrigger x={state ? state.x : 0} y={state ? state.y : 0} />
+      <PopoverContent>
         {props.node && props?.node.type !== 'logic' && (
           <>
             <DropdownItem
@@ -133,7 +133,7 @@ export const ContextMenu = (props: {
           </>
         )}
         <DropdownItem value="Remove" className="text-danger" onClick={e => removeNode()} />
-      </TooltipContent>
-    </Tooltip>
+      </PopoverContent>
+    </Popover>
   );
 };
diff --git a/src/lib/querybuilder/panel/QueryBuilderNav.tsx b/src/lib/querybuilder/panel/QueryBuilderNav.tsx
index f0be3bff9..ae7c9afab 100644
--- a/src/lib/querybuilder/panel/QueryBuilderNav.tsx
+++ b/src/lib/querybuilder/panel/QueryBuilderNav.tsx
@@ -1,6 +1,6 @@
 import { useMemo, useState } from 'react';
 import { ControlContainer, TooltipProvider, Tooltip, TooltipTrigger, Button, TooltipContent, Input } from '../../components';
-import { Popover, PopoverTrigger, PopoverContent } from '../../components/layout/Popover';
+import { Popover, PopoverTrigger, PopoverContent } from '@/lib/components/popover';
 import {
   useActiveQuery,
   useActiveSaveState,
@@ -188,7 +188,7 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
       </Tabs>
       <div className="sticky right-0 px-0.5 ml-auto items-center flex truncate">
         <ControlContainer>
-          <TooltipProvider delayDuration={0}>
+          <TooltipProvider>
             <Tooltip>
               <TooltipTrigger>
                 <Button
@@ -291,11 +291,10 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                   <TooltipTrigger>
                     <Button
                       variantType={mlEnabled ? 'primary' : 'secondary'}
-                      variant="ghost"
+                      variant={mlEnabled ? 'outline' : 'ghost'}
                       size="xs"
                       disabled={!saveStateAuthorization.query.W}
                       iconComponent="icon-[ic--baseline-lightbulb]"
-                      className={mlEnabled ? 'border-primary-600' : ''}
                     />
                   </TooltipTrigger>
                   <TooltipContent disabled={props.toggleSettings === 'ml'}>
@@ -349,45 +348,42 @@ export const QueryBuilderNav = (props: QueryBuilderNavProps) => {
                 <QueryMLDialog />
               </PopoverContent>
             </Popover>
-            <Popover>
+            <Popover placement="bottom">
               <PopoverTrigger>
                 <Tooltip>
                   <TooltipTrigger>
                     <Button
                       variantType={activeQuery.settings.limit <= resultSize ? 'primary' : 'secondary'}
-                      variant="ghost"
+                      variant={activeQuery.settings.limit <= resultSize ? 'outline' : 'ghost'}
                       size="xs"
                       disabled={!saveStateAuthorization.query.W}
                       iconComponent="icon-[ic--baseline-filter-alt]"
-                      className={activeQuery.settings.limit <= resultSize ? 'border-primary-600' : ''}
                     />
                   </TooltipTrigger>
                   <TooltipContent disabled={props.toggleSettings === 'ml'}>
                     <p className="font-bold text-base">Limit</p>
                     <p>Limits the number of edges retrieved from the database.</p>
                     <p>Required to manage performance.</p>
-                    <p className={`font-semibold${activeQuery.settings.limit <= resultSize ? ' text-primary-800' : ''}`}>
+                    <p className={`font-semibold${activeQuery.settings.limit <= resultSize ? ' text-primary-200' : ''}`}>
                       Fetched {resultSize} of a maximum of {activeQuery.settings.limit} edges
                     </p>
                   </TooltipContent>
                 </Tooltip>
               </PopoverTrigger>
               <PopoverContent>
-                <div className="flex flex-col w-full gap-2 px-4 py-2">
-                  <span className="text-xs font-bold">Limit</span>
-                  <Input
-                    type="number"
-                    size="xs"
-                    value={activeQuery.settings.limit}
-                    lazy
-                    label=""
-                    onChange={e => {
-                      dispatch(setQuerybuilderSettings({ ...activeQuery.settings, limit: Number(e) }));
-                    }}
-                    className={`w-24${activeQuery.settings.limit <= resultSize ? ' border-danger-600' : ''}`}
-                    containerClassName=""
-                  />
-                </div>
+                <Input
+                  type="number"
+                  size="sm"
+                  label="Limit"
+                  value={activeQuery.settings.limit}
+                  lazy
+                  label=""
+                  onChange={e => {
+                    dispatch(setQuerybuilderSettings({ ...activeQuery.settings, limit: Number(e) }));
+                  }}
+                  className={`w-24${activeQuery.settings.limit <= resultSize ? ' border-danger-600' : ''}`}
+                  containerClassName="p-2"
+                />
               </PopoverContent>
             </Popover>
             <Popover>
diff --git a/src/lib/querybuilder/panel/querysidepanel/QueryBuilderLogicPillsPanel.tsx b/src/lib/querybuilder/panel/querysidepanel/QueryBuilderLogicPillsPanel.tsx
index a94f560e6..746313ca8 100644
--- a/src/lib/querybuilder/panel/querysidepanel/QueryBuilderLogicPillsPanel.tsx
+++ b/src/lib/querybuilder/panel/querysidepanel/QueryBuilderLogicPillsPanel.tsx
@@ -171,7 +171,7 @@ export const QueryBuilderLogicPillsPanel = (props: {
     <div className={props.className + ' card'}>
       {props.title && <h1 className="card-title mb-2 mx-auto">{props.title}</h1>}
       <div className="gap-1 flex justify-center">
-        <TooltipProvider delayDuration={50}>
+        <TooltipProvider delay={50}>
           {dataOps.map((item, index) => (
             <Tooltip key={'QB_Type_' + item.title}>
               <TooltipContent>{item.description}</TooltipContent>
@@ -212,7 +212,7 @@ export const QueryBuilderLogicPillsPanel = (props: {
         </TooltipProvider>
       </div>
       <div className="mt-1 overflow-x-hidden h-[80vh]">
-        <TooltipProvider delayDuration={50}>
+        <TooltipProvider delay={50}>
           <ul className="pb-10 gap-1 flex flex-col w-full h-full">
             {AllLogicMapAvailable.map((item, index) => (
               <Tooltip key={'QB_Options_' + index}>
diff --git a/src/lib/querybuilder/panel/querysidepanel/QueryMLDialog.tsx b/src/lib/querybuilder/panel/querysidepanel/QueryMLDialog.tsx
index aebf595a5..c82f1dc26 100644
--- a/src/lib/querybuilder/panel/querysidepanel/QueryMLDialog.tsx
+++ b/src/lib/querybuilder/panel/querysidepanel/QueryMLDialog.tsx
@@ -6,7 +6,7 @@ import {
   setLinkPredictionEnabled,
   setShortestPathEnabled,
 } from '@/lib/data-access/store/mlSlice';
-import { FormCard, FormBody, FormTitle, FormHBar } from '@/lib/components/forms';
+import { FormBody, FormTitle } from '@/lib/components/forms';
 import { Input } from '@/lib/components/inputs';
 import { FeatureEnabled } from '@/lib/components/featureFlags';
 
@@ -15,73 +15,81 @@ export const QueryMLDialog = () => {
   const ml = useML();
 
   return (
-    <div>
-      <FormCard>
-        <FormBody
-          onSubmit={e => {
-            e.preventDefault();
-          }}
-        >
-          <FormTitle title="Machine Learning Options" />
-          <FormHBar />
+    <FormBody
+      onSubmit={e => {
+        e.preventDefault();
+      }}
+      className="divide-y divide-secondary-200"
+    >
+      <FormTitle title="Machine Learning Options" className="p-1 text-sm" />
 
-          <div className="px-5">
-            <FeatureEnabled featureFlag="LINK_PREDICTION">
-              <Input
-                type="boolean"
-                label="Link Prediction"
-                value={ml.linkPrediction.enabled}
-                onChange={() => dispatch(setLinkPredictionEnabled(!ml.linkPrediction.enabled))}
-              />
-              {ml.linkPrediction.enabled && ml.linkPrediction.result && <span># of predictions: {ml.linkPrediction.result.length}</span>}
-              {ml.linkPrediction.enabled && !ml.linkPrediction.result && <span>Loading...</span>}
-            </FeatureEnabled>
+      <div className="flex flex-col p-1 text-sm divide-y divider-secondary-200">
+        <FeatureEnabled featureFlag="LINK_PREDICTION">
+          <div className="p-1">
+            <Input
+              size="sm"
+              type="boolean"
+              label="Link Prediction"
+              value={ml.linkPrediction.enabled}
+              onChange={() => dispatch(setLinkPredictionEnabled(!ml.linkPrediction.enabled))}
+            />
+            {ml.linkPrediction.enabled && ml.linkPrediction.result && <span># of predictions: {ml.linkPrediction.result.length}</span>}
+            {ml.linkPrediction.enabled && !ml.linkPrediction.result && <span>Loading...</span>}
+          </div>
+        </FeatureEnabled>
 
-            <FeatureEnabled featureFlag="CENTRALITY">
-              <Input
-                type="boolean"
-                label="Centrality"
-                value={ml.centrality.enabled}
-                onChange={() => dispatch(setCentralityEnabled(!ml.centrality.enabled))}
-              />
-              {ml.centrality.enabled && Object.values(ml.centrality.result).length > 0 && (
-                <span>
-                  sum of centers:
-                  {Object.values(ml.centrality.result)
-                    .reduce((a, b) => b + a)
-                    .toFixed(2)}
-                </span>
-              )}
-              {ml.centrality.enabled && Object.values(ml.centrality.result).length === 0 && <span>No Centers Found</span>}
-            </FeatureEnabled>
+        <FeatureEnabled featureFlag="CENTRALITY">
+          <div className="p-1">
+            <Input
+              size="sm"
+              type="boolean"
+              label="Centrality"
+              value={ml.centrality.enabled}
+              onChange={() => dispatch(setCentralityEnabled(!ml.centrality.enabled))}
+            />
+            {ml.centrality.enabled && Object.values(ml.centrality.result).length > 0 && (
+              <span>
+                sum of centers:
+                {Object.values(ml.centrality.result)
+                  .reduce((a, b) => b + a)
+                  .toFixed(2)}
+              </span>
+            )}
+            {ml.centrality.enabled && Object.values(ml.centrality.result).length === 0 && <span>No Centers Found</span>}
+          </div>
+        </FeatureEnabled>
 
-            <FeatureEnabled featureFlag="COMMUNITY_DETECTION">
-              <Input
-                type="boolean"
-                label="Community detection"
-                value={ml.communityDetection.enabled}
-                onChange={() => dispatch(setCommunityDetectionEnabled(!ml.communityDetection.enabled))}
-              />
-              {ml.communityDetection.enabled && ml.communityDetection.result && (
-                <span># of communities: {ml.communityDetection.result.length}</span>
-              )}
-              {ml.communityDetection.enabled && !ml.communityDetection.result && <span>Loading...</span>}
-            </FeatureEnabled>
+        <FeatureEnabled featureFlag="COMMUNITY_DETECTION">
+          <div className="p-1">
+            <Input
+              size="sm"
+              type="boolean"
+              label="Community detection"
+              value={ml.communityDetection.enabled}
+              onChange={() => dispatch(setCommunityDetectionEnabled(!ml.communityDetection.enabled))}
+            />
+            {ml.communityDetection.enabled && ml.communityDetection.result && (
+              <span># of communities: {ml.communityDetection.result.length}</span>
+            )}
+            {ml.communityDetection.enabled && !ml.communityDetection.result && <span>Loading...</span>}
+          </div>
+        </FeatureEnabled>
 
-            <FeatureEnabled featureFlag="SHORTEST_PATH">
-              <Input
-                type="boolean"
-                label="Shortest path"
-                value={ml.shortestPath.enabled}
-                onChange={() => dispatch(setShortestPathEnabled(!ml.shortestPath.enabled))}
-              />
-              {ml.shortestPath.enabled && ml.shortestPath.result?.length > 0 && <span># of hops: {ml.shortestPath.result.length}</span>}
-              {ml.shortestPath.enabled && !ml.shortestPath.srcNode && <span>Please select source node</span>}
-              {ml.shortestPath.enabled && ml.shortestPath.srcNode && !ml.shortestPath.trtNode && <span>Please select target node</span>}
-            </FeatureEnabled>
+        <FeatureEnabled featureFlag="SHORTEST_PATH">
+          <div className="p-1">
+            <Input
+              size="sm"
+              type="boolean"
+              label="Shortest path"
+              value={ml.shortestPath.enabled}
+              onChange={() => dispatch(setShortestPathEnabled(!ml.shortestPath.enabled))}
+            />
+            {ml.shortestPath.enabled && ml.shortestPath.result?.length > 0 && <span># of hops: {ml.shortestPath.result.length}</span>}
+            {ml.shortestPath.enabled && !ml.shortestPath.srcNode && <span>Please select source node</span>}
+            {ml.shortestPath.enabled && ml.shortestPath.srcNode && !ml.shortestPath.trtNode && <span>Please select target node</span>}
           </div>
-        </FormBody>
-      </FormCard>
-    </div>
+        </FeatureEnabled>
+      </div>
+    </FormBody>
   );
 };
diff --git a/src/lib/querybuilder/panel/querysidepanel/QuerySettings.tsx b/src/lib/querybuilder/panel/querysidepanel/QuerySettings.tsx
index c293641cf..b8c1104f2 100644
--- a/src/lib/querybuilder/panel/querysidepanel/QuerySettings.tsx
+++ b/src/lib/querybuilder/panel/querysidepanel/QuerySettings.tsx
@@ -31,9 +31,10 @@ export const QuerySettings = React.forwardRef<HTMLDivElement, object>((props, re
   }
 
   return (
-    <div className="flex flex-col w-full gap-2 px-4 py-2">
+    <div className="flex flex-col w-full gap-2 p-2">
       <span className="text-xs font-bold">Query Settings</span>
       <Input
+        size="sm"
         type="boolean"
         value={state.autocompleteRelation}
         label="Autocomplete Edges"
@@ -85,6 +86,7 @@ export const QuerySettings = React.forwardRef<HTMLDivElement, object>((props, re
       />
 
       <FormActions
+        size={'sm'}
         onApply={() => {
           submit();
         }}
diff --git a/src/lib/querybuilder/pills/pillattributes/PillAttributesItem.tsx b/src/lib/querybuilder/pills/pillattributes/PillAttributesItem.tsx
index dad095294..62ef62985 100644
--- a/src/lib/querybuilder/pills/pillattributes/PillAttributesItem.tsx
+++ b/src/lib/querybuilder/pills/pillattributes/PillAttributesItem.tsx
@@ -38,7 +38,7 @@ export const PillAttributesItem = (props: PillAttributesItemProps) => {
   }
 
   return (
-    <div className="px-2 py-1 bg-secondary-100 flex justify-between items-center">
+    <div className="px-1.5 py-1 bg-secondary-100 flex justify-between items-center">
       <p className="truncate w-[90%]">{props.attribute.handleData.attributeName}</p>
       <Button
         variantType="secondary"
diff --git a/src/lib/schema/model/reactflow.tsx b/src/lib/schema/model/reactflow.tsx
index 70649ba36..c80a44aa2 100644
--- a/src/lib/schema/model/reactflow.tsx
+++ b/src/lib/schema/model/reactflow.tsx
@@ -37,7 +37,7 @@ export type SchemaReactflowEntity = SchemaReactflowData & {
   x: number;
   y: number;
   reactFlowRef: any;
-  tooltipClose: boolean;
+  popoverClose: boolean;
 };
 
 export type SchemaReactflowRelation = SchemaReactflowData & {
@@ -49,7 +49,7 @@ export type SchemaReactflowRelation = SchemaReactflowData & {
   x: number;
   y: number;
   reactFlowRef: any;
-  tooltipClose: boolean;
+  popoverClose: boolean;
 };
 
 export type SchemaReactflowNodeWithFunctions = SchemaReactflowEntity & {
diff --git a/src/lib/schema/panel/LayoutDescription/iconsLayout/GridIcon.tsx b/src/lib/schema/panel/LayoutDescription/iconsLayout/GridIcon.tsx
index 79c5c08ec..a2c28b70b 100644
--- a/src/lib/schema/panel/LayoutDescription/iconsLayout/GridIcon.tsx
+++ b/src/lib/schema/panel/LayoutDescription/iconsLayout/GridIcon.tsx
@@ -14,22 +14,8 @@ export const GridIcon: React.FC<IconProps> = ({ className = '' }) => (
     preserveAspectRatio="xMidYMid meet"
     fill="none"
   >
-    <rect
-      fill="hsl(var(--clr-node))"
-      id="rect1-97"
-      width="7.3312178"
-      height="2.7723093"
-      x="-7.0483686e-10"
-      y="-1.7570567e-09"
-    />
-    <rect
-      fill="hsl(var(--clr-node))"
-      id="rect1-97-4"
-      width="7.3312178"
-      height="2.7723093"
-      x="-7.0483686e-10"
-      y="6.3607378"
-    />
+    <rect fill="hsl(var(--clr-node))" id="rect1-97" width="7.3312178" height="2.7723093" x="-7.0483686e-10" y="-1.7570567e-09" />
+    <rect fill="hsl(var(--clr-node))" id="rect1-97-4" width="7.3312178" height="2.7723093" x="-7.0483686e-10" y="6.3607378" />
     <rect fill="hsl(var(--clr-relation))" width="7.3312178" height="2.7723093" x="-7.0483686e-10" y="12.721476" />
     <rect fill="hsl(var(--clr-relation))" width="7.3312178" height="2.7723093" x="8.6687822" y="-1.7570567e-09" />
     <rect fill="hsl(var(--clr-relation))" width="7.3312178" height="2.7723093" x="8.6687822" y="6.3607378" />
diff --git a/src/lib/schema/panel/Schema.tsx b/src/lib/schema/panel/Schema.tsx
index 84cb4feef..320393687 100644
--- a/src/lib/schema/panel/Schema.tsx
+++ b/src/lib/schema/panel/Schema.tsx
@@ -3,9 +3,9 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
 import { useDispatch } from 'react-redux';
 import ReactFlow, { Edge, MiniMap, Node, ReactFlowInstance, ReactFlowProvider, useEdgesState, useNodesState } from 'reactflow';
 import 'reactflow/dist/style.css';
-import { Icon, Panel } from '../../components';
+import { Icon, Panel, TooltipProvider } from '../../components';
 import { Button } from '../../components/buttons';
-import { Popover, PopoverContent, PopoverTrigger } from '../../components/layout/Popover';
+import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
 import { Tooltip, TooltipContent, TooltipTrigger } from '../../components/tooltip/Tooltip';
 import { useSchema, useSchemaSettings, useSearchResultSchema } from '../../data-access';
 import { toSchemaGraphology } from '../../data-access/store/schemaSlice';
@@ -103,14 +103,14 @@ export const Schema = (props: Props) => {
       nodesWithRef = schemaFlow.nodes.map(node => {
         return {
           ...node,
-          data: { ...node.data, reactFlowRef, tooltipClose: false },
+          data: { ...node.data, reactFlowRef, popoverClose: false },
         };
       });
 
       edgesWithRef = schemaFlow.edges.map(edge => {
         return {
           ...edge,
-          data: { ...edge.data, reactFlowRef, tooltipClose: false },
+          data: { ...edge.data, reactFlowRef, popoverClose: false },
         };
       });
 
@@ -156,14 +156,14 @@ export const Schema = (props: Props) => {
       nodesWithRef = schemaFlow.nodes.map(node => {
         return {
           ...node,
-          data: { ...node.data, reactFlowRef, tooltipClose: false },
+          data: { ...node.data, reactFlowRef, popoverClose: false },
         };
       });
 
       edgesWithRef = schemaFlow.edges.map(edge => {
         return {
           ...edge,
-          data: { ...edge.data, reactFlowRef, tooltipClose: false },
+          data: { ...edge.data, reactFlowRef, popoverClose: false },
         };
       });
 
@@ -234,7 +234,7 @@ export const Schema = (props: Props) => {
         ...node,
         data: {
           ...node.data,
-          tooltipClose: clickedOutsideNode,
+          popoverClose: clickedOutsideNode,
         },
       })),
     );
@@ -244,7 +244,7 @@ export const Schema = (props: Props) => {
         ...edge,
         data: {
           ...edge.data,
-          tooltipClose: clickedOutsideNode,
+          popoverClose: clickedOutsideNode,
         },
       })),
     );
@@ -256,76 +256,78 @@ export const Schema = (props: Props) => {
       className="schema-panel"
       tooltips={
         <>
-          <Tooltip>
-            <TooltipTrigger>
-              <Button
-                variantType="secondary"
-                variant="ghost"
-                size="xs"
-                iconComponent="icon-[ic--baseline-remove]"
-                onClick={() => {
-                  if (props.onRemove) props.onRemove();
-                }}
-              />
-            </TooltipTrigger>
-            <TooltipContent>
-              <p>Hide</p>
-            </TooltipContent>
-          </Tooltip>
-          <Tooltip>
-            <TooltipTrigger>
-              <Button
-                variantType="secondary"
-                variant="ghost"
-                size="xs"
-                iconComponent="icon-[ic--baseline-content-copy]"
-                onClick={() => {
-                  // Copy the schema to the clipboard
-                  navigator.clipboard.writeText(JSON.stringify(schema.graph, null, 2));
-                }}
-              />
-            </TooltipTrigger>
-            <TooltipContent>
-              <p>Copy Schema to Clipboard</p>
-            </TooltipContent>
-          </Tooltip>
-          <Tooltip>
-            <TooltipTrigger>
-              <Button
-                variantType="secondary"
-                variant="ghost"
-                size="xs"
-                iconComponent="icon-[ic--baseline-fullscreen]"
-                onClick={() => {
-                  fitView();
-                }}
-              />
-            </TooltipTrigger>
-            <TooltipContent>
-              <p>Fit to screen</p>
-            </TooltipContent>
-          </Tooltip>
-          <Popover>
-            <PopoverTrigger>
-              <Tooltip>
-                <TooltipTrigger>
-                  <Button
-                    variantType="secondary"
-                    variant="ghost"
-                    size="xs"
-                    iconComponent="icon-[ic--baseline-settings]"
-                    className="schema-settings"
-                  />
-                </TooltipTrigger>
-                <TooltipContent>
-                  <p>Schema Settings</p>
-                </TooltipContent>
-              </Tooltip>
-            </PopoverTrigger>
-            <PopoverContent>
-              <SchemaSettings />
-            </PopoverContent>
-          </Popover>
+          <TooltipProvider>
+            <Tooltip>
+              <TooltipTrigger>
+                <Button
+                  variantType="secondary"
+                  variant="ghost"
+                  size="xs"
+                  iconComponent="icon-[ic--baseline-remove]"
+                  onClick={() => {
+                    if (props.onRemove) props.onRemove();
+                  }}
+                />
+              </TooltipTrigger>
+              <TooltipContent>
+                <p>Hide</p>
+              </TooltipContent>
+            </Tooltip>
+            <Tooltip>
+              <TooltipTrigger>
+                <Button
+                  variantType="secondary"
+                  variant="ghost"
+                  size="xs"
+                  iconComponent="icon-[ic--baseline-content-copy]"
+                  onClick={() => {
+                    // Copy the schema to the clipboard
+                    navigator.clipboard.writeText(JSON.stringify(schema.graph, null, 2));
+                  }}
+                />
+              </TooltipTrigger>
+              <TooltipContent>
+                <p>Copy Schema to Clipboard</p>
+              </TooltipContent>
+            </Tooltip>
+            <Tooltip>
+              <TooltipTrigger>
+                <Button
+                  variantType="secondary"
+                  variant="ghost"
+                  size="xs"
+                  iconComponent="icon-[ic--baseline-fullscreen]"
+                  onClick={() => {
+                    fitView();
+                  }}
+                />
+              </TooltipTrigger>
+              <TooltipContent>
+                <p>Fit to screen</p>
+              </TooltipContent>
+            </Tooltip>
+            <Popover>
+              <PopoverTrigger>
+                <Tooltip>
+                  <TooltipTrigger>
+                    <Button
+                      variantType="secondary"
+                      variant="ghost"
+                      size="xs"
+                      iconComponent="icon-[ic--baseline-settings]"
+                      className="schema-settings"
+                    />
+                  </TooltipTrigger>
+                  <TooltipContent>
+                    <p>Schema Settings</p>
+                  </TooltipContent>
+                </Tooltip>
+              </PopoverTrigger>
+              <PopoverContent>
+                <SchemaSettings />
+              </PopoverContent>
+            </Popover>
+          </TooltipProvider>
         </>
       }
     >
diff --git a/src/lib/schema/panel/SchemaList.tsx b/src/lib/schema/panel/SchemaList.tsx
index 7db15c954..8b3762e35 100644
--- a/src/lib/schema/panel/SchemaList.tsx
+++ b/src/lib/schema/panel/SchemaList.tsx
@@ -14,9 +14,10 @@ import { AlgorithmToLayoutProvider, AllLayoutAlgorithms, LayoutFactory } from '.
 import { ConnectionLine, ConnectionDragLine } from '../../querybuilder';
 import { schemaExpandRelation, schemaGraphology2Reactflow } from '../schema-utils';
 import { Panel } from '../../components';
-import { Tooltip, TooltipContent, TooltipTrigger } from '../../components/tooltip/Tooltip';
+import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/components/tooltip';
+import { resultSetFocus } from '../../data-access/store/interactionSlice';
 import { useDispatch } from 'react-redux';
-import { Popover, PopoverContent, PopoverTrigger } from '../../components/layout/Popover';
+import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
 
 interface Props {
   content?: string;
@@ -102,14 +103,14 @@ export const Schema = (props: Props) => {
       nodesWithRef = schemaFlow.nodes.map(node => {
         return {
           ...node,
-          data: { ...node.data, reactFlowRef, tooltipClose: false },
+          data: { ...node.data, reactFlowRef, popoverClose: false },
         };
       });
 
       edgesWithRef = schemaFlow.edges.map(edge => {
         return {
           ...edge,
-          data: { ...edge.data, reactFlowRef, tooltipClose: false },
+          data: { ...edge.data, reactFlowRef, popoverClose: false },
         };
       });
 
@@ -168,7 +169,7 @@ export const Schema = (props: Props) => {
         ...node,
         data: {
           ...node.data,
-          tooltipClose: clickedOutsideNode,
+          popoverClose: clickedOutsideNode,
         },
       })),
     );
@@ -178,7 +179,7 @@ export const Schema = (props: Props) => {
         ...edge,
         data: {
           ...edge.data,
-          tooltipClose: clickedOutsideNode,
+          popoverClose: clickedOutsideNode,
         },
       })),
     );
@@ -277,6 +278,7 @@ export const Schema = (props: Props) => {
               connectionLineComponent={ConnectionDragLine}
               onNodesChange={onNodesChange}
               onEdgesChange={onEdgesChange}
+              onMouseDownCapture={() => dispatch(resultSetFocus({ focusType: 'schema' }))}
               nodes={nodes}
               edges={edges}
               onInit={reactFlowInstance => {
diff --git a/src/lib/schema/panel/SchemaSettings.tsx b/src/lib/schema/panel/SchemaSettings.tsx
index 1d946b941..36c22e596 100644
--- a/src/lib/schema/panel/SchemaSettings.tsx
+++ b/src/lib/schema/panel/SchemaSettings.tsx
@@ -14,9 +14,10 @@ export const SchemaSettings = () => {
     Object.values(SchemaLayoutConfig).find(layout => layout.id === settings.layoutName) || Object.values(SchemaLayoutConfig)[0],
   );
   return (
-    <div className="flex flex-col w-full gap-2 px-4 py-2">
+    <div className="flex flex-col w-full gap-2 p-2">
       <span className="text-xs font-bold">Schema Settings</span>
       <Input
+        size="sm"
         type="boolean"
         value={settings.animatedEdges}
         label="Animated Edges"
@@ -25,6 +26,7 @@ export const SchemaSettings = () => {
         }}
       />
       <Input
+        size="sm"
         type="boolean"
         value={settings.showMinimap}
         label="Show Minimap"
@@ -51,7 +53,7 @@ export const SchemaSettings = () => {
               <span className="text-secondary-700 m-2">Layout types</span>
             </div>
             <div className="grid grid-cols-2 gap-4 p-2">
-              <TooltipProvider delayDuration={0}>
+              <TooltipProvider delay={0}>
                 {Object.values(SchemaLayoutConfig).map(thisSchemaLayoutConfig => (
                   <Tooltip key={thisSchemaLayoutConfig.id}>
                     <TooltipTrigger asChild>
diff --git a/src/lib/schema/pills/nodes/SchemaPopUp/SchemaPopUp.tsx b/src/lib/schema/pills/nodes/SchemaPopUp/SchemaPopUp.tsx
index 83efed72b..008bf1030 100644
--- a/src/lib/schema/pills/nodes/SchemaPopUp/SchemaPopUp.tsx
+++ b/src/lib/schema/pills/nodes/SchemaPopUp/SchemaPopUp.tsx
@@ -16,29 +16,27 @@ export type SchemaPopUpProps = {
 export const SchemaPopUp: React.FC<SchemaPopUpProps> = ({ data, numberOfElements, connections }) => {
   return (
     <>
-      <div className="">
+      <div className="divide-y divide-y-secondary-200">
         {numberOfElements != null && numberOfElements != 0 && (
-          <div className="border-b border-sec-200">
-            <div className="flex flex-row gap-1 items-center justify-between px-3 py-1">
-              <Icon component="icon-[ic--baseline-numbers]" size={24} />
-              <span className="ml-auto text-right">{formatNumber(numberOfElements)}</span>
-            </div>
+          <div className="flex flex-row gap-1 items-center justify-between px-3 py-1">
+            <Icon component="icon-[ic--baseline-numbers]" size={24} />
+            <span className="ml-auto text-right">{formatNumber(numberOfElements)}</span>
           </div>
         )}
         {connections && (
-          <div className="border-b border-sec-200 px-3 py-1">
-            <div className="flex flex-row gap-3 items-center justify-between">
-              <span className="font-semibold">From</span>
-              <span className="ml-auto text-right truncate w-[90%]">{connections.from}</span>
+          <div className="px-1.5 py-1">
+            <div className="flex flex-row gap-1 items-center justify-between">
+              <span className="font-medium shrink-0">From</span>
+              <span className="ml-auto text-right truncate grow">{connections.from}</span>
             </div>
             <div className="flex flex-row gap-1 items-center justify-between">
-              <span className="font-semibold">To</span>
-              <span className="ml-auto text-right truncate w-[90%]">{connections.to}</span>
+              <span className="font-medium shrink-0">To</span>
+              <span className="ml-auto text-right truncate grow">{connections.to}</span>
             </div>
           </div>
         )}
-        <TooltipProvider delayDuration={300}>
-          <div className="px-3 py-1">
+        <TooltipProvider delay={300}>
+          <div className="px-1.5 py-1">
             {Object.keys(data).length === 0 ? (
               <div className="flex justify-center items-center h-full ">
                 <span>No attributes</span>
@@ -47,19 +45,14 @@ export const SchemaPopUp: React.FC<SchemaPopUpProps> = ({ data, numberOfElements
               Object.entries(data).map(([k, v]) => (
                 <Tooltip key={k}>
                   <div className="flex flex-row gap-1 items-center min-h-6">
-                    <span className="font-semibold truncate w-[90%]">{k}</span>
+                    <span className="font-medium truncate">{k}</span>
                     <TooltipTrigger asChild>
-                      <span className="ml-auto text-right truncate grow-1 flex items-center">
-                        <Icon
-                          className="ml-auto text-right flex-shrink-0"
-                          component={<Icon component={getDataTypeIcon(v)} size={24} color={'hsl(var(--clr-sec--500))'} />}
-                          color="hsl(var(--clr-sec--400))"
-                          size={24}
-                        />
+                      <span className="ml-auto text-right truncate shrink-0 flex items-center text-secondary-400 hover:text-secondary-600">
+                        <Icon component={<Icon component={getDataTypeIcon(v)} size={24} />} size={24} />
                       </span>
                     </TooltipTrigger>
                     <TooltipContent side="right">
-                      <div className="max-w-[18rem] break-all line-clamp-6 mx-1">
+                      <div className="max-w-[18rem] break-all line-clamp-6">
                         {v !== undefined && (typeof v !== 'object' || Array.isArray(v)) && v != '' ? v : 'noData'}
                       </div>
                     </TooltipContent>
diff --git a/src/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx b/src/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx
index 41b288fd2..d57983004 100644
--- a/src/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx
+++ b/src/lib/schema/pills/nodes/entity/SchemaEntityPill.tsx
@@ -1,6 +1,6 @@
 import { EntityPill } from '@/lib/components';
-import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/components/tooltip';
-import { VisualizationTooltip } from '@/lib/components/VisualizationTooltip';
+import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
+import { NodeDetails } from '@/lib/components/nodeDetails';
 import { useSchemaStats } from '@/lib/data-access';
 import React, { useEffect, useMemo, useRef, useState } from 'react';
 import { Handle, NodeProps, Position, useViewport } from 'reactflow';
@@ -29,18 +29,18 @@ export const SchemaEntityPill = React.memo(({ id, selected, data }: NodeProps<Sc
   };
 
   useEffect(() => {
-    if (data.tooltipClose === true) {
+    if (data.popoverClose) {
       setOpenPopupLocation(null);
     }
-  }, [data.tooltipClose]);
+  }, [data.popoverClose]);
 
-  const tooltipX = useMemo(() => {
+  const popoverX = useMemo(() => {
     if (ref.current == null || openPopupLocation == null) return -1;
     const rect = ref.current.getBoundingClientRect();
     return rect.x - openPopupLocation.x + rect.width / 2;
   }, [viewport.x, openPopupLocation]);
 
-  const tooltipY = useMemo(() => {
+  const popoverY = useMemo(() => {
     if (ref.current == null || openPopupLocation == null) return -1;
     const rect = ref.current.getBoundingClientRect();
     return rect.y - openPopupLocation.y + rect.height / 2;
@@ -66,27 +66,25 @@ export const SchemaEntityPill = React.memo(({ id, selected, data }: NodeProps<Sc
         ref={ref}
       >
         {openPopupLocation !== null && (
-          <Tooltip key={data.name} open={true} boundaryElement={data.reactFlowRef} showArrow={true}>
-            <TooltipTrigger x={tooltipX} y={tooltipY} />
-            <TooltipContent>
-              <div>
-                <VisualizationTooltip name={data.name} colorHeader={'hsl(var(--clr-node))'}>
-                  <SchemaPopUp
-                    data={data.attributes.reduce(
-                      (acc, attr) => {
-                        if (attr.name && attr.type) {
-                          acc[attr.name] = attr.type;
-                        }
-                        return acc;
-                      },
-                      {} as Record<string, string>,
-                    )}
-                    numberOfElements={schemaStats.nodes.stats[data.name]?.count}
-                  />
-                </VisualizationTooltip>
-              </div>
-            </TooltipContent>
-          </Tooltip>
+          <Popover key={data.name} open={true} boundaryElement={data.reactFlowRef} showArrow={true}>
+            <PopoverTrigger x={popoverX} y={popoverY} />
+            <PopoverContent>
+              <NodeDetails name={data.name} colorHeader={'hsl(var(--clr-node))'}>
+                <SchemaPopUp
+                  data={data.attributes.reduce(
+                    (acc, attr) => {
+                      if (attr.name && attr.type) {
+                        acc[attr.name] = attr.type;
+                      }
+                      return acc;
+                    },
+                    {} as Record<string, string>,
+                  )}
+                  numberOfElements={schemaStats.nodes.stats[data.name]?.count}
+                />
+              </NodeDetails>
+            </PopoverContent>
+          </Popover>
         )}
 
         <EntityPill
diff --git a/src/lib/schema/pills/nodes/entity/SchemaListEntityPill.tsx b/src/lib/schema/pills/nodes/entity/SchemaListEntityPill.tsx
index 210a45480..f036c7026 100644
--- a/src/lib/schema/pills/nodes/entity/SchemaListEntityPill.tsx
+++ b/src/lib/schema/pills/nodes/entity/SchemaListEntityPill.tsx
@@ -1,6 +1,6 @@
 import { EntityPill } from '@/lib/components';
-import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/components/tooltip';
-import { VisualizationTooltip } from '@/lib/components/VisualizationTooltip';
+import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
+import { NodeDetails } from '@/lib/components/nodeDetails';
 import { useSchemaStats } from '@/lib/data-access';
 import React, { useEffect, useMemo, useRef, useState } from 'react';
 import { Handle, NodeProps, Position, useViewport } from 'reactflow';
@@ -30,18 +30,18 @@ export const SchemaListEntityPill = React.memo(({ id, selected, data }: NodeProp
   };
 
   useEffect(() => {
-    if (data.tooltipClose === true) {
+    if (data.popoverClose) {
       setOpenPopupLocation(null);
     }
-  }, [data.tooltipClose]);
+  }, [data.popoverClose]);
 
-  const tooltipX = useMemo(() => {
+  const popoverX = useMemo(() => {
     if (ref.current == null || openPopupLocation == null) return -1;
     const rect = ref.current.getBoundingClientRect();
     return rect.x - openPopupLocation.x + rect.width / 2;
   }, [viewport.x, openPopupLocation]);
 
-  const tooltipY = useMemo(() => {
+  const popoverY = useMemo(() => {
     if (ref.current == null || openPopupLocation == null) return -1;
     const rect = ref.current.getBoundingClientRect();
     return rect.y - openPopupLocation.y + rect.height / 2;
@@ -67,27 +67,25 @@ export const SchemaListEntityPill = React.memo(({ id, selected, data }: NodeProp
         ref={ref}
       >
         {openPopupLocation !== null && (
-          <Tooltip key={data.name} open={true} boundaryElement={data.reactFlowRef} showArrow={true}>
-            <TooltipTrigger x={tooltipX} y={tooltipY} />
-            <TooltipContent>
-              <div>
-                <VisualizationTooltip name={data.name} colorHeader={'hsl(var(--clr-node))'}>
-                  <SchemaPopUp
-                    data={data.attributes.reduce(
-                      (acc, attr) => {
-                        if (attr.name && attr.type) {
-                          acc[attr.name] = attr.type;
-                        }
-                        return acc;
-                      },
-                      {} as Record<string, string>,
-                    )}
-                    numberOfElements={schemaStats?.nodes?.stats[data.name]?.count}
-                  />
-                </VisualizationTooltip>
-              </div>
-            </TooltipContent>
-          </Tooltip>
+          <Popover key={data.name} open={true} boundaryElement={data.reactFlowRef} showArrow={true}>
+            <PopoverTrigger x={popoverX} y={popoverY} />
+            <PopoverContent>
+              <NodeDetails name={data.name} colorHeader={'hsl(var(--clr-node))'}>
+                <SchemaPopUp
+                  data={data.attributes.reduce(
+                    (acc, attr) => {
+                      if (attr.name && attr.type) {
+                        acc[attr.name] = attr.type;
+                      }
+                      return acc;
+                    },
+                    {} as Record<string, string>,
+                  )}
+                  numberOfElements={schemaStats?.nodes?.stats[data.name]?.count}
+                />
+              </NodeDetails>
+            </PopoverContent>
+          </Popover>
         )}
 
         <EntityPill
diff --git a/src/lib/schema/pills/nodes/popup/node-quality-relation-popup.stories.tsx b/src/lib/schema/pills/nodes/popup/node-quality-relation-popup.stories.tsx
index 351ef7143..95739f5e3 100644
--- a/src/lib/schema/pills/nodes/popup/node-quality-relation-popup.stories.tsx
+++ b/src/lib/schema/pills/nodes/popup/node-quality-relation-popup.stories.tsx
@@ -3,7 +3,6 @@ import { Meta } from '@storybook/react';
 import { configureStore } from '@reduxjs/toolkit';
 import { Provider } from 'react-redux';
 
-import { querybuilderSlice } from '@/lib/data-access/store';
 import { ReactFlowProvider } from 'reactflow';
 import { NodeQualityRelationPopupNode } from './node-quality-relation-popup';
 
@@ -28,7 +27,6 @@ export default Component;
 // A super-simple mock of a redux store
 const Mockstore = configureStore({
   reducer: {
-    querybuilder: querybuilderSlice.reducer,
     // schema: schemaSlice.reducer,
   },
 });
diff --git a/src/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.stories.tsx b/src/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.stories.tsx
index ba24de3bb..0f499192a 100644
--- a/src/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.stories.tsx
+++ b/src/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.stories.tsx
@@ -2,7 +2,6 @@ import React from 'react';
 import { Meta } from '@storybook/react';
 import { configureStore } from '@reduxjs/toolkit';
 import { Provider } from 'react-redux';
-import { querybuilderSlice } from '@/lib/data-access/store';
 import { ReactFlowProvider } from 'reactflow';
 import { NodeQualityEntityPopupNode } from './node-quality-entity-popup';
 
@@ -27,7 +26,6 @@ export default Component;
 // A super-simple mock of a redux store
 const Mockstore = configureStore({
   reducer: {
-    querybuilder: querybuilderSlice.reducer,
     // schema: schemaSlice.reducer,
   },
 });
diff --git a/src/lib/schema/pills/nodes/relation/SchemaListRelationPill.tsx b/src/lib/schema/pills/nodes/relation/SchemaListRelationPill.tsx
index 57136c8f5..c64e40168 100644
--- a/src/lib/schema/pills/nodes/relation/SchemaListRelationPill.tsx
+++ b/src/lib/schema/pills/nodes/relation/SchemaListRelationPill.tsx
@@ -3,8 +3,8 @@ import React, { useEffect, useMemo, useRef, useState } from 'react';
 import { Handle, NodeProps, Position, useViewport } from 'reactflow';
 import { SchemaReactflowRelationWithFunctions } from '../../../model/reactflow';
 
-import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/components/tooltip';
-import { VisualizationTooltip } from '@/lib/components/VisualizationTooltip';
+import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
+import { NodeDetails } from '@/lib/components/nodeDetails';
 import { useSchemaStats } from '@/lib/data-access';
 import { SchemaPopUp } from '../SchemaPopUp/SchemaPopUp';
 import { SchemaEdge, QueryElementTypes } from 'ts-common';
@@ -37,18 +37,18 @@ export const SchemaListRelationPill = React.memo(({ id, selected, data, ...props
   };
 
   useEffect(() => {
-    if (data.tooltipClose === true) {
+    if (data.popoverClose === true) {
       setOpenPopupLocation(null);
     }
-  }, [data.tooltipClose]);
+  }, [data.popoverClose]);
 
-  const tooltipX = useMemo(() => {
+  const popoverX = useMemo(() => {
     if (ref.current == null || openPopupLocation == null) return -1;
     const rect = ref.current.getBoundingClientRect();
     return rect.x - openPopupLocation.x + rect.width / 2;
   }, [viewport.x, openPopupLocation]);
 
-  const tooltipY = useMemo(() => {
+  const popoverY = useMemo(() => {
     if (ref.current == null || openPopupLocation == null) return -1;
     const rect = ref.current.getBoundingClientRect();
     return rect.y - openPopupLocation.y + rect.height / 2;
@@ -74,32 +74,30 @@ export const SchemaListRelationPill = React.memo(({ id, selected, data, ...props
         ref={ref}
       >
         {openPopupLocation !== null && (
-          <Tooltip key={data.name} open={true} boundaryElement={data.reactFlowRef} showArrow={true}>
-            <TooltipTrigger x={tooltipX} y={tooltipY} />
-            <TooltipContent>
-              <div>
-                <VisualizationTooltip name={data.collection} colorHeader={'hsl(var(--clr-relation))'}>
-                  <SchemaPopUp
-                    data={
-                      data.attributes.length > 0
-                        ? data.attributes.reduce(
-                            (acc, attr) => {
-                              if (attr.name && attr.type) {
-                                acc[attr.name] = attr.type;
-                              }
-                              return acc;
-                            },
-                            {} as Record<string, string>,
-                          )
-                        : {}
-                    }
-                    connections={{ from: data.from, to: data.to }}
-                    numberOfElements={schemaStats?.edges?.stats[data.collection]?.count}
-                  />
-                </VisualizationTooltip>
-              </div>
-            </TooltipContent>
-          </Tooltip>
+          <Popover key={data.name} open={true} boundaryElement={data.reactFlowRef} showArrow={true}>
+            <PopoverTrigger x={popoverX} y={popoverY} />
+            <PopoverContent>
+              <NodeDetails name={data.collection} colorHeader={'hsl(var(--clr-relation))'}>
+                <SchemaPopUp
+                  data={
+                    data.attributes.length > 0
+                      ? data.attributes.reduce(
+                          (acc, attr) => {
+                            if (attr.name && attr.type) {
+                              acc[attr.name] = attr.type;
+                            }
+                            return acc;
+                          },
+                          {} as Record<string, string>,
+                        )
+                      : {}
+                  }
+                  connections={{ from: data.from, to: data.to }}
+                  numberOfElements={schemaStats?.edges?.stats[data.collection]?.count}
+                />
+              </NodeDetails>
+            </PopoverContent>
+          </Popover>
         )}
         <RelationPill
           draggable
diff --git a/src/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx b/src/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx
index bc5b333ec..316c5d5d6 100644
--- a/src/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx
+++ b/src/lib/schema/pills/nodes/relation/SchemaRelationPill.tsx
@@ -3,8 +3,8 @@ import { Handle, Position, NodeProps, useViewport } from 'reactflow';
 import { SchemaReactflowRelationWithFunctions } from '../../../model/reactflow';
 import { SchemaEdge, QueryElementTypes } from 'ts-common';
 import { RelationPill } from '@/lib/components';
-import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/components/tooltip';
-import { VisualizationTooltip } from '@/lib/components/VisualizationTooltip';
+import { Popover, PopoverContent, PopoverTrigger } from '@/lib/components/popover';
+import { NodeDetails } from '@/lib/components/nodeDetails';
 import { SchemaPopUp } from '../SchemaPopUp/SchemaPopUp';
 import { useSchemaStats } from '@/lib/data-access';
 
@@ -36,18 +36,18 @@ export const SchemaRelationPill = React.memo(({ id, selected, data, ...props }:
   };
 
   useEffect(() => {
-    if (data.tooltipClose === true) {
+    if (data.popoverClose === true) {
       setOpenPopupLocation(null);
     }
-  }, [data.tooltipClose]);
+  }, [data.popoverClose]);
 
-  const tooltipX = useMemo(() => {
+  const popoverX = useMemo(() => {
     if (ref.current == null || openPopupLocation == null) return -1;
     const rect = ref.current.getBoundingClientRect();
     return rect.x - openPopupLocation.x + rect.width / 2;
   }, [viewport.x, openPopupLocation]);
 
-  const tooltipY = useMemo(() => {
+  const popoverY = useMemo(() => {
     if (ref.current == null || openPopupLocation == null) return -1;
     const rect = ref.current.getBoundingClientRect();
     return rect.y - openPopupLocation.y + rect.height / 2;
@@ -73,32 +73,30 @@ export const SchemaRelationPill = React.memo(({ id, selected, data, ...props }:
         ref={ref}
       >
         {openPopupLocation !== null && (
-          <Tooltip key={data.name} open={true} boundaryElement={data.reactFlowRef} showArrow={true}>
-            <TooltipTrigger x={tooltipX} y={tooltipY} />
-            <TooltipContent>
-              <div>
-                <VisualizationTooltip name={data.collection} colorHeader={'hsl(var(--clr-relation))'}>
-                  <SchemaPopUp
-                    data={
-                      data.attributes.length > 0
-                        ? data.attributes.reduce(
-                            (acc, attr) => {
-                              if (attr.name && attr.type) {
-                                acc[attr.name] = attr.type;
-                              }
-                              return acc;
-                            },
-                            {} as Record<string, string>,
-                          )
-                        : {}
-                    }
-                    connections={{ from: data.from, to: data.to }}
-                    numberOfElements={schemaStats.edges.stats[data.collection]?.count}
-                  />
-                </VisualizationTooltip>
-              </div>
-            </TooltipContent>
-          </Tooltip>
+          <Popover key={data.name} open={true} boundaryElement={data.reactFlowRef} showArrow={true}>
+            <PopoverTrigger x={popoverX} y={popoverY} />
+            <PopoverContent>
+              <NodeDetails name={data.collection} colorHeader={'hsl(var(--clr-relation))'}>
+                <SchemaPopUp
+                  data={
+                    data.attributes.length > 0
+                      ? data.attributes.reduce(
+                          (acc, attr) => {
+                            if (attr.name && attr.type) {
+                              acc[attr.name] = attr.type;
+                            }
+                            return acc;
+                          },
+                          {} as Record<string, string>,
+                        )
+                      : {}
+                  }
+                  connections={{ from: data.from, to: data.to }}
+                  numberOfElements={schemaStats.edges.stats[data.collection]?.count}
+                />
+              </NodeDetails>
+            </PopoverContent>
+          </Popover>
         )}
         <RelationPill
           draggable
diff --git a/src/lib/sidebar/index.tsx b/src/lib/sidebar/index.tsx
index cebf79ffe..504212e65 100644
--- a/src/lib/sidebar/index.tsx
+++ b/src/lib/sidebar/index.tsx
@@ -32,7 +32,7 @@ export function Sidebar({
 }) {
   return (
     <div className="side-bar w-fit h-full flex shrink">
-      <TooltipProvider delayDuration={100}>
+      <TooltipProvider>
         <div className="w-11 flex flex-col items-center">
           {tabs.map(t => (
             <Tooltip key={t.name} placement={'right'}>
diff --git a/src/lib/sidebar/search/SearchBar.tsx b/src/lib/sidebar/search/SearchBar.tsx
index ff9dc5583..191d3347e 100644
--- a/src/lib/sidebar/search/SearchBar.tsx
+++ b/src/lib/sidebar/search/SearchBar.tsx
@@ -112,7 +112,7 @@ export function SearchBar(props: { onRemove?: () => void }) {
     <Panel
       title="Search"
       tooltips={
-        <TooltipProvider delayDuration={10}>
+        <TooltipProvider delay={10}>
           <Tooltip>
             <TooltipTrigger asChild>
               <Button
@@ -179,7 +179,7 @@ export function SearchBar(props: { onRemove?: () => void }) {
                           <p className="font-bold text-sm">{results[category].nodes.length + results[category].edges.length} results</p>
                         </div>
                         <div className="h-[1px] w-full bg-secondary-200"></div>
-                        <TooltipProvider delayDuration={300}>
+                        <TooltipProvider delay={300}>
                           {Object.values(Object.values(results[category]))
                             .flat()
                             .map((item, idx) => (
diff --git a/src/lib/vis/components/VisualizationPanel.tsx b/src/lib/vis/components/VisualizationPanel.tsx
index 1d56ab818..eaf4a7a17 100644
--- a/src/lib/vis/components/VisualizationPanel.tsx
+++ b/src/lib/vis/components/VisualizationPanel.tsx
@@ -18,6 +18,7 @@ import { ErrorBoundary } from '../../components/errorBoundary';
 import { addError } from '../../data-access/store/configSlice';
 import { canViewFeature } from '../../components/featureFlags';
 import { NodeQueryResult, EdgeQueryResult } from 'ts-common';
+import { PopoverProvider } from '@/lib';
 
 type PromiseFunc = () => Promise<{ default: VISComponentType<any> }>;
 export const Visualizations: Record<string, PromiseFunc> = {
@@ -132,7 +133,9 @@ export const VisualizationPanel = ({ fullSize }: { fullSize: () => void }) => {
           </div>
         )}
       </div>
-      <VisualizationTabBar fullSize={fullSize} exportImage={exportImage} handleSelect={handleSelect} />
+      <PopoverProvider>
+        <VisualizationTabBar fullSize={fullSize} exportImage={exportImage} handleSelect={handleSelect} />
+      </PopoverProvider>
     </div>
   );
 };
diff --git a/src/lib/vis/components/VisualizationTabBar.tsx b/src/lib/vis/components/VisualizationTabBar.tsx
index be0648e58..c8ecfa51d 100644
--- a/src/lib/vis/components/VisualizationTabBar.tsx
+++ b/src/lib/vis/components/VisualizationTabBar.tsx
@@ -1,8 +1,8 @@
-import { useState, useEffect, useRef } from 'react';
+import React, { useState, useEffect, useRef } from 'react';
 import { Button, DropdownContainer, DropdownItem, DropdownItemContainer, DropdownTrigger } from '../../components';
 import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../components/tooltip';
 import { ControlContainer } from '../../components/controls';
-import { Tabs, Tab } from "@/lib/components";
+import { Tabs, Tab } from '@/lib/components';
 import { useActiveSaveStateAuthorization, useAppDispatch, useVisualization } from '../../data-access';
 import { addVisualization, removeVisualization, reorderVisState, setActiveVisualization } from '../../data-access/store/visualizationSlice';
 import { VisualizationsConfig } from './config';
@@ -22,20 +22,16 @@ export default function VisualizationTabBar(props: { fullSize: () => void; expor
 
     const sortable = new Sortable(tabsRef.current, {
       animation: 150,
-      draggable: "[data-type=\"tab\"]",
-      ghostClass: "bg-secondary-300",
-      dragClass: "bg-secondary-100",
-      onEnd: (evt) => {
-        if (
-          evt.oldIndex != null &&
-          evt.newIndex != null &&
-          evt.oldIndex !== evt.newIndex
-        ) {
+      draggable: '[data-type="tab"]',
+      ghostClass: 'bg-secondary-300',
+      dragClass: 'bg-secondary-100',
+      onEnd: evt => {
+        if (evt.oldIndex != null && evt.newIndex != null && evt.oldIndex !== evt.newIndex) {
           dispatch(
             reorderVisState({
               id: evt.oldIndex,
               newPosition: evt.newIndex,
-            })
+            }),
           );
         }
       },
@@ -80,7 +76,7 @@ export default function VisualizationTabBar(props: { fullSize: () => void; expor
         <h1 className="text-xs font-semibold text-secondary-600 truncate">Visualization</h1>
       </div>
       <div className="flex items-center px-0.5 gap-1 border-l border-secondary-200">
-        <TooltipProvider delayDuration={0}>
+        <TooltipProvider>
           <Tooltip>
             <TooltipTrigger>
               <DropdownContainer open={open} onOpenChange={setOpen}>
@@ -113,13 +109,12 @@ export default function VisualizationTabBar(props: { fullSize: () => void; expor
         </TooltipProvider>
       </div>
 
-
       {openVisualizationArray.length > 0 && (
-      <Tabs ref={tabsRef}  className="-my-px overflow-x-auto overflow-y-hidden no-scrollbar divide-x divide-secondary-200 border-x">
-        {openVisualizationArray.map((vis, i) => {
-          const isActive = activeVisualizationIndex === i;
-          const config = VisualizationsConfig[vis.id];
-          const IconComponent = config?.icons.sm;
+        <Tabs ref={tabsRef} className="-my-px overflow-x-auto overflow-y-hidden no-scrollbar divide-x divide-secondary-200 border-x">
+          {openVisualizationArray.map((vis, i) => {
+            const isActive = activeVisualizationIndex === i;
+            const config = VisualizationsConfig[vis.id];
+            const IconComponent = config?.icons.sm;
 
             return (
               <Tab
@@ -130,7 +125,6 @@ export default function VisualizationTabBar(props: { fullSize: () => void; expor
                 className="group"
                 onClick={() => onSelect(i)}
               >
-                {/*{vis.id},{config.id}*/}
                 <Button
                   variantType="secondary"
                   variant="ghost"
@@ -139,7 +133,7 @@ export default function VisualizationTabBar(props: { fullSize: () => void; expor
                   size="2xs"
                   iconComponent="icon-[ic--baseline-close]"
                   className={!isActive ? 'opacity-50 group-hover:opacity-100 group-focus-within:opacity-100' : ''}
-                  onClick={(e) => {
+                  onClick={e => {
                     e.stopPropagation();
                     onDelete(i);
                   }}
@@ -153,7 +147,7 @@ export default function VisualizationTabBar(props: { fullSize: () => void; expor
       {openVisualizationArray.length > 0 && (
         <div className="shrink-0 sticky right-0 px-0.5 ml-auto flex">
           <ControlContainer>
-            <TooltipProvider delayDuration={0}>
+            <TooltipProvider>
               <Tooltip>
                 <TooltipTrigger asChild>
                   <Button
diff --git a/src/lib/vis/components/config/VisualizationSettings.tsx b/src/lib/vis/components/config/VisualizationSettings.tsx
index 237050e87..020918868 100644
--- a/src/lib/vis/components/config/VisualizationSettings.tsx
+++ b/src/lib/vis/components/config/VisualizationSettings.tsx
@@ -51,7 +51,7 @@ export function VisualizationSettings() {
 
   return (
     <div className="flex flex-col w-full overflow-auto">
-      <div className="text-sm px-4 py-2 flex flex-col gap-1">
+      <div className="text-sm p-2 flex flex-col gap-1">
         <Input
           type="text"
           size="sm"
diff --git a/src/lib/vis/visualizations/arcplotvis/arcplotvis.stories.tsx b/src/lib/vis/visualizations/arcplotvis/arcplotvis.stories.tsx
index 861588757..50618ed07 100644
--- a/src/lib/vis/visualizations/arcplotvis/arcplotvis.stories.tsx
+++ b/src/lib/vis/visualizations/arcplotvis/arcplotvis.stories.tsx
@@ -1,7 +1,7 @@
 import { configureStore } from '@reduxjs/toolkit';
 import { Meta } from '@storybook/react';
 import { Provider } from 'react-redux';
-import { graphQueryResultSlice, querybuilderSlice, schemaSlice, visualizationSlice } from '../../../data-access/store';
+import { graphQueryResultSlice, schemaSlice, visualizationSlice } from '../../../data-access/store';
 import { mockData } from '../../../mock-data';
 import ArcPlotComponent from './arcplotvis';
 
@@ -10,7 +10,6 @@ const Mockstore = configureStore({
     schema: schemaSlice.reducer,
     graphQueryResult: graphQueryResultSlice.reducer,
     visualize: visualizationSlice.reducer,
-    querybuilder: querybuilderSlice.reducer,
   },
 });
 
diff --git a/src/lib/vis/visualizations/mapvis/components/MapTooltip.tsx b/src/lib/vis/visualizations/mapvis/components/MapDataInspector.tsx
similarity index 87%
rename from src/lib/vis/visualizations/mapvis/components/MapTooltip.tsx
rename to src/lib/vis/visualizations/mapvis/components/MapDataInspector.tsx
index 280d94194..234665cfc 100644
--- a/src/lib/vis/visualizations/mapvis/components/MapTooltip.tsx
+++ b/src/lib/vis/visualizations/mapvis/components/MapDataInspector.tsx
@@ -2,7 +2,7 @@ import React from 'react';
 import { NodeType } from '../../nodelinkvis/types';
 import { GeoJsonType } from '../mapvis.types';
 import { SearchResultType } from '../mapvis.types';
-import { TooltipProvider } from '@/lib/components';
+import { PopoverProvider } from '@/lib/components';
 
 export type NodelinkPopupProps = {
   type: 'node' | 'area' | 'location';
@@ -13,7 +13,7 @@ const isGeoJsonType = (data: NodeType | GeoJsonType | SearchResultType): data is
   return (data as GeoJsonType).properties !== undefined;
 };
 
-const MapTooltipNode = (node: NodeType) => (
+const MapNodeDetails = (node: NodeType) => (
   <div>
     {Object.keys(node.attributes).length === 0 ? (
       <div className="flex justify-center items-center h-full">
@@ -41,7 +41,7 @@ const MapTooltipNode = (node: NodeType) => (
     )}
   </div>
 );
-const MapTooltipChoropleth = (geoJson: GeoJsonType) => (
+const MapChoroplethDetails = (geoJson: GeoJsonType) => (
   <div>
     <div className="flex flex-row gap-3">
       <span>Area&nbsp;id: </span>
@@ -89,26 +89,25 @@ const renderLocationDetails = (location: SearchResultType) => (
   </div>
 );
 
-export const MapTooltip = (props: NodelinkPopupProps) => {
+export const MapDataInspector = (props: NodelinkPopupProps) => {
   const { type, data } = props;
 
   return (
-    <TooltipProvider delayDuration={100}>
+    <PopoverProvider delay={100}>
       <div className="text-[0.9rem] min-w-[10rem]">
-        <div className="card-body p-0">
-          <div className="h-[1px] w-full bg-secondary-200"></div>
+        <div className="p-0">
           <div className="px-2.5 text-[0.8rem]">
             {type === 'node'
               ? data && 'attributes' in data
-                ? MapTooltipNode(data as NodeType)
+                ? MapNodeDetails(data as NodeType)
                 : null
               : data && isGeoJsonType(data)
-                ? MapTooltipChoropleth(data as GeoJsonType)
+                ? MapChoroplethDetails(data as GeoJsonType)
                 : renderLocationDetails(data as SearchResultType)}
           </div>
           <div className="h-[1px] w-full"></div>
         </div>
       </div>
-    </TooltipProvider>
+    </PopoverProvider>
   );
 };
diff --git a/src/lib/vis/visualizations/mapvis/components/index.ts b/src/lib/vis/visualizations/mapvis/components/index.ts
index 6d9b03270..ca9aded7f 100644
--- a/src/lib/vis/visualizations/mapvis/components/index.ts
+++ b/src/lib/vis/visualizations/mapvis/components/index.ts
@@ -1,4 +1,4 @@
 export * from './ActionBar';
 export * from './Attribution';
 export * from './MapSettings';
-export * from './MapTooltip';
+export * from './MapDataInspector.tsx';
diff --git a/src/lib/vis/visualizations/mapvis/mapvis.stories.tsx b/src/lib/vis/visualizations/mapvis/mapvis.stories.tsx
index 3a8cbab45..f8bf22a81 100644
--- a/src/lib/vis/visualizations/mapvis/mapvis.stories.tsx
+++ b/src/lib/vis/visualizations/mapvis/mapvis.stories.tsx
@@ -1,7 +1,7 @@
 import { configureStore } from '@reduxjs/toolkit';
 import { Meta } from '@storybook/react';
 import { Provider } from 'react-redux';
-import { graphQueryResultSlice, querybuilderSlice, schemaSlice, visualizationSlice } from '../../../data-access/store';
+import { graphQueryResultSlice, schemaSlice, visualizationSlice } from '../../../data-access/store';
 import MapComponent from './mapvis';
 import { mockData } from '../../../mock-data/query-result/mockData';
 
@@ -10,7 +10,6 @@ const Mockstore = configureStore({
     schema: schemaSlice.reducer,
     graphQueryResult: graphQueryResultSlice.reducer,
     visualize: visualizationSlice.reducer,
-    querybuilder: querybuilderSlice.reducer,
   },
 });
 
diff --git a/src/lib/vis/visualizations/mapvis/mapvis.tsx b/src/lib/vis/visualizations/mapvis/mapvis.tsx
index 86a8d9df0..78a0607f3 100644
--- a/src/lib/vis/visualizations/mapvis/mapvis.tsx
+++ b/src/lib/vis/visualizations/mapvis/mapvis.tsx
@@ -1,14 +1,14 @@
-import React, { useEffect, useCallback, useState, useRef, forwardRef, useImperativeHandle } from 'react';
+import React, { useEffect, useCallback, useState, useRef, forwardRef, RefObject, useImperativeHandle } from 'react';
 import DeckGL from '@deck.gl/react';
 import { CompositeLayer, FlyToInterpolator, MapViewState, WebMercatorViewport } from '@deck.gl/core';
 import { CompositeLayerType, Coordinate, LayerSettingsType, LocationInfo, SearchResultType } from './mapvis.types';
 import { VISComponentType, VisualizationPropTypes } from '../../common';
 import { layerTypes, createBaseMap, LayerTypes } from './layers';
 import { geoCentroid } from 'd3';
-import { Attribution, ActionBar, MapTooltip, MapSettings } from './components';
+import { Attribution, ActionBar, MapDataInspector, MapSettings } from './components';
 import { useSelectionLayer, useCoordinateLookup } from './hooks';
-import { VisualizationTooltip } from '@/lib/components/VisualizationTooltip';
-import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/components/tooltip';
+import { NodeDetails } from '@/lib/components/nodeDetails';
+import { Popover, PopoverContent, PopoverProvider, PopoverTrigger } from '@/lib/components/popover';
 import { isGeoJsonType, nodeColorHex, rgbToHex } from './utils';
 import { NodeType } from '../nodelinkvis/types';
 import { ChoroplethLayer } from './layers/choropleth-layer/ChoroplethLayer';
@@ -303,10 +303,10 @@ export const MapVis = forwardRef((props: VisualizationPropTypes<MapProps>, refEx
       />
       {selected.length > 0 &&
         selected.map((node, index) => (
-          <Tooltip key={index} open={true} interactive={false} boundaryElement={ref} showArrow={true}>
-            <TooltipTrigger x={node.x} y={node.y} />
-            <TooltipContent>
-              <VisualizationTooltip
+          <Popover key={index} open={true} interactive={false} boundaryElement={ref as RefObject<HTMLElement>} showArrow={true}>
+            <PopoverTrigger x={node.x} y={node.y} />
+            <PopoverContent>
+              <NodeDetails
                 name={
                   node.selectedType === 'node'
                     ? (node as NodeType)?._id
@@ -324,20 +324,20 @@ export const MapVis = forwardRef((props: VisualizationPropTypes<MapProps>, refEx
                       : 'hsl(var(--clr-node))'
                 }
               >
-                <MapTooltip type={node.selectedType} data={{ ...node }} key={node._id} />
-              </VisualizationTooltip>
-            </TooltipContent>
-          </Tooltip>
+                <MapDataInspector type={node.selectedType} data={{ ...node }} key={node._id} />
+              </NodeDetails>
+            </PopoverContent>
+          </Popover>
         ))}
       {searchResult && (
-        <Tooltip open={true} interactive={false} boundaryElement={ref} showArrow={true}>
-          <TooltipTrigger x={searchResult.x} y={searchResult.y} />
-          <TooltipContent>
-            <VisualizationTooltip name={searchResult.name} colorHeader="hsl(var(--clr-node))">
-              <MapTooltip type="location" data={{ ...searchResult }} key={searchResult.name} />
-            </VisualizationTooltip>
-          </TooltipContent>
-        </Tooltip>
+        <Popover open={true} boundaryElement={ref as RefObject<HTMLElement>} showArrow={true}>
+          <PopoverTrigger x={searchResult.x} y={searchResult.y} />
+          <PopoverContent>
+            <NodeDetails name={searchResult.name} colorHeader="hsl(var(--clr-node))">
+              <MapDataInspector type="location" data={{ ...searchResult }} key={searchResult.name} />
+            </NodeDetails>
+          </PopoverContent>
+        </Popover>
       )}
       <Attribution />
     </div>
diff --git a/src/lib/vis/visualizations/matrixvis/matrix.stories.tsx b/src/lib/vis/visualizations/matrixvis/matrix.stories.tsx
index 48ee5407f..4e5e67971 100644
--- a/src/lib/vis/visualizations/matrixvis/matrix.stories.tsx
+++ b/src/lib/vis/visualizations/matrixvis/matrix.stories.tsx
@@ -2,7 +2,7 @@ import { Meta } from '@storybook/react';
 import { configureStore } from '@reduxjs/toolkit';
 import { Provider } from 'react-redux';
 import { mockData } from '../../../mock-data';
-import { graphQueryResultSlice, querybuilderSlice, schemaSlice, visualizationSlice } from '../../../data-access/store';
+import { graphQueryResultSlice, schemaSlice, visualizationSlice } from '../../../data-access/store';
 import MatrixVisComponent from './matrixvis';
 import { configSlice } from '@/lib/data-access/store/configSlice';
 
@@ -30,7 +30,6 @@ const Mockstore: any = configureStore({
     schema: schemaSlice.reducer,
     graphQueryResult: graphQueryResultSlice.reducer,
     visualize: visualizationSlice.reducer,
-    querybuilder: querybuilderSlice.reducer,
     config: configSlice.reducer,
   },
 });
diff --git a/src/lib/vis/visualizations/nodelinkvis/components/NLPixi.tsx b/src/lib/vis/visualizations/nodelinkvis/components/NLPixi.tsx
index 17b139c18..1660f7ca3 100644
--- a/src/lib/vis/visualizations/nodelinkvis/components/NLPixi.tsx
+++ b/src/lib/vis/visualizations/nodelinkvis/components/NLPixi.tsx
@@ -1,5 +1,5 @@
-import { Tooltip, TooltipContent, TooltipTrigger } from '@/lib/components/tooltip';
-import { VisualizationTooltip } from '@/lib/components/VisualizationTooltip';
+import { Popover, PopoverContent, PopoverTrigger, PopoverProvider } from '@/lib/components/popover';
+import { NodeDetails } from '@/lib/components/nodeDetails';
 import { useConfig } from '@/lib/data-access/store';
 import { Theme } from '@/lib/data-access/store/configSlice';
 import { dataColors, visualizationColors } from '@/config';
@@ -17,7 +17,7 @@ import {
   Texture,
   type StrokeStyle,
 } from 'pixi.js';
-import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
+import { forwardRef, RefObject, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
 import { useML, useSearchResultData } from '../../../../data-access';
 import { AllLayoutAlgorithms, GraphologyForceAtlas2Webworker, LayoutFactory, Layouts, LayoutTypes } from '../../../../graph-layout';
 import { NodelinkVisProps } from '../nodelinkvis';
@@ -1064,7 +1064,7 @@ export const NLPixi = forwardRef((props: Props, refExternal) => {
         updateEdgeLabel(link);
       });
 
-      // Move tooltips while layouter is running and moving nodes
+      // Move Popovers while layouter is running and moving nodes
       imperative.current?.onMoved(viewport.current);
     }
   };
@@ -1245,24 +1245,24 @@ export const NLPixi = forwardRef((props: Props, refExternal) => {
   return (
     <>
       {popups.map(popup => (
-        <Tooltip key={popup.node._id} open={true} interactive={!dragging} boundaryElement={ref} showArrow={true}>
-          <TooltipTrigger x={popup.pos.x} y={popup.pos.y} />
-          <TooltipContent>
-            <VisualizationTooltip name={popup.node._id} colorHeader={nodeColorHex(props.graph.nodes[popup.node._id].type)}>
+        <Popover key={popup.node._id} open={true} interactive={!dragging} boundaryElement={ref as RefObject<HTMLElement>} showArrow={true}>
+          <PopoverTrigger x={popup.pos.x} y={popup.pos.y} />
+          <PopoverContent>
+            <NodeDetails name={popup.node._id} colorHeader={nodeColorHex(props.graph.nodes[popup.node._id].type)}>
               <NLPopUp data={props.graph.nodes[popup.node._id].attributes} />
-            </VisualizationTooltip>
-          </TooltipContent>
-        </Tooltip>
+            </NodeDetails>
+          </PopoverContent>
+        </Popover>
       ))}
       {quickPopup != null && (
-        <Tooltip key={quickPopup.node._id} open={true} boundaryElement={ref} showArrow={true}>
-          <TooltipTrigger x={quickPopup.pos.x} y={quickPopup.pos.y} />
-          <TooltipContent>
-            <VisualizationTooltip name={quickPopup.node._id} colorHeader={nodeColorHex(props.graph.nodes[quickPopup.node._id].type)}>
+        <Popover key={quickPopup.node._id} open={true} boundaryElement={ref as RefObject<HTMLElement>} showArrow={true}>
+          <PopoverTrigger x={quickPopup.pos.x} y={quickPopup.pos.y} />
+          <PopoverContent>
+            <NodeDetails name={quickPopup.node._id} colorHeader={nodeColorHex(props.graph.nodes[quickPopup.node._id].type)}>
               <NLPopUp data={props.graph.nodes[quickPopup.node._id].attributes} />
-            </VisualizationTooltip>
-          </TooltipContent>
-        </Tooltip>
+            </NodeDetails>
+          </PopoverContent>
+        </Popover>
       )}
       <div
         className="h-full w-full overflow-hidden"
diff --git a/src/lib/vis/visualizations/nodelinkvis/components/NLPopup.tsx b/src/lib/vis/visualizations/nodelinkvis/components/NLPopup.tsx
index e4368b7de..0d6cfa8a9 100644
--- a/src/lib/vis/visualizations/nodelinkvis/components/NLPopup.tsx
+++ b/src/lib/vis/visualizations/nodelinkvis/components/NLPopup.tsx
@@ -11,7 +11,7 @@ export type NLPopUpProps = {
 
 export const NLPopUp: React.FC<NLPopUpProps> = ({ data }) => {
   return (
-    <TooltipProvider delayDuration={100}>
+    <TooltipProvider delay={100}>
       <div className={`px-2`}>
         {Object.keys(data).length === 0 ? (
           <div className="flex justify-center items-center h-full">
diff --git a/src/lib/vis/visualizations/nodelinkvis/nodelinkvis.stories.tsx b/src/lib/vis/visualizations/nodelinkvis/nodelinkvis.stories.tsx
index d6d072ae4..1249c3f21 100644
--- a/src/lib/vis/visualizations/nodelinkvis/nodelinkvis.stories.tsx
+++ b/src/lib/vis/visualizations/nodelinkvis/nodelinkvis.stories.tsx
@@ -1,6 +1,6 @@
 import React from 'react';
 import { Meta } from '@storybook/react';
-import { graphQueryResultSlice, querybuilderSlice, schemaSlice, visualizationSlice, searchResultSlice } from '../../../data-access/store';
+import { graphQueryResultSlice, schemaSlice, visualizationSlice, searchResultSlice } from '../../../data-access/store';
 import { configureStore } from '@reduxjs/toolkit';
 import { Provider } from 'react-redux';
 import { mockData } from '../../../mock-data';
@@ -12,7 +12,6 @@ const Mockstore = configureStore({
     schema: schemaSlice.reducer,
     graphQueryResult: graphQueryResultSlice.reducer,
     visualize: visualizationSlice.reducer,
-    querybuilder: querybuilderSlice.reducer,
     config: configSlice.reducer,
     searchResults: searchResultSlice.reducer,
   },
diff --git a/src/lib/vis/visualizations/paohvis/components/HyperRangeBlock.tsx b/src/lib/vis/visualizations/paohvis/components/HyperRangeBlock.tsx
index f7f8bea3e..8725751a4 100644
--- a/src/lib/vis/visualizations/paohvis/components/HyperRangeBlock.tsx
+++ b/src/lib/vis/visualizations/paohvis/components/HyperRangeBlock.tsx
@@ -152,7 +152,7 @@ export const HyperEdgeRangesBlock: React.FC<HyperEdgeRangesBlockProps> = ({
           className="hyperEdgeInformation text-columns "
           transform={'translate(' + rowLabelColumnWidth + ',' + widthColumns + ')'}
         >
-          <TooltipProvider delayDuration={300}>
+          <TooltipProvider delay={300}>
             {columnHeaderInformation[0] &&
               columnHeaderInformation[0].data.map((rowLabel, indexRows) => (
                 <g
diff --git a/src/lib/vis/visualizations/paohvis/components/RowLabels.tsx b/src/lib/vis/visualizations/paohvis/components/RowLabels.tsx
index f241069d2..a47cea6bc 100644
--- a/src/lib/vis/visualizations/paohvis/components/RowLabels.tsx
+++ b/src/lib/vis/visualizations/paohvis/components/RowLabels.tsx
@@ -95,7 +95,7 @@ export const RowLabels = ({
             <g key={'parent_' + indexRows}>
               <g key={'content_' + indexRows} transform={'translate(0,' + (yOffset + indexRows * rowHeight) + ')'}>
                 <g className={'rowsLabel row-' + indexRows} onMouseEnter={onMouseEnterRowLabels} onMouseLeave={onMouseLeaveRowLabels}>
-                  <TooltipProvider delayDuration={300}>
+                  <TooltipProvider delay={300}>
                     {dataRows.map((row, index) => (
                       <Tooltip key={'gRowTableTooltip-' + index}>
                         <TooltipTrigger asChild>
diff --git a/src/lib/vis/visualizations/paohvis/paohvis.stories.tsx b/src/lib/vis/visualizations/paohvis/paohvis.stories.tsx
index ee498ea2c..9e54e748c 100644
--- a/src/lib/vis/visualizations/paohvis/paohvis.stories.tsx
+++ b/src/lib/vis/visualizations/paohvis/paohvis.stories.tsx
@@ -1,5 +1,5 @@
 import { Meta } from '@storybook/react';
-import { graphQueryResultSlice, querybuilderSlice, schemaSlice, visualizationSlice } from '../../../data-access/store';
+import { graphQueryResultSlice, schemaSlice, visualizationSlice } from '../../../data-access/store';
 import { configureStore } from '@reduxjs/toolkit';
 import { Provider } from 'react-redux';
 import {
@@ -16,7 +16,6 @@ const Mockstore = configureStore({
     schema: schemaSlice.reducer,
     graphQueryResult: graphQueryResultSlice.reducer,
     visualize: visualizationSlice.reducer,
-    querybuilder: querybuilderSlice.reducer,
   },
 });
 
diff --git a/src/lib/vis/visualizations/vis1D/components/CustomChartPlotly.tsx b/src/lib/vis/visualizations/vis1D/components/CustomChartPlotly.tsx
index ef6262009..690b221b1 100644
--- a/src/lib/vis/visualizations/vis1D/components/CustomChartPlotly.tsx
+++ b/src/lib/vis/visualizations/vis1D/components/CustomChartPlotly.tsx
@@ -112,8 +112,8 @@ export const preparePlotData = (
   const mainColors = visualizationColors.GPCat.colors[14];
 
   const sharedTickFont = {
-    family: 'monospace',
-    size: 12,
+    family: 'Inter',
+    size: 11,
     color: '#374151', // !TODO get GP value
   };
 
@@ -537,10 +537,11 @@ export const preparePlotData = (
     },
     hoverlabel: {
       bgcolor: 'rgba(255, 255, 255, 0.8)',
+      className: 'text-dark',
       bordercolor: 'rgba(0, 0, 0, 0.2)',
       font: {
-        family: 'monospace',
-        size: 14,
+        family: 'Inter',
+        size: 13,
         color: '#374151',
       },
     },
@@ -695,7 +696,7 @@ export const CustomChartPlotly: React.FC<CustomChartPlotlyProps> = ({
         onHover={handleHover}
         onUnhover={handleUnhover}
       />
-      {/* 
+      {/*
 
       {hoveredPoint && (
         <div>
-- 
GitLab