<?php
$page_title = "Epoxy Quartz Flooring Calculator | Epoxy.com";
$meta_description = "Epoxy quartz flooring calculator. Enter square footage and choose single, double, triple, or quad broadcast to estimate raw gallons of Product #15 and raw pounds of quartz, plus final 3-gallon kit and 50-lb bag counts rounded up at totals only.";
include $_SERVER['DOCUMENT_ROOT'].'/includes/header.php';
?>

<!--
File: epoxy-quartz-flooring-calculator.aspx
Purpose:
  Replace the existing quartz flooring calculator without changing file name or location.

System assumptions:
  - Primer coverage: 250 SF per gallon
  - Broadcast Base 1 coverage: 100 SF per gallon
  - Additional broadcast lift coverage: 80 SF per gallon
  - Topcoat 1 coverage: 80 SF per gallon
  - Optional Topcoat 2 coverage: 120 SF per gallon
  - Quartz usage per broadcast: 0.5 lb per SF
  - Product #15 unit size: 3 gallons
  - Quartz bag size: 50 lb

Important:
  - Outputs raw gallons and pounds by layer
  - Rounds up only once at totals for ordering
  - No waste factor included
-->

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WebApplication",
  "name": "Epoxy Quartz Flooring Calculator",
  "applicationCategory": "Calculator",
  "operatingSystem": "All",
  "publisher": {
    "@type": "Organization",
    "name": "Epoxy.com"
  }
}
</script>

<h1>Epoxy Quartz Flooring Calculator</h1>

<p>
Enter your total floor area and choose the number of broadcast layers.
This calculator outputs <strong>raw</strong> gallons and pounds per layer,
then rounds up only once at the bottom for ordering.
No waste factor is included.
Calculations are based on <a href="https://www.epoxy.com/15.aspx">Epoxy.com Product #15</a>.
</p>

<div style="max-width:820px;">

  <div style="margin:1em 0;">
    <label for="sqft"><strong>Total Area (square feet)</strong></label><br />
    <input type="number" id="sqft" min="0" step="0.01" style="max-width:220px;" />
  </div>

  <div style="margin:1em 0;">
    <label for="broadcasts"><strong>Broadcast System</strong></label><br />
    <select id="broadcasts">
      <option value="1">Single Broadcast (+/- 1/16 inch)</option>
      <option value="2">Double Broadcast (+/- 1/8 inch)</option>
      <option value="3">Triple Broadcast (+/- 3/16 inch)</option>
      <option value="4">Quad Broadcast (+/- 1/4 inch)</option>
    </select>
  </div>

  <div style="margin:1em 0;">
    <label>
      <input type="checkbox" id="includeTop2" />
      Include optional second topcoat (120 SF/gal)
    </label>
  </div>

  <div style="margin:1em 0;">
    <button type="button" onclick="calculateQuartzFlooring()">Calculate</button>
  </div>

  <div id="calcError" style="display:none; border:1px solid #f3c2c2; background:#fff5f5; padding:1em; border-radius:6px; color:#b00000;">
  </div>

  <div id="calcResults" style="display:none; border:1px solid #ccc; padding:1em; margin-top:1em;">
    <h2>Results</h2>

    <p>
      <strong>Area:</strong> <span id="outArea"></span><br />
      <strong>Broadcast layers:</strong> <span id="outBroadcast"></span><br />
      <strong>Second topcoat:</strong> <span id="outSecondTop"></span>
    </p>

    <h3>Layer Breakdown (Raw Numbers)</h3>

    <table style="width:100%;">
      <thead>
        <tr>
          <th style="text-align:left;">Layer</th>
          <th style="text-align:left;">#15 (gallons)</th>
          <th style="text-align:left;">Quartz (lb)</th>
        </tr>
      </thead>
      <tbody id="resultsTableBody">
      </tbody>
    </table>

    <hr />

    <h3>Totals (Round Up Only Here)</h3>

    <p>
      <strong>Total #15 (raw gallons):</strong>
      <span id="outTotal15Gal"></span><br />

      <strong>#15 Units (3-gal, rounded up):</strong>
      <span id="outTotal15Kits"></span><br />

      <strong>Total Quartz (raw lb):</strong>
      <span id="outTotalQuartzLb"></span><br />

      <strong>Quartz Bags (50-lb, rounded up):</strong>
      <span id="outTotalQuartzBags"></span>
    </p>

  </div>

  <p style="font-size:0.95em; margin-top:1em;">
    This calculator is provided for estimating and double-checking your own calculations.
    While Epoxy.com believes the formulas used are accurate, this tool is provided "as is"
    without warranty or guarantee of accuracy. Quantities shown are based on theoretical
    coverage rates. Actual jobsite conditions, surface profile, porosity, mixing loss,
    broadcast loss, and installer technique may require additional material.
  </p>
</div>

<script>
function formatNumber(value, decimals) {
  return Number(value).toFixed(decimals);
}

function ceilUnits(amountNeeded, unitSize) {
  let units = Math.ceil(amountNeeded / unitSize);
  if (units < 1) units = 1;
  return units;
}

function addResultRow(tbody, label, gallons, quartz) {
  const tr = document.createElement("tr");

  const td1 = document.createElement("td");
  td1.textContent = label;
  tr.appendChild(td1);

  const td2 = document.createElement("td");
  td2.textContent = formatNumber(gallons, 2);
  tr.appendChild(td2);

  const td3 = document.createElement("td");
  td3.textContent = formatNumber(quartz, 1);
  tr.appendChild(td3);

  tbody.appendChild(tr);
}

function calculateQuartzFlooring() {
  const PRIMER_SF_PER_GAL = 250.0;
  const BASE1_SF_PER_GAL = 100.0;
  const LIFT_SF_PER_GAL = 80.0;
  const TOP1_SF_PER_GAL = 80.0;
  const TOP2_SF_PER_GAL = 120.0;

  const QUARTZ_LB_PER_SF = 0.5;

  const RESIN_UNIT_GAL = 3.0;
  const QUARTZ_BAG_LB = 50.0;

  const sqft = parseFloat(document.getElementById("sqft").value);
  const broadcasts = parseInt(document.getElementById("broadcasts").value, 10);
  const includeTop2 = document.getElementById("includeTop2").checked;

  const errorBox = document.getElementById("calcError");
  const resultsBox = document.getElementById("calcResults");
  const tbody = document.getElementById("resultsTableBody");

  errorBox.style.display = "none";
  errorBox.innerHTML = "";
  resultsBox.style.display = "none";
  tbody.innerHTML = "";

  if (isNaN(sqft) || sqft <= 0) {
    errorBox.innerHTML = "<strong>Error:</strong> Please enter a valid positive square footage.";
    errorBox.style.display = "block";
    return;
  }

  if (isNaN(broadcasts) || broadcasts < 1 || broadcasts > 4) {
    errorBox.innerHTML = "<strong>Error:</strong> Please choose a valid broadcast system.";
    errorBox.style.display = "block";
    return;
  }

  const primerGal = sqft / PRIMER_SF_PER_GAL;
  const base1Gal = sqft / BASE1_SF_PER_GAL;
  const quartzPerBroadcast = sqft * QUARTZ_LB_PER_SF;

  let extraLiftTotal = 0.0;

  const top1Gal = sqft / TOP1_SF_PER_GAL;
  let top2Gal = 0.0;

  if (includeTop2) {
    top2Gal = sqft / TOP2_SF_PER_GAL;
  }

  addResultRow(tbody, "Primer (250 SF/gal)", primerGal, 0.0);
  addResultRow(tbody, "Broadcast Base 1 (100 SF/gal)", base1Gal, quartzPerBroadcast);

  if (broadcasts >= 2) {
    for (let i = 2; i <= broadcasts; i++) {
      const liftGal = sqft / LIFT_SF_PER_GAL;
      extraLiftTotal += liftGal;
      addResultRow(tbody, "Broadcast Lift " + i + " (80 SF/gal)", liftGal, quartzPerBroadcast);
    }
  }

  addResultRow(tbody, "Topcoat 1 (80 SF/gal)", top1Gal, 0.0);

  if (includeTop2) {
    addResultRow(tbody, "Topcoat 2 (120 SF/gal)", top2Gal, 0.0);
  }

  const quartzTotal = quartzPerBroadcast * broadcasts;
  const total15 = primerGal + base1Gal + extraLiftTotal + top1Gal + top2Gal;

  document.getElementById("outArea").textContent = formatNumber(sqft, 2) + " SF";
  document.getElementById("outBroadcast").textContent = broadcasts;
  document.getElementById("outSecondTop").textContent = includeTop2 ? "Included" : "Not included";

  document.getElementById("outTotal15Gal").textContent = formatNumber(total15, 2);
  document.getElementById("outTotal15Kits").textContent = ceilUnits(total15, RESIN_UNIT_GAL);
  document.getElementById("outTotalQuartzLb").textContent = formatNumber(quartzTotal, 1);
  document.getElementById("outTotalQuartzBags").textContent = Math.ceil(quartzTotal / QUARTZ_BAG_LB);

  resultsBox.style.display = "block";
}
</script>

<?php include $_SERVER['DOCUMENT_ROOT'].'/includes/footer.php'; ?>