User Tools

Site Tools


handleiding_nieuw:sub_spacematrix

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
handleiding_nieuw:sub_spacematrix [2025/05/07 09:29] supporthandleiding_nieuw:sub_spacematrix [2026/05/25 10:44] (current) – external edit 127.0.0.1
Line 1: Line 1:
 <html> <html>
-<html lang="nl"> 
-<head> 
 <meta charset="UTF-8"> <meta charset="UTF-8">
-<title>Spacematrix Rekenblok + Voorzieningen</title+<meta name="viewport" content="width=device-width, initial-scale=1"> 
-<style> +<meta name="referrer" content="origin"> 
-    body { font-family: sans-serif; margin: 20px; } +<script src="https://cdn.jsdelivr.net/npm/chart.js"></script
-    .tabs { display: flex; gap: 10px; margin-bottom: 15px; } +  <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script> 
-    .tab { padding: 10px 15px; background: #ddd; cursor: pointer; border-radius: 5px 5px 0 0; } +  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"> 
-    .tab.active { background: #f0f0f0font-weightbold; } +  <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> 
-    .tabcontent { display: none; border: 1px solid #ccc; padding: 15px; border-radius:5px 5px 5px; } +  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css"> 
-    .tabcontent.active { display: block; } +  <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js"></script> 
-    .inputrow { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; } +  <style> 
-    .inputrow label { width: 240px; } +    *, *::before, *::after { box-sizing: border-box; } 
-    .inputrow input { width: 80px; } +    :root { 
-    table { border-collapse: collapse; width: 100%; margin-top: 10px; } +      --font:      system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; 
-    th, td { border: 1px solid #ccc; padding: 5px; text-align: right; } +      --teal:      #0d9488;  --teal-h: #0f766e;  --teal-light: #f0fdfa;  --teal-dim: #ccfbf1; 
-    th { background: #f0f0f0; } +      --green:     #22c55e;  --green-h: #16a34a; 
-    td:first-child, th:first-child { text-align: left; } +      --red:       #dc2626;  --red-light: #fef2f2; 
-</style>+      --amber:     #d97706; 
 +      --gray-50:   #f8fafc;  --gray-100: #f1f5f9;  --gray-200: #e2e8f0; 
 +      --gray-300:  #cbd5e1;  --gray-400: #94a3b8; 
 +      --gray-500:  #64748b;  --gray-600: #475569;  --gray-700: #334155;  --gray-900: #0f172a; 
 +      --radius: 7px; 
 +      --shadow-sm: 0 1px 2px rgba(0,0,0,.06); 
 +      --shadow:    0 1px 3px rgba(0,0,0,.10), 0 1px 2px rgba(0,0,0,.06); 
 +    } 
 +    html,body { margin:0; padding:0; font-family:var(--font); font-size:14px; color:var(--gray-700); background:var(--gray-50);
 + 
 +    /* Anti-copy */ 
 +    .sm-page { max-width:1100px; margin:0 auto; padding:16px 16px 64px; user-select:none; -webkit-user-select:none; } 
 +    .sm-page input, .sm-page select, .sm-page textarea { user-select:text; -webkit-user-select:text;
 + 
 +    /* ===== Header ===== */ 
 +    .sm-header { display:flex; align-items:flex-start; justify-content:space-between; gap:16px; flex-wrap:wrap; margin-bottom:14px; } 
 +    .sm-header h1 margin:0; font-size:20px; font-weight:700; line-height:1.1; color:var(--gray-900);
 +    .sm-header h1 .v { font-size:11px; font-weight:500; color:var(--gray-400); margin-left:4px; vertical-align:middle; background:var(--gray-100); padding:1px 5px; border-radius:4px;
 + 
 +    /* ===== Scenario bar ===== */ 
 +    .scenario-bar { display:flex; align-items:center; gap:8px; flex-wrap:wrap; justify-content:flex-end;
 +    .scenario-bar select { height:32px; padding:10px; border-radius:6px; border:1px solid var(--gray-300); background:#fff; font-size:13px; min-width:200px;
 +    .scenario-bar .btn { height:32px; padding:0 12px; border-radius:6px; border:1px solid var(--gray-200); background:#fff; color:var(--gray-700); font-weight:600; cursor:pointer; font-size:12px; font-family:var(--font); transition:background .12s; white-space:nowrap;
 +    .scenario-bar .btn:hover { background:var(--gray-100); border-color:var(--gray-300);
 +    .scenario-bar .btn.primary { background:var(--teal); border-color:var(--teal-h); color:#fff; } 
 +    .scenario-bar .btn.primary:hover { background:var(--teal-h);
 +    .scenario-bar .btn.danger { background:var(--red-light); border-color:#fca5a5; color:var(--red);
 +    .scenario-bar .btn.danger:hover { background:#fee2e2;
 +    #sm_loaded_label { font-size:12px; color:var(--teal-h); font-weight:500;
 +    #sm_save_status  { font-size:11px; color:var(--gray-500); white-space:nowrap;
 + 
 +    /* ===== Buttons ===== */ 
 +    button { border:1px solid var(--gray-200); background:#fff; padding:7px 12px; border-radius:var(--radius); cursor:pointer; font-size:13px; font-family:var(--font); font-weight:500; color:var(--gray-700); transition:background .12s,border-color .12s; } 
 +    button:hover { background:var(--gray-100); border-color:var(--gray-300);
 +    button.btn-primary { background:var(--teal); border-color:var(--teal-h); color:#fff; font-weight:600;
 +    button.btn-primary:hover { background:var(--teal-h);
 +    button.btn-danger   { background:var(--red-light); border-color:#fca5a5; color:var(--red);
 +    button.btn-danger:hover { background:#fee2e2;
 + 
 +    /* ===== Tabs ===== */ 
 +    .sm-tabs { display:flex; gap:4px; flex-wrap:wrap; border-bottom:2px solid var(--gray-200); margin-bottom:0; } 
 +    .sm-tab  { padding:8px 15px; background:transparent; border:1px solid transparent; border-bottom:none; border-radius:6px 6px 0; font-weight:600; font-size:13px; cursor:pointer; color:var(--gray-500); margin-bottom:-2px; transition:background .12s; } 
 +    .sm-tab:hover  { background:var(--gray-50); color:var(--gray-900);
 +    .sm-tab.active { background:#fffcolor:var(--teal); border-color:var(--gray-200); border-bottom-color:#fff; position:relative; z-index:1; } 
 +    .sm-tabcontent { display:none; border:1px solid var(--gray-200); border-top:none; background:#fff; padding:18px; border-radius:0 var(--radius) var(--radius); } 
 +    .sm-tabcontent.active { display:block; } 
 + 
 +    /* Voorzieningen naast elkaar */ 
 +    .voorz-grid { display:grid; grid-template-columns:1fr 1fr; gap:16px; } 
 +    @media(max-width:700px) { .voorz-grid { grid-template-columns:1fr; } } 
 + 
 +    /* Modal */ 
 +    .sm-modal-bg  { display:none; position:fixed; inset:0; background:rgba(0,0,0,.5); z-index:3000; align-items:center; justify-content:center;
 +    .sm-modal-box { background:#ffffff; border-radius:12px; box-shadow:0 8px 40px rgba(0,0,0,.22); display:flex; flex-direction:column; overflow:hidden;
 + 
 +    /* Kaart tab */ 
 +    #kaart-map { height:480px; border-radius:var(--radius); border:1px solid var(--gray-200);
 +    .kaart-info { background:var(--teal-light); border:1px solid var(--teal-dim); border-radius:var(--radius); padding:10px 14px; font-size:13px; margin-top:10px;
 +    .kaart-info strong { color:var(--teal-h);
 + 
 +    /* ===== STICKY KEY METRICS BAR ===== */ 
 +    .sm-metrics-bar { 
 +      display:grid; 
 +      grid-template-columns: 1fr 1px 1fr 1px 1fr 1px 1fr 1px 1fr; 
 +      background:var(--teal-light); 
 +      border:1px solid var(--teal-dim); 
 +      border-top:none; 
 +      position:sticky; top:0; z-index:10; 
 +    } 
 +    .sm-km { padding:10px 12px; text-align:center; min-width:0;
 +    .sm-km-val   { font-size:26px; font-weight:800; color:var(--teal); font-variant-numeric:tabular-nums; line-height:1;
 +    .sm-km-label { font-size:10px; color:var(--gray-600); text-transform:uppercase; letter-spacing:.04em; margin-top:3px;
 +    .sm-km-sub   { font-size:10px; color:var(--gray-500); margin-top:2px; font-variant-numeric:tabular-nums;
 +    .sm-km-sep   { background:var(--teal-dim);
 + 
 +    /* ===== Form / inputs ===== */ 
 +    .sm-inputrow { display:flex; align-items:center; gap:10px; margin-bottom:9px; flex-wrap:nowrap; } 
 +    .sm-inputrow label { font-size:13px; color:var(--gray-700); flex-shrink:0;
 +    .sm-inputrow.full-label  label { width:280px; } 
 +    .sm-inputrow.short-label label { width:50px; } 
 +    .sm-inputrow input[type="number"], .sm-inputrow select { 
 +      width:90pxpadding:5px 8px; border:1px solid var(--gray-200); border-radius:var(--radius); font-size:13px; background:#fff; flex-shrink:0; 
 +    } 
 +    .sm-inputrow input:focus, .sm-inputrow select:focus { outline:none; border-color:var(--teal); box-shadow:0 0 0 2px rgba(13,148,136,.12);
 +    .sm-display-val { font-size:13px; font-weight:700; color:var(--teal);
 +    .sm-calc-badge { display:inline-flex; align-items:center; gap:4px; font-size:12px; color:var(--teal-h); font-weight:600; background:var(--teal-light); border:1px solid var(--teal-dim); border-radius:20px; padding:3px 10px; white-space:nowrap; flex-shrink:0;
 +    .sm-calc-badge::before { content:"="; color:var(--gray-400); font-weight:400; margin-right:2px;
 + 
 +    /* ===== Cards ===== */ 
 +    .sm-box { border:1px solid var(--gray-200); border-radius:var(--radius); background:#fff; padding:13px 15px; margin-bottom:12px; box-shadow:var(--shadow-sm);
 +    .sm-box-title { font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--gray-500); margin-bottom:11px;
 +    .sm-box-new { border-left:3px solid var(--teal); background:var(--teal-light);
 +    .sm-box-new .sm-box-title { color:var(--teal-h);
 + 
 +    /* ===== Spacematrix ===== */ 
 +    .sm-bovenblok { display:flex; gap:20px; align-items:flex-start; flex-wrap:wrap;
 +    .sm-inputvelden { flex:1; min-width:280px;
 +    .sm-kaartcontainer { position:relative; width:420px; max-width:100%; flex-shrink:0;
 +    .sm-kaartcontainer img { width:100%; display:block; border-radius:var(--radius); border:1px solid var(--gray-200);
 +    .stipje { position:absolute; width:14px; height:14px; background:#ef4444; border-radius:50%; transform:translate(-50%,-50%); border:2px solid #fff; box-shadow:0 1px 4px rgba(0,0,0,.35); pointer-events:none;
 +    .sm-legend { margin-top:12px;
 +    .sm-legend-title { font-size:10px; font-weight:700; color:var(--gray-500); margin-bottom:5px; text-transform:uppercase; letter-spacing:.05em;
 +    .sm-legend-grid  { display:grid; grid-template-columns:1fr 1fr; gap:3px 10px; } 
 +    .sm-legend-item  { display:flex; align-items:center; gap:5px; font-size:11px; color:var(--gray-700);
 +    .sm-zone-badge   { width:17px; height:17px; border-radius:4px; font-size:10px; font-weight:800; background:var(--gray-100); border:1px solid var(--gray-200); color:var(--gray-600); display:inline-flex; align-items:center; justify-content:center; flex-shrink:0;
 +    .sm-legend-i     { width:13px; height:13px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; font-size:9px; font-weight:800; border:1px solid var(--gray-200); background:var(--gray-50); color:var(--gray-500); cursor:help;
 +    .sm-tip { position:relative; display:inline-flex;
 +    .sm-tip::after  { content:attr(data-tip); position:absolute; left:0; top:calc(100% + 7px); width:210px; background:var(--gray-900); color:#fff; padding:6px 9px; border-radius:6px; font-size:11px; line-height:1.35; opacity:0; transform:translateY(-3px); pointer-events:none; transition:opacity .12s,transform .12s; z-index:50; white-space:normal;
 +    .sm-tip::before { content:""; position:absolute; left:8px; top:calc(100% + 1px); border:5px solid transparent; border-bottom-color:var(--gray-900); opacity:0; transform:translateY(-3px); pointer-events:none; transition:opacity .12s,transform .12s; z-index:51; } 
 +    .sm-tip:hover::after, .sm-tip:hover::before { opacity:1; transform:translateY(0);
 + 
 +    /* ===== Sectie-koptekst ===== */ 
 +    .sm-section-head { font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--gray-600); margin:18px 0 8px; padding-left:10px; border-left:3px solid var(--teal);
 + 
 +    /* ===== Tabellen ===== */ 
 +    table { border-collapse:collapse; width:100%; margin-top:8px; } 
 +    th,td { border:1px solid var(--gray-200); padding:5px 8px; text-align:right; font-size:13px; } 
 +    th    { background:var(--gray-50); font-weight:600; color:var(--gray-700); font-size:12px; } 
 +    td:first-child, th:first-child { text-align:left;
 +    tbody tr:nth-child(even) td { background:var(--gray-50);
 +    td input[type="number"] { width:70px; padding:3px 6px; border:1px solid var(--gray-200); border-radius:4px; font-size:13px; background:#fff;
 +    td input:focus { outline:none; border-color:var(--teal);
 +    tfoot td, tfoot th { background:var(--gray-100); font-weight:700;
 +    .perc-warning { color:var(--red); font-weight:700;
 +    .sum-section-row td { background:var(--gray-100) !important; font-weight:700; text-transform:uppercase; font-size:10.5px; letter-spacing:.04em; color:var(--gray-500); border-top:2px solid var(--gray-300); padding:4px 8px; } 
 +    .sum-totaal td { background:var(--teal-light) !important; font-weight:700; color:var(--teal-h); border-top:2px solid var(--teal-dim);
 +    .norm-col { width:140px; } .chk-col { width:60px; text-align:center !important; } 
 +    .pp-count-cell { color:var(--teal); font-weight:600; font-size:12px;
 + 
 +    /* ===== Export-balk ===== */ 
 +    .sm-export-bar { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-top:16px; padding-top:14px; border-top:2px solid var(--gray-100);
 + 
 +    /* ===== Parkeren ===== */ 
 +    .park-derived-row { display:flex; align-items:center; gap:10px; margin-bottom:9px;
 +    .park-derived-row label { width:280px; font-size:13px; color:var(--gray-700);
 +    .sm-derived { font-size:13px; font-weight:600; color:var(--teal); background:var(--teal-light); border:1px solid var(--teal-dim); border-radius:var(--radius); padding:4px 10px; } 
 + 
 +    /* ===== Onbebouwde ruimte ===== */ 
 +    .or-table input[type="number"] { width:68px; } 
 +    .sm-tuin-egw       { margin-top:12px; padding:12px 14px; border:1px solid var(--gray-200); border-radius:var(--radius); background:var(--gray-50); border-left:3px solid var(--amber);
 +    .sm-tuin-egw-title { font-size:12px; font-weight:700; color:var(--amber); margin-bottom:8px;
 +    .sm-tuin-egw-result{ font-size:12px; margin-top:8px; color:var(--teal); font-weight:600;
 + 
 +    /* ===== Note ===== */ 
 +    .sm-note { font-size:12px; color:var(--gray-600); background:var(--gray-50); border:1px solid var(--gray-200); border-radius:var(--radius); padding:9px 12px; margin-top:10px; line-height:1.5;
 + 
 +    /* Meta-badge voor type project */ 
 +    .sm-meta-badge { font-size:11px; color:var(--gray-500); font-weight:400; background:var(--gray-100); border:1px solid var(--gray-200); border-radius:4px; padding:1px 5px; margin-left:4px; cursor:help;
 + 
 +    /* ===== Collapsibles ===== */ 
 +    .sm-collapsible-header { cursor:pointer; user-select:none; -webkit-user-select:none;
 +    .sm-collapsible-header:hover .sm-collapse-chevron { color:var(--teal-h);
 +    .sm-collapse-chevron { display:inline-block; color:var(--teal); font-size:10px; width:10px; text-align:center; transition:transform .15s ease; transform:rotate(0deg); margin-right:4px;
 +    .sm-collapsible-header[aria-expanded="true"] .sm-collapse-chevron { transform:rotate(90deg);
 +    .sm-collapsible .sm-collapsible-body { display:none;
 +    .sm-collapsible.sm-collapsible-open .sm-collapsible-body { display:block;
 +    #collapse_egw_tuinen:not(.sm-collapsible-open) .sm-tuin-egw-title { margin-bottom:0;
 +    .sm-box > .sm-box-title.sm-collapsible-header[aria-expanded="false"] { margin-bottom:0;
 +    .sm-tab-toolbar { display:flex; justify-content:flex-end; margin-bottom:10px;
 +    .sm-btn-collapse-all { font-size:11px; padding:4px 12px; color:var(--gray-600); background:transparent; border:1px solid var(--gray-200); border-radius:var(--radius); font-weight:500; cursor:pointer;
 +    .sm-btn-collapse-all:hover { background:var(--gray-50); color:var(--teal-h); border-color:var(--gray-300);
 + 
 +    /* ===== Bronnen-modal ===== */ 
 +    .bt-tab { padding:9px 18px; background:none; border:none; border-bottom:2px solid transparent; font-size:12px; font-weight:600; color:var(--gray-600); cursor:pointer; font-family:var(--font); transition:background .12s,color .12s,border-color .12s; } 
 +    .bt-tab:hover { background:#fff; color:var(--gray-900);
 +    .bt-tab-active { color:var(--teal); border-bottom-color:var(--teal); background:#fff;
 + 
 +    /* ===== Powered-by badge ===== */ 
 +    .sm-powered { position:fixed; left:14px; bottom:14px; z-index:100; display:flex; align-items:center; gap:6px; padding:5px 10px; background:rgba(255,255,255,0.90); border-radius:8px; backdrop-filter:blur(2px); font-size:11px; color:var(--gray-500); text-decoration:none; border:1px solid var(--gray-200);
 +    .sm-powered:hover { color:var(--teal); border-color:var(--teal-dim);
 +    @media print { .sm-page, .sm-powered { display:none !important; } body::after { content:"Dit document is auteursrechtelijk beschermd — Sumsonite BV"; font-size:24px; padding:40px; } } 
 +  </style>
 </head> </head>
-<body>+<body oncopy="return false" oncontextmenu="return false" ondragstart="return false" onselectstart="return false" onkeydown="if((event.ctrlKey||event.metaKey)&&['u','s','p'].includes(event.key.toLowerCase())){event.preventDefault();return false;}"> 
 +<div class="sm-page">
  
-<h1>Spacematrix & Voorzieningen</h1> +  <!-- ===== Header + Scenario bar ===== --> 
-<div class="tabs"> +  <div class="sm-header"> 
-    <div class="tab active" onclick="switchTab('rekenblok')">Spacematrix Rekenblok</div+    <h1>Programmaverkenner <span class="v">v2 light</span></h1> 
-    <div class="tab" onclick="switchTab('voorzieningen')">Voorzieningen</div+    <div class="scenario-bar"
-</div>+      <span id="sm_loaded_label"></span> 
 +      <select id="sm_scenario_select" onchange="smUI_onScenarioChange()"></select> 
 +      <button class="btn primary" onclick="smUI_save()">💾 Opslaan</button> 
 +      <button class="btn" onclick="smUI_loadSelected()">📂 Openen</button> 
 +      <button class="btn danger" onclick="smUI_deleteSelected()">🗑️</button> 
 +      <button class="btn" onclick="smUI_resetAll()">↺ Reset</button> 
 +      <button class="btn" onclick="smUI_openHelp()">? Help</button> 
 +      <span id="sm_save_status"></span
 +    </div
 +  </div> 
 + 
 +  <!-- ===== Tabs ===== --> 
 +  <div class="sm-tabs"> 
 +    <button class="sm-tab active" data-tab="locatie"       onclick="switchTab('locatie')">Locatie</button> 
 +    <button class="sm-tab"        data-tab="rekenblok"     onclick="switchTab('rekenblok')">Laadvermogen Rekenblok</button
 +    <button class="sm-tab       data-tab="voorzieningen" onclick="switchTab('voorzieningen')">Voorzieningen &amp; Niet-Wonen</button> 
 +    <button class="sm-tab"        data-tab="parkeren"      onclick="switchTab('parkeren')">Parkeren</button> 
 +    <button class="sm-tab"        data-tab="openbareruimte" onclick="switchTab('openbareruimte')">Onbebouwde Ruimte</button
 +  </div>
  
-<div id="rekenblok" class="tabcontent active"> +  <!-- ===== KEY METRICS BAR ===== --> 
-    <div class="inputrow"> +  <div class="sm-metrics-bar"> 
-        <label for="opp">Oppervlak projectgebied (m²):</label+    <div class="sm-km"> 
-        <input id="opp" type="number" value="10000" oninput="updateLaadvermogen()">+      <div class="sm-km-val" id="km_opp"></div
 +      <div class="sm-km-label">m² projectgebied</div>
     </div>     </div>
-    <div class="inputrow"> +    <div class="sm-km-sep"></div
-        <label for="fsi">FSI:</label+    <div class="sm-km"> 
-        <input id="fsitype="numberstep="0.01" value="1.6" oninput="updateLaadvermogen()">+      <div class="sm-km-valid="km_fsi">–</div> 
 +      <div class="sm-km-label">FSI</div>
     </div>     </div>
-    <div class="inputrow"> +    <div class="sm-km-sep"></div
-        <label for="voorzieningenruimte">Voorzieningenruimte per woning (m²):</label+    <div class="sm-km"> 
-        <input id="voorzieningenruimtetype="numberstep="0.1value="12.0oninput="updateLaadvermogen()">+      <div class="sm-km-val" id="km_woningen">–</div> 
 +      <div class="sm-km-label">woningen</div> 
 +      <div class="sm-km-subid="km_perc_warningstyle="display:none;color:#b00020;font-weight:700;font-size:10px;">⚠️ % ≠ 100</div>
     </div>     </div>
 +    <div class="sm-km-sep"></div>
 +    <div class="sm-km">
 +      <div class="sm-km-val" id="km_bvo">–</div>
 +      <div class="sm-km-label">m² laadvermogen BVO</div>
 +    </div>
 +    <div class="sm-km-sep"></div>
 +    <div class="sm-km">
 +      <div class="sm-km-val" id="km_pp">–</div>
 +      <div class="sm-km-label">parkeerplaatsen totaal</div>
 +      <div class="sm-km-sub" id="km_pp_sub">boven: – &nbsp;·&nbsp; onder: –</div>
 +    </div>
 +  </div>
 +
 +  <!-- ===== TAB 0: LOCATIE ===== -->
 +  <div id="locatie" class="sm-tabcontent active">
 +    <div style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;margin-bottom:10px;">
 +      <div>
 +        <div style="font-size:15px;font-weight:700;color:var(--gray-900);margin-bottom:2px;">Projectlocatie tekenen</div>
 +        <div style="font-size:12px;color:var(--gray-500);">Teken het projectgebied op de kaart. Oppervlak wordt automatisch berekend en gemeente herkend.</div>
 +      </div>
 +      <div style="display:flex;gap:8px;flex-wrap:wrap;">
 +        <button onclick="kaartClearPolygon()" style="font-size:12px;padding:5px 10px;">✕ Wis tekening</button>
 +        <button onclick="kaartNaarRekenblok()" class="btn-primary" style="font-size:12px;padding:6px 12px;">✓ Gebruik dit oppervlak →</button>
 +      </div>
 +    </div>
 +    <div style="display:flex;gap:10px;align-items:flex-start;">
 +      <div style="flex:1;min-width:0;">
 +        <div id="kaart-map" style="height:560px;border-radius:var(--radius);border:1px solid var(--gray-200);background:var(--gray-100);"></div>
 +      </div>
 +      <div style="width:180px;flex-shrink:0;background:#fff;border:1px solid var(--gray-200);border-radius:var(--radius);padding:10px 0;">
 +        <div style="font-size:11px;font-weight:600;color:var(--gray-600);padding:0 8px 6px;border-bottom:1px solid var(--gray-100);margin-bottom:4px;">Analysethema's</div>
 +        <div id="kaart-thema-panel"></div>
 +      </div>
 +    </div>
 +    <div class="kaart-info" id="kaart-info" style="display:none;margin-top:8px;">
 +      <div style="display:flex;gap:24px;flex-wrap:wrap;align-items:center;">
 +        <div><strong>Oppervlak:</strong> <span id="kaart-opp">–</span> m²</div>
 +        <div><strong>Gemeente:</strong> <span id="kaart-gemeente">–</span></div>
 +        <div><strong>Centroïde:</strong> <span id="kaart-coords" style="font-size:11px;color:var(--gray-500);">–</span></div>
 +      </div>
 +    </div>
 +    <div style="font-size:11px;color:var(--gray-400);margin-top:6px;">
 +      Gebruik de tekenknop (veelhoek) linksboven op de kaart · Klik "Gebruik dit oppervlak" om door te gaan naar het Laadvermogen Rekenblok
 +    </div>
 +  </div>
 +
 +  <!-- ===== TAB 1: LAADVERMOGEN REKENBLOK ===== -->
 +  <div id="rekenblok" class="sm-tabcontent">
 +    <div class="sm-tab-toolbar">
 +      <button class="sm-btn-collapse-all" id="btn_collapse_rekenblok" onclick="smToggleAllCollapse('rekenblok')">▾ Alles uitklappen</button>
 +    </div>
 +    <div class="sm-bovenblok">
 +      <div class="sm-inputvelden">
 +        <div class="sm-box">
 +          <div class="sm-box-title">Plangebied &amp; Spacematrix</div>
 +          <div class="sm-inputrow full-label">
 +            <label for="opp">Oppervlak projectgebied (m²):</label>
 +            <input id="opp" type="number" value="10000" min="0" oninput="updateLaadvermogen()">
 +          </div>
 +          <div class="sm-inputrow short-label">
 +            <label for="fsi">FSI:</label>
 +            <input id="fsi" type="number" step="0.01" value="1.6" min="0" oninput="updateLaadvermogen()">
 +            <span class="sm-calc-badge" id="laadvermogen_calc">laadvermogen: –</span>
 +          </div>
 +          <div class="sm-inputrow short-label">
 +            <label for="gsi">GSI:</label>
 +            <input id="gsi" type="number" step="0.01" value="0.3" min="0" max="1" oninput="updateLaadvermogen()">
 +            <span class="sm-calc-badge" id="footprint_calc">footprint: –</span>
 +          </div>
 +          <div class="sm-inputrow" style="gap:10px;">
 +            <label for="type_project" style="width:140px;flex-shrink:0;font-size:13px;">
 +              Type project:
 +              <span class="sm-meta-badge sm-tip" data-tip="Metadata — wordt meegegeven in de seed JSON export.">?</span>
 +            </label>
 +            <select id="type_project" style="width:170px;" onchange="smSaveSessionDebounced()">
 +              <option value="wonen">Wonen</option>
 +              <option value="wonen_gemengd" selected>Wonen gemengd</option>
 +              <option value="gemengd">Gemengd stedelijk</option>
 +              <option value="werklocatie">Werklocatie</option>
 +            </select>
 +          </div>
 +          <div class="sm-inputrow full-label">
 +            <label>Voorzieningenruimte per woning:</label>
 +            <span class="sm-display-val" id="voorzieningenruimte_display">–</span>
 +            <input type="hidden" id="voorzieningenruimte_waarde" value="0">
 +          </div>
 +        </div>
 +        <div class="sm-legend">
 +          <div class="sm-legend-title">Legenda zones A–H</div>
 +          <div class="sm-legend-grid">
 +            <div class="sm-legend-item"><span class="sm-zone-badge">A</span><span class="sm-tip" data-tip="Lage bouwhoogte met veel open ruimte."><span class="sm-legend-i">i</span></span> Low-rise spacious</div>
 +            <div class="sm-legend-item"><span class="sm-zone-badge">B</span><span class="sm-tip" data-tip="Lage bouwhoogte met compacte verkaveling."><span class="sm-legend-i">i</span></span> Low-rise compact</div>
 +            <div class="sm-legend-item"><span class="sm-zone-badge">C</span><span class="sm-tip" data-tip="Middelhoge bebouwing met open opzet."><span class="sm-legend-i">i</span></span> Mid-rise open</div>
 +            <div class="sm-legend-item"><span class="sm-zone-badge">D</span><span class="sm-tip" data-tip="Middelhoge bebouwing, ruimtelijk karakter."><span class="sm-legend-i">i</span></span> Mid-rise spacious</div>
 +            <div class="sm-legend-item"><span class="sm-zone-badge">E</span><span class="sm-tip" data-tip="Compact stedelijk, hogere dichtheid."><span class="sm-legend-i">i</span></span> Mid-rise compact</div>
 +            <div class="sm-legend-item"><span class="sm-zone-badge">F</span><span class="sm-tip" data-tip="Gesloten bouwblokken."><span class="sm-legend-i">i</span></span> Mid-rise closed</div>
 +            <div class="sm-legend-item"><span class="sm-zone-badge">G</span><span class="sm-tip" data-tip="Intensieve stedelijke blokken, hoge FSI."><span class="sm-legend-i">i</span></span> Mid-rise super</div>
 +            <div class="sm-legend-item"><span class="sm-zone-badge">H</span><span class="sm-tip" data-tip="Hoogbouw gecombineerd met open maaiveld."><span class="sm-legend-i">i</span></span> High-rise</div>
 +          </div>
 +        </div>
 +      </div>
 +      <div class="sm-kaartcontainer">
 +        <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:SPACEMATE1.png"
 +             alt="Spacematrix kaart" onerror="this.style.opacity='0.3';">
 +        <div class="stipje" id="stipje"></div>
 +      </div>
 +    </div>
 +
 +    <div class="sm-section-head">Woningprogramma</div>
     <table>     <table>
-        <thead> +      <thead><tr><th>Type</th><th>%</th><th>m²/won</th><th>Aantal</th><th>Tot. BVO</th></tr></thead> 
-            <tr><th>Type</th><th>%</th><th>m²/won</th><th>Aantal</th><th>Tot. BVO</th></tr> +      <tbody id="woningtypes"></tbody> 
-        </thead> +      <tfoot><tr><th>Totaal</th><th id="totaal_perc"></th><th id="totaal_gewbvo"></th><th id="totaal_won"></th><th id="totaal_bvo"></th></tr></tfoot>
-        <tbody id="woningtypes"></tbody> +
-        <tfoot> +
-            <tr><th>Totaal</th><th id="totaal_perc">-</th><th id="totaal_gewbvo">-</th><th id="totaal_won">-</th><th id="totaal_bvo">-</th></tr> +
-        </tfoot>+
     </table>     </table>
-    <div id="output"></div> +    <div id="output" style="font-size:12px;color:var(--gray-600);margin-top:6px;"></div>
-</div>+
  
-<div id="voorzieningenclass="tabcontent"> +    <div class="sm-section-head sm-collapsible-header" 
-    <div class="inputrow"> +         data-collapse-target="collapse_samenvatting
-        <label>Aantal bewoners per woning:</label+         aria-expanded="false" 
-        <input id="bewoners_per_woningtype="number" step="0.1" value="2.2"> +         onclick="smToggleCollapse('collapse_samenvatting')"><span class="sm-collapse-chevron"></span>Samenvatting laadvermogen</div
-    </div>+    <div id="collapse_samenvattingclass="sm-collapsible"> 
 +      <div class="sm-collapsible-body">
     <table>     <table>
-        <thead+      <tbody
-            <tr><th>Voorziening</th><th>Norm (m² per 1000)</th><th>Selecteer</th></tr> +        <tr class="sum-section-row"><td colspan="2">BVO-verdeling</td></tr> 
-        </thead+        <tr><td>Woonruimte (BVO)</td                         <td id="summary_wonen_bvo"></td></tr> 
-        <tbody id="voorzieningentabel"></tbody>+        <tr><td>Voorzieningenruimte wonen (BVO)</td>           <td id="summary_voorz_tot">–</td></tr
 +        <tr><td>Niet-wonen programma (BVO)</td>                <td id="summary_nw_totaal">–</td></tr> 
 +        <tr><td>Parkeerruimte wonen bovengronds (BVO)</td>     <td id="summary_parkeren_wonen_tot">–</td></tr> 
 +        <tr><td>Parkeerruimte niet-wonen bovengronds (BVO)</td><td id="summary_parkeren_nw_tot">–</td></tr> 
 +        <tr class="sum-totaal"><td><strong>Totaal laadvermogen (BVO)</strong></td><td id="summary_bvo_tot">–</td></tr> 
 +        <tr class="sum-section-row"><td colspan="2">Kengetallen</td></tr> 
 +        <tr><td>Voorzieningenruimte per woning</td>            <td id="summary_voorz_per_won">–</td></tr> 
 +        <tr><td>Parkeerruimte per woning bovengronds</td>      <td id="summary_parkeren_per_won">–</td></tr> 
 +        <tr><td>Totaal parkeerplaatsen</td>                    <td id="summary_pp_tot">–</td></tr> 
 +        <tr><td>BVO ondergronds parkeren</td>                  <td id="summary_bvo_ondergronds">–</td></tr> 
 +        <tr><td>Uitgeefbaar (footprint + tuinen)</td>          <td id="summary_uitgeefbaar">–</td></tr> 
 +        <tr class="sum-totaal"><td><strong>Totaal woningen</strong></td><td><strong id="summary_woningen">–</strong></td></tr> 
 +      </tbody>
     </table>     </table>
-    <div class="inputrow"> +      </div>
-        <button onclick="berekenVoorzieningenruimte()">Toepassen in rekenblok</button> +
-        <div id="voorziening_resultaat"></div>+
     </div>     </div>
-</div> 
  
-<script> +    <div class="sm-export-bar"> 
-const voorzieningen +      <button onclick="smExportSeedJSON()style="padding:9px 14px;">⬇ Download seed JSON</button> 
-    { naam: "Huisarts", norm: 56 }, +      <button onclick="smUI_importSeed()style="padding:9px 14px;">⬆ Importeer seed JSON</button> 
-    { naam: "Fysiotherapie", norm: 54 }, +      <button onclick="downloadKickstartDump()" style="padding:9px 14px;">📄 Kickstart Dump</button> 
-    { naam: "Tandarts", norm: 57 }, +    </div> 
-    { naam: "Kinderopvang", norm: 2025 }, +  </div>
-    { naam: "Basisschool", norm: 5800 }, +
-    { naam: "Bibliotheek", norm: 60 }, +
-    { naam: "Buurtcentrum", norm: 70 }, +
-    { naam: "Sporthal", norm: 165 }, +
-    { naam: "Zwemmen (overdekt)", norm45 }, +
-    { naam: "Winkels dagelijkse goederen", norm: 420 } +
-];+
  
-const types = ["egw sociaal", "egw goedkoop", "egw midden", "egw duur", "egw top", "mgw sociaal", "mgw goedkoop", "mgw midden", "mgw duur", "mgw top"]; 
  
-function switchTab(tabId) { +  <!-- ===== TAB 2: VOORZIENINGEN & NIET-WONEN ===== --> 
-    document.querySelectorAll('.tab').forEach(t => t.classList.remove('active')); +  <div id="voorzieningen" class="sm-tabcontent"> 
-    document.querySelectorAll('.tabcontent').forEach(c => c.classList.remove('active')); +    <div class="sm-tab-toolbar"> 
-    document.querySelector(`.tab[onclick*="${tabId}"]`).classList.add('active')+      <button class="sm-btn-collapse-all" id="btn_collapse_voorzieningen" onclick="smToggleAllCollapse('voorzieningen')">▾ Alles uitklappen</button> 
-    document.getElementById(tabId).classList.add('active'); +    </div> 
-}+    <div class="sm-box"> 
 +      <div class="sm-box-title">Instellingen</div> 
 +      <div class="sm-inputrow full-label"> 
 +        <label for="bewoners_per_woning">Bewoners per woning:</label> 
 +        <input id="bewoners_per_woning" type="number" step="0.1" value="2.2" min="0" oninput="updateLaadvermogen()"> 
 +      </div> 
 +      <div class="sm-inputrow full-label" style="margin-top:8px;"> 
 +        <label for="bevolkingsprofiel" style="flex-shrink:0;">CBS bevolkingsprofiel:</label> 
 +        <select id="bevolkingsprofiel" style="flex:1;min-width:0;" onchange="smProfielWijzig()"> 
 +          <option>Landelijk Nederland 2040</option> 
 +        </select> 
 +      </div> 
 +      <div style="font-size:11px;color:var(--gray-500);margin-top:4px;line-height:1.4;"> 
 +        Het profiel bepaalt de doelgroep-verdeling voor voorzieningen die niet per inwoner maar per kinderen, jongeren of ouderen genormeerd zijn. 
 +        <span style="color:var(--teal-h);font-weight:500;">In het Sumsonite-abonnement zijn 15+ wijk-specifieke CBS-profielen beschikbaar (o.a. Amsterdam, Rotterdam, Breda, Eindhoven).</span> 
 +      </div> 
 +      <div class="sm-inputrow" style="align-items:flex-start;gap:8px;margin-top:10px;"> 
 +        <input type="checkbox" id="voorz_auto" checked onchange="toggleVoorzAuto();updateLaadvermogen()" style="margin-top:3px;flex-shrink:0;width:auto;"> 
 +        <label for="voorz_autostyle="cursor:pointer;width:auto;line-height:1.4;"> 
 +          <strong>Automatisch doorrekenen</strong> — berekend uit geselecteerde normen. 
 +          Schakel uit voor vaste m²/woning. 
 +        </label> 
 +      </div> 
 +      <div id="voorz_handmatig_wrap" class="sm-inputrow full-label" style="display:none;margin-top:4px;"> 
 +        <label for="voorz_handmatig">Voorzieningenruimte per woning (m², handmatig):</label> 
 +        <input id="voorz_handmatig" type="number" step="0.1" value="0" min="0" oninput="updateLaadvermogen()"> 
 +      </div> 
 +    </div>
  
-function renderWoningtypes() { +    <div class="sm-section-head" style="display:flex;justify-content:space-between;align-items:center;"> 
-    const tbody document.getElementById("woningtypes")+      <div class="sm-collapsible-header" 
-    tbody.innerHTML = ""; +           data-collapse-target="collapse_normentabel" 
-    types.forEach((type, i) => { +           aria-expanded="false" 
-        const row document.createElement("tr"); +           onclick="smToggleCollapse('collapse_normentabel')" 
-        row.innerHTML ` +           style="display:flex;align-items:center;gap:6px;flex-wrap:wrap;flex:1;"
-            <td>${type}</td+        <span class="sm-collapse-chevron">▸</span> 
-            <td><input type="number" id="perc_${i}value="10step="0.1oninput="updateLaadvermogen()"></td+        <span>Normentabel &ampselectie</span> 
-            <td><input type="numberid="bvo_${i}value="${i < 5 ? 130 90}step="1oninput="updateLaadvermogen()"></td+        <span id="normen_gemeente_labelstyle="font-size:11px;color:var(--teal);font-weight:500;"></span> 
-            <td id="aantal_${i}">-</td+        <span id="normen_peildatum" 
-            <td id="totbvo_${i}">-</td+          onclick="event.stopPropagation();smOpenBronnenModal()
-        `; +          style="font-size:10px;background:var(--teal-light);color:var(--teal-h);border:1px solid var(--teal-dim);border-radius:12px;padding:2px 10px;cursor:pointer;white-space:nowrap;font-weight:500;transition:background .12s,border-color .12s;" 
-        tbody.appendChild(row); +          onmouseenter="this.style.background='var(--teal-dim)';this.style.borderColor='var(--teal)';" 
-    }); +          onmouseleave="this.style.background='var(--teal-light)';this.style.borderColor='var(--teal-dim)';" 
-}+          title="Bekijk landelijke referentienormen"> 
 +          🔄 landelijke referentienormen → 
 +        </span
 +      </div> 
 +      <button onclick="smOpenProfielModal()style="padding:4px 10px;font-size:11px;border:1px solid var(--gray-300);color:var(--gray-600);background:var(--gray-50);border-radius:var(--radius);cursor:pointer;">👥 Bevolkingsprofiel →</button> 
 +    </div> 
 +    <div id="collapse_normentabelclass="sm-collapsible"
 +      <div class="sm-collapsible-body"
 +        <div class="voorz-grid"> 
 +          <div
 +            <table style="width:100%"> 
 +              <thead><tr><th>Voorziening <span style="font-weight:400;font-size:10px;color:var(--gray-500);">· doelgroep</span></th><th class="norm-col">Eff. norm<br><span style="font-weight:400;font-size:10px;">/1000 inw.</span></th><th class="chk-col">✓</th></tr></thead> 
 +              <tbody id="voorzieningentabel"></tbody> 
 +            </table> 
 +          </div> 
 +          <div> 
 +            <div style="font-size:12px;font-weight:600;color:var(--gray-600);margin-bottom:6px;padding-bottom:4px;border-bottom:1px solid var(--gray-200);">Geselecteerde voorzieningen</div
 +            <table style="width:100%"> 
 +              <thead><tr><th>Voorziening</th><th>Berekend m²</th></tr></thead> 
 +              <tbody id="voorziening_summary_tabel"></tbody
 +              <tfoot><tr><th>Totaal</th><th id="voorziening_summary_totaal"></th></tr></tfoot
 +            </table> 
 +          </div> 
 +        </div> 
 +      </div> 
 +    </div>
  
-function updateLaadvermogen() { +    <div class="sm-section-head">Niet-wonen programma</div> 
-    const opp parseFloat(document.getElementById("opp").value); +    <div class="sm-box sm-box-new"> 
-    const fsi parseFloat(document.getElementById("fsi").value); +      <p style="font-size:13px;color:var(--gray-700);margin:0 0 10px;"> 
-    const bvoTot opp * fsi+        Extra commercieel of werkprogramma per categorieBVO trekt direct af van laadvermogen. 
-    const voorzieningenruimte parseFloat(document.getElementById("voorzieningenruimte").value);+        Parkeernormen → tabblad <strong>Parkeren</strong>
 +      </p> 
 +      <div id="nietwonen_bvo_inputs"></div> 
 +      <div style="font-size:12px;margin-top:8px;color:var(--gray-600);"> 
 +        Totaal niet-wonen: <strong id="nw_totaal_display">–</strong> 
 +        &nbsp;·&nbsp; Bovengronds parkeer-BVO: <strong id="nw_parkbvo_display">–</strong> 
 +      </div> 
 +    </div>
  
-    let gewogenBVO = 0; +    <div class="sm-note"> 
-    let totalPerc = 0; +      Voorzieningenruimte/woning en voorzieningenparkeren/woning zijn beide constanten — het systeem is analytisch oplosbaar zonder iteratie
-    const details = []; +    </div> 
-    for (let i = 0; i types.length; i++) { +  </div>
-        const perc parseFloat(document.getElementById(`perc_${i}`).value) || 0; +
-        const bvo = parseFloat(document.getElementById(`bvo_${i}`).value) || 0; +
-        gewogenBVO += (perc 100) * bvo; +
-        totalPerc += perc; +
-        details.push({ i, perc, bvo }); +
-    } +
-    if (gewogenBVO === 0) return;+
  
-    let woningen = Math.floor(bvoTot / (gewogenBVO + voorzieningenruimte)); 
-    let sumWon = 0; 
-    let sumBVO = 0; 
-    let wonPerType = []; 
-    let restant = woningen; 
  
-    for (let i 0; i details.length; i++{ +  <!-- ===== TAB 3: PARKEREN ===== --> 
-        const { perc } details[i]; +  <div id="parkeren" class="sm-tabcontent"> 
-        let aant = (perc 100* woningen; +    <div class="sm-tab-toolbar"> 
-        let afgerond Math.floor(aant); +      <button class="sm-btn-collapse-all" id="btn_collapse_parkeren" onclick="smToggleAllCollapse('parkeren')">▾ Alles uitklappen</button> 
-        wonPerType.push(afgerond); +    </div> 
-        restant -afgerond; +    <div class="sm-box"> 
-    } +      <div class="sm-box-title">Parkeren woningen</div> 
-    const decimaalSort details.map((d, i=({ i, rest: ((d.perc / 100* woningen) % 1 })) +      <div class="sm-inputrow full-label"> 
-        .sort((a, b=> b.rest a.rest); +        <label for="pp_per_woning">Parkeerplaatsen per woning (pp/won):</label> 
-    for (let j 0; j < restantj++{ +        <input id="pp_per_woning" type="number" step="0.1" value="1.0" min="0" oninput="updateLaadvermogen()"> 
-        wonPerType[decimaalSort[j].i]++; +      </div> 
-    } +      <div class="sm-inputrow full-label"> 
-    for (let i = 0; i < details.lengthi++{ +        <label for="bvo_per_pp">BVO per parkeerplaats gebouwd (m²/pp):</label> 
-        const aant wonPerType[i]; +        <input id="bvo_per_pp" type="number" step="1" value="25" min="10" oninput="updateLaadvermogen()"> 
-        const bvoTot aant * details[i].bvo; +      </div> 
-        document.getElementById(`aantal_${i}`).innerText aant; +      <div class="sm-inputrow full-label" style="background:var(--gray-50);padding:5px 8px;border-radius:var(--radius);border:1px solid var(--gray-200);"> 
-        document.getElementById(`totbvo_${i}`).innerText bvoTot.toFixed(0); +        <label for="bvo_per_pp_straat" style="color:var(--gray-600);">Oppervlak per pp openbare ruimte (m²/pp):</label> 
-        sumWon +aant; +        <input id="bvo_per_pp_straat" type="number" step="0.5" value="12.5" min="5" style="width:80px;" oninput="updateLaadvermogen()"> 
-        sumBVO +bvoTot; +      </div> 
-    } +      <div class="sm-inputrow full-label"> 
-    document.getElementById("totaal_perc").innerText `${totalPerc.toFixed(1)}%`; +        <label for="pp_bovengronds">% Bovengronds:</label> 
-    document.getElementById("totaal_gewbvo").innerText = `${gewogenBVO.toFixed(1)} m²`; +        <input id="pp_bovengronds" type="number" step="1" value="50" min="0" max="100" oninput="syncPercOndergronds()"> 
-    document.getElementById("totaal_won").innerText sumWon; +      </div> 
-    document.getElementById("totaal_bvo").innerText sumBVO.toFixed(0);+      <div class="park-derived-row"> 
 +        <label>% Ondergronds (= 100 − bovengronds):</label> 
 +        <span class="sm-derived" id="pp_ondergronds_display">50%</span> 
 +      </div> 
 +      <div class="sm-inputrow full-labelstyle="background:var(--gray-50);padding:5px 8px;border-radius:var(--radius);margin-top:6px;border:1px solid var(--gray-200);"
 +        <label for="pp_per_woning_bezoeker" style="color:var(--gray-600);">w.vbezoekers woningen (pp/won):</label> 
 +        <input id="pp_per_woning_bezoeker" type="number" step="0.05value="0.3" min="0" style="width:70px;" oninput="updateLaadvermogen()"> 
 +        <span style="font-size:11px;color:var(--gray-500);">ook te realiseren in openbare ruimte of als gebouwd parkeren</span> 
 +      </div> 
 +    </div>
  
-    document.getElementById("output").innerHTML = +    <div class="sm-box sm-box-new"
-        `<p><b>Gewogen BVO/ehd:</b${gewogenBVO.toFixed(1)} m²<br><b>Totaal aantal woningen:</b${sumWon}</p>`; +      <div class="sm-box-title">Parkeernormen niet-wonen &amp; voorzieningen</div> 
-}+      <p style="font-size:13px;color:var(--gray-700);margin:0 0 10px;"> 
 +        BVO per niet-wonen categorie → tabblad <strong>Voorzieningen &amp; Niet-Wonen</strong>
 +        Voorzieningen-BVO wordt afgeleid uit het woningaantal en de normen. 
 +        Zelfde % boven/onder als woningen. 
 +      </p> 
 +      <div class="sm-inputrow full-label" style="background:var(--teal-light);padding:6px 8px;border-radius:var(--radius);margin-bottom:8px;"> 
 +        <label for="pp_voorzieningen" style="font-weight:600;">Voorzieningen (pp 100 m² BVO):</label> 
 +        <input id="pp_voorzieningen" type="number" step="0.1" value="1.5" min="0" style="width:80px;" oninput="updateLaadvermogen()"> 
 +        <span style="font-size:12px;color:var(--teal-h);margin-left:6px;">→ <span id="pp_voorzieningen_count"></spanpp</span
 +      </div> 
 +      <div id="nietwonen_pp_inputs"></div> 
 +    </div>
  
-function maakVoorzieningentabel() { +    <!-- Dubbelgebruiksanalyse CROW 317 --> 
-    const tbody document.getElementById("voorzieningentabel"); +    <div class="sm-boxstyle="margin-top:12px;"> 
-    voorzieningen.forEach((v, i) => { +      <div class="sm-box-title sm-collapsible-header" 
-        const row document.createElement("tr"); +           data-collapse-target="collapse_dubbelgebruik_tabel" 
-        row.innerHTML ` +           aria-expanded="false" 
-            <td>${v.naam}</td+           onclick="smToggleCollapse('collapse_dubbelgebruik_tabel')
-            <td>${v.norm}</td+           style="display:flex;align-items:center;justify-content:space-between;gap:8px;"> 
-            <td><input type="checkboxid="vchk_${i}checked></td+        <span><span class="sm-collapse-chevron">▸</span>Dubbelgebruiksanalyse (CROW 317)</span> 
-        `+        <button onclick="event.stopPropagation();showCrowModal()" style="font-size:11px;padding:3px 9px;border-radius:4px;white-space:nowrap;">ℹ️ Aanwezigheidspercentages</button> 
-        tbody.appendChild(row); +      </div> 
-    }); +      <div id="collapse_dubbelgebruik_tabel" class="sm-collapsible"
-}+        <div class="sm-collapsible-body"> 
 +          <div style="margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid var(--gray-200);"
 +            <div style="display:flex;gap:20px;flex-wrap:wrap;align-items:center;margin-bottom:8px;"> 
 +              <label style="display:flex;align-items:center;gap:7px;cursor:pointer;font-size:13px;font-weight:600;color:var(--teal);"> 
 +                <input type="radio" name="dubbelgebruik_route" id="route_crow" value="crow" checked onchange="updateLaadvermogen()"> 
 +                Route 1 — CROW aanwezigheidspercentages 
 +              </label> 
 +              <label style="display:flex;align-items:center;gap:7px;cursor:pointer;font-size:13px;"> 
 +                <input type="radio" name="dubbelgebruik_route" id="route_factor" value="factor" onchange="updateLaadvermogen()"> 
 +                Route 2 — Eigen factor: 
 +                <input id="dubbelgebruik_factor" type="number" step="1" value="10" min="0" max="50" style="width:52px;" oninput="updateLaadvermogen()"> 
 +                <span>%</span
 +                <span style="font-size:11px;color:var(--gray-500);">over totaal norm-based pp</span> 
 +              </label
 +            </div> 
 +            <div class="sm-inputrow" style="margin:0;gap:8px;"> 
 +              <label style="width:auto;font-size:13px;">Deelmobiliteit:</label> 
 +              <input id="deel_reductie_pct" type="numberstep="1" value="0" min="0" max="50" style="width:52px;" oninput="updateLaadvermogen()"> 
 +              <span style="font-size:13px;">% reductie op woon-pp</span
 +              <span style="font-size:12px;color:var(--gray-500);">→ 1 deelauto pp per</span> 
 +              <input id="deel_ratio" type="number" step="1" value="4" min="1" style="width:48px;" oninput="updateLaadvermogen()"> 
 +              <span style="font-size:13px;">gereduceerde pp</span> 
 +            </div> 
 +          </div> 
 +          <div id="dubbelgebruik_tabel_wrap"> 
 +            <p style="font-size:12px;color:var(--gray-400);">Vul woningaantal in om de analyse te starten.</p> 
 +          </div> 
 +        </div> 
 +      </div> 
 +    </div>
  
-function berekenVoorzieningenruimte() { +    <div class="sm-section-head sm-collapsible-header" 
-    const bewonersPerWoning parseFloat(document.getElementById("bewoners_per_woning").value); +         data-collapse-target="collapse_parkeerbalans" 
-    const woningen 131; // Voor nu vastlater dynamisch maken +         aria-expanded="false" 
-    const totaalBewoners woningen * bewonersPerWoning;+         onclick="smToggleCollapse('collapse_parkeerbalans')"><span class="sm-collapse-chevron">▸</span>Parkeerbalans per categorie (op basis van norm)</div> 
 +    <div id="collapse_parkeerbalans" class="sm-collapsible"> 
 +      <div class="sm-collapsible-body"> 
 +    <table> 
 +      <thead><tr> 
 +        <th>Categorie</th> 
 +        <th># won / m²BVO</th> 
 +        <th>Norm</th> 
 +        <th>Aantal pp</th> 
 +        <th>% verdeling</th> 
 +      </tr></thead> 
 +      <tbody id="parkeer_cat_tbody"></tbody> 
 +      <tfoot> 
 +        <tr class="sum-totaal"> 
 +          <th colspan="3">Totaal norm-based (inclbezoekers)</th> 
 +          <th id="pk_tot_pp">–</th> 
 +          <th>100%</th> 
 +        </tr> 
 +        <tr style="background:var(--teal-light);border-top:1px solid var(--teal-dim);"
 +          <th colspan="3" id="pk_dubbelgebruik_label" style="color:var(--teal-h);font-weight:600;font-size:11px;">Na dubbelgebruik</th> 
 +          <th id="pk_benodigd_na_dub" style="color:var(--teal-h);">–</th> 
 +          <th>–</th> 
 +        </tr> 
 +        <tr id="pk_deelmob_row" style="display:none;"> 
 +          <th colspan="3" id="pk_deelmob_label">− Deelmobiliteit</th> 
 +          <th id="pk_deelmob_pp">–</th> 
 +          <th>–</th> 
 +        </tr> 
 +        <tr style="border-top:2px solid var(--teal-dim);background:var(--teal-light);"> 
 +          <th colspan="3"><strong>= Benodigd totaal</strong></th> 
 +          <th id="pk_benodigd_pp"><strong>–</strong></th> 
 +          <th>–</th> 
 +        </tr> 
 +        <tr> 
 +          <th colspan="3">w.v. Parkeren openbare ruimte</th> 
 +          <th id="pp_openbaar_pp">–</th> 
 +          <th id="pp_openbaar_bvo">–</th> 
 +        </tr> 
 +        <tr> 
 +          <th colspan="3">w.v. Gebouwd (te bouwen)</th> 
 +          <th id="pp_tebouwen_pp">–</th> 
 +          <th>–</th> 
 +        </tr> 
 +        <tr> 
 +          <th colspan="2">w.v. Bovengronds</th> 
 +          <th id="pp_boven_pct">–</th> 
 +          <th id="pp_boven_pp">–</th> 
 +          <th id="pp_boven_bvo">–</th> 
 +        </tr> 
 +        <tr> 
 +          <th colspan="2">w.v. Ondergronds</th> 
 +          <th id="pp_onder_pct">–</th> 
 +          <th id="pp_onder_pp">–</th> 
 +          <th id="pp_onder_bvo">–</th> 
 +        </tr> 
 +      </tfoot> 
 +    </table> 
 +      </div> 
 +    </div> 
 +    <span id="pp_totaal"       style="display:none"></span> 
 +    <span id="pp_totaal_bvo"   style="display:none"></span> 
 +    <span id="pp_boven_display"style="display:none"></span> 
 +    <span id="pp_onder_display"style="display:none"></span> 
 +  </div>
  
-    let totaal_m2 = 0; 
-    voorzieningen.forEach((v, i) => { 
-        const checked = document.getElementById(`vchk_${i}`).checked; 
-        if (checked) { 
-            totaal_m2 += v.norm * totaalBewoners / 1000; 
-        } 
-    }); 
-    const m2_per_woning = totaal_m2 / woningen; 
-    document.getElementById("voorziening_resultaat").innerHTML = 
-        `<b>${totaal_m2.toFixed(1)} m² totaal</b> → ${m2_per_woning.toFixed(1)} m² per woning`; 
-    document.getElementById("voorzieningenruimte").value = m2_per_woning.toFixed(1); 
-    updateLaadvermogen(); 
-} 
  
-window.onload = () ={ +  <!-- ===== TAB 4: ONBEBOUWDE RUIMTE ===== --> 
-    renderWoningtypes(); +  <div id="openbareruimte" class="sm-tabcontent"> 
-    maakVoorzieningentabel(); +    <div class="sm-tab-toolbar"> 
-    updateLaadvermogen(); +      <button class="sm-btn-collapse-all" id="btn_collapse_openbareruimte" onclick="smToggleAllCollapse('openbareruimte')">▾ Alles uitklappen</button
-}+    </div> 
-</script>+    <div class="sm-box"> 
 +      <div class="sm-box-title">Verdeling onbebouwde ruimte (opp − bebouwde footprint)</div> 
 +      <div style="display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:12px;"> 
 +        <div class="sm-inputrow full-label" style="margin:0;"> 
 +          <label for="stedelijkheidstype">Stedelijkheidstype:</label> 
 +          <select id="stedelijkheidstype" style="width:190px;" onchange="setVerdelingStedelijkheid()"> 
 +            <option value="centrum">Centrumstedelijk</option> 
 +            <option value="gemengd">Gemengd</option> 
 +            <option value="suburbaan">Suburbaan</option> 
 +          </select> 
 +        </div> 
 +        <span id="or_suggestie" style="font-size:11px;color:var(--teal);font-style:italic;"></span> 
 +      </div> 
 +      <table class="or-table"> 
 +        <thead><tr> 
 +          <th>Type onbebouwde ruimte</th> 
 +          <th style="width:90px;">Preset (%)</th> 
 +          <th style="width:90px;">Ingevoerd (%)</th> 
 +          <th style="width:110px;">Oppervlak (m²)</th> 
 +        </tr></thead> 
 +        <tbody> 
 +          <tr><td>Openbaar groen</td><td id="preset_groen" style="text-align:right;font-size:12px;color:var(--gray-500);">18</td><td><input type="number" id="perc_groen" value="18" oninput="updateOpenbareRuimte()"></td><td id="m2_groen">–</td></tr> 
 +          <tr><td>Water</td><td id="preset_water" style="text-align:right;font-size:12px;color:var(--gray-500);">4</td><td><input type="number" id="perc_water" value="4" oninput="updateOpenbareRuimte()"></td><td id="m2_water">–</td></tr> 
 +          <tr><td>Tuinen (privé EGW + MGW-binnenplaatsen)</td><td id="preset_tuinen" style="text-align:right;font-size:12px;color:var(--gray-500);">8</td><td><input type="number" id="perc_tuinen" value="8" oninput="updateOpenbareRuimte()"></td><td id="m2_tuinen">–</td></tr> 
 +          <tr><td>Rijbanen</td><td id="preset_rijbanen" style="text-align:right;font-size:12px;color:var(--gray-500);">25</td><td><input type="number" id="perc_rijbanen" value="25" oninput="updateOpenbareRuimte()"></td><td id="m2_rijbanen">–</td></tr> 
 +          <tr><td>Trottoirs &amp; fietspad</td><td id="preset_trottoirs" style="text-align:right;font-size:12px;color:var(--gray-500);">20</td><td><input type="number" id="perc_trottoirs" value="20" oninput="updateOpenbareRuimte()"></td><td id="m2_trottoirs">–</td></tr> 
 +          <tr><td>Parkeren openbare ruimte</td><td id="preset_parkeren" style="text-align:right;font-size:12px;color:var(--gray-500);">10</td><td><input type="number" id="perc_parkeren" value="10" oninput="updateOpenbareRuimte()"></td><td id="m2_parkeren">–</td></tr> 
 +          <tr><td>Pleinen &amp; verblijfsruimte</td><td id="preset_pleinen" style="text-align:right;font-size:12px;color:var(--gray-500);">15</td><td><input type="number" id="perc_pleinen" value="15" oninput="updateOpenbareRuimte()"></td><td id="m2_pleinen">–</td></tr> 
 +        </tbody> 
 +        <tfoot> 
 +          <tr><th colspan="2">Totaal ingevoerd</th> 
 +            <th id="or_totaal_perc" style="text-align:right;">–</th> 
 +            <th id="m2_totaal_onbebouwd">–</th> 
 +          </tr> 
 +        </tfoot> 
 +      </table> 
 +      <div id="warning_openbareruimte" style="color:var(--red);font-weight:700;margin-top:6px;font-size:13px;"></div> 
 +    </div>
  
-</body>+    <!-- EGW Privétuinen --> 
 +    <div class="sm-tuin-egw sm-collapsible" id="collapse_egw_tuinen"> 
 +      <div class="sm-tuin-egw-title sm-collapsible-header" 
 +           data-collapse-target="collapse_egw_tuinen" 
 +           aria-expanded="false" 
 +           onclick="smToggleCollapse('collapse_egw_tuinen')"><span class="sm-collapse-chevron"></span>EGW Privétuinen 
 +        <span style="font-weight:400;font-size:11px;">— verificatie van de Tuinen-rij hierboven</span> 
 +      </div> 
 +      <div class="sm-collapsible-body"> 
 +      <p style="font-size:12px;color:var(--gray-600);margin:0 0 10px;"> 
 +        De rij <strong>Tuinen</strong> bevat <em>alle</em> privétuinen — EGW-voor/achtertuinen én MGW-binnenplaatsen. 
 +        Vul tuindiepte en beukmaat in om te controleren of het tuinpercentage voldoende is voor de EGW's in het programma. 
 +      </p> 
 +      <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px 20px;max-width:500px;"> 
 +        <div class="sm-inputrow" style="margin:0;flex-wrap:nowrap;"> 
 +          <label for="egw_tuindiepte" style="width:160px;font-size:13px;flex-shrink:0;">Tuindiepte EGW (m):</label> 
 +          <input id="egw_tuindiepte" type="number" step="0.5" value="0" min="0" style="width:70px;" oninput="updateOpenbareRuimte()"> 
 +        </div> 
 +        <div class="sm-inputrow" style="margin:0;flex-wrap:nowrap;"> 
 +          <label for="egw_beukmaat" style="width:160px;font-size:13px;flex-shrink:0;">Beukmaat EGW (m):</label> 
 +          <input id="egw_beukmaat" type="number" step="0.1" value="0" min="0" style="width:70px;" oninput="updateOpenbareRuimte()"> 
 +        </div> 
 +      </div> 
 +      <div id="egw_tuin_resultaat" style="margin-top:10px;font-size:12px;color:var(--gray-600);background:var(--gray-50);border:1px solid var(--gray-200);border-radius:var(--radius);padding:8px 12px;line-height:1.6;display:none;"></div> 
 +      <div id="egw_tuin_conflict" style="margin-top:8px;display:none;background:var(--red-light);border:1px solid #fca5a5;border-radius:var(--radius);padding:8px 12px;font-size:12px;color:var(--red);font-weight:600;line-height:1.5;"></div> 
 +      <div class="sm-tuin-egw-result" id="m2_tuinen_egw">–</div> 
 +      </div> 
 +    </div> 
 + 
 +    <canvas id="openbareRuimteChart" style="max-width:480px;max-height:280px;margin-top:20px;display:block;"></canvas> 
 +  </div> 
 + 
 +</div><!-- .sm-page --> 
 + 
 +<!-- ===== Bronnen modal (vereenvoudigd — alleen per gemeente) ===== --> 
 +<div id="bronnen_modal" onclick="if(event.target===this)smCloseBronnenModal()" 
 +     style="display:none;position:fixed;inset:0;z-index:3000;background:rgba(0,0,0,.5);align-items:center;justify-content:center;"> 
 +  <div style="background:#ffffff;border-radius:12px;width:min(640px,96vw);max-height:88vh;display:flex;flex-direction:column;box-shadow:0 8px 40px rgba(0,0,0,.18);"> 
 +    <div style="background:var(--teal);color:#fff;padding:14px 18px;border-radius:12px 12px 0 0;display:flex;justify-content:space-between;align-items:flex-start;flex-shrink:0;"> 
 +      <div> 
 +        <div style="font-size:15px;font-weight:700;margin-bottom:3px;">Voorzieningsnormen — landelijke referentiewaarden</div> 
 +        <div style="font-size:11px;opacity:.8;">Statische normen · jaarlijks bijgewerkt · CBS, DUO, RIVM open data</div> 
 +      </div> 
 +      <button onclick="smCloseBronnenModal()" style="background:none;border:none;color:#fff;font-size:20px;cursor:pointer;line-height:1;padding:0 4px;opacity:.8;">✕</button> 
 +    </div> 
 +    <!-- Upsell banner --> 
 +    <div style="padding:10px 18px;background:linear-gradient(135deg,#f0fdfa,#fefce8);border-bottom:1px solid var(--teal-dim);flex-shrink:0;"> 
 +      <div style="font-size:12px;color:var(--teal-h);font-weight:600;">🔒 Gemeente-specifieke normen beschikbaar met Sumsonite-abonnement</div> 
 +      <div style="font-size:11px;color:var(--gray-600);margin-top:2px;">Automatisch afgestemd op uw projectlocatie · maandelijks bijgewerkt via AI · inclusief trendanalyse</div> 
 +    </div> 
 +    <span id="bt_gemeente_status" style="display:none;"></span> 
 +    <!-- Tabel --> 
 +    <div style="overflow-y:auto;flex:1;padding:14px 18px;"> 
 +      <div id="bt_loading" style="text-align:center;padding:40px;color:var(--gray-500);font-size:13px;">Data laden...</div> 
 +      <div id="bt_content" style="display:none;"> 
 +        <table style="width:100%;border-collapse:collapse;font-size:12px;"> 
 +          <thead> 
 +            <tr style="background:var(--gray-50);"> 
 +              <th style="padding:7px 10px;border:1px solid var(--gray-200);text-align:left;font-weight:600;">Voorziening</th> 
 +              <th style="padding:7px 10px;border:1px solid var(--gray-200);text-align:right;font-weight:600;">Norm (m²)</th> 
 +              <th style="padding:7px 10px;border:1px solid var(--gray-200);text-align:left;font-weight:600;font-size:10px;">Eenheid</th> 
 +              <th style="padding:7px 10px;border:1px solid var(--gray-200);text-align:left;font-weight:600;font-size:10px;">Bron</th> 
 +            </tr> 
 +          </thead> 
 +          <tbody id="bt_tabel_body"></tbody> 
 +        </table> 
 +        <div id="bt_footer" style="margin-top:12px;font-size:10px;color:var(--gray-500);line-height:1.6;"></div> 
 +      </div> 
 +    </div> 
 +    <div style="padding:10px 18px;border-top:1px solid var(--gray-200);display:flex;justify-content:space-between;align-items:center;flex-shrink:0;background:var(--gray-50);border-radius:0 0 12px 12px;"> 
 +      <div id="bt_peildatum" style="font-size:10px;color:var(--gray-500);"></div> 
 +      <button onclick="smCloseBronnenModal()" style="padding:7px 18px;background:var(--teal);color:#fff;border:none;border-radius:6px;font-size:12px;cursor:pointer;">Sluiten</button> 
 +    </div> 
 +  </div> 
 +</div> 
 + 
 +<!-- ===== CROW 317 Modal ===== --> 
 +<div id="crow_modal" onclick="if(event.target===this)closeCrowModal()" 
 +     style="display:none;position:fixed;inset:0;z-index:200;background:rgba(0,0,0,0.5);align-items:center;justify-content:center;"> 
 +  <div style="background:#fff;border-radius:10px;max-width:96vw;max-height:92vh;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,0.3);display:flex;flex-direction:column;"> 
 +    <div style="display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #e2e8f0;flex-shrink:0;gap:16px;"> 
 +      <strong style="font-size:14px;">CROW Publicatie 317 — Aanwezigheidspercentages parkeren</strong> 
 +      <button onclick="closeCrowModal()" style="padding:4px 12px;flex-shrink:0;">✕ Sluiten</button> 
 +    </div> 
 +    <div style="overflow:auto;padding:12px 16px;"> 
 +      <table style="border-collapse:collapse;font-size:12px;white-space:nowrap;"> 
 +        <thead><tr> 
 +          <th style="text-align:left;padding:6px 10px;background:#f8fafc;border:1px solid #e2e8f0;min-width:210px;">Functie</th> 
 +          <th style="padding:5px 8px;background:#f8fafc;border:1px solid #e2e8f0;text-align:center;font-size:10px;">Wkd<br>Ocht.</th> 
 +          <th style="padding:5px 8px;background:#f8fafc;border:1px solid #e2e8f0;text-align:center;font-size:10px;">Wkd<br>Mid.</th> 
 +          <th style="padding:5px 8px;background:#f8fafc;border:1px solid #e2e8f0;text-align:center;font-size:10px;">Wkd<br>Avond</th> 
 +          <th style="padding:5px 8px;background:#f8fafc;border:1px solid #e2e8f0;text-align:center;font-size:10px;">Koop-<br>avond</th> 
 +          <th style="padding:5px 8px;background:#f8fafc;border:1px solid #e2e8f0;text-align:center;font-size:10px;">Nacht</th> 
 +          <th style="padding:5px 8px;background:#f8fafc;border:1px solid #e2e8f0;text-align:center;font-size:10px;">Zat.<br>Mid.</th> 
 +          <th style="padding:5px 8px;background:#f8fafc;border:1px solid #e2e8f0;text-align:center;font-size:10px;">Zat.<br>Avond</th> 
 +          <th style="padding:5px 8px;background:#f8fafc;border:1px solid #e2e8f0;text-align:center;font-size:10px;">Zon.<br>Mid.</th> 
 +        </tr></thead> 
 +        <tbody id="crow_modal_tbody"></tbody> 
 +      </table> 
 +      <p style="font-size:11px;color:#94a3b8;margin-top:8px;">Bron: Aanwezigheidspercentages op basis van CROW publicatie 317 &nbsp;·&nbsp; Groen = hoog aanwezig &nbsp;·&nbsp; Grijs = afwezig</p> 
 +    </div> 
 +  </div> 
 +</div> 
 + 
 +<!-- ===== Powered-by badge ===== --> 
 +<a class="sm-powered" href="https://www.sumsonite.nl" target="_blank" rel="noopener" title="Sumsonite"> 
 +  ◈ Sumsonite 
 +</a> 
 + 
 +<script src="/wiki/tools/dichtheid_V2/sm_rekenmachine_light.js?v=2"></script> 
 +<script src="/wiki/tools/dichtheid_V2/kaart_light.js?v=2"></script> 
 +<script src="/wiki/tools/dichtheid_V2/bronnen_light.js?v=2"></script> 
 + 
 +<!-- CROW 317 tabel vullen na page load --> 
 +<script> 
 +document.addEventListener("DOMContentLoaded", function(){ 
 +  var tbody = document.getElementById("crow_modal_tbody"); 
 +  if(!tbody || typeof CROW_317 === "undefined") return; 
 +  CROW_317.volledig.forEach(function(row){ 
 +    var naam = row[0], pcts = row[1]; 
 +    var tr = document.createElement("tr"); 
 +    var html = '<td style="padding:5px 10px;border:1px solid #e2e8f0;">' + naam + '</td>'; 
 +    pcts.forEach(function(p){ 
 +      var bg = "", fw = ""; 
 +      if(p >= 90){ bg = "background:#dcfce7;"; fw = "font-weight:700;";
 +      else if(p >= 50){ bg = "background:#f0fdfa;";
 +      else if(p <= 5){ bg = ""; fw = "color:#d1d5db;";
 +      html += '<td style="padding:4px 8px;border:1px solid #e2e8f0;text-align:center;' + bg + fw + '">' + p + '%</td>'; 
 +    }); 
 +    tr.innerHTML = html; 
 +    tbody.appendChild(tr); 
 +  }); 
 +}); 
 +</script>
 </html> </html>
handleiding_nieuw/sub_spacematrix.1746610161.txt.gz · Last modified: 2025/05/07 09:29 by support

© Sumsonite B.V. Alle rechten voorbehouden. Documentatie, rekenmethodes, databanken en (bron)code mogen niet worden gekopieerd, verspreid of (reverse) engineered zonder voorafgaande schriftelijke toestemming. · Rechten & gebruik