diff --git a/Content.Shared/ContainerHeld/ContainerHeldComponent.cs b/Content.Shared/ContainerHeld/ContainerHeldComponent.cs
new file mode 100644
index 0000000000..cc6d2bf872
--- /dev/null
+++ b/Content.Shared/ContainerHeld/ContainerHeldComponent.cs
@@ -0,0 +1,14 @@
+namespace Content.Shared.ContainerHeld;
+
+[RegisterComponent]
+public sealed partial class ContainerHeldComponent: Component
+{
+ ///
+ /// The amount of weight needed to be in the container
+ /// in order for it to toggle it's appearance
+ /// to ToggleVisuals.Toggled = true, and
+ /// SetHeldPrefix() to "full" instead of "empty".
+ ///
+ [DataField("threshold")]
+ public int Threshold { get; private set; } = 1;
+}
diff --git a/Content.Shared/ContainerHeld/ContainerHeldSystem.cs b/Content.Shared/ContainerHeld/ContainerHeldSystem.cs
new file mode 100644
index 0000000000..e0ecfe1992
--- /dev/null
+++ b/Content.Shared/ContainerHeld/ContainerHeldSystem.cs
@@ -0,0 +1,43 @@
+using Robust.Shared.Containers;
+
+using Content.Shared.Item;
+using Content.Shared.Storage;
+using Content.Shared.Storage.EntitySystems;
+using Content.Shared.Toggleable;
+
+namespace Content.Shared.ContainerHeld;
+
+public sealed class ContainerHeldSystem : EntitySystem
+{
+ [Dependency] private readonly SharedItemSystem _item = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+ [Dependency] private readonly SharedStorageSystem _storage = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnContainerModified);
+ SubscribeLocalEvent(OnContainerModified);
+ }
+
+ private void OnContainerModified(EntityUid uid, ContainerHeldComponent comp, ContainerModifiedMessage args)
+ {
+ if (!(TryComp(uid, out var storage)
+ && TryComp(uid, out var appearance)
+ && TryComp(uid, out var item)))
+ {
+ return;
+ }
+ if (_storage.GetCumulativeItemSizes(uid, storage) >= comp.Threshold)
+ {
+ _item.SetHeldPrefix(uid, "full", item);
+ _appearance.SetData(uid, ToggleVisuals.Toggled, true, appearance);
+ }
+ else
+ {
+ _item.SetHeldPrefix(uid, "empty", item);
+ _appearance.SetData(uid, ToggleVisuals.Toggled, false, appearance);
+ }
+ }
+}
diff --git a/Resources/Prototypes/Entities/Objects/Fun/candy_bucket.yml b/Resources/Prototypes/Entities/Objects/Fun/candy_bucket.yml
new file mode 100644
index 0000000000..5bdf80f645
--- /dev/null
+++ b/Resources/Prototypes/Entities/Objects/Fun/candy_bucket.yml
@@ -0,0 +1,42 @@
+- type: entity
+ name: "candy bucket"
+ parent: BaseItem
+ id: CandyBucket
+ description: A festive bucket for all your treats.
+ components:
+ - type: Sprite
+ sprite: Objects/Fun/candy_bucket.rsi
+ layers:
+ - state: empty_icon
+ map: [ "enum.ToggleVisuals.Layer" ]
+ - type: ContainerHeld
+ threshold: 1
+ - type: Item
+ heldPrefix: empty
+ size: 20
+ - type: Appearance
+ - type: GenericVisualizer
+ visuals:
+ enum.ToggleVisuals.Toggled:
+ enum.ToggleVisuals.Layer:
+ True: {state: full_icon}
+ False: {state: empty_icon}
+ - type: Storage
+ maxItemSize: Small
+ maxTotalWeight: 10
+ whitelist:
+ components:
+ - Pill
+ tags:
+ - FoodSnack
+ - type: ContainerContainer
+ containers:
+ storagebase: !type:Container
+ ents: []
+ - type: UserInterface
+ interfaces:
+ - key: enum.StorageUiKey.Key
+ type: StorageBoundUserInterface
+ # to prevent bag open/honk spam
+ - type: UseDelay
+ delay: 0.5
diff --git a/Resources/Textures/Objects/Fun/candy_bucket.rsi/empty-inhand-left.png b/Resources/Textures/Objects/Fun/candy_bucket.rsi/empty-inhand-left.png
new file mode 100644
index 0000000000..b1a487b9ee
Binary files /dev/null and b/Resources/Textures/Objects/Fun/candy_bucket.rsi/empty-inhand-left.png differ
diff --git a/Resources/Textures/Objects/Fun/candy_bucket.rsi/empty-inhand-right.png b/Resources/Textures/Objects/Fun/candy_bucket.rsi/empty-inhand-right.png
new file mode 100644
index 0000000000..3cdffed9c3
Binary files /dev/null and b/Resources/Textures/Objects/Fun/candy_bucket.rsi/empty-inhand-right.png differ
diff --git a/Resources/Textures/Objects/Fun/candy_bucket.rsi/empty_icon.png b/Resources/Textures/Objects/Fun/candy_bucket.rsi/empty_icon.png
new file mode 100644
index 0000000000..b2216f0573
Binary files /dev/null and b/Resources/Textures/Objects/Fun/candy_bucket.rsi/empty_icon.png differ
diff --git a/Resources/Textures/Objects/Fun/candy_bucket.rsi/full-inhand-left.png b/Resources/Textures/Objects/Fun/candy_bucket.rsi/full-inhand-left.png
new file mode 100644
index 0000000000..2a804cffc5
Binary files /dev/null and b/Resources/Textures/Objects/Fun/candy_bucket.rsi/full-inhand-left.png differ
diff --git a/Resources/Textures/Objects/Fun/candy_bucket.rsi/full-inhand-right.png b/Resources/Textures/Objects/Fun/candy_bucket.rsi/full-inhand-right.png
new file mode 100644
index 0000000000..32a28cbaf9
Binary files /dev/null and b/Resources/Textures/Objects/Fun/candy_bucket.rsi/full-inhand-right.png differ
diff --git a/Resources/Textures/Objects/Fun/candy_bucket.rsi/full_icon.png b/Resources/Textures/Objects/Fun/candy_bucket.rsi/full_icon.png
new file mode 100644
index 0000000000..673d50f6ec
Binary files /dev/null and b/Resources/Textures/Objects/Fun/candy_bucket.rsi/full_icon.png differ
diff --git a/Resources/Textures/Objects/Fun/candy_bucket.rsi/meta.json b/Resources/Textures/Objects/Fun/candy_bucket.rsi/meta.json
new file mode 100644
index 0000000000..e5d850f948
--- /dev/null
+++ b/Resources/Textures/Objects/Fun/candy_bucket.rsi/meta.json
@@ -0,0 +1,33 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Made by @ps3moira#9488",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "empty_icon"
+ },
+ {
+ "name": "full_icon"
+ },
+ {
+ "name": "empty-inhand-right",
+ "directions": 4
+ },
+ {
+ "name": "empty-inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "full-inhand-right",
+ "directions": 4
+ },
+ {
+ "name": "full-inhand-left",
+ "directions": 4
+ }
+ ]
+}