README opgeschoond: korte opzet met bulletpoints, geen changelog meer

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Machiel
2026-09-30 13:41:01 +02:00
co-authored by Claude Opus 5.5
parent 9126588df7
commit 001206a108
+66 -277
View File
@@ -1,293 +1,82 @@
# Tectum — configurator Van Emous Mantelzorgwoningen (intern) # Tectum — configurator Van Emous Mantelzorgwoningen (intern)
Losse, meerdere-bestanden-opzet van de eerdere single-file wand-tool, nu met Configurator voor mantelzorgwoningen: wand, vloer en woning (gekoppelde units)
een menubalk om tussen objecttypen (muur/vloer) te schakelen. met 2D, 3D, specificaties en PDF-tekenbladen.
Copyright © 2026 Machiel Heinen. Alle rechten Copyright © 2026 Machiel Heinen. Alle rechten voorbehouden; gebruik
voorbehouden; gebruik uitsluitend met schriftelijke toestemming. Zie uitsluitend met schriftelijke toestemming. Zie [LICENTIE.md](LICENTIE.md).
[LICENTIE.md](LICENTIE.md). Elk bronbestand begint met deze copyright-kop. Elk bronbestand begint met deze copyright-kop.
## Draaien ## Draaien
Tectum draait via een (lokale) webserver; direct openen via `file://` wordt
niet meer ondersteund (texturen/lucht laden dan niet, de app toont een melding).
``` ```
./start.sh # of: python3 -m http.server 8000 ./start.sh # of: python3 -m http.server 8000
``` ```
en open `http://localhost:8000`. Elke statische webserver volstaat (geen Open `http://localhost:8000`. Elke statische webserver volstaat; geen
build-stap; gewone `<script src>`-tags, geen ES-modules). build-stap. Direct openen via `file://` werkt niet (texturen/lucht).
## Structuur ## Structuur
``` ```
index.html app-shell: menubalk, splashscreen, over-deze-software index.html app-shell: menubalk, splashscreen
css/ css/app.css alle stijl
app.css alle stijl, in één bestand js/vendor/ three.js r128, eigen OrbitControls, jsPDF
js/ js/core/ gedeelde helpers: geometrie, UI-kit, PDF-bladen, labels,
vendor/ camerageheugen, weergavefilter, skybox, licentie, logo
three.min.js three.js r128, lokaal gevendord (geen CDN meer) js/wall/ WallModel (logica) + wand-PDF + wand-editor
OrbitControls.js eigen, compacte OrbitControls-vervanging (zie js/floor/ FloorModel (logica) + vloer-PDF + vloer-editor
"Bewuste keuzes" hieronder) — leunt op three.min.js js/roof/ RoofModel: plat dak + dakrand (boeidelen/daktrim)
core/ js/lighting/ LightingModel: gevellampen, boeideel-spots, binnenspots
geometry.js gedeelde, pure functies (regelwerk-verdeling, js/sandwich/ SandwichModel: sandwichpanelen rondom
polygon-oppervlaktes, clip-functies) — gebruikt js/unit/ UnitModel: 1 vloer + 4 wanden, naden, wandstukken
door zowel wall.js als floor.js, niet gedupliceerd js/house/ HouseModel (woning) + woning-PDF + woning-editor
canvas-labels.js gedeelde stijl voor maatlabels ("X: 6000mm") in de js/app.js menubalk, versienummer, actieve editor
2D-canvassen van wand, vloer en unit json/defaults/ referentie-JSON's (niet runtime ingeladen)
pdf-sheet.js gedeelde PDF-bouwstenen: titelblok, maatlijn, tabel assets/ logo, texturen, skybox
camera-memory.js onthoudt de 3D-camerastand per tabblad + onderdeel
view-filter.js "Weergave"-dropdown met vinkjes voor de 3D-weergaven
license.js licentietekst voor "Over deze software" (kopie van
LICENTIE.md, dat bestand is leidend)
logo-data.js logo als PNG-data voor de PDF-titelblokken
(opnieuw genereren uit assets/logo.svg, zie kop)
wall/
wall-model.js WallModel: ENIGE bron van de wand-logica (anker-
resolutie openingen, regelwerk, 3D-opbouw, specs,
validatie) — geen DOM
wall-pdf.js WallPdf: het wand-tekenblad (aanzicht, boven- en
zijaanzicht, materiaallijst) — losse wand én unit
wall.js wand-editor (UI: invoer, 2D, interactie, JSON/PDF)
floor/
floor-model.js FloorModel: ENIGE bron van de vloer-logica (balken,
doorvoeren, chassis, 3D-opbouw, specs, validatie)
floor-pdf.js FloorPdf: het vloer-tekenblad — losse vloer én unit
floor.js vloer-editor (UI, uitsluitend cirkelvormige
openingen/doorvoeren)
roof/
roof-model.js RoofModel: plat dak = vloer (FloorModel) 180°
gespiegeld + dakleer; dakrand (boeidelen met spots
of daktrim) als één doorlopende rand om de woning
lighting/
lighting-model.js LightingModel: buitenverlichting per unit (geen /
boeideel-spots / gevellampen), gevellampen per
wandstuk met terugval naar spots, override per wand
unit/
unit-model.js UnitModel: 1 vloer + 4 wanden, hoekaansluiting,
naden (wand vervalt deels/geheel) en wandstukken
house/
house-model.js HouseModel: woning = gekoppelde units + binnenwanden;
posities (koppelen aan zijde + uitlijning), naden,
totalen
house-pdf.js HousePdf: samenhangende PDF (plattegrond, per unit
vloer + wandstukken, binnenwanden, totalen)
house.js woning-editor (UI): navigatieboom, plattegrond met
selecteren/binnenwand tekenen, eigenschappen, 3D;
mount de echte wand-/vloer-editor per onderdeel
app.js menubalk-logica, versienummer, mount/unmount van
de actieve editor
json/
defaults/ referentie-JSON's die tonen wat "Nieuw" oplevert
(worden NIET ingeladen via fetch(), zie hieronder)
premade/ bestemmingsmap voor opgeslagen/geëxporteerde designs
assets/ logo (preloader) + bestemmingsmap voor toekomstige
GLB's/texturen
``` ```
## Bewuste keuzes / bekende beperkingen ## Uitgangspunten
- **Volledig CDN-vrij.** three.js (r128) staat lokaal in `js/vendor/three.min.js`. - **Eén bron per logica.** Rekenwerk en 3D-opbouw zitten alleen in de
OrbitControls is een eigen, compacte implementatie (`js/vendor/OrbitControls.js`) `*Model`/`*Pdf`-modules; editors en woning hergebruiken die.
— het originele addon-bestand was niet beschikbaar om te vendoren, dus is de - **Geen ES-modules, geen CDN.** Gewone `<script>`-tags in vaste volgorde
gebruikte subset (roteren via slepen, zoomen via scrollwiel, pannen via (zie `index.html`), alle libraries lokaal.
rechts-slepen, `target`/`update()`) opnieuw geschreven en losstaand getest - **Assen/zijden.** Bovenaanzicht boven = noord: voor = noord, achter = zuid,
(rotatie/zoom-richting/grenzen/pannen/dispose). Functioneel gelijkwaardig links = west, rechts = oost (interne sleutels blijven voor/achter/…).
voor wat deze tool nodig heeft, maar geen 1-op-1 kopie van alle opties van - **Hoogtes** gelden vanaf bovenkant vloer (loopvlak).
de officiële addon (bijv. geen damping/inertia).
- **Geen ES-modules.** Alle JS-bestanden zijn gewone `<script>`-tags, geladen ## Functionaliteit
in een vaste volgorde (`geometry.js` → `canvas-labels.js` → jsPDF →
`pdf-sheet.js` → `wall-model.js` → `wall-pdf.js` → `floor-model.js` → - **Wand:** openingen (raam/deur/voordeur) met ankers, regelwerk 38x235 met
`floor-pdf.js` → `roof-model.js` → `lighting-model.js` → `wall.js` → `floor.js` → `unit-model.js` → `house-model.js` dubbele hoekstijlen, zaagplan op handelslengtes, spaanplaat binnen,
→ `house-pdf.js` → `house.js` → `app.js`). vochtdoek (met kruislat en trasraam) of cementplaat buiten.
Reden: ES-module-imports (`import ... from`) breken bij rechtstreeks openen - **Wandhoogte:** schuine bovenrand of middenpunt (nok) met goothoogtes. In
via `file://` door browser-CORS-beleid. Dit was expliciet een vereiste een unit bepaalt de laatst gewijzigde wand de dakvorm: de tegenoverliggende
("gewoon via een index file"), dus is hier bewust voor gekozen. wand spiegelt mee, de haakse wanden worden vlak op de hoekhoogtes.
- **`json/defaults/*.json` worden niet gefetcht.** Om dezelfde reden (fetch() - **Vloer:** balken, cirkelvormige doorvoeren, OSB, optioneel chassis.
van lokale bestanden werkt ook niet betrouwbaar via `file://`): de - **Woning:** units koppelen aan een zijde (uitlijning + verschuiving); op
standaardwaarden van "Nieuw" staan hardcoded in `wall.js`/`floor.js` zelf, naden vervallen de buitenwanden en komt een naadwand in twee delen (één per
en komen overeen met deze JSON-bestanden. De JSON's zijn dus referentie/ unit, met deur). Binnenwanden teken je in de plattegrond.
documentatie, en (voor wanden) een bestand dat je via "Importeer JSON" kan - **Dak:** plat dak per unit (vloer gespiegeld + dakleer), dakrand als één
inladen — geen runtime-configuratiebron. doorlopende rand met boeidelen of daktrim. Daklogica voor schuine
- **Alleen wall.js heeft Exporteer/Importeer JSON.** floor.js nog niet. wanden/nok volgt nog.
- **Floor.js heeft nu dezelfde soorten logica als wall.js.** 2D-bovenaanzicht - **Gevel:** latwerk en vochtdoek lopen per gevel door over unit-naden;
+ doorsnede, regelwerk (vloerbalken), cirkelvormige doorvoeren, een sandwichpanelen rondom, 600 mm de grond in.
onderlaag van OSB-plaat (standaard 22mm, dikte + oppervlak + volume + - **Verlichting:** boeideel-spots of gevellampen (per gevel verdeeld,
gewicht), een isolatielaag (leegte tussen de balken, analytisch bepaald — override per wand) en binnenspots in een raster per unit.
net als bij de wand krijgt isolatie zelf bewust geen dichtheid/gewicht), - **3D:** weergavefilters, omgeving Ontwerp/Dag/Nacht, Render met lampen als
een volwaardig 3D-perspectief (balken/isolatie/OSB met doorvoer-gaten/ echte lichtbronnen.
chassis-wielen, met aan/uit-toggles voor OSB en isolatie, plus fullscreen- - **Uitvoer:** JSON opslaan/openen en een samenhangende PDF (plattegrond,
2D/3D) en een specificaties-paneel met een gewichtstotaal. Losse, vloeren, wandstukken, binnenwanden, totalen).
optionele chassis-laag (4 transportwielen in een "dobbelsteen 4"-indeling,
exact gecentreerd op de vloer — spoorbreedte/wielbasis/wieldiameter ## Bekende beperkingen
instelbaar, geen interactie met de balkposities).
- **Single point of truth wand/vloer/unit.** Alle reken- en 3D-logica zit in - Units kunnen niet gedraaid worden.
`WallModel`/`FloorModel`. De losse editors én de unit roepen die aan, dus - Binnen- en naadwanden volgen de dakvorm (nog) niet.
een wijziging in de wand- of vloerlogica geldt automatisch overal. De unit - Geen schaduw per lamp in de render (browserlimiet).
bewaart per onderdeel een gewone wand-/vloer-state; wandbreedtes worden - Eigen OrbitControls: roteren/zoomen/pannen, geen damping.
afgeleid uit vloermaat + wanddiktes + hoekaansluiting, openingen houden
hun anker (links/midden/rechts). "Opslaan als" bij een unit geeft JSON + ## Versie
één samenhangende PDF: bovenaanzicht unit (U-1), vloer (V-1), elke wand
(W-1…W-4, via WallPdf/FloorPdf) en een totalenblad (balken, zaaglijst, `APP_VERSION` in `js/app.js`: laatste cijfer per iteratie, middelste per
glaswol, plaatwerk, gewichten). Projectgegevens van de unit staan in mijlpaal (met git-tag), eerste bij live-gang. De changelog staat in git.
`state.project` en gelden voor alle bladen.
- **Standaarden (WallModel).** Muurbalk 38 x 235 mm (stijlen én regels),
ingekocht in 3600/4200/4800/5400 mm; een zaagplan (`planStockCutting` in
geometry.js) kiest per staaf de lengte met het minste snijverlies — bij een
unit over alle wanden samen. Stukken langer dan 5400 worden opgeknipt.
Elke wandkop heeft een dubbele hoekstijl (2 x 38 mm). De app start met een
unit.
- **Woning (v0.2).** Bestand → Nieuw → Woning (1 unit) of Woning L-vorm. Een
unit koppel je aan een zijde van een andere unit (uitlijning start/midden/
eind + verschuiving). Op de naad vervalt de wand van beide units over het
gedeelde stuk; een wand kan daardoor in meerdere stukken uiteenvallen
(bijv. A-W2a/b), haakse wanden lopen dan door tot de vloerrand. Binnen-
wanden teken je in de plattegrond (standaard 100 mm, spaanplaat beide
zijden) en bewerk je met de gewone wand-editor. Een wandstuk dat aan een
naad eindigt loopt de naad in door met de dikte van de haakse buurwand,
zodat binnenhoeken (L-vorm) dicht zijn. Zijden heten naar windrichting
t.o.v. het bovenaanzicht (boven = noord): voor = noord, achter = zuid,
links = west, rechts = oost (intern blijven de oude sleutels). Oude unit-JSON's kunnen in
een woning worden geïmporteerd. Units kunnen (nog) niet gedraaid worden.
- **UI-opschoning (v0.4.1).** Gedeelde UI-kit (js/core/ui-kit.js, window.UI):
velden, schakelaars, secties, tabbladen, specificatie-kaarten en iconen
(Bootstrap Icons 1.11.3, MIT, lokaal in css/vendor met ingebed lettertype,
werkt via file://). Woning-instellingen staan in tabbladen (Algemeen, Gevel,
Regelwerk, Dakrand, Verlichting); unit-eigenschappen ook (Afmetingen,
Koppeling, Dak). Labels: zelfstandig naamwoord, geen dubbele punt, uitleg
in een hint (i-icoon) i.p.v. tussen haakjes. Sneltoets T wisselt in drie
stappen: standaard -> 3D groot -> alleen de render -> standaard.
- **Omgeving en render (v0.4.6).** Keuzemenu in elke 3D-werkbalk: Ontwerp
(geen omgeving) / Dag / Nacht (core/skybox.js, keuze onthouden). Het
panorama (assets/skybox.webp / skybox-night.webp) wordt op de grond
geprojecteerd (port van three.js GroundedSkybox); onder het object ligt een
ronde tegelvloer (assets/tiles.jpg, 20% ruimer dan object + 1,5 m) met een
witte opstaande rand van 100 x 25 mm. Vloer en rand vangen licht en
schaduw. Woning: de tegelvloer ligt op het maaiveld (woning-instelling,
standaard 350 mm onder bovenkant vloer). Knop "Render" (camera): lampen en
spots als echte lichtbronnen in het gewone daglicht; Nacht: omgevingslicht
15%, lampen altijd aan. Buitenlampen 15% minder fel dan in v0.4.5.
- **Binnenspots (v0.4.6).** LightingModel.computeIndoor: per unit een raster
spots in het plafond (onderkant dak), min. 800 / max. 1500 mm h.o.h. in
beide richtingen, min. 600 mm van de binnenzijde van elke wand (of van de
unitrand bij een naad); spots te dicht bij een binnenwand vervallen.
Woning-instellingen › Verlichting › Binnenspots. In 3D (filter Lampen),
plattegrond (open cirkeltje), render en totalen.
- **Naden (v0.4.9).** Op elke naad staat standaard een tussenwand met in het
midden een deur (900 x 2150), ook bij "unit toevoegen"; verwijderen en
aanpassen kan gewoon. Hij bestaat uit twee delen, één per unit
(HouseModel.seamLeaves, elementen NW-1A / NW-1B), met balken en isolatie in
beide delen maar beplating alleen aan de kamerzijde (WallModel buitenzijde
'geen'); de openingen gelden voor beide delen en worden gespiegeld. Vloer en
dak krijgen op een naad langs voor-/achterrand een kopbalk
(FloorModel.computeFrame rims), langs de zijranden ligt al een balk.
- **Wandhoogtes gekoppeld + nok (v0.4.10).** Een wand kan een middenpunt
(nok, wall.heightMid) krijgen: de bovenrand wordt dan twee stukken, links/
rechts zijn goothoogtes (WallModel.topLine; bovenregels in verstek). In een
unit bepaalt de laatst in hoogte gewijzigde wand de dakvorm
(UnitModel.syncWallHeights): de tegenoverliggende wand krijgt dezelfde
hoogtes gespiegeld (incl. nok), de haakse wanden worden vlak op de
hoekhoogtes. Binnen- en naadwanden doen (nog) niet mee; de daklogica volgt
apart.
- **Binnenspots langs naadwanden (v0.4.10).** Het raster begint vanaf de
binnenzijde van het eigen naadwanddeel (niet de unitrand), zodat de rij
langs de naad niet meer wegvalt.
- **Isolatie niet meer getekend (v0.4.9).** Filter "Isolatie" en de 3D-lagen
zijn weg; de spouw-/leegte-inhoud blijft in specificaties en totalen.
- **Startpunt gevellampen (v0.4.8).** Een gevel telt vanaf de zichtbare,
afgewerkte hoek: elk uiteinde + afwerking van de haakse wand (52 mm bij
vochtdoek), plus de bedekte kopse kant (skinExt) bij tussenpassende wanden.
Delen van een gevel achter een andere wand (bijv. een wandstuk dat de naad
in loopt om een binnenhoek te sluiten, zoals A-W2 bij een L) worden
afgetrokken via de voetafdruk van die wand; de gevel begint dan bij diens
afgewerkte buitenkant.
- **Lichtbronnen (v0.4.7).** Geen echte schaduw per lamp (één schaduwkaart
per lamp overschrijdt de browserlimiet); licht door muren wordt geometrisch
voorkomen: buitenlampen en boeideel-spots zijn half hun bundelhoek naar
buiten gekanteld (boeideel: normaal van de dakrand, op hoeken diagonaal),
binnenspots reiken hard tot net voorbij de vloer. Buitenlampen overdag op
35% (LightingModel.DAY_OUTDOOR_FACTOR), 's nachts 100%; binnenspots feller.
- **Mijlpaal v0.4 — gevelopbouw.** Samenvatting van de v0.3.11–0.3.19-iteraties:
kruislat-latwerk op vochtdoek (richting gevelbekleding globaal), lampen op de
afgewerkte gevel (+52 mm), logo-watermerk op het doek, trasraam (cement-
gebonden plaat, 350 mm vanaf het loopvlak), sandwichpanelen rondom (600 mm de
grond in), hoekdoorloop van de buitenlagen over de hoekstijlen, en latwerk/
doek per doorlopende gevel over unit-naden heen. Details per onderdeel hieronder.
- **Plat dak (v0.3).** Elke unit heeft een dak (tweede laag) dat standaard
de vloermaat volgt, maar een eigen maat/verschuiving mag krijgen. Opbouw =
vloer 180° gespiegeld (OSB als plafond onder, balken, dakleer bovenop); het
dak wordt bewerkt met de vloer-editor in dakmodus. De dakrand is woning-
breed: boeidelen (overstek 200–400 mm vanaf de dakrand = standaard de
gevel, 300 mm hoog, spots op 40% van de overstek, op elke (unit-)hoek en
daartussen verdeeld met min/max h.o.h.) of een daktrim van 80 mm. De rand
loopt als één geheel over de naden tussen units. Het dak ligt op de hoogste
wandbovenkant van de unit; bij units met verschillende hoogtes ligt de
dakrand op het hoogste dak.
- **Dakrand & buitenverlichting (v0.3.3).** Boeidelen aan/uit per unit
(anders daktrim); de rand wordt per ribbe opgebouwd (in verstek, geen
zichtbare naad). Verlichting is woning-breed: type (geen / boeideel-spots /
gevellampen), lichtrichting en alle afstanden. Gevellampen worden per
GEVEL verdeeld (aansluitende wandstukken in hetzelfde vlak, ook over een
naad tussen units), niet per wand: op lamphoogte (standaard 1950) alleen op
vrije stukken >= 2000 mm (openingen incl. raamwerk eraf), eerste/laatste
300 mm van hoek/opening, daartussen min/max h.o.h.; smallere stukken krijgen
geen lampen. Gevellampen en boeideel-spots sluiten elkaar uit. De min.
h.o.h. geldt over alle lampen van een gevel samen (ook bij afstand hoek/
opening en overrides): te dicht bij elkaar = samengevoegd tot één lamp in
het midden. Per wandzijde blijft een override: automatisch / 500 mm
naast elke opening / geen. Standaard unithoogte 2600 mm.
- **3D-weergave (v0.3.5).** Filters als dropdown met vinkjes. Woning:
Beplating (wandplaten, vloer- en plafondplaten, dakleer, boeideel/daktrim),
Isolatie, Dak, Lampen. "Volle render": avondscène met maaiveld, elke
gevellamp (per lichtrichting) en boeideel-spot is een echte SpotLight
(zonder schaduwen, om het licht te houden); de nep-lichtkegels zijn dan
verborgen.
- **Latwerk gevelbekleding (v0.3.11).** Bij vochtdoek komt er een kruislat
op (WallModel.computeBattens): latten 20x30 mm, handelslengte 4000, 400 mm
h.o.h. in beide richtingen, uitgespaard rond openingen en afgekapt op de
(schuine) bovenrand. De bovenste laag staat haaks op de gevelbekleding
(WEO/Novalit, 12 mm; richting per losse wand, in een woning voorlopig
globaal als woning-instelling). Gevellampen hangen op de afgewerkte gevel:
wandvlak + kruislat (40) + bekleding (12) = 52 mm naar buiten. Cement-gebonden
platen (steenstrips) krijgen geen latwerk. Latten tellen mee in gewicht,
specificaties, wand-PDF en woningtotalen; zichtbaar met "Beplating".
- **Vochtdoek-bedrukking (v0.3.13).** Net als op de echte doeken staat het logo
als medium-grijs watermerk (geen kleur) onder 45° op het vochtdoek, 1,5 m
breed, herhaald per tegel van 2 m (WallModel.createMaterials, CanvasTexture).
- **Trasraam (v0.3.14).** Woning-instelling (aan/uit + hoogte, standaard 350 mm
vanaf Y=0 van de vloer = het beloopbare vlak / bovenkant vloer). Onderaan
elke vochtdoek-gevel komt een strook cement-gebonden plaat (montage-
achterkant), vóór het doek; het doek loopt er ongewijzigd achter door en
het latwerk begint erboven. Zelfde plaat- en uitsparingslogica als de
buitenplaten, dus openingen blijven gerespecteerd (WallModel.trasraamFor,
build3D opts.trasraam, computeBattens). Telt mee in gewicht, wand-PDF en de
woningtotalen ("Cementplaat (trasraam)").
- **Hoekdoorloop buitenlagen (v0.3.18).** Een wand die tussen twee doorlopende
wanden past, bedekt met zijn buitenlagen ook de kopse kant (hoekstijlen) van
die wanden: UnitModel geeft per wand(stuk) skinExt { left, right } (= dikte
van de doorlopende wand, 0 bij naden/vrije einden), WallModel.cornerExt telt
per laag de eigen diepte erbij. Latwerk en trasraam lopen door; vochtdoek
en cementplaat (liggen in de beplatingsruimte) krijgen een strook net vóór
het wandvlak.
- **Latwerk en doek per gevel (v0.3.19).** HouseModel.assignFacades groepeert
collineaire, aansluitende buitenwandstukken over alle units tot gevels
(groupFacadeRuns in core/geometry.js, ook gebruikt door de buitenverlichting)
en geeft elk stuk p.facade { u0, extStart, isEnd }. Het verticale
latten-raster (400 h.o.h.) en het watermerk op het doek lopen daardoor over
unit-naden door; een eindlat komt alleen aan het einde van de gevel.
- **Sandwichpanelen (v0.3.16).** Woning-instelling aan/uit. SandwichModel
(js/sandwich/sandwich-model.js) legt één doorlopende rand (in verstek) om de
vereniging van alle unit-vloeren: 40 mm dik, van het loopvlak (bovenkant
vloer) 600 mm naar beneden, de grond in. Plaat 495 x 1000 x 40 (9 kg),
verticaal: één plaat per 495 mm gevel, 1000 afgezaagd op 600. Naden per
495 mm; zichtbaar met "Beplating"; m2, aantal platen en gewicht (hele
platen) in de woningtotalen.
- **Openingtypes.** Raam (500x1900), deur (900x2150) en voordeur (1150x2150);
type kiezen zet de standaardmaat, daarna vrij aan te passen. De app start
met een L-woning met een voordeur (noord, unit A) en 3 ramen (zuid, unit B).
- **Woning-instellingen.** Regelwerk-h.o.h. (min/max) geldt globaal voor alle
buitenwanden resp. alle binnenwanden; in de wand-editor zijn die velden
binnen een woning vergrendeld.
- **Versienummer** staat als enkele constante (`APP_VERSION`) in `app.js`.
Conventie: laatste cijfer per kleine iteratie, middelste per mijlpaal
(aangegeven in chat), eerste bij live-gang.