  // Bjørnsveen adapter v1. Geometry stays with Layerling; print profiles stay in the shell.
  useEffect(() => {
    if (window.parent === window) return;
    let busy = false;
    const receive = async (event: MessageEvent) => {
      if (event.origin !== window.location.origin || event.source !== window.parent) return;
      const request = event.data;
      if (request?.channel !== "skaperstudio-v1" || request.type !== "export-model" || typeof request.id !== "string") return;
      const reply = (payload: Record<string, unknown>) => window.parent.postMessage({ channel: "skaperstudio-v1", id: request.id, ...payload }, window.location.origin);
      if (busy) { reply({ type: "model-error", message: "En eksport pågår allerede." }); return; }
      busy = true;
      try {
        const { visible } = visibleExportShapes(shapes);
        if (!visible.some((shape) => !shape.hole && !isNonSolidShape(shape))) throw new Error("Legg til en solid figur i 3D-prosjektet først.");
        const { solids, meshes, cut, holeCutsFailed } = await exportBodiesWithLooseHoles(visible);
        if (holeCutsFailed) throw new Error("Et hull kunne ikke beregnes. Rett modellen før eksport.");
        const result = await colorSeparatedExportMeshes(solids, meshes, cut);
        if (result.gescheitert) throw new Error("Deler av geometrien kunne ikke beregnes. Kontroller grupper og hull før eksport.");
        const bodies = result.meshes.map((mesh, index) => {
          const source = solids[result.quellen[index]];
          const parts = source ? multicolorExportSolids(source) : null;
          const faceColors = source && parts ? exportFaceColors(mesh, parts, source.color) : undefined;
          parts?.forEach(({ probe }) => { disposeBoundsTree.call(probe.geometry); probe.geometry.dispose(); (probe.material as THREE.Material).dispose(); });
          // Layerling's world is Y-up; Bambu and 3MF are Z-up.
          return { name: source?.name || mesh.name || "Del", color: source?.color || "#259c91", faceColors, vertices: mesh.vertices.map(([x, y, z]) => [x, -z, y]), faces: mesh.faces };
        });
        reply({ type: "model-ready", title: projectName, meshes: bodies });
      } catch (error) {
        reply({ type: "model-error", message: error instanceof Error ? error.message : "Kunne ikke hente modellen." });
      } finally { busy = false; }
    };
    window.addEventListener("message", receive);
    window.parent.postMessage({ channel: "skaperstudio-v1", type: "editor-ready" }, window.location.origin);
    return () => window.removeEventListener("message", receive);
  }, [shapes, projectName]);

