Leia kiiresti vajalik küttelahendus

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

				
					console.log( 'Code is Poetry' );
<!doctype html>
<html lang="et">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Küttevajaduse päringuvorm</title>
  <style>
    :root{
      --bg:#0b1220; --card:#0f1a30; --muted:#9fb0d0; --text:#eaf0ff;
      --border:rgba(255,255,255,.12); --accent:#66e3b4; --danger:#ff6b6b;
      --shadow: 0 10px 30px rgba(0,0,0,.25);
      --radius: 14px;
      font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
    }
    body{ margin:0; background:linear-gradient(180deg,#0b1220,#081022); color:var(--text); }
    .wrap{ max-width:1100px; margin:28px auto; padding:0 14px; }
    .card{ background:rgba(15,26,48,.82); border:1px solid var(--border); border-radius:var(--radius); box-shadow:var(--shadow); }
    header.card{ padding:18px 18px 14px; }
    h1{ margin:0 0 6px; font-size:22px; letter-spacing:.2px; }
    p.sub{ margin:0; color:var(--muted); font-size:14px; line-height:1.35; }
    .grid{ display:grid; gap:12px; grid-template-columns: 1fr 1fr; padding:18px; }
    .grid-3{ grid-template-columns: 1.2fr 1.2fr .8fr; }
    .field{ display:flex; flex-direction:column; gap:6px; }
    label{ font-size:13px; color:var(--muted); }
    input, select{
      background:rgba(255,255,255,.06);
      border:1px solid var(--border);
      color:var(--text);
      padding:10px 12px;
      border-radius:12px;
      outline:none;
    }
    input::placeholder{ color:rgba(234,240,255,.45); }
    .req{ color:var(--accent); font-weight:600; }
    .section-title{ padding:0 18px 12px; margin-top:6px; color:var(--muted); font-size:13px; text-transform:uppercase; letter-spacing:.12em; }
    .table-wrap{ padding:0 18px 18px; }
    table{ width:100%; border-collapse:separate; border-spacing:0; overflow:hidden; border-radius:12px; border:1px solid var(--border); }
    thead th{
      background:rgba(255,255,255,.06);
      color:var(--muted);
      font-size:12px; text-align:left;
      padding:10px 10px;
      border-bottom:1px solid var(--border);
      white-space:nowrap;
    }
    tbody td{
      padding:8px 8px;
      border-bottom:1px solid rgba(255,255,255,.08);
      vertical-align:top;
    }
    tbody tr:last-child td{ border-bottom:none; }
    .td-input input, .td-input select{ width:100%; padding:8px 10px; border-radius:10px; }
    .td-center{ text-align:center; }
    .pill{
      display:inline-flex; align-items:center; gap:8px;
      padding:8px 10px; border-radius:999px;
      background:rgba(102,227,180,.12); border:1px solid rgba(102,227,180,.25);
      color:var(--text); font-size:13px;
    }
    .muted{ color:var(--muted); font-size:13px; line-height:1.4; }
    .row-actions{ display:flex; gap:8px; justify-content:flex-end; }
    button{
      border:1px solid var(--border);
      background:rgba(255,255,255,.07);
      color:var(--text);
      padding:10px 12px;
      border-radius:12px;
      cursor:pointer;
    }
    button.primary{
      background:linear-gradient(180deg, rgba(102,227,180,.9), rgba(102,227,180,.65));
      border-color: rgba(102,227,180,.35);
      color:#072014;
      font-weight:700;
    }
    button.danger{ border-color: rgba(255,107,107,.35); background:rgba(255,107,107,.08); }
    button:disabled{ opacity:.5; cursor:not-allowed; }
    .totals{
      display:flex; gap:12px; flex-wrap:wrap; align-items:center; justify-content:space-between;
      padding:14px 18px 18px;
    }
    .totals .right{ display:flex; gap:10px; align-items:center; flex-wrap:wrap; justify-content:flex-end; }
    .kpi{
      padding:10px 12px; border-radius:12px;
      background:rgba(255,255,255,.06); border:1px solid var(--border);
      min-width:220px;
    }
    .kpi .v{ font-size:18px; font-weight:800; margin-top:2px; }
    .warn{
      margin:10px 18px 0; padding:12px 12px;
      border-radius:12px;
      background:rgba(255,193,7,.08);
      border:1px solid rgba(255,193,7,.25);
      color:var(--text);
      display:none;
    }
    .error{
      margin:10px 18px 0; padding:12px 12px;
      border-radius:12px;
      background:rgba(255,107,107,.08);
      border:1px solid rgba(255,107,107,.25);
      display:none;
    }
    footer.card{ padding:18px; }
    .small{ font-size:12px; color:rgba(234,240,255,.72); line-height:1.45; }
    @media (max-width:900px){
      .grid, .grid-3{ grid-template-columns:1fr; }
      thead{ display:none; }
      table, tbody, tr, td{ display:block; width:100%; }
      tbody td{ border-bottom:none; }
      tbody tr{ border-bottom:1px solid rgba(255,255,255,.08); padding:10px 8px; }
      .td-input{ margin-bottom:8px; }
    }
  </style>
</head>
<body>
  <div class="wrap">
    <header class="card">
      <h1>Küttevajaduse päringuvorm (kogemuslik)</h1>
      <p class="sub">
        Täida projekti andmed ja ruumide tabel. Vorm arvutab vajaliku ligikaudse võimsuse (W) ning kogusumma.
      </p>
    </header>

    <form id="heatForm" class="card" novalidate>
      <div class="section-title">Projektiandmed</div>

      <div class="grid grid-3">
        <div class="field">
          <label for="title">Projekti pealkiri <span class="req">*</span></label>
          <input id="title" name="title" required placeholder="nt. Kadrioru korteri kütteprojekt" />
        </div>

        <div class="field">
          <label for="address">Aadress <span class="req">*</span></label>
          <input id="address" name="address" required placeholder="Tänav, linn, maakond" />
        </div>

        <div class="field">
          <label for="createdBy">Koostaja</label>
          <input id="createdBy" name="createdBy" placeholder="Nimi / ettevõte" />
        </div>
      </div>

      <div class="grid">
        <div class="field">
          <label for="buildingType">Hoonetüüp</label>
          <select id="buildingType" name="buildingType">
            <option value="passive">Passiivmaja / A++ / HWB ~10 kWh/m²a</option>
            <option value="aPlus">Ligi-nullenergia / A+ / HWB ~15 kWh/m²a</option>
            <option value="a">Ligi-nullenergia / A / HWB ~25 kWh/m²a (u 40/Plus)</option>
            <option value="b" selected>Madala energiakuluga / B / HWB ~50 kWh/m²a (u 70)</option>
            <option value="c">Standardobjekt 2008 / C / HWB ~100 kWh/m²a</option>
            <option value="d">Vana hoone / D / HWB ~150 kWh/m²a</option>
            <option value="e">Vana hoone / E / HWB ~200 kWh/m²a</option>
          </select>
        </div>

        <div class="field">
          <label for="outdoorTemp">Normvälisõhu temperatuur</label>
          <select id="outdoorTemp" name="outdoorTemp">
            <option value="-10">-10°C</option>
            <option value="-11">-11°C</option>
            <option value="-12" selected>-12°C</option>
          </select>
        </div>
      </div>

      <div class="section-title">Ruumid</div>

      <div id="warning" class="warn">
        <strong>Soovitus:</strong> ruumides, kus põrandapind on üle <strong>20 m²</strong>, soovitame jagada vajalik võimsus vähemalt <strong>kahele</strong> küttekehale.
      </div>

      <div id="errorBox" class="error"></div>

      <div class="table-wrap">
        <table aria-label="Ruumide tabel">
          <thead>
            <tr>
              <th>Ruumitüüp</th>
              <th>Nimi</th>
              <th>m²</th>
              <th>Pikkus (m)</th>
              <th>Laius (m)</th>
              <th>Kõrgus (m)</th>
              <th>Välisseinad</th>
              <th>Vajalik võimsus</th>
              <th></th>
            </tr>
          </thead>
          <tbody id="roomsBody"></tbody>
        </table>

        <div class="row-actions" style="margin-top:12px;">
          <button type="button" id="addRoomBtn">+ Lisa ruum</button>
        </div>
      </div>

      <div class="totals">
        <div class="pill">
          <span>Arvutuslik koefitsient:</span>
          <strong id="wpm2Label">—</strong>
          <span class="muted">(W/m²)</span>
        </div>

        <div class="right">
          <div class="kpi">
            <div class="muted">Kokku vajalik võimsus</div>
            <div class="v" id="totalPower">0 W</div>
          </div>
        </div>
      </div>

      <div class="section-title">Saada päring</div>

      <div class="grid">
        <div class="field">
          <label for="email">E-post <span class="req">*</span></label>
          <input id="email" name="email" type="email" required placeholder="nimi@ettevõte.ee" />
          <div class="muted">Saadame sulle koondtulemuse ja vajadusel täpsustavad küsimused.</div>
        </div>
        <div class="field">
          <label for="notes">Lisainfo (soovi korral)</label>
          <input id="notes" name="notes" placeholder="nt. põhi-/lisaküte, termostaadid, ajakava, eritingimused" />
        </div>
      </div>

      <div class="totals">
        <div class="muted">Vormi saab integreerida e-poodi, WordPressi või CRM-i (POST endpointi kaudu).</div>
        <div class="right">
          <button type="button" id="previewBtn">Eelvaade (kokkuvõte)</button>
          <button class="primary" type="submit">Saada e-postiga</button>
        </div>
      </div>
    </form>

    <footer class="card">
      <div class="small">
        <strong>Info:</strong> See kalkulaator annab kogemuslikud väärtused ja tugineb üldistele praktikale lähedastele eeldustele (DIN 4701 / DIN EN 12831 loogika suunas).
        Esitatud andmete ning arvutatud tulemuste õigsuse eest ei anta garantiid ega võeta vastutust.
        Normikohane küttevajaduse (küttekoormuse) arvutus on ette nähtud ainult vastava pädevusega isikutele.
      </div>
    </footer>
  </div>

  <dialog id="summaryDialog" style="border:none; border-radius:14px; max-width:820px; width:calc(100% - 24px); background:#0f1a30; color:#eaf0ff; box-shadow:0 20px 50px rgba(0,0,0,.45);">
    <div style="padding:16px 16px 6px;">
      <div style="display:flex; align-items:center; justify-content:space-between; gap:12px;">
        <h2 style="margin:0; font-size:18px;">Kokkuvõte</h2>
        <button id="closeDialogBtn" type="button">Sulge</button>
      </div>
      <div id="summaryContent" style="margin-top:10px; color:#9fb0d0; font-size:13px; line-height:1.5;"></div>
    </div>
    <div style="padding:0 16px 16px;">
      <button id="copyBtn" type="button" class="primary" style="width:100%;">Kopeeri kokkuvõte</button>
    </div>
  </dialog>

  <script>
    // --- Seadista W/m² baasväärtused vastavalt hoonetüübile (muuda julgelt oma standardi järgi) ---
    const WPM2_BASE = {
      passive: 25,  // Passiivmaja
      aPlus: 30,    // A+
      a: 40,        // A
      b: 55,        // B
      c: 75,        // C
      d: 95,        // D
      e: 110        // E
    };

    // Normvälisõhu temp korrigeerimine (lihtsustatud)
    // -10°C: -5%, -11°C: 0%, -12°C: +5% (saad muuta)
    const OUTDOOR_FACTOR = {
      "-10": 0.95,
      "-11": 1.00,
      "-12": 1.05
    };

    const ROOM_TYPES = [
      { value: "living", label: "Elutuba / Lastetuba (22°C)" },
      { value: "bedroom", label: "Magamistuba (20–22°C)" },
      { value: "kitchen", label: "Köök (20–22°C)" },
      { value: "bathroom", label: "Vannituba (24°C)" },
      { value: "hall", label: "Esik / Koridor (18–20°C)" },
      { value: "office", label: "Kontor (21–22°C)" },
      { value: "garage", label: "Garaaž / Töötuba (10–18°C)" },
      { value: "other", label: "Muu" }
    ];

    const EXTERNAL_WALLS = [
      { value: 0, label: "Puudub" },
      { value: 1, label: "1" },
      { value: 2, label: "2" },
      { value: 3, label: "3" },
      { value: 4, label: "4" }
    ];

    const form = document.getElementById("heatForm");
    const roomsBody = document.getElementById("roomsBody");
    const addRoomBtn = document.getElementById("addRoomBtn");
    const buildingTypeEl = document.getElementById("buildingType");
    const outdoorTempEl = document.getElementById("outdoorTemp");
    const wpm2Label = document.getElementById("wpm2Label");
    const totalPowerEl = document.getElementById("totalPower");
    const warningEl = document.getElementById("warning");
    const errorBox = document.getElementById("errorBox");

    const dialog = document.getElementById("summaryDialog");
    const summaryContent = document.getElementById("summaryContent");
    const previewBtn = document.getElementById("previewBtn");
    const closeDialogBtn = document.getElementById("closeDialogBtn");
    const copyBtn = document.getElementById("copyBtn");

    function fmtW(w){
      if (!isFinite(w)) return "0 W";
      const rounded = Math.round(w);
      return rounded.toLocaleString("et-EE") + " W";
    }

    function getWpm2(){
      const base = WPM2_BASE[buildingTypeEl.value] ?? 55;
      const factor = OUTDOOR_FACTOR[outdoorTempEl.value] ?? 1.0;
      return base * factor;
    }

    function createSelect(options, value){
      const sel = document.createElement("select");
      options.forEach(o=>{
        const opt = document.createElement("option");
        opt.value = o.value;
        opt.textContent = o.label;
        sel.appendChild(opt);
      });
      if (value !== undefined) sel.value = value;
      return sel;
    }

    function createInput(type="text", placeholder=""){
      const inp = document.createElement("input");
      inp.type = type;
      inp.placeholder = placeholder;
      return inp;
    }

    function toNumber(v){
      const n = parseFloat(String(v).replace(",", "."));
      return isFinite(n) ? n : 0;
    }

    function computeArea(row){
      const areaEl = row.querySelector("[data-field='area']");
      const lenEl  = row.querySelector("[data-field='len']");
      const widEl  = row.querySelector("[data-field='wid']");

      const area = toNumber(areaEl.value);
      const len = toNumber(lenEl.value);
      const wid = toNumber(widEl.value);

      // Kui pikkus & laius antud, kasuta neid; muidu m² välja
      const computed = (len > 0 && wid > 0) ? (len * wid) : area;
      return computed > 0 ? computed : 0;
    }

    function computeRoomPower(row){
      const area = computeArea(row);
      const walls = toNumber(row.querySelector("[data-field='walls']").value);

      // Välisseinte lihtne mõju (0..4): +0%..+12% (muuda soovi korral)
      const wallFactor = 1 + (Math.min(Math.max(walls,0),4) * 0.03);

      const wpm2 = getWpm2();
      const power = area * wpm2 * wallFactor;

      row.querySelector("[data-field='computedArea']").textContent =
        (area ? area.toFixed(2).replace(".", ",") : "0,00");

      row.querySelector("[data-field='power']").textContent = fmtW(power);
      row.dataset.area = String(area);
      row.dataset.power = String(power);

      return { area, power };
    }

    function recomputeAll(){
      const wpm2 = getWpm2();
      wpm2Label.textContent = wpm2.toFixed(0);

      let total = 0;
      let hasBigRoom = false;

      [...roomsBody.querySelectorAll("tr")].forEach(row=>{
        const { area, power } = computeRoomPower(row);
        total += power;
        if (area > 20)