diff --git a/src/lib/components/ui/menu/ContextMenuWrapper.svelte b/src/lib/components/ui/menu/ContextMenuWrapper.svelte
new file mode 100644
index 00000000..a79fe762
--- /dev/null
+++ b/src/lib/components/ui/menu/ContextMenuWrapper.svelte
@@ -0,0 +1,36 @@
+
+
+
+
+ {#snippet child({ props })}
+
+ {@render trigger()}
+
+ {/snippet}
+
+
+
+
+
+
+
+
diff --git a/src/lib/components/ui/menu/GearMenuButton.svelte b/src/lib/components/ui/menu/GearMenuButton.svelte
new file mode 100644
index 00000000..29afa99d
--- /dev/null
+++ b/src/lib/components/ui/menu/GearMenuButton.svelte
@@ -0,0 +1,123 @@
+
+
+
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
+
+
+
+
+
+
+
diff --git a/src/lib/components/ui/menu/MenuItems.svelte b/src/lib/components/ui/menu/MenuItems.svelte
new file mode 100644
index 00000000..b287dfa7
--- /dev/null
+++ b/src/lib/components/ui/menu/MenuItems.svelte
@@ -0,0 +1,52 @@
+
+
+{#if onViewDetails}
+ -
+ {viewDetailsLabel}
+
+{/if}
+
+{#if canEdit}
+ {#if onReplace}
+ -
+ {replaceLabel}
+
+ {/if}
+
+ {#if onRemove}
+
+ -
+ {removeLabel}
+
+ {/if}
+{/if}
diff --git a/src/lib/components/ui/menu/UnitMenuContainer.svelte b/src/lib/components/ui/menu/UnitMenuContainer.svelte
new file mode 100644
index 00000000..1536269e
--- /dev/null
+++ b/src/lib/components/ui/menu/UnitMenuContainer.svelte
@@ -0,0 +1,55 @@
+
+
+
+
+
diff --git a/src/lib/components/ui/menu/menu-styles.scss b/src/lib/components/ui/menu/menu-styles.scss
new file mode 100644
index 00000000..3e1465df
--- /dev/null
+++ b/src/lib/components/ui/menu/menu-styles.scss
@@ -0,0 +1,102 @@
+@use '$src/themes/spacing' as *;
+@use '$src/themes/layout' as *;
+@use '$src/themes/typography' as *;
+@use '$src/themes/effects' as *;
+
+// Shared menu container styles
+@mixin menu-container {
+ background: var(--menu-bg);
+ border: 1px solid var(--border-subtle);
+ border-radius: $card-corner;
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
+ padding: $unit-half;
+ min-width: calc($unit * 22.5);
+ z-index: 200;
+ animation: slideIn $duration-quick ease-out;
+}
+
+// Shared menu item styles
+@mixin menu-item {
+ padding: $unit $unit-2x;
+ border-radius: $item-corner-small;
+ cursor: pointer;
+ font-size: $font-regular;
+ color: var(--menu-text);
+ display: flex;
+ align-items: center;
+ gap: $unit;
+ @include smooth-transition($duration-standard, background);
+
+ &:hover {
+ background: var(--menu-bg-item-hover);
+ }
+
+ &:first-child {
+ border-top-left-radius: $item-corner;
+ border-top-right-radius: $item-corner;
+ }
+
+ &:last-child {
+ border-bottom-left-radius: $item-corner;
+ border-bottom-right-radius: $item-corner;
+ }
+
+ &:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ }
+
+ &.danger {
+ color: var(--danger);
+
+ &:hover {
+ background: var(--danger-bg);
+ }
+ }
+}
+
+// Shared menu separator styles
+@mixin menu-separator {
+ border-radius: $full-corner;
+ height: 2px;
+ background: var(--menu-separator);
+ margin: $unit-half ($unit * 0.75);
+}
+
+// Slide in animation
+@keyframes slideIn {
+ from {
+ opacity: 0;
+ transform: translateY(-$unit-fourth);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+// Global styles for context menu
+:global(.context-menu) {
+ @include menu-container;
+}
+
+:global(.context-menu-item) {
+ @include menu-item;
+}
+
+:global(.context-menu-separator) {
+ @include menu-separator;
+}
+
+// Global styles for dropdown menu
+:global(.dropdown-menu) {
+ @include menu-container;
+}
+
+:global(.dropdown-menu-item) {
+ @include menu-item;
+}
+
+:global(.dropdown-menu-separator) {
+ @include menu-separator;
+}