# BIM-Elementtiefe — Tür, Fenster, Dach, Decke ("wirklich 1:1")

## 0. Zweck und Abgrenzung

DOSSIER modelliert Bauteile heute semantisch (kein reines Zeichenprogramm) und
hat für Wand/Decke bereits eine mehrschichtige Aufbaulogik (`Component[]` via
`WallType`/`CeilingType`). Türen und Fenster haben seit
`docs/design/window-editor-vectorworks-study.md` einen dedizierten,
phasierten Ausbauplan (Flügeltabelle, Verglasung, Sonnenschutz). Was fehlt,
ist die gleiche Tiefe für **Dach** (keine Schichtlogik, keine Mansard-
Untertypen, kein Kehl-/Gaubenmodell) und für die **Decken-Randterminierung**
(Deckenrand als reines Polygon ohne Kantendetail).

Dieses Dokument nimmt die vier Bauteile Tür, Fenster, Dach, Decke und hält
sie gegen die reale Tiefe vollständiger BIM-Programme (Vectorworks Architektur,
ArchiCAD, Revit, Allplan). Ziel ist NICHT, jedes Feature dieser Programme zu
kopieren, sondern zu benennen, welche Lücken einen echten "1:1-Zuwachs" für
ein Einfamilienhaus-/Wohnbau-Tool wie DOSSIER bringen — und welche reiner
Ballast wären (Abschnitt 6).

Für Fenster/Tür dupliziert dieses Dokument NICHT die Mapping-Tabelle aus
`window-editor-vectorworks-study.md` — es referenziert sie und ergänzt, was
dort fehlt (v. a. Tür-Tiefe, die die Studie nur am Rand behandelt, und die
architektonischen Grenzen des heutigen Öffnungsmodells). Für Wand-Schichtlogik
siehe `docs/design/parametric-walls.md` (Raster/Modul-Regeln, nicht
Gegenstand hier) und `docs/design/elements.md` (ältere Gesamtplanung, Stand
vor der aktuellen `Component`/`Layer`-Implementierung — dort abweichende
Typnamen wie `Slab`/`ProfileDef`, hier durchgängig der IST-Code zitiert).

Alle IST-Aussagen sind mit Datei:Zeile belegt (verifiziert per Lesen des
Codes, Stand dieses Commits). Status-Legende der Lücken-Tabellen: **✓**
vorhanden und gerendert · **~** Feld existiert, Renderer liest es nicht oder
nur grob · **✗** fehlt vollständig. Priorität P0 (grösster 1:1-Zuwachs, bald)
… P3 (Ballast, nur auf Nachfrage). Aufwand grob in Personentagen (PT).

---

## 1. Gemeinsames Fundament: das Schicht-Muster

Der zentrale Baustein, den DOSSIER bereits hat und der sich wiederverwenden
lässt, ist `Component`/`Layer`:

- `Component` (`src/model/types.ts:196`) — ein Bauteil-Material: Poché-Farbe
  (`color`/`foreground`/`background`), Schnitt-Schraffur (`hatchId`) UND
  Ansichts-Schraffur (`viewHatchId`, für unaufgeschnittene Aufsicht),
  optionales PBR-Material (`material`), Kürzel (`abbrev`) und ein
  Verschneidungs-Rang (`joinPriority`, `types.ts:241`) für die Boolean-
  Dominanz am Stoss.
- `Layer` (`types.ts:245`) — eine Schicht: `componentId` + `thickness` +
  optionaler Fugen-Linienstil (`jointLineStyleId`).
- `WallType` (`types.ts:260`) und `CeilingType` (`types.ts:273`) sind BEIDE
  nur `{ id, name, layers: Layer[] }` — bewusst derselbe Typ, "das
  horizontale Gegenstück zum WallType" (Kommentar `types.ts:266-271`).

Das Muster ist also bereits zweimal (Wand, Decke) verifiziert:
`ceilingThickness()` (`types.ts:2104`) summiert die Layer-Dicken,
`emitSlabs()` (`src/plan/toWalls3d.ts:1352-1419`) stapelt sie im 3D als
einzelne `RSlab`-Scheiben proportional in `[zBottom, zTop]`, `addCeilingPoche`
(`src/plan/generatePlan.ts:2453`) zeichnet die Aufsicht mit der
Ansichts-Schraffur der ERSTEN Schicht, und `toSection.ts:633`
(`splitSlabLayers`) zerlegt die Decke im ECHTEN Schnitt in
Einzel-Bänder je Schicht (mit `resolveCeilingSectionStyle`,
`generatePlan.ts:591`, als Schraffur-/Farbquelle).

**Der Dach-Vorschlag in Abschnitt 4 ist im Kern: dasselbe Muster ein drittes
Mal anwenden.** Das ist der günstigste Weg zu echter Dach-1:1-Tiefe, weil
Layer-Resolver, Schraffur-Ketten (`resolveHatch`/`resolveForeground` etc.,
`generatePlan.ts:409-536`) und die 3D-Stapel-Logik bereits bestehen und nur
auf einen neuen Aufbau-Typ angewendet werden müssen statt neu erfunden.

Architektonische Randbemerkung: `Project` führt bereits `wallTypes`,
`ceilingTypes?`, `doorTypes?`, `windowTypes?`, `stairTypes?`
(`types.ts:1936-1958`) als eigene Bibliotheken — aber **kein `roofTypes?`**.
`Roof` (`types.ts:1022`) trägt nur ein einzelnes `thickness: number`
(`types.ts:1044`), keinen Aufbau-Verweis. Das ist die strukturelle Lücke,
die Abschnitt 4 schliesst.

---

## 2. Tür (Door)

### 2.1 Was ein vollständiges BIM-Tool bietet

| Bereich | Typische Parameter (VW/ArchiCAD/Revit/Allplan) |
|---|---|
| Bauart | Dreh-, Schiebe- (auf/vor Wand), Falt-, Pendel-, Karusselltür, reiner Durchbruch |
| Blattzahl/-teilung | 1-/2-flügelig, Gangflügel + Standflügel (unterschiedliche Breite), Seitenteile links/rechts |
| Blattausführung | glatt, kassettiert, Glasfüllung (Anteil/Sprossenbild), Brandschutz-/Schallschutz-Kennwert |
| Rahmen/Zarge | Zarge vs. Blockrahmen, Rahmenbreite je Kante, Zargentiefe, Bekleidung/Abdeckleiste, Falz |
| Schwelle | ohne, Alu-Flachschwelle, Anschlagdichtung, Bodenanschluss/Gefälle bei Aussentüren |
| Sturz/Oberlicht | festverglastes Oberlicht mit eigenem Rahmen, Kämpfer, Sprossenbild |
| Seitenteile | fest verglaste Seitenteile links/rechts, eigene Breite |
| Form | rechteckig, Rundbogen, Segmentbogen, Stichbogen — bei Aussen-/Haustüren verbreitet |
| Beschlag | Drücker/Knauf-Typ, Schild, Schliesszylinder, Bänder sichtbar/verdeckt |
| 2D-Darstellung | Blatt + Schwenkbogen (Grundriss), eigene Ansichtssymbolik in Schnitt/Elevation, Sturzlinien |
| Material/Schichten | Blatt-Kernaufbau (bei Brand-/Schallschutztüren mehrschichtig, analog Wand) |
| IFC-Rolle | `IfcDoor` mit `IfcDoorType` (PredefinedType), `OverallWidth/Height`, `IfcDoorPanelProperties`, Void in der Wirtswand |

### 2.2 IST in DOSSIER

`Opening` mit `kind: "door"` (`src/model/types.ts:1068`) referenziert
optional einen `DoorType` (`types.ts:296`). Vorhanden am Typ: `kind`
("dreh"/"schiebe"/"wandoeffnung", :303), `leafCount` (1|2, :305), `leafStyle`
("glatt"/"kassette"/"glas", :307), `glazingRatio` (:309), `frameThickness`/
`frameDepth`/`frameKind`("zarge"/"blockrahmen")/`frameWidth`
(:311-328), `insetFromFace`/`insetFace` (:335-337), `transomHeight` (:343),
`threshold` (:349). Am Element selbst: `swing`/`hinge`/`swingAngle`/
`openingDir` (:1104-1108), `lintelLines` (Sturzlinien, :1119) und
`doorType: "normal"|"wandoeffnung"` (:1100) — ein zweites, mit `DoorType.kind`
teilweise redundantes Feld.

Renderer-Konsum, real geprüft:

- **2D-Blatt ist IMMER einflügelig.** `addOpeningSymbol` (Tür-Zweig,
  `src/plan/generatePlan.ts:2091-2213`) zeichnet genau EINE Blattlinie
  (`sym.hinge → sym.openEnd`) und EINEN Schwenkbogen — `DoorType.leafCount`
  wird an keiner Stelle in `generatePlan.ts` gelesen (kein Treffer für
  `leafCount` im ganzen Plan-Renderer). Eine zweiflügelige Tür sieht im Plan
  aus wie eine einflügelige.
- **3D genauso**: `resolveOpeningFrame` (`src/plan/toWalls3d.ts:1861-1886`)
  setzt für Türen hart `wingCount: 1`, unabhängig von `leafCount`.
- `leafStyle` wirkt NUR binär: `"glas"` schaltet eine volle Verglasung frei
  (`glazed: dt.leafStyle === "glas"`, `toWalls3d.ts:1883`) — `glazingRatio`
  (Teilverglasung, z. B. 60 % Glasanteil im oberen Blattbereich) wird an
  keiner Stelle gelesen. "kassette" (Kassettentür) hat keine eigene Geometrie,
  fällt auf dieselbe Quader-Darstellung wie "glatt" zurück.
  `frameKind: "blockrahmen"` wirkt NUR im 2D-Rahmenband
  (`generatePlan.ts:1996`, `isBlock`), im 3D gibt es keinen Unterschied zur
  Zarge (`frameMeshesForOpening`, `toWalls3d.ts:1936`, kennt kein
  `frameKind`).
- `threshold` steuert `hasSill` im 3D-Rahmen (`toWalls3d.ts:1880`), was einen
  einfachen Schwellen-Riegel zeichnet — kein eigenes Schwellenprofil,
  keine Gefälle-/Dichtungsdarstellung.
- Es gibt eine ZWEITE, ältere Tür-Repräsentation: `Door`
  (`types.ts:1333`, `project.doors: Door[]`) mit eigenem Symbol-Renderer
  `addDoorSymbol` (`generatePlan.ts:1840-1899`) — strukturell identisch zum
  `Opening`-Pfad, aber ohne jeden Typ-Bezug. Zwei parallele Datenwege für
  dieselbe Bauteilart sind selbst technische Schuld, nicht nur ein
  BIM-Feature-Gap.
- Form (Rundbogen etc.) existiert nicht: `Opening.width`/`height` sind ein
  reines Rechteck, `wallGaps`/`buildWallFootprints`
  (`generatePlan.ts:1363-1457`) schneiden nur rechteckige Bänder aus der
  Wand-Poché.
- IFC-Export: `IfcDoor` wird erzeugt (`src/export/exportIfc.ts:30-31`), aber
  als reine Box-Geometrie ohne `IfcDoorType`/`PredefinedType` und ohne
  `IfcOpeningElement`-Void (bewusste Design-Entscheidung, siehe Kommentar
  `exportIfc.ts:18-31`: das Loch steckt bereits im geschnittenen Wand-Mesh).

### 2.3 Lücken (Tür)

| Feature | Status | Priorität | Aufwand |
|---|---|---|---|
| Zweiflügelige Tür rendert 2 Blätter (2D+3D) | ✗ (`leafCount` ungelesen) | **P0** | 2 PT |
| Teilverglasung nach `glazingRatio` (2D-Linie + 3D-Split) | ✗ | P1 | 1.5 PT |
| Kassettentür eigene Blattgeometrie (Füllungsfelder) | ✗ | P2 | 2 PT |
| `frameKind` (Blockrahmen) auch im 3D wirksam | ~ | P1 | 1 PT |
| Seitenteile (feste Verglasung links/rechts der Tür) | ✗ | P1 | 2 PT |
| Rundbogen-/Segmentbogen-Türform | ✗ | P2 | 4 PT (braucht gekrümmten Wandausschnitt, s. §5.3) |
| Schwellenprofil (Alu-Flachschwelle, Dichtung) statt Riegel | ✗ | P2 | 1 PT |
| `Door`/`Opening`-Doppelpfad konsolidieren | technische Schuld | P1 | 3 PT (Migration) |
| Beschlag (Drücker/Knauf) als Mesh + 2D-Symbol | ✗ | P2 | 1.5 PT |
| IFC `IfcDoorType`/PredefinedType/OverallWidth-Height-Properties | ~ | P2 | 1 PT |

### 2.4 Umsetzungsvorschlag

**Modell**: `DoorType.leafs?: { width: number; hingeSide: "left"|"right";
fixed?: boolean }[]` analog `WindowType.sashes` (`SashDef`, `types.ts:367`) —
bewusst dieselbe Struktur, damit `resolveSashSpans` (`toWalls3d.ts:2019`) UND
die 2D-Pfostenlinien-Logik direkt wiederverwendet werden können, statt eine
Tür-eigene Variante zu bauen. Ein `fixed: true`-Leaf ist das Seitenteil.
`glazingRatio` wandert vom Skalar zu einer klaren Geometrie: Kämpferhöhe
innerhalb des Blatts, gerendert wie das bestehende Oberlicht
(`transomHeight`), nur INNERHALB des Blattrahmens statt darüber.

**2D**: `addOpeningSymbol` (Tür-Zweig) über die Leaf-Liste iterieren statt
einer festen Blattlinie; pro Leaf ein eigenes `hinge`/`swing` (Default:
alternierend wie bei Fenstern, `sashesOfWindowType`, `types.ts:2132`).

**3D**: `resolveOpeningFrame` liefert `wingCount = leafs.length` statt hart 1;
`frameMeshesForOpening` (bereits generisch über `params.sashes`) übernimmt
die Mehrflügel-Darstellung ohne Änderung — das ist der Vorteil der
Struktur-Wiederverwendung.

**UI**: Im Tür-Editor (sofern nach dem Muster von
`window-editor-vectorworks-study.md` gebaut) eine Flügeltabelle wie bei
Fenstern, nur mit Tür-Vokabular (Gangflügel/Standflügel statt Flügel 1/2).

---

## 3. Fenster (Window)

Für Fenster existiert bereits eine vollständige Referenzmatrix in
`docs/design/window-editor-vectorworks-study.md` §2 (Basiseinstellungen,
Grösse, Brüstung, Rahmen, Flügeltabelle, Laibung/Form/Ober-Unterlicht,
Sonnenschutz/Beschlag, Attribute/IFC) mit eigener P0–P3-Phasierung. Diese
Studie ist der massgebliche Bezugspunkt; hier nur die Delta-Punkte, die dort
fehlen oder seither vom IST abweichen.

### 3.1 IST-Ergänzung (was die Studie nicht/knapp behandelt)

- `WindowType.glazing` (einfach/zweifach/dreifach) ist bis heute NICHT
  renderwirksam — bestätigt weiterhin: `glazingPanesOf()` (`types.ts:2149`)
  wird von `glassPanesForOpening` in `toWalls3d.ts` konsumiert, aber die
  Studie selbst vermerkt (Zeile 61-65 dort), dass der 2D-Pfad die
  Scheibenzahl weiterhin allein aus `DetailLevel` ableitet, nicht aus
  `glazingPanes`. Das ist über ein Jahr nach der Studie noch offen — ein
  Hinweis, dass P0/P1-Posten aus Fenster-Studien real liegen bleiben, wenn
  niemand sie explizit nachzieht.
- `sillBoard` (Fensterbank keine/innen/aussen/beide, `types.ts:447`) ist
  weiterhin ungenutzt (kein Treffer für `sillBoard` in `toWalls3d.ts` oder
  `generatePlan.ts` ausserhalb der Typ-Definition und des Editors) —
  entspricht dem in der Studie als P1 markierten "Fensterbank erstellen".

### 3.2 Architektonische Grenze: gekrümmte Öffnungen

Sowohl die Fenster-Studie (§2.6, "Form Eckig/Schräg/Spitz/Rund", P2, 4 PT)
als auch dieser Auftrag nennen Rundbogen-/Spitzbogenfenster. Das ist teurer,
als die Aufwandschätzung suggeriert, weil das gesamte Öffnungsmodell auf
GERADEN Bändern basiert: `buildWallFootprints`/`wallGaps`
(`generatePlan.ts:1363-1457`) schneiden ein rechteckiges Intervall `[from,to]`
entlang der Wandachse aus der Poché, `openingAxisBox`
(`toWalls3d.ts:1739`) baut im 3D ebenso einen achsparallelen Quader. Eine
Bogenform braucht entweder (a) eine gekrümmte Zusatzkontur, die die
Rechteck-Aussparung oben kappt (2D: zusätzliche Polygon-Boolean gegen die
Poché; 3D: gekrümmte Deckfläche statt ebenem Sturz) oder (b) ein komplett
neues, polygonbasiertes Öffnungsmodell. Vorschlag: (a) zuerst — ein
`headShape: "eckig"|"segment"|"spitz"|"rund"` mit Zusatzparametern
(Stichhöhe/Radius), das NUR die obere Kante der bestehenden Rechteck-Öffnung
ersetzt, während Pfosten/Sohlbank rechteckig bleiben. Deckt die reale
Mehrheit der Fälle (Haustür mit Rundbogen, Dachflächenfenster-Giebel) ohne
das Kernmodell umzubauen.

### 3.3 Lücken (Fenster, Delta zur Studie)

| Feature | Status | Priorität | Aufwand |
|---|---|---|---|
| `glazing`/`glazingPanes` 2D-wirksam (Scheibenzahl statt nur DetailLevel) | ~ (weiter offen seit Studie) | **P0** | 1 PT |
| `sillBoard` gerendert (2D-Kontur + 3D-Box) | ✗ | P1 | 2 PT |
| Kopfform (Rundbogen/Spitzbogen/Schräge) über Zusatzkontur | ✗ | P2 | 5 PT (s. §3.2) |
| Echtes Sprossengitter (Glasteilung UNABHÄNGIG von Flügelrahmen) | ✗ | P1 | 2 PT |
| Alle übrigen Fenster-Lücken | siehe window-editor-vectorworks-study.md §2/§4 | — | — |

---

## 4. Dach (Roof)

### 4.1 Was ein vollständiges BIM-Tool bietet

| Bereich | Typische Parameter |
|---|---|
| Grundform | Pult, Sattel, Walm, Krüppelwalm, Zeltdach, Mansarde (mit Untertyp Giebel-/Walm-/Zeltmansarde), Flach/Terrassendach, Sheddach, Tonnendach, freie Neigungsflächen je Kante |
| Grundriss | beliebiges Polygon (nicht nur Rechteck), automatische Kehlen/Grate über Straight-Skeleton bei L-/T-/U-Grundrissen |
| Neigung | je Dachfläche einzeln editierbar, unterschiedliche Neigungen je Seite |
| Schichtaufbau | Eindeckung (Ziegel/Blech/Bitumen), Lattung, Konterlattung, Unterdach/-spannbahn, Sparren/Dämmung zwischen Sparren, Dampfbremse, Innenverkleidung — analog Wandaufbau, mit Deckenanschluss |
| Überstand | Traufe und Ortgang UNABHÄNGIG editierbar (Betrag + Ausbildung), Aufschiebling (Neigungsknick am Traufende), Ortganddetail (Windbrett, Blech) |
| Kniestock/Drempel | vertikale Wandaufkantung zwischen Deckenoberkante und Dach-Traufpunkt, definiert First-/Trauf-Geometrie mit |
| Öffnungen im Dach | Dachflächenfenster (schräg, in der Dachebene), Dachgauben (Schlepp-, Sattel-, Walm-, Spitzgaube, Fledermausgaube) als eigenständige Sekundärdächer mit eigenem First |
| First/Grat/Kehl/Ortgang | eigene Linientypen in 2D-Ansicht (Dachaufsicht) UND im Schnitt sichtbar (Sparrenlage, Dämmstärke) |
| Material/Poché | Dachfläche in der Aufsicht mit Eindeckungs-Symbol/-Schraffur (Ziegel-Textur o. Ä.), im Schnitt Vollschichten wie eine geneigte Wand |
| IFC-Rolle | `IfcRoof` (aggregiert `IfcRoofType`), Dachflächen selbst oft als `IfcSlab`-artige Elemente mit `IfcMaterialLayerSetUsage`, Gauben als eigene `IfcRoof`/`IfcBuildingElementProxy`-Unterobjekte |

### 4.2 IST in DOSSIER

`Roof` (`src/model/types.ts:1022-1047`) rechnet ausschliesslich auf der
**Bounding-Box** des Umrisses (Kommentar `types.ts:1016-1020`: "First entlang
einer Hauptachse ... die gängige, intuitive Vereinfachung"). Geometrie kommt
aus `roofGeometry()`/`computeCanonical()` (`src/geometry/roof.ts:80-267`),
explizit **"ohne Straight-Skeleton"** (Kommentar `roof.ts:5`). Unterstützte
`RoofShape` (`types.ts:1013`): flach/pult/sattel/walm/mansarde/zelt — je EINE
feste Berechnung, keine Untertypen. Mansarde hat eine feste, nicht editierbare
Knick-Geometrie (`d1 = halfD * 0.4`, `roof.ts:181` — 40 % der Tiefe von der
Traufe, hart codiert, keine Möglichkeit den Umbruchpunkt zu verschieben).

Konkrete, verifizierte Lücken:

- **Kein Schichtaufbau.** `Roof.thickness` (`types.ts:1044`) ist ein
  einzelner Skalar. Er wird an KEINER Stelle im Code gelesen (`grep
  "roof.thickness"` über `toWalls3d.ts`/`generatePlan.ts`/`roof.ts` liefert
  null Treffer) — das Feld existiert im Typ, ist aber komplett tot. Die
  3D-Dachfläche ist eine unendlich dünne, einfarbige Fläche
  (`emitRoofs()`, `src/plan/toWalls3d.ts:1670-1684`: nur `plane.pts`/
  `gable`-Fans, EINE Farbe `ROOF_RGB` bzw. `roof.color`, keine Dicke, keine
  Materialschichten).
- **Kein `RoofType`.** `Project` hat `wallTypes`, `ceilingTypes?`,
  `doorTypes?`, `windowTypes?`, `stairTypes?` (`types.ts:1936-1958`), aber
  kein `roofTypes?`. Es gibt keinen Bauteil-Bibliothekseintrag für Dächer.
- **2D-Grundriss zeigt keine Poché.** `addRoof()`
  (`src/plan/generatePlan.ts:2549-2605`) zeichnet AUSSCHLIESSLICH Linien
  (Traufe/First/Grat/Knick, je feste Strichstärke `ROOF_EAVES_MM`/
  `ROOF_RIDGE_MM`/`ROOF_HIP_MM`) — keine Fläche, keine Schraffur, keine
  Materialkennzeichnung. Deckungsgleich mit Wand/Decke, die BEIDE eine
  Poché-Füllung mit Schraffur haben (`addWallPoche`, `addCeilingPoche`),
  bleibt das Dach in der Aufsicht ein reines Liniendiagramm.
- **Kein Schnitt.** `src/plan/toSection.ts` hat KEINE Roof-Behandlung (kein
  Treffer für `roof`/`Roof` im gesamten Datei-Grep). Ein Vertikalschnitt
  durch ein Gebäude mit Satteldach zeigt heute keine Dachlinie, keine
  Sparrenlage, keine Firstprojektion — ein Kernstück der BIM-1:1-Erwartung
  fehlt vollständig.
- **Kein IFC.** `exportIfc.ts` erzeugt `IfcWall`, `IfcSlab`, `IfcDoor`/
  `IfcWindow`, `IfcStair`, `IfcBuildingElementProxy` (Kommentar
  `exportIfc.ts:18-36`) — `Roof`/`IfcRoof` ist in der Abbildungsliste NICHT
  aufgeführt und wird beim Export komplett übersprungen.
- **Kein Straight-Skeleton, kein L-Grundriss mit Kehle.** Ein L-förmiger
  Baukörper mit durchgehendem Satteldach (Kehle an der Innenecke) lässt sich
  nicht abbilden — die BBox-Rechnung würde ein Rechteck über die ganze
  L-Ausdehnung legen.
- **Keine Gauben, keine Dachfenster.** Kein Treffer für Gaube/Dormer im
  gesamten `src`-Baum (verifiziert per Suche).
- **Kein Kniestock als Bauteilbeziehung.** `baseElevation` (`types.ts:1042`)
  erlaubt zwar, die Traufhöhe manuell über die Geschoss-Oberkante zu heben
  (ein Kommentar in `ObjectInfoPanel.tsx:549` erwähnt das explizit als
  Nutzungsmuster), aber es gibt keine Wand-Dach-Kopplung, die einen
  Drempel/Kniestock als eigenes, vermasstes Bauteil führt — der Nutzer muss
  die Zahl manuell abstimmen.
- **Traufe/Ortgang nicht unabhängig.** `overhang` (`types.ts:1038`) ist EIN
  Wert "ringsum" — Traufüberstand und Ortgangüberstand (oft unterschiedlich,
  z. B. 0.5 m Traufe / 0.3 m Ortgang) sind nicht trennbar.
- **UI**: `ObjectInfoPanel.tsx:479-561` bietet volle Instanz-Bearbeitung
  (shape/ridgeAxis/pitch/pitchUpper/width/depth/overhang/thickness/
  baseElevation), aber keine Typ-/Stil-Verwaltung (kein `ResourceManager`-
  Eintrag für Dächer, anders als Wand/Decke/Tür/Fenster/Treppe).

### 4.3 Dach-Schichtlogik — konkreter Vorschlag (Kernthema dieses Dokuments)

Der Vorschlag überträgt exakt das `WallType`/`CeilingType`-Muster:

```
export interface RoofType {
  id: string;
  name: string;
  /** Aussen (Eindeckung) → innen (Verkleidung), analog WallType.layers. */
  layers: Layer[];
}
```

Kein neuer Layer-Typ nötig — `Layer` (`types.ts:245`) ist bereits
"Bauteil + Dicke + optionaler Fugen-Linienstil", unabhängig davon ob sie
horizontal (Decke), vertikal (Wand) oder GENEIGT (Dach) gestapelt wird, weil
die Stapel-Richtung beim jeweiligen Renderer entschieden wird, nicht im
Datentyp. Typische Schichtfolge eines Steildachs (Eindeckung → Konterlattung
→ Lattung → Unterdach/Unterdeckbahn → Sparren+Dämmung → Dampfbremse →
Innenverkleidung/GKB) bildet sich 1:1 auf `Layer[]` ab, jede Schicht bekommt
ein `Component` mit eigener Schraffur/Farbe/Material wie bei Wand/Decke.

`Roof.thickness: number` wird zu `Roof.roofTypeId?: string` (Verweis, analog
`Ceiling.ceilingTypeId`) mit optionaler `thicknessOverride?: number` — exakt
das Muster aus `Ceiling.thickness?` (`types.ts:952-953`, "Optionale
Übersteuerung der Gesamtdicke ... sonst Typ-Dicke"). `Project.roofTypes?:
RoofType[]` ergänzt die Bibliothek.

**3D-Konsum**: `emitRoofs()` (`toWalls3d.ts:1670`) baut heute EINE
Dreiecksfläche je Dachfläche+Giebel. Mit Layern wird daraus — analog
`emitSlabs()` (`toWalls3d.ts:1352-1419`, das bereits genau diese
Proportional-Stapel-Logik für Decken hat) — ein Stapel PARALLEL versetzter
Flächen entlang der Flächennormalen (nicht entlang Z wie bei der Decke,
sondern entlang der Dachflächen-Normalen `n`, siehe `RoofGeometry.planes`
in `roof.ts:19-21`). Jede Schicht wird zum eigenen `RMesh` mit eigener Farbe/
Schraffur-Metadaten (`RCutMeta`, wie bei `emitSlabs`). Der Versatz macht
zugleich die Dachdicke sichtbar (heute unendlich dünn) — ein Nebengewinn ohne
Mehraufwand.

**2D-Konsum (Grundriss/Aufsicht)**: `addRoof()` bekommt eine Poché-Fläche
analog `addCeilingPoche` — Füllung mit der `viewHatchId` der obersten Schicht
(Eindeckungssymbol), gerahmt von den bestehenden Traufe/First/Grat/Knick-
Linien (die bleiben unverändert, sie sind flächen-unabhängig).

**2D-Konsum (Schnitt, der grössere Umbau)**: `toSection.ts` braucht einen
neuen Roof-Zweig. Ansatz: die Dachebene mit der Schnittebene schneiden
(Ebene-Ebene-Schnitt, da `RoofPlane` eben ist), daraus ein Liniensegment je
betroffener Dachfläche gewinnen, dann `Layer[]` senkrecht ZUR
Dachneigung als Bandsequenz auftragen (wie `resolveWallBands`,
`toWalls3d.ts:521`, aber gedreht um den Neigungswinkel `pitchDeg`) und mit
`splitSlabLayers`-Logik (`toSection.ts:633`) füllen. Das ist der aufwendigste
Einzelposten dieses Dokuments (siehe Prioritätsliste), aber ohne ihn bleibt
"Dach im Schnitt" eine reine Lücke.

**UI**: Ein `RoofType`-Eintrag im `ResourceManager`
(`src/ui/ResourceManager.tsx`), identisch zum bestehenden Ceiling-Typ-Editor
(Schicht-Liste, Dicke, Bauteil-Zuweisung) — kein neues UI-Paradigma.

### 4.4 Dach 1:1 — Formen, Kehlen, Gauben (konkreter Vorschlag)

Reihenfolge nach Aufwand/Nutzen, NICHT alles auf einmal:

1. **Traufe/Ortgang trennen**: `overhang` → `{ eaves: number; gable: number
   }`. Kleine, lokale Änderung in `roof.ts` (zwei statt einer Offset-Variable
   je nach Kantentyp), grosser optischer Gewinn (das ist die häufigste
   Rückmeldung "sieht nicht echt aus" bei Steildächern mit gleich langem
   Überstand allseitig).
2. **Mansard-Untertyp** (`mansardVariant: "walm"|"giebel"|"zelt"`, wie in der
   älteren Planung `elements.md:298` bereits vorgesehen, aber nie gebaut):
   steuert nur, wie die STIRNSEITE der Mansarde behandelt wird (heute IMMER
   `gables` = vertikale Giebelfläche, `roof.ts:200-203`) — bei "walm" wird
   daraus eine geneigte Fläche wie beim Walmdach. Mittlerer Aufwand, da die
   Mansard-Berechnung (`roof.ts:176-206`) bereits alle Eckpunkte hat, nur die
   Gable-Erzeugung muss konditional werden.
3. **Editierbarer Mansard-Knickpunkt** (`kinkDepthRatio?: number` statt hart
   `0.4`, `roof.ts:181`) — 0.5 PT, reine Parametrisierung einer bestehenden
   Konstante.
4. **Krüppelwalm** (`hipTruncation?: number`, 0 = voller Walm, 1 = voller
   Giebel/Sattel): der First bleibt voll lang, nur ein kleines Walmstück am
   First-Ende — technisch eine Variation der bestehenden `walm`-Berechnung
   (`roof.ts:147-174`, der First-Verkürzungs-Faktor `halfD` wird
   parametrisiert statt fix).
5. **Dachflächenfenster** (kein neues Bauteil — ein `Opening`-ähnliches
   Element, das in eine Dachfläche statt eine Wand einschneidet): neuer
   `hostRoofId`-Pfad, eigenständiger Vorschlag; lohnt sich erst NACH der
   Schichtlogik, weil das Fenster sonst nicht "in die Dämmebene" passt.
6. **Gauben** (Schlepp-/Sattelgaube als eigenständiges Sekundär-`Roof` mit
   eigenem `outline`/`baseElevation`, das in die Hauptdachfläche einschneidet):
   grösster Einzelposten, weil er eine echte Boolean-Verschneidung zwischen
   zwei Dachkörpern braucht (ähnlich der bestehenden Wand-Boolean-Dominanz
   über `joinPriority`, aber räumlich in 3D). Realistisch erst nach einem
   Mesh-Boolean-Werkzeug (die begonnene truck-Integration,
   `src-tauri/trucksolid/`, ist ein Kandidat dafür).
7. **L-/T-Grundriss mit Kehle (Straight-Skeleton)**: bewusst NICHT vor 6,
   weil es die Bounding-Box-Vereinfachung komplett ersetzt (neue
   Geometrie-Engine, kein inkrementeller Ausbau von `roof.ts`) — separates,
   grosses Vorhaben, siehe Prioritätsliste.

### 4.5 Lücken (Dach)

| Feature | Status | Priorität | Aufwand |
|---|---|---|---|
| `RoofType`/`Layer[]`-Schichtaufbau (Modell) | ✗ (`thickness` toter Skalar) | **P0** | 3 PT |
| 3D-Schichten (gestapelte Flächen entlang Normalen) | ✗ | **P0** | 3 PT |
| 2D-Aufsicht-Poché (Eindeckungssymbol) | ✗ | P1 | 1.5 PT |
| Dach im Vertikalschnitt (Ebene-Ebene-Schnitt + Bänder) | ✗ | **P0** | 5 PT |
| Traufe/Ortgang getrennter Überstand | ✗ | **P0** | 1 PT |
| Mansard-Untertyp (Walm/Giebel/Zelt-Stirn) | ✗ | P1 | 2 PT |
| Editierbarer Mansard-Knick | ✗ | P2 | 0.5 PT |
| Krüppelwalm | ✗ | P2 | 1.5 PT |
| Dachflächenfenster | ✗ | P2 | 4 PT |
| Gauben (Boolean-Einschnitt) | ✗ | P3 | 8+ PT |
| L-/T-Grundriss, Straight-Skeleton-Kehle | ✗ | P3 | 10+ PT |
| `RoofType`-Ressourcen-UI | ✗ | P1 (folgt aus RoofType) | 1 PT |
| IFC `IfcRoof`-Export | ✗ | P2 | 1.5 PT |

---

## 5. Decke (Ceiling / Slab)

### 5.1 Was ein vollständiges BIM-Tool bietet

| Bereich | Typische Parameter |
|---|---|
| Grundfläche | beliebiges Polygon inkl. Aussparungen (Treppenauge, Schacht, Kamindurchbruch) |
| Schichtaufbau | Rohdecke, Trittschalldämmung, Estrich, Bodenbelag — analog Wand, mit Deckenspiegel/Untersicht (abgehängte Decke, Akustikplatten) als eigene Schicht(en) |
| Randausbildung | gerader Rand, auskragender Balkon-/Vordachrand mit thermischer Trennung (Isokorb/Randdämmstreifen), Randschalung/Abschalungsprofil, Attika-Anschluss, Tropfkante |
| Deckenspiegel | abgehängte Untersicht mit eigener Höhe/Raster (Akustik-/Gipskarton-Decke), UNABHÄNGIG von der tragenden Rohdecke |
| Öffnungen | Deckenaussparungen als eigene, editierbare Polygone (nicht nur Gesamtumriss) |
| Neigung | geneigte Decke (Garagenrampe, Terrasse mit Gefälle) — nicht nur horizontal |
| 2D-Darstellung | Aufsicht mit Ansichts-Poché (unaufgeschnitten), Schnitt mit Vollschichten je Lage, Deckenspiegel-Plan (reflected ceiling plan) als eigene Zeichnungsart |
| IFC-Rolle | `IfcSlab` (PredefinedType FLOOR/ROOF/BASESLAB), `IfcMaterialLayerSetUsage` für den Schichtaufbau, `IfcCovering` für abgehängte Decken |

### 5.2 IST in DOSSIER

`Ceiling` (`types.ts:928-1000`) hat bereits die stärkste Tiefe der vier
Bauteile in diesem Dokument: geschlossenes Umriss-Polygon (`outline`),
`ceilingTypeId` mit Legacy-Fallback auf `wallTypeId` (`getCeilingType`,
`types.ts:2089`), volle Attribut-Override-Kette (`foreground`/`background`/
`strokeWeight`/`hatchId` + `*Source`, wie bei `Wall`) und unabhängige
vertikale Bindung von OK/UK über `VerticalAnchor` (`top?`/`bottom?`,
`types.ts:990-999` — "floor"-gebunden oder "custom"-Z, exakt wie bei
`Wall.top`/`Wall.bottom`, `types.ts:887-893`). 3D-Schichtstapel ist
implementiert (`emitSlabs`, `toWalls3d.ts:1352-1419`), Schnitt-Schichtsplit
ebenfalls (`splitSlabLayers`, `toSection.ts:633`).

Verifizierte Lücken:

- **Keine Aussparungen.** `Ceiling.outline: Vec2[]` ist EIN geschlossenes
  Polygon (`types.ts:936-939`) — kein `openings?: Vec2[][]` für
  Treppenauge/Schacht/Kamin. Ein Treppenloch in der Decke muss heute über
  die Aussenkontur der Decke "herumgeschnitten" werden (Decke als
  komplexes, nicht-konvexes Polygon), nicht als saubere Innenaussparung.
  (`elements.md:217` sah dieses Feld in der älteren Planung explizit vor,
  es wurde nie in `types.ts` übernommen.)
- **Kein Randdetail.** Die Decke ist über die gesamte `outline` exakt
  `thickness` dick, EINHEITLICH. Es gibt kein Feld für eine abweichende
  Randausbildung (Aufkantung, Randdämmstreifen, Tropfkante, andere Dicke am
  Balkonrand). Ein auskragender Balkon lässt sich zwar über eine erweiterte
  `outline` modellieren, bekommt aber zwangsläufig denselben Vollschicht-
  Aufbau wie die Innendecke — eine thermisch getrennte Balkonplatte
  (Isokorb) ist nicht abbildbar.
- **Kein Deckenspiegel.** Abgehängte Untersicht (Akustik-/GKB-Decke mit
  eigener, tieferer Kote) existiert nicht als eigenes Konzept — nur der
  tragende Aufbau über `ceilingTypeId`.
  Ein "Deckenspiegel-Plan" (reflected ceiling plan) fehlt als Zeichnungsart
  komplett (`DrawingLevelKind`, `types.ts:722`, kennt nur "floor"/"section"/
  "elevation"/"drawing").
  (Randbemerkung: Beleuchtungsplanung/Deckenspiegel ist ein Elektro-Thema und
  damit bewusst ausserhalb des DOSSIER-Kernscopes — siehe "nicht bauen",
  Abschnitt 6. Die reine Geometrie einer zweiten, tiefer liegenden Fläche
  bleibt aber ein legitimer BIM-1:1-Punkt.)
- **Keine Neigung.** `top`/`bottom` sind je EIN `VerticalAnchor` (ein
  Z-Wert), keine Neigungsebene — eine geneigte Garagen-/Terrassendecke ist
  nicht modellierbar, nur über mehrere ebene Teildecken behelfsweise
  annäherbar.
- **2D-Aufsicht nutzt nur die erste Schicht.** `addCeilingPoche`
  (`generatePlan.ts:2453-2536`) liest `wt.layers[0]` (Kommentar/Code
  `generatePlan.ts:2465`) für die Ansichts-Schraffur — bei einer
  mehrschichtigen Decke (z. B. Beton unten, Dämmung oben) zeigt die Aufsicht
  immer nur die OBERSTE (erste) Schicht, was für eine unaufgeschnittene
  Draufsicht baupraktisch korrekt ist (man sieht von unten die
  Untersicht/erste Lage), aber nicht konfigurierbar ist, welche Lage als
  "sichtbare" gilt, falls der Deckenaufbau umgekehrt sortiert wäre.
- IFC: `IfcSlab` wird erzeugt (`exportIfc.ts:28`), aber laut Kopfkommentar
  (`exportIfc.ts:38-41`) bewusst OHNE `IfcMaterialLayerSet`/-`Usage` — der
  Export verliert den Schichtaufbau, den DOSSIER intern bereits hat.

### 5.3 Deckenrand/Randterminierung — vertieft

Der Nutzer nennt explizit "Deckenränder, Stirnabschlüsse, Anschluss an Wand/
Aussenkante, auskragende Ränder, Randabschalung" als Schwerpunkt. IST-Bild:
keines davon existiert als eigenes Konzept — die Decke ist ein reines
Extrusions-Polygon. Konkreter Vorschlag, dreistufig nach Aufwand:

1. **Aussparungen** (`Ceiling.openings?: Vec2[][]`) — niedrigster Aufwand,
   grösster praktischer Nutzen (Treppenauge ist im Wohnbau der Regelfall,
   nicht die Ausnahme). 2D: zusätzliche Ausschnitts-Polygone in
   `addCeilingPoche` (Loch im Fill, zusätzliche Randlinien). 3D: `emitSlabs`
   bekommt Löcher im Extrusions-Profil (analog dem bereits vorhandenen
   Loch-Schnitt bei Wand-Öffnungen, `wallMeshCut.ts`, als Vorlage).
2. **Randschicht-Override** (`Ceiling.edgeOverride?: { ringOffset: number;
   ceilingTypeId: string }` — ein schmaler Innenring der Decke entlang des
   Randes bekommt einen ANDEREN Layer-Aufbau, z. B. mit zusätzlicher
   Randdämmschicht oder reduzierter Dicke für eine Tropfkante). Technisch:
   `emitSlabs` erzeugt für den Ringbereich einen zweiten Layer-Stapel mit dem
   Override-Typ, geometrisch als Offset-Polygon-Differenz (`outline` minus
   `outline.offset(-ringOffset)`), eine Operation, die für Wandbänder
   bereits ähnlich existiert (`buildWallFootprints`).
3. **Thermisch getrennte Auskragung (Isokorb-Fall)**: ein eigenes,
   sekundäres `Ceiling`-Objekt für den auskragenden Teil mit eigenem
   `ceilingTypeId` (dünnerer/anderer Aufbau) UND eigener `top`/`bottom`-
   Bindung, das an die Hauptdecke stösst — kein neues Feld nötig, nur eine
   UI-Erleichterung ("Deckenrand abtrennen"-Werkzeug, das die Decke entlang
   einer gewählten Kante in zwei `Ceiling`-Objekte teilt). Niedrigster
   Modell-Aufwand, weil er das bestehende Mehrfach-Decken-Prinzip nutzt statt
   ein neues Konzept einzuführen.

### 5.4 Lücken (Decke)

| Feature | Status | Priorität | Aufwand |
|---|---|---|---|
| Aussparungen (`openings?: Vec2[][]`) in 2D+3D | ✗ | **P0** | 3 PT |
| Randschicht-Override (Ringzone anderer Aufbau) | ✗ | P1 | 3 PT |
| Deckentrenn-Werkzeug für Isokorb-Fall (UI, kein neues Modellfeld) | ✗ | P1 | 1.5 PT |
| Geneigte Decke (Rampe/Gefälle) | ✗ | P2 | 3 PT |
| Deckenspiegel (zweite, abgehängte Fläche) | ✗ | P3 | 2 PT (reine Geometrie) |
| IFC `IfcMaterialLayerSetUsage` für Decke (UND Wand) | ~ (bewusst ausgelassen) | P2 | 2 PT |
| Konfigurierbare "oberste Schicht" für Aufsicht-Poché | ✓ implizit (Layer-Reihenfolge = Sortierung) | — | — |

---

## 6. Konsolidierte Priorisierung (über alle vier Bauteile)

Sortiert nach "1:1-Zuwachs pro Aufwand", nicht nach Aufwand allein:

1. **Dach-Schichtaufbau (Modell + 3D-Stapel)** — schliesst die grösste
   strukturelle Lücke (totes `thickness`-Feld, kein `RoofType`) und liefert
   sofort sichtbaren Tiefengewinn im 3D (§4.3, ~6 PT gesamt).
2. **Traufe/Ortgang getrennter Überstand** — 1 PT, sofortiger optischer
   Sprung bei jedem Steildach-Projekt (§4.4 Punkt 1).
3. **Zweiflügelige Tür rendert wirklich 2 Blätter** — das `leafCount`-Feld
   existiert seit der Türtyp-Einführung, wird aber komplett ignoriert; sehr
   sichtbarer Bug-artiger Gap (§2.3, 2 PT).
4. **Deckenaussparungen** — Treppenauge ist der Wohnbau-Regelfall, heute nur
   über Umweg (nicht-konvexes Aussenpolygon) lösbar (§5.3 Punkt 1, 3 PT).
5. **Fenster-Glazing 2D-wirksam** — seit über einem Jahr als P0 in der
   Fenster-Studie dokumentiert und weiterhin offen; niedriger Aufwand,
   sollte nicht liegen bleiben (§3.1, 1 PT).
6. **Dach im Vertikalschnitt** — grösster Einzelposten (5 PT), aber ohne ihn
   bleibt jeder Gebäudeschnitt mit Steildach unvollständig; das ist die
   Art Lücke, die bei einer Bemusterung/Baueingabe sofort auffällt.
7. **Deckenrand-Override / Isokorb-Trennwerkzeug** — folgt danach, weil er
   auf demselben Mehrfach-Decken-Prinzip aufbaut wie Punkt 4.
8. **Mansard-Untertyp + editierbarer Knick** — mittlere Priorität, weil
   Mansarde in der Schweiz/Süddeutschland baupraktisch häufig ist und die
   heutige starre 40 %-Konstante sichtbar unrealistisch wirkt.
9. **Tür/Fenster-Rahmentiefe** (asymmetrische Rahmenbreiten, Beschlag,
   Kopfform) — bewusst NACH den strukturellen Lücken, weil sie additive
   Detailverbesserungen an einem bereits funktionierenden Pfad sind, während
   1–7 fehlende oder falsch dargestellte Kernfunktionen betreffen.
10. **Gauben, L-Grundriss/Kehle, Dachflächenfenster** — grösste Einzel-
    Aufwände (8–10+ PT), architektonisch am voraussetzungsreichsten (Boolean-
    Werkzeug bzw. neue Geometrie-Engine); erst nach 1–9 angehen.

### 6.1 NICHT bauen (VW/Revit-Ballast ohne Nutzen für DOSSIER)

- **Vollständiger Massketten-/Bezugsapparat** (VW B1..B5/H1..H7,
  Roh-/Fertigmass-Umschaltung) — DOSSIER arbeitet mit lichten Massen, das
  genügt für ein Schweizer Wohnbau-/Kleinprojekt-Tool (bereits so in
  `window-editor-vectorworks-study.md` §5 entschieden, hier bestätigt für
  Dach/Decke: keine Dach-Rohmass-/Fertigmass-Unterscheidung).
- **Sichtbarkeitsmatrix 3D-Objekte × Ansichten** (Augen-Tabelle je
  Kategorie×Ansicht×Detailstufe) — DOSSIERs Layer-Sichtbarkeit +
  `DetailLevel` deckt den praktischen Bedarf; eine volle Matrix ist
  Verwaltungsaufwand ohne Mehrwert für Einzelprojekte.
- **Eckfenster/Eckdach als generischer Sonderfall über zwei Wirtsbauteile**
  — seltene Geometrie, hoher Modellierungsaufwand (zwei Hosts, ein Element);
  bei Bedarf als manueller Workaround (zwei separate Öffnungen) lösbar.
  Ebenso: freie Neigungsflächen je Dachkante (VW erlaubt jede Kante einzeln
  zu kippen) — für die abgedeckten Standardformen (Pult/Sattel/Walm/
  Mansarde/Zelt/Krüppelwalm) nicht nötig; wer eine Freiform-Dachlandschaft
  braucht, ist besser mit den `ExtrudedSolid`/truck-Werkzeugen bedient.
- **Vollständige Beschlags-/Baubeschlag-Bibliothek** (Marken-Beschlagsätze,
  Schliessplan) — Beschlag als generisches Griff-Mesh (§2.4) genügt für die
  visuelle 1:1-Wirkung; eine Beschlags-PRODUKTBIBLIOTHEK ist Kataloggeschäft,
  kein CAD-Kernfeature.
- **Deckenspiegel als vollwertige Beleuchtungsplanung** (Leuchtenraster,
  Lichtberechnung) — reine Geometrie einer zweiten Fläche ist ok (P3), die
  Elektro-/Lichtplanungslogik selbst liegt ausserhalb des Tool-Zwecks.
- **IFC `IfcOpeningElement`/Void-Semantik nachrüsten** — bewusste
  Design-Entscheidung im bestehenden Export (`exportIfc.ts:22-27`), NICHT
  revidieren: die heutige "Loch steckt im Mesh"-Lösung liefert visuelle
  Parität in jedem Viewer ohne Boolean-Pflicht beim Empfänger; der reine
  IFC4-Purismus (Wand als parametrische Extrusion + Void) würde
  bestehende, bewusst getroffene Trade-offs zunichtemachen.
- **Straight-Skeleton/Kehlen und Gauben SOFORT** — nicht "nicht bauen", aber
  bewusst zurückgestellt (§6, Punkt 10): ohne die Schichtlogik (Punkt 1)
  vorher zu bauen, würde jede Kehlen-/Gauben-Lösung auf dem unendlich dünnen,
  ungeschichteten Dach aufsetzen und müsste bei Einführung der Schichten
  ohnehin neu gefasst werden.
