diff --git a/demo/effect-integrator.html b/demo/effect-integrator.html
new file mode 100644
index 0000000..0927722
--- /dev/null
+++ b/demo/effect-integrator.html
@@ -0,0 +1,61 @@
+
+
+
+
+
+ Physics
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/common/EffectIntegrator.ts b/src/common/EffectIntegrator.ts
new file mode 100644
index 0000000..f50e849
--- /dev/null
+++ b/src/common/EffectIntegrator.ts
@@ -0,0 +1,119 @@
+import type { FolkShape } from '../folk-shape';
+
+/**
+ * Coordinates effects between multiple systems, integrating their proposals into a single result.
+ * Systems register, yield effects, and await integration when all systems are ready.
+ */
+export class EffectIntegrator {
+ private pending = new Map();
+ private systems = new Set();
+ private waiting = new Set();
+ private resolvers: ((value: Map) => void)[] = [];
+
+ /** Register a system to participate in effect integration */
+ register(id: string) {
+ this.systems.add(id);
+ return {
+ yield: (element: Element, effect: T) => {
+ if (!this.pending.has(element)) {
+ this.pending.set(element, []);
+ }
+ (this.pending.get(element)! as T[]).push(effect);
+ },
+
+ /** Wait for all systems to submit effects, then receive integrated results */
+ integrate: async (): Promise