diff --git a/PENDENZEN.md b/PENDENZEN.md
index cd5d2e0..8f69d50 100644
--- a/PENDENZEN.md
+++ b/PENDENZEN.md
@@ -18,6 +18,10 @@
---
+## 📅 Geplant
+
+- [ ] **truck-Integration (Profil-Extrusion / B-Rep)** — **Start: 2026-07-07 (Dienstag, nach Reset).** Nutzer zeichnet 2D-Querschnitt (L-Profil, T-Träger, Freiform) → truck-Extrusion → 3D-Körper + Boolean gegen Wand/Decke. Voraussetzung: truck-Booleans stabil + WASM-Integration. Umfang: ~4–6 Wochen. Mit Nutzer Scope/MVP klären vor Start.
+
## ⛔ Blocker (zuerst klären)
- [x] ~~**Toolchain prüfen**~~ — **ERLEDIGT 2026-07-04 (macOS-Gerät):** `node`/`npm`/`cargo` (1.96.0)/`wasm-pack` (0.15.0) alle vorhanden. `npm install` + `npm approve-scripts esbuild wasm-pack …` (npm gated Install-Scripts → `allowScripts`-Block in `package.json`, ungetrackt gelassen), `rustup target add wasm32-unknown-unknown`, beide WASM-Engines gebaut, Frontend gebaut, **`npm run tauri:build` → Mac-App (`cad.app` + `cad_0.1.0_aarch64.dmg`, arm64) läuft.** Verifikations-Baseline grün: `tsc --noEmit` sauber, `vitest run` 230/230, `cargo test render3d` 56/56. **Kein Blocker mehr für Engine-Slices auf diesem Gerät.**
diff --git a/src/App.tsx b/src/App.tsx
index c6eb0a4..77ec77f 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -69,7 +69,7 @@ import type { Pick3dHit } from "./viewport/Wasm3DViewport";
import { ResourceManager } from "./ui/ResourceManager";
import type { ResourceManagerHandlers } from "./ui/ResourceManager";
import { HatchSwatch } from "./ui/hatchPreview";
-import { TopBar, ViewRibbonTab } from "./ui/TopBar";
+import { TopBar, ViewRibbonTab, Ribbon3dTab } from "./ui/TopBar";
import { RibbonBar } from "./ui/ribbon/RibbonBar";
import type { RibbonTabId } from "./ui/ribbon/ribbonItems";
import { Dropdown } from "./ui/Dropdown";
@@ -3320,6 +3320,20 @@ export default function App() {
textTarget={textTarget}
/>
),
+ "3d": (
+
+ ),
}}
/>
diff --git a/src/ui/TopBar.tsx b/src/ui/TopBar.tsx
index 62ead48..9be63af 100644
--- a/src/ui/TopBar.tsx
+++ b/src/ui/TopBar.tsx
@@ -1262,6 +1262,99 @@ export function ViewRibbonTab({
);
}
+export interface Ribbon3dTabProps {
+ viewToggleEnabled: boolean;
+ viewType: ViewType;
+ onViewType: (v: ViewType) => void;
+ view3d: View3d;
+ onView3d: (v: View3d) => void;
+ fov: number;
+ onFov: (n: number) => void;
+ renderMode: RenderMode;
+ onRenderMode: (m: RenderMode) => void;
+ renderModeEnabled: boolean;
+}
+
+/** 3D-Tab des Ribbons — Kamera-Presets + Darstellungsart. Kein Duplikat des
+ * Ansichten-Tabs: hier nur 3D-relevante Steuerung (Blickwinkel, Rendermodus). */
+export function Ribbon3dTab({
+ viewToggleEnabled,
+ viewType,
+ onViewType,
+ view3d,
+ onView3d,
+ fov,
+ onFov,
+ renderMode,
+ onRenderMode,
+ renderModeEnabled,
+}: Ribbon3dTabProps) {
+ return (
+
+
+
+
+ {(
+ [
+ ["top", t("view3d.top")],
+ ["iso", t("view3d.iso")],
+ ["perspective", t("view3d.perspective")],
+ ["front", t("view3d.front")],
+ ["side", t("view3d.side")],
+ ] as [View3d, string][]
+ ).map(([key, label]) => (
+
+ ))}
+
+
+
+
+
+
+
+
+ );
+}
+
export function TopBar({
project,
ribbonTab,