{"id":2597,"date":"2026-06-15T07:56:56","date_gmt":"2026-06-15T07:56:56","guid":{"rendered":"https:\/\/aiper.com\/blogs\/?page_id=2597"},"modified":"2026-06-24T04:19:18","modified_gmt":"2026-06-24T04:19:18","slug":"decking-calculator","status":"publish","type":"page","link":"https:\/\/aiper.com\/blogs\/decking-calculator\/","title":{"rendered":"Decking Calculator"},"content":{"rendered":"\n<div class=\"dc-calculator\" id=\"deckingCalculator\">\n  <!-- Region \/ Unit Toggle -->\n  <div class=\"dc-region-toggle\">\n    <span class=\"dc-region-label\">Region \/ Unit System:<\/span>\n    <div class=\"dc-region-buttons\">\n      <button type=\"button\" class=\"dc-region-btn active\" data-unit=\"imperial\">USA (ft, in)<\/button>\n      <button type=\"button\" class=\"dc-region-btn\" data-unit=\"metric\">Australia \/ Europe (m, mm)<\/button>\n    <\/div>\n  <\/div>\n\n  <!-- Error message area -->\n  <div class=\"dc-error\" id=\"dcError\" aria-live=\"polite\"><\/div>\n\n  <!-- Form -->\n  <div class=\"dc-form\">\n    <!-- Shape -->\n    <div class=\"dc-field\">\n      <label for=\"dcShape\">Deck Shape<\/label>\n      <select id=\"dcShape\">\n        <option value=\"rectangle\">Rectangle<\/option>\n        <option value=\"l-shaped\">L-shaped<\/option>\n        <option value=\"t-shaped\">T-shaped<\/option>\n        <option value=\"trapezoid\">Trapezoid<\/option>\n        <option value=\"irregular\">Irregular \/ Custom Polygon<\/option>\n      <\/select>\n    <\/div>\n\n    <!-- Dimensions - Rectangle -->\n    <div id=\"dcDimsRect\" class=\"dc-dimensions\">\n      <div class=\"dc-dim-row\">\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcLengthFt\">Length<\/label>\n          <div class=\"dc-dual-input\" id=\"dcLengthGroup\">\n            <input type=\"number\" id=\"dcLengthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcLengthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcWidthFt\">Width<\/label>\n          <div class=\"dc-dual-input\" id=\"dcWidthGroup\">\n            <input type=\"number\" id=\"dcWidthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcWidthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- Dimensions - L-shaped -->\n    <div id=\"dcDimsL\" class=\"dc-dimensions\" style=\"display:none;\">\n      <div class=\"dc-dim-row\">\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcMainLengthFt\">Main Length<\/label>\n          <div class=\"dc-dual-input\" id=\"dcMainLengthGroup\">\n            <input type=\"number\" id=\"dcMainLengthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcMainLengthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcMainWidthFt\">Main Width<\/label>\n          <div class=\"dc-dual-input\" id=\"dcMainWidthGroup\">\n            <input type=\"number\" id=\"dcMainWidthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcMainWidthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n      <div class=\"dc-dim-row\">\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcExtLengthFt\">Extension Length<\/label>\n          <div class=\"dc-dual-input\" id=\"dcExtLengthGroup\">\n            <input type=\"number\" id=\"dcExtLengthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcExtLengthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcExtWidthFt\">Extension Width<\/label>\n          <div class=\"dc-dual-input\" id=\"dcExtWidthGroup\">\n            <input type=\"number\" id=\"dcExtWidthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcExtWidthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- Dimensions - T-shaped -->\n    <div id=\"dcDimsT\" class=\"dc-dimensions\" style=\"display:none;\">\n      <div class=\"dc-dim-row\">\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcFlangeLengthFt\">Flange Length<\/label>\n          <div class=\"dc-dual-input\" id=\"dcFlangeLengthGroup\">\n            <input type=\"number\" id=\"dcFlangeLengthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcFlangeLengthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcFlangeWidthFt\">Flange Width<\/label>\n          <div class=\"dc-dual-input\" id=\"dcFlangeWidthGroup\">\n            <input type=\"number\" id=\"dcFlangeWidthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcFlangeWidthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n      <div class=\"dc-dim-row\">\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcStemLengthFt\">Stem Length<\/label>\n          <div class=\"dc-dual-input\" id=\"dcStemLengthGroup\">\n            <input type=\"number\" id=\"dcStemLengthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcStemLengthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcStemWidthFt\">Stem Width<\/label>\n          <div class=\"dc-dual-input\" id=\"dcStemWidthGroup\">\n            <input type=\"number\" id=\"dcStemWidthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcStemWidthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- Dimensions - Trapezoid -->\n    <div id=\"dcDimsTrapezoid\" class=\"dc-dimensions\" style=\"display:none;\">\n      <div class=\"dc-dim-row\">\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcTopWidthFt\">Top Width<\/label>\n          <div class=\"dc-dual-input\" id=\"dcTopWidthGroup\">\n            <input type=\"number\" id=\"dcTopWidthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcTopWidthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcBottomWidthFt\">Bottom Width<\/label>\n          <div class=\"dc-dual-input\" id=\"dcBottomWidthGroup\">\n            <input type=\"number\" id=\"dcBottomWidthFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcBottomWidthIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n      <div class=\"dc-dim-row\">\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcHeightFt\">Height<\/label>\n          <div class=\"dc-dual-input\" id=\"dcHeightGroup\">\n            <input type=\"number\" id=\"dcHeightFt\" placeholder=\"ft\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft<\/span>\n            <input type=\"number\" id=\"dcHeightIn\" placeholder=\"in\" step=\"any\" min=\"0\" class=\"dc-input-inches\">\n            <span class=\"dc-unit\">in<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"dc-field dc-dim-field\"><\/div>\n      <\/div>\n    <\/div>\n\n    <!-- Dimensions - Irregular Polygon -->\n    <div id=\"dcDimsIrregular\" class=\"dc-dimensions\" style=\"display:none;\">\n      <div class=\"dc-dim-row\">\n        <div class=\"dc-field dc-dim-field\">\n          <label for=\"dcTotalAreaFt\">Total Deck Area<\/label>\n          <div class=\"dc-dual-input\" id=\"dcTotalAreaGroup\">\n            <input type=\"number\" id=\"dcTotalAreaFt\" placeholder=\"ft\u00b2\" step=\"any\" min=\"0\" class=\"dc-input-feet\">\n            <span class=\"dc-unit\">ft\u00b2<\/span>\n            <input type=\"number\" id=\"dcTotalAreaIn\" placeholder=\"in\u00b2\" step=\"any\" min=\"0\" class=\"dc-input-inches\" style=\"display:none;\">\n            <span class=\"dc-unit\" style=\"display:none;\">in\u00b2<\/span>\n          <\/div>\n          <div class=\"dc-hint\">Square footage \/ meterage is used to approximate board layout.<\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- Board Specifications -->\n    <div class=\"dc-field\">\n      <label for=\"dcBoardWidth\">Board Width<\/label>\n      <div class=\"dc-select-custom\">\n        <select id=\"dcBoardWidthSelect\"><\/select>\n        <input type=\"number\" id=\"dcBoardWidthCustom\" placeholder=\"Custom\" step=\"any\" min=\"0\" class=\"dc-custom-input\">\n      <\/div>\n      <span class=\"dc-unit-suffix\" id=\"dcBoardWidthUnit\">in<\/span>\n    <\/div>\n    <div class=\"dc-field\">\n      <label for=\"dcBoardLength\">Board Length<\/label>\n      <div class=\"dc-select-custom\">\n        <select id=\"dcBoardLengthSelect\"><\/select>\n        <input type=\"number\" id=\"dcBoardLengthCustom\" placeholder=\"Custom\" step=\"any\" min=\"0\" class=\"dc-custom-input\">\n      <\/div>\n      <span class=\"dc-unit-suffix\" id=\"dcBoardLengthUnit\">ft<\/span>\n    <\/div>\n    <div class=\"dc-field\">\n      <label for=\"dcGap\">Gap Spacing<\/label>\n      <div class=\"dc-select-custom\">\n        <select id=\"dcGapSelect\"><\/select>\n        <input type=\"number\" id=\"dcGapCustom\" placeholder=\"Custom\" step=\"any\" min=\"0\" class=\"dc-custom-input\">\n      <\/div>\n      <span class=\"dc-unit-suffix\" id=\"dcGapUnit\">in<\/span>\n    <\/div>\n\n    <!-- Framing & Substructure -->\n    <div class=\"dc-field\">\n      <label for=\"dcJoistSpacing\">Joist Spacing<\/label>\n      <div class=\"dc-select-custom\">\n        <select id=\"dcJoistSpacingSelect\"><\/select>\n        <input type=\"number\" id=\"dcJoistSpacingCustom\" placeholder=\"Custom\" step=\"any\" min=\"0\" class=\"dc-custom-input\">\n      <\/div>\n      <span class=\"dc-unit-suffix\" id=\"dcJoistSpacingUnit\">in<\/span>\n    <\/div>\n    <div class=\"dc-field\">\n      <label for=\"dcWaste\">Wastage Factor (%)<\/label>\n      <input type=\"number\" id=\"dcWaste\" value=\"10\" step=\"any\" min=\"0\" max=\"100\">\n    <\/div>\n\n    <!-- Cost -->\n    <div class=\"dc-field\">\n      <label for=\"dcCost\">Estimated Material Cost (per sq <span id=\"dcCostAreaUnit\">ft<\/span>)<\/label>\n      <div class=\"dc-cost-input-wrapper\">\n        <span class=\"dc-currency-symbol\" id=\"dcCurrencySymbol\">$<\/span>\n        <input type=\"number\" id=\"dcCost\" placeholder=\"Optional\" step=\"any\" min=\"0\">\n      <\/div>\n    <\/div>\n\n    <!-- Buttons -->\n    <div class=\"dc-buttons\">\n      <button type=\"button\" id=\"dcCalculate\" class=\"dc-btn dc-btn-calculate\">Calculate<\/button>\n      <button type=\"button\" id=\"dcReset\" class=\"dc-btn dc-btn-reset\">Reset<\/button>\n    <\/div>\n  <\/div>\n\n  <!-- Results Panel -->\n  <div class=\"dc-results\" id=\"dcResults\" style=\"display:none;\" aria-live=\"polite\">\n    <h2 class=\"dc-results-title\">Material Estimate<\/h2>\n    <dl class=\"dc-results-list\">\n      <div class=\"dc-result-item\">\n        <dt class=\"dc-label\">Total Area<\/dt>\n        <dd class=\"dc-value\" id=\"resArea\">0<\/dd>\n      <\/div>\n      <div class=\"dc-result-item\">\n        <dt class=\"dc-label\">Deck Boards Required<\/dt>\n        <dd class=\"dc-value\" id=\"resBoards\">0<\/dd>\n      <\/div>\n      <div class=\"dc-result-item\">\n        <dt class=\"dc-label\">Total Linear Footage \/ Meterage<\/dt>\n        <dd class=\"dc-value\" id=\"resLinear\">0<\/dd>\n      <\/div>\n      <div class=\"dc-result-item\">\n        <dt class=\"dc-label\">Estimated Joists<\/dt>\n        <dd class=\"dc-value\" id=\"resJoists\">0<\/dd>\n      <\/div>\n      <div class=\"dc-result-item\">\n        <dt class=\"dc-label\">Estimated Fasteners (Screws)<\/dt>\n        <dd class=\"dc-value\" id=\"resFasteners\">0<\/dd>\n      <\/div>\n      <div class=\"dc-result-item\">\n        <dt class=\"dc-label\">Total Estimated Material Cost<\/dt>\n        <dd class=\"dc-value\" id=\"resCost\">N\/A<\/dd>\n      <\/div>\n    <\/dl>\n  <\/div>\n<\/div>\n\n<style>\n  .dc-calculator {\n    max-width: 780px;\n    margin: 0 auto;\n    font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n    color: #1a1a2e;\n    background: #fff;\n    border-radius: 16px;\n    padding: 2rem 1.5rem;\n    box-shadow: 0 12px 30px rgba(0,0,0,0.06);\n    box-sizing: border-box;\n    line-height: 1.5;\n  }\n  .dc-calculator *,\n  .dc-calculator *::before,\n  .dc-calculator *::after {\n    box-sizing: border-box;\n  }\n  .dc-region-toggle {\n    display: flex;\n    flex-direction: column;\n    gap: 0.6rem;\n    margin-bottom: 2rem;\n  }\n  .dc-region-label {\n    font-weight: 600;\n    font-size: 0.95rem;\n    color: #2d2d44;\n  }\n  .dc-region-buttons {\n    display: flex;\n    gap: 0.75rem;\n    flex-wrap: nowrap;\n  }\n  .dc-region-btn {\n    background: #f4f4f8;\n    border: 1px solid #dcdce4;\n    padding: 0.5rem 1rem;\n    border-radius: 24px;\n    font-size: 0.85rem;\n    font-weight: 500;\n    cursor: pointer;\n    transition: all 0.2s;\n    color: #444;\n    white-space: nowrap;\n  }\n  .dc-region-btn.active {\n    background: linear-gradient(135deg, #1ecad3 0%, #9486f7 100%);\n    color: #fff;\n    border-color: transparent;\n    font-weight: 600;\n  }\n  .dc-error {\n    background: #fff0f0;\n    border-left: 4px solid #d32f2f;\n    color: #b71c1c;\n    padding: 0.8rem 1rem;\n    border-radius: 6px;\n    margin-bottom: 1.5rem;\n    font-size: 0.9rem;\n    display: none;\n  }\n  .dc-form {\n    display: flex;\n    flex-direction: column;\n    gap: 1.25rem;\n  }\n  .dc-field {\n    display: flex;\n    flex-direction: column;\n    gap: 0.35rem;\n  }\n  .dc-field > label {\n    font-weight: 600;\n    font-size: 0.9rem;\n    color: #2d2d44;\n  }\n  .dc-field select,\n  .dc-field input {\n    width: 100%;\n    padding: 0.5rem;\n    border: 1px solid #dcdce4;\n    border-radius: 8px;\n    font-size: 0.9rem;\n    background: #fff;\n    transition: border-color 0.2s;\n  }\n  .dc-field select:focus,\n  .dc-field input:focus {\n    outline: none;\n    border-color: #1ecad3;\n    box-shadow: 0 0 0 3px rgba(30,202,211,0.15);\n  }\n  .dc-dual-input input {\n    width: 70px;\n    padding: 0.5rem;\n    border: 1px solid #dcdce4;\n    border-radius: 8px;\n    font-size: 0.9rem;\n    transition: border-color 0.2s;\n  }\n  .dc-dual-input input:focus {\n    outline: none;\n    border-color: #1ecad3;\n    box-shadow: 0 0 0 3px rgba(30,202,211,0.15);\n  }\n  .dc-dimensions {\n    display: flex;\n    flex-direction: column;\n    gap: 0.75rem;\n  }\n  .dc-dim-row {\n    display: flex;\n    gap: 1rem;\n    flex-wrap: wrap;\n  }\n  .dc-dim-field {\n    flex: 1 1 180px;\n  }\n  .dc-dual-input {\n    display: flex;\n    align-items: center;\n    gap: 0.35rem;\n    flex-wrap: wrap;\n  }\n  .dc-unit {\n    font-size: 0.8rem;\n    color: #666;\n    min-width: 20px;\n  }\n  .dc-select-custom {\n    display: flex;\n    gap: 0.5rem;\n    align-items: center;\n    flex-wrap: wrap;\n  }\n  .dc-select-custom select {\n    min-width: 120px;\n    padding: 0.5rem;\n    border: 1px solid #dcdce4;\n    border-radius: 8px;\n    font-size: 0.9rem;\n    background: #fff;\n    transition: border-color 0.2s;\n    flex: 1 1 auto;\n  }\n  .dc-select-custom select:focus {\n    outline: none;\n    border-color: #1ecad3;\n    box-shadow: 0 0 0 3px rgba(30,202,211,0.15);\n  }\n  .dc-custom-input {\n    width: 100px;\n    padding: 0.5rem;\n    border: 1px solid #dcdce4;\n    border-radius: 8px;\n    font-size: 0.9rem;\n    flex-shrink: 0;\n  }\n  .dc-custom-input:focus {\n    outline: none;\n    border-color: #1ecad3;\n    box-shadow: 0 0 0 3px rgba(30,202,211,0.15);\n  }\n  .dc-unit-suffix {\n    font-size: 0.8rem;\n    color: #666;\n    margin-left: 0.25rem;\n    font-weight: 500;\n  }\n  .dc-hint {\n    font-size: 0.8rem;\n    color: #777;\n    margin-top: 0.2rem;\n  }\n  .dc-cost-input-wrapper {\n    display: flex;\n    align-items: center;\n    gap: 0.3rem;\n  }\n  .dc-currency-symbol {\n    font-size: 1rem;\n    font-weight: 600;\n    color: #2d2d44;\n  }\n  .dc-cost-input-wrapper input {\n    width: 130px;\n  }\n  .dc-buttons {\n    display: flex;\n    gap: 1rem;\n    margin-top: 0.5rem;\n    flex-wrap: wrap;\n  }\n  .dc-btn {\n    padding: 0.75rem 2rem;\n    border-radius: 30px;\n    font-weight: 600;\n    font-size: 0.95rem;\n    border: none;\n    cursor: pointer;\n    transition: all 0.25s;\n    background: #f4f4f8;\n    color: #333;\n    white-space: nowrap;\n  }\n  .dc-btn-calculate {\n    background: linear-gradient(135deg, #1ecad3 0%, #9486f7 100%);\n    color: #fff;\n    box-shadow: 0 6px 16px rgba(30,202,211,0.3);\n  }\n  .dc-btn-calculate:hover {\n    box-shadow: 0 8px 22px rgba(30,202,211,0.45);\n    transform: translateY(-1px);\n  }\n  .dc-btn-reset {\n    background: #fff;\n    border: 1px solid #dcdce4;\n    color: #555;\n  }\n  .dc-btn-reset:hover {\n    background: #f9f9fc;\n    border-color: #aaa;\n  }\n  .dc-results {\n    margin-top: 2rem;\n    background: linear-gradient(135deg, rgba(30,202,211,0.05) 0%, rgba(148,134,247,0.08) 100%);\n    border-radius: 16px;\n    padding: 1.5rem;\n    border: 1px solid rgba(148,134,247,0.2);\n    transition: opacity 0.3s ease;\n  }\n  .dc-results-title {\n    margin: 0 0 1rem 0;\n    font-size: 1.2rem;\n    font-weight: 700;\n    color: #2d2d44;\n  }\n  .dc-results-list {\n    margin: 0;\n    padding: 0;\n    display: grid;\n    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n    gap: 1rem;\n  }\n  .dc-result-item {\n    display: flex;\n    flex-direction: column;\n    gap: 0.25rem;\n  }\n  .dc-label {\n    font-weight: 600;\n    font-size: 0.8rem;\n    text-transform: uppercase;\n    letter-spacing: 0.4px;\n    color: #5a5a7a;\n    margin: 0;\n  }\n  .dc-value {\n    font-size: 1.3rem;\n    font-weight: 700;\n    color: #1e1e2f;\n    margin: 0;\n    word-break: break-word;\n  }\n\n  \/* Mobile adjustments *\/\n  @media (max-width: 500px) {\n    .dc-calculator {\n      padding: 1.25rem;\n    }\n    .dc-region-toggle {\n      gap: 0.5rem;\n    }\n    .dc-region-label {\n      font-size: 0.85rem;\n    }\n    .dc-region-buttons {\n      gap: 0.4rem;\n    }\n    .dc-region-btn {\n      padding: 0.4rem 0.6rem;\n      font-size: 0.75rem;\n      flex-shrink: 0;\n    }\n    .dc-buttons {\n      flex-wrap: nowrap; \/* buttons stay side by side *\/\n      gap: 0.5rem;\n    }\n    .dc-btn {\n      padding: 0.7rem 1rem;\n      font-size: 0.85rem;\n    }\n    .dc-dual-input input {\n      width: 60px;\n    }\n  }\n<\/style>\n\n<script>\n(function() {\n  const calculator = document.getElementById('deckingCalculator');\n  let currentUnit = 'imperial';\n\n  const regionBtns = calculator.querySelectorAll('.dc-region-btn');\n  const shapeSelect = document.getElementById('dcShape');\n  const dimsRect = document.getElementById('dcDimsRect');\n  const dimsL = document.getElementById('dcDimsL');\n  const dimsT = document.getElementById('dcDimsT');\n  const dimsTrapezoid = document.getElementById('dcDimsTrapezoid');\n  const dimsIrregular = document.getElementById('dcDimsIrregular');\n  const errorDiv = document.getElementById('dcError');\n  const resultsDiv = document.getElementById('dcResults');\n  const calculateBtn = document.getElementById('dcCalculate');\n  const resetBtn = document.getElementById('dcReset');\n\n  const boardWidthSelect = document.getElementById('dcBoardWidthSelect');\n  const boardWidthCustom = document.getElementById('dcBoardWidthCustom');\n  const boardLengthSelect = document.getElementById('dcBoardLengthSelect');\n  const boardLengthCustom = document.getElementById('dcBoardLengthCustom');\n  const gapSelect = document.getElementById('dcGapSelect');\n  const gapCustom = document.getElementById('dcGapCustom');\n  const joistSpacingSelect = document.getElementById('dcJoistSpacingSelect');\n  const joistSpacingCustom = document.getElementById('dcJoistSpacingCustom');\n  const wasteInput = document.getElementById('dcWaste');\n  const costInput = document.getElementById('dcCost');\n\n  const boardWidthUnit = document.getElementById('dcBoardWidthUnit');\n  const boardLengthUnit = document.getElementById('dcBoardLengthUnit');\n  const gapUnit = document.getElementById('dcGapUnit');\n  const joistSpacingUnit = document.getElementById('dcJoistSpacingUnit');\n  const costAreaUnit = document.getElementById('dcCostAreaUnit');\n  const currencySymbol = document.getElementById('dcCurrencySymbol');\n\n  const dimGroups = {\n    rectLength: document.getElementById('dcLengthGroup'),\n    rectWidth: document.getElementById('dcWidthGroup'),\n    mainLength: document.getElementById('dcMainLengthGroup'),\n    mainWidth: document.getElementById('dcMainWidthGroup'),\n    extLength: document.getElementById('dcExtLengthGroup'),\n    extWidth: document.getElementById('dcExtWidthGroup'),\n    flangeLength: document.getElementById('dcFlangeLengthGroup'),\n    flangeWidth: document.getElementById('dcFlangeWidthGroup'),\n    stemLength: document.getElementById('dcStemLengthGroup'),\n    stemWidth: document.getElementById('dcStemWidthGroup'),\n    topWidth: document.getElementById('dcTopWidthGroup'),\n    bottomWidth: document.getElementById('dcBottomWidthGroup'),\n    height: document.getElementById('dcHeightGroup'),\n    totalArea: document.getElementById('dcTotalAreaGroup')\n  };\n\n  const imperialOptions = {\n    boardWidth: [{ value: '5.5', text: '5.5 in' }, { value: '3.5', text: '3.5 in' }, { value: '7.25', text: '7.25 in' }],\n    boardLength: [{ value: '96', text: '8 ft' }, { value: '144', text: '12 ft' }, { value: '192', text: '16 ft' }],\n    gap: [{ value: '0.125', text: '1\/8 in' }, { value: '0.25', text: '1\/4 in' }, { value: '0.375', text: '3\/8 in' }],\n    joistSpacing: [{ value: '12', text: '12 in' }, { value: '16', text: '16 in' }, { value: '24', text: '24 in' }]\n  };\n  const metricOptions = {\n    boardWidth: [{ value: '140', text: '140 mm' }, { value: '90', text: '90 mm' }, { value: '120', text: '120 mm' }],\n    boardLength: [{ value: '2400', text: '2.4 m' }, { value: '3600', text: '3.6 m' }, { value: '4800', text: '4.8 m' }],\n    gap: [{ value: '3', text: '3 mm' }, { value: '5', text: '5 mm' }, { value: '6', text: '6 mm' }],\n    joistSpacing: [{ value: '300', text: '300 mm' }, { value: '400', text: '400 mm' }, { value: '600', text: '600 mm' }]\n  };\n\n  function populateSelect(selectEl, options) {\n    selectEl.innerHTML = '';\n    options.forEach(opt => {\n      const option = document.createElement('option');\n      option.value = opt.value;\n      option.textContent = opt.text;\n      selectEl.appendChild(option);\n    });\n  }\n\n  function updateUnitUI(unit) {\n    const options = unit === 'imperial' ? imperialOptions : metricOptions;\n    populateSelect(boardWidthSelect, options.boardWidth);\n    populateSelect(boardLengthSelect, options.boardLength);\n    populateSelect(gapSelect, options.gap);\n    populateSelect(joistSpacingSelect, options.joistSpacing);\n\n    if (unit === 'imperial') {\n      boardWidthUnit.textContent = 'in';\n      boardLengthUnit.textContent = 'ft';\n      gapUnit.textContent = 'in';\n      joistSpacingUnit.textContent = 'in';\n      costAreaUnit.textContent = 'ft';\n      currencySymbol.textContent = '$';\n    } else {\n      boardWidthUnit.textContent = 'mm';\n      boardLengthUnit.textContent = 'm';\n      gapUnit.textContent = 'mm';\n      joistSpacingUnit.textContent = 'mm';\n      costAreaUnit.textContent = 'm\u00b2';\n      currencySymbol.textContent = '\u20ac';\n    }\n  }\n\n  function applyUnitToAllGroups(unit) {\n    for (let key in dimGroups) {\n      const group = dimGroups[key];\n      if (!group) continue;\n      const feetInput = group.querySelector('.dc-input-feet');\n      const inchesInput = group.querySelector('.dc-input-inches');\n      const unitSpans = group.querySelectorAll('.dc-unit');\n      if (unit === 'imperial') {\n        feetInput.placeholder = 'ft';\n        if (inchesInput) inchesInput.style.display = '';\n        if (unitSpans.length >= 2) {\n          unitSpans[0].textContent = 'ft';\n          unitSpans[1].textContent = 'in';\n          unitSpans[1].style.display = '';\n        }\n        if (key === 'totalArea') {\n          feetInput.placeholder = 'ft\u00b2';\n          if (inchesInput) inchesInput.style.display = 'none';\n          if (unitSpans[0]) unitSpans[0].textContent = 'ft\u00b2';\n          if (unitSpans[1]) unitSpans[1].style.display = 'none';\n        }\n      } else {\n        feetInput.placeholder = 'm';\n        if (inchesInput) inchesInput.style.display = 'none';\n        if (unitSpans.length >= 2) {\n          unitSpans[0].textContent = 'm';\n          unitSpans[1].style.display = 'none';\n        }\n        if (key === 'totalArea') {\n          feetInput.placeholder = 'm\u00b2';\n          if (unitSpans[0]) unitSpans[0].textContent = 'm\u00b2';\n        }\n      }\n    }\n  }\n\n  function setUnit(unit) {\n    currentUnit = unit;\n    regionBtns.forEach(btn => {\n      const btnUnit = btn.getAttribute('data-unit');\n      if (btnUnit === unit) btn.classList.add('active');\n      else btn.classList.remove('active');\n    });\n    updateUnitUI(unit);\n    applyUnitToAllGroups(unit);\n  }\n\n  regionBtns.forEach(btn => {\n    btn.addEventListener('click', () => {\n      setUnit(btn.getAttribute('data-unit'));\n    });\n  });\n\n  const allDims = [dimsRect, dimsL, dimsT, dimsTrapezoid, dimsIrregular];\n  function showDimsPanel(panel) {\n    allDims.forEach(d => d.style.display = 'none');\n    if (panel) panel.style.display = '';\n  }\n  shapeSelect.addEventListener('change', () => {\n    const shape = shapeSelect.value;\n    if (shape === 'rectangle') showDimsPanel(dimsRect);\n    else if (shape === 'l-shaped') showDimsPanel(dimsL);\n    else if (shape === 't-shaped') showDimsPanel(dimsT);\n    else if (shape === 'trapezoid') showDimsPanel(dimsTrapezoid);\n    else if (shape === 'irregular') showDimsPanel(dimsIrregular);\n    else showDimsPanel(dimsRect);\n  });\n\n  function getSelectValue(selectEl, customInput) {\n    if (customInput.value !== '' && customInput.value !== null) {\n      return parseFloat(customInput.value);\n    }\n    return parseFloat(selectEl.value);\n  }\n\n  function getDimensionInBase(feetInputId, inchesInputId) {\n    const ftInput = document.getElementById(feetInputId);\n    const inInput = document.getElementById(inchesInputId);\n    if (currentUnit === 'imperial') {\n      const ft = ftInput.value !== '' ? parseFloat(ftInput.value) || 0 : 0;\n      const inch = inInput && inInput.style.display !== 'none' ? (inInput.value !== '' ? parseFloat(inInput.value) || 0 : 0) : 0;\n      return ft * 12 + inch;\n    } else {\n      const meters = ftInput.value !== '' ? parseFloat(ftInput.value) || 0 : 0;\n      return meters * 1000;\n    }\n  }\n\n  function collectInputs() {\n    const shape = shapeSelect.value;\n    const errors = [];\n    let areas = [];\n\n    if (shape === 'rectangle') {\n      const length = getDimensionInBase('dcLengthFt', 'dcLengthIn');\n      const width = getDimensionInBase('dcWidthFt', 'dcWidthIn');\n      if (length <= 0) errors.push('Length must be greater than 0.');\n      if (width <= 0) errors.push('Width must be greater than 0.');\n      areas.push({length, width});\n    } else if (shape === 'l-shaped') {\n      const mainL = getDimensionInBase('dcMainLengthFt', 'dcMainLengthIn');\n      const mainW = getDimensionInBase('dcMainWidthFt', 'dcMainWidthIn');\n      const extL = getDimensionInBase('dcExtLengthFt', 'dcExtLengthIn');\n      const extW = getDimensionInBase('dcExtWidthFt', 'dcExtWidthIn');\n      if (mainL <= 0) errors.push('Main Length must be greater than 0.');\n      if (mainW <= 0) errors.push('Main Width must be greater than 0.');\n      if (extL <= 0) errors.push('Extension Length must be greater than 0.');\n      if (extW <= 0) errors.push('Extension Width must be greater than 0.');\n      areas.push({length: mainL, width: mainW});\n      areas.push({length: extL, width: extW});\n    } else if (shape === 't-shaped') {\n      const flangeL = getDimensionInBase('dcFlangeLengthFt', 'dcFlangeLengthIn');\n      const flangeW = getDimensionInBase('dcFlangeWidthFt', 'dcFlangeWidthIn');\n      const stemL = getDimensionInBase('dcStemLengthFt', 'dcStemLengthIn');\n      const stemW = getDimensionInBase('dcStemWidthFt', 'dcStemWidthIn');\n      if (flangeL <= 0) errors.push('Flange Length must be greater than 0.');\n      if (flangeW <= 0) errors.push('Flange Width must be greater than 0.');\n      if (stemL <= 0) errors.push('Stem Length must be greater than 0.');\n      if (stemW <= 0) errors.push('Stem Width must be greater than 0.');\n      areas.push({length: flangeL, width: flangeW});\n      areas.push({length: stemL, width: stemW});\n    } else if (shape === 'trapezoid') {\n      const topW = getDimensionInBase('dcTopWidthFt', 'dcTopWidthIn');\n      const bottomW = getDimensionInBase('dcBottomWidthFt', 'dcBottomWidthIn');\n      const height = getDimensionInBase('dcHeightFt', 'dcHeightIn');\n      if (topW <= 0) errors.push('Top Width must be greater than 0.');\n      if (bottomW <= 0) errors.push('Bottom Width must be greater than 0.');\n      if (height <= 0) errors.push('Height must be greater than 0.');\n      const avgWidth = (topW + bottomW) \/ 2;\n      areas.push({length: height, width: avgWidth});\n    } else if (shape === 'irregular') {\n      const totalAreaBase = getDimensionInBase('dcTotalAreaFt', 'dcTotalAreaIn');\n      if (totalAreaBase <= 0) errors.push('Total area must be greater than 0.');\n      const side = Math.sqrt(totalAreaBase);\n      areas.push({length: side, width: side});\n    }\n\n    const boardWidth = getSelectValue(boardWidthSelect, boardWidthCustom);\n    const boardLength = getSelectValue(boardLengthSelect, boardLengthCustom);\n    const gap = getSelectValue(gapSelect, gapCustom);\n    const joistSpacing = getSelectValue(joistSpacingSelect, joistSpacingCustom);\n    const waste = parseFloat(wasteInput.value);\n    const cost = costInput.value !== '' ? parseFloat(costInput.value) : null;\n\n    if (isNaN(boardWidth) || boardWidth <= 0) errors.push('Board width must be > 0.');\n    if (isNaN(boardLength) || boardLength <= 0) errors.push('Board length must be > 0.');\n    if (isNaN(gap) || gap < 0) errors.push('Gap spacing must be >= 0.');\n    if (isNaN(joistSpacing) || joistSpacing <= 0) errors.push('Joist spacing must be > 0.');\n    if (isNaN(waste) || waste < 0 || waste > 100) errors.push('Wastage factor must be between 0 and 100.');\n    if (cost !== null && (isNaN(cost) || cost < 0)) errors.push('Cost must be a non-negative number.');\n\n    return { shape, areas, boardWidth, boardLength, gap, joistSpacing, waste, cost, errors };\n  }\n\n  function computeResults(inputs) {\n    const { areas, boardWidth, boardLength, gap, joistSpacing, waste, cost } = inputs;\n    let totalAreaBase = 0;\n    let totalBoardsWithoutWaste = 0;\n    let totalJoists = 0;\n    let totalFastenersBase = 0;\n\n    areas.forEach(area => {\n      const L = area.length;\n      const W = area.width;\n      totalAreaBase += L * W;\n\n      const rows = Math.ceil(W \/ (boardWidth + gap));\n      const planksPerRow = Math.ceil(L \/ boardLength);\n      const boardsRegion = rows * planksPerRow;\n      totalBoardsWithoutWaste += boardsRegion;\n      totalJoists += Math.ceil(L \/ joistSpacing) + 1;\n      totalFastenersBase += boardsRegion * Math.ceil(boardLength \/ joistSpacing) * 2;\n    });\n\n    const totalBoards = Math.ceil(totalBoardsWithoutWaste * (1 + waste \/ 100));\n    const totalFasteners = Math.ceil(totalFastenersBase * (1 + waste \/ 100));\n\n    let totalAreaFormatted, linearFormatted, areaUnit, linearUnit;\n    if (currentUnit === 'imperial') {\n      totalAreaFormatted = (totalAreaBase \/ 144).toFixed(2);\n      areaUnit = 'sq ft';\n      linearFormatted = (totalBoards * boardLength \/ 12).toFixed(2);\n      linearUnit = 'ft';\n    } else {\n      totalAreaFormatted = (totalAreaBase \/ 1e6).toFixed(2);\n      areaUnit = 'm\u00b2';\n      linearFormatted = (totalBoards * boardLength \/ 1000).toFixed(2);\n      linearUnit = 'm';\n    }\n\n    let costFormatted = 'N\/A';\n    if (cost !== null && !isNaN(cost)) {\n      const totalCost = (parseFloat(totalAreaFormatted) * cost).toFixed(2);\n      const symbol = currentUnit === 'imperial' ? '$' : '\u20ac';\n      costFormatted = symbol + totalCost;\n    }\n\n    return {\n      totalArea: totalAreaFormatted + ' ' + areaUnit,\n      totalBoards,\n      totalLinear: linearFormatted + ' ' + linearUnit,\n      totalJoists,\n      totalFasteners,\n      totalCost: costFormatted\n    };\n  }\n\n  function displayResults(results) {\n    document.getElementById('resArea').textContent = results.totalArea;\n    document.getElementById('resBoards').textContent = results.totalBoards;\n    document.getElementById('resLinear').textContent = results.totalLinear;\n    document.getElementById('resJoists').textContent = results.totalJoists;\n    document.getElementById('resFasteners').textContent = results.totalFasteners;\n    document.getElementById('resCost').textContent = results.totalCost;\n    resultsDiv.style.display = 'block';\n  }\n\n  function hideResults() {\n    resultsDiv.style.display = 'none';\n  }\n\n  function showError(errors) {\n    if (errors.length === 0) {\n      errorDiv.style.display = 'none';\n      errorDiv.innerHTML = '';\n      return;\n    }\n    errorDiv.style.display = 'block';\n    errorDiv.innerHTML = errors.map(e => `<div>\u2022 ${e}<\/div>`).join('');\n  }\n\n  calculateBtn.addEventListener('click', () => {\n    const inputs = collectInputs();\n    if (inputs.errors.length > 0) {\n      showError(inputs.errors);\n      hideResults();\n      return;\n    }\n    showError([]);\n    const results = computeResults(inputs);\n    displayResults(results);\n  });\n\n  resetBtn.addEventListener('click', () => {\n    shapeSelect.value = 'rectangle';\n    showDimsPanel(dimsRect);\n    const allFeet = calculator.querySelectorAll('.dc-input-feet');\n    const allInches = calculator.querySelectorAll('.dc-input-inches');\n    allFeet.forEach(inp => { inp.value = ''; });\n    allInches.forEach(inp => { inp.value = ''; });\n    boardWidthCustom.value = '';\n    boardLengthCustom.value = '';\n    gapCustom.value = '';\n    joistSpacingCustom.value = '';\n    wasteInput.value = '10';\n    costInput.value = '';\n    boardWidthSelect.selectedIndex = 0;\n    boardLengthSelect.selectedIndex = 0;\n    gapSelect.selectedIndex = 0;\n    joistSpacingSelect.selectedIndex = 0;\n    hideResults();\n    showError([]);\n  });\n\n  \/\/ Initialize\n  setUnit('imperial');\n  shapeSelect.dispatchEvent(new Event('change'));\n  hideResults();\n})();\n<\/script>\n\n\n<!-- aiper-tool-links -->\n<div class=\"aiper-tool-links\">\n  <div class=\"aiper-tl-section\">\n    <div class=\"aiper-tl-heading\">More Tools<\/div>\n    <div class=\"aiper-tl-tags\">\n      <a href=\"https:\/\/aiper.com\/blogs\/fence-calculator\/\" class=\"aiper-tl-tag\">Fence Calculator<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/paver-calculator\/\" class=\"aiper-tl-tag\">Paver Calculator<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/retaining-wall-calculator\/\" class=\"aiper-tl-tag\">Retaining Wall Calculator<\/a>\n    <\/div>\n  <\/div>\n  <div class=\"aiper-tl-section\">\n    <div class=\"aiper-tl-heading\">Related Articles<\/div>\n    <div class=\"aiper-tl-tags\">\n      <a href=\"https:\/\/aiper.com\/blogs\/how-to-keep-geese-off-lawn\/\" class=\"aiper-tl-tag\">How to Keep Geese Off Your Lawn<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/how-to-get-rid-of-mushrooms-in-lawn\/\" class=\"aiper-tl-tag\">How to Get Rid of Mushrooms in a Lawn (And Should You?)<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/how-to-dethatch-a-lawn\/\" class=\"aiper-tl-tag\">How to Dethatch a Lawn: Diagnose Thatch, Then Treat It<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/how-to-get-rid-of-creeping-charlie-in-lawn\/\" class=\"aiper-tl-tag\">How to Get Rid of Creeping Charlie in Your Lawn<\/a>\n    <\/div>\n  <\/div>\n<\/div>\n\n<style>\n.aiper-tool-links{margin:2.5rem 0 1.5rem;padding:1.5rem 1.75rem;background:linear-gradient(135deg,rgba(148,134,247,.04),rgba(30,202,211,.04));border-radius:12px;border:1px solid rgba(148,134,247,.10)}\n.aiper-tl-section{margin-bottom:1.25rem}\n.aiper-tl-section:last-child{margin-bottom:0}\n.aiper-tl-heading{font-size:.75rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:#8899aa;margin:0 0 .65rem}\n.aiper-tl-tags{display:flex;flex-wrap:wrap;gap:.5rem}\n.aiper-tl-tag{display:inline-block;padding:.4rem .95rem;font-size:.82rem;font-weight:500;line-height:1.35;color:#9486f7;background:rgba(148,134,247,.055);border:1px solid rgba(30,202,211,.25);border-radius:22px;text-decoration:none;transition:all .18s}\n.aiper-tl-tag:hover{background:#1ecad3;color:#fff;border-color:#1ecad3;box-shadow:0 2px 10px rgba(30,202,211,.22)}\n<\/style>","protected":false},"excerpt":{"rendered":"<p>Region \/ Unit System: USA (ft, in) Australia \/ Europe (m, mm) Deck Shape RectangleL-shapedT-shapedTrapezoidIrregular \/ Custom Polygon Length ft in Width ft in Main Length ft in Main Width ft in Extension Length ft in Extension Width ft in Flange Length ft in Flange Width ft in Stem Length ft in Stem Width ft&#8230;<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"class_list":["post-2597","page","type-page","status-publish","hentry"],"lang":"en","translations":{"en":2597,"es":2606,"de":2602,"fr":2604},"_links":{"self":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/2597","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/comments?post=2597"}],"version-history":[{"count":8,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/2597\/revisions"}],"predecessor-version":[{"id":4307,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/2597\/revisions\/4307"}],"wp:attachment":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/media?parent=2597"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}