JSFiddle - React, Tailwind, and code Playground

by dmather

HTML

<div class="calculator-container">
    <h1>Gulfport City Property Tax Allocation Calculator</h1>
    <p class="subtitle">
      Enter your <strong>taxable value</strong> (after exemptions). The calculator estimates how much of your
      <strong>City of Gulfport property tax</strong> supports each major service area, using the FY 2026 adopted budget.
    </p>

    <div class="input-row">
      <div class="field">
        <label for="taxableValue">Taxable value of your property ($)</label>
        <input type="number" id="taxableValue" value="200000" min="0" step="1000" />
        <div class="hint">Example: if your home’s taxable value is $200,000, enter 200000.</div>
      </div>
      <div class="field">
        <label for="millageRate">City millage rate (mills)</label>
        <input type="number" id="millageRate" value="4.0258" step="0.0001" />
        <div class="hint">FY 2026 City of Gulfport millage: 4.0258</div>
      </div>
    </div>

    <button type="button" onclick="calculateTax()">Calculate</button>

    <div class="results" id="results" style="display:none;">
      <div class="results-summary" id="summaryText"></div>

      <table>
        <thead>
          <tr>
            <th>Service Area</th>
            <th>Share of City General Fund</th>
            <th>Estimated Amount of Your City Tax</th>
          </tr>
        </thead>
        <tbody id="resultsBody"></tbody>
        <tfoot>
          <tr>
            <td>Total</td>
            <td>100%</td>
            <td id="totalCell"></td>
          </tr>
        </tfoot>
      </table>

      <div class="footer-note">
        This calculator uses FY 2026 adopted General Fund shares by function:<br />
        Public Safety 40.39%, Public Works 17.27%, Recreation 13.26%, Legislative &amp; Administrative 13.08%,
        Community Development 8.34%, Library &amp; Technology 7.65%.<br />
        It is an educational estimate and does not replace your official...

CSS

body {
      font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      margin: 0;
      padding: 20px;
      background: #f5f7fb;
      color: #222;
    }
    .calculator-container {
      max-width: 900px;
      margin: 0 auto;
      background: #ffffff;
      border-radius: 12px;
      padding: 24px 24px 32px;
      box-shadow: 0 4px 12px rgba(0,0,0,0.08);
    }
    h1 {
      font-size: 1.6rem;
      margin-bottom: 0.5rem;
      color: #003f87; /* Gulfport-ish blue */
    }
    p.subtitle {
      margin-top: 0;
      margin-bottom: 1.25rem;
      color: #555;
      font-size: 0.95rem;
    }
    .input-row {
      display: flex;
      flex-wrap: wrap;
      gap: 16px;
      margin-bottom: 16px;
    }
    .field {
      flex: 1 1 220px;
    }
    label {
      display: block;
      font-weight: 600;
      margin-bottom: 4px;
      font-size: 0.9rem;
    }
    input[type="number"] {
      width: 100%;
      padding: 8px 10px;
      border-radius: 6px;
      border: 1px solid #ccc;
      font-size: 0.95rem;
      box-sizing: border-box;
    }
    .hint {
      font-size: 0.8rem;
      color: #777;
      margin-top: 2px;
    }
    button {
      background: #003f87;
      color: white;
      border: none;
      border-radius: 8px;
      padding: 10px 18px;
      font-size: 0.95rem;
      font-weight: 600;
      cursor: pointer;
      margin-top: 4px;
    }
    button:hover {
      background: #0053b8;
    }
    .results {
      margin-top: 24px;
    }
    .results-summary {
      background: #f0f5ff;
      border-radius: 10px;
      padding: 12px 14px;
      font-size: 0.95rem;
      margin-bottom: 16px;
    }
    .results-summary strong {
      color: #003f87;
    }
    table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 8px;
      font-size: 0.9rem;
    }
    th, td {
      border-bottom: 1px solid #e1e1e1;
     ...

JavaScript

// Service areas and their share of the General Fund (in percent)
    const services = [
      { name: "Public Safety (Police & Fire/EMS)", share: 40.39 },
      { name: "Public Works (Streets, Facilities, Infrastructure Support)", share: 17.27 },
      { name: "Recreation & Parks", share: 13.26 },
      { name: "Legislative & Administrative", share: 13.08 },
      { name: "Community Development (Planning, Building, Code)", share: 8.34 },
      { name: "Library & Technology Services", share: 7.65 }
    ];

    function formatDollar(amount) {
      return amount.toLocaleString("en-US", {
        style: "currency",
        currency: "USD",
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
      });
    }

    function calculateTax() {
      const taxableValueInput = document.getElementById("taxableValue");
      const millageRateInput = document.getElementById("millageRate");
      const resultsDiv = document.getElementById("results");
      const resultsBody = document.getElementById("resultsBody");
      const summaryText = document.getElementById("summaryText");
      const totalCell = document.getElementById("totalCell");

      const taxableValue = parseFloat(taxableValueInput.value) || 0;
      const millage = parseFloat(millageRateInput.value) || 0;

      if (taxableValue <= 0 || millage <= 0) {
        alert("Please enter a taxable value and millage rate greater than zero.");
        return;
      }

      // City tax formula: taxable value * millage / 1000
      const annualCityTax = taxableValue * millage / 1000;

      const monthlyCityTax = annualCityTax / 12;

      // Build summary text
      summaryText.innerHTML =
        "Estimated <strong>annual City of Gulfport property tax</strong> on a taxable value of " +
        formatDollar(taxableValue) + " at " + millage.toFixed(4) +
        " mills is <strong>" + formatDollar(annualCityTax) + "</strong> (" +
       ...