{"id":2908,"date":"2026-06-17T01:37:53","date_gmt":"2026-06-17T01:37:53","guid":{"rendered":"https:\/\/aiper.com\/blogs\/?page_id=2908"},"modified":"2026-10-21T09:14:22","modified_gmt":"2026-10-21T09:14:22","slug":"fence-calculator","status":"publish","type":"page","link":"https:\/\/aiper.com\/blogs\/fence-calculator\/","title":{"rendered":"Fence Calculator"},"content":{"rendered":"\n<style>#fence-calc-wrapper *, #fence-calc-wrapper *::before, #fence-calc-wrapper *::after { box-sizing: border-box; }\n#fence-calc-wrapper { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, sans-serif; max-width: 760px; margin: 20px auto; padding: 0; line-height: 1.5; --fcc-teal: #1ecad3; --fcc-teal-dark: #17a8b0; --fcc-teal-light: #e8fafa; --fcc-border: #e2e8f0; --fcc-text: #2d3748; --fcc-text-light: #5a6c7d; }\n#fence-calc-wrapper .fcc-intro { max-width: 680px; margin: 0 auto 16px; padding: 0 24px; text-align: center; color: var(--fcc-text-light); font-size: 15px; line-height: 1.5; }\n#fence-calc-wrapper .fcc-card { background: #fff; border-radius: 16px; box-shadow: 0 4px 24px rgba(0,0,0,0.07); padding: 28px 24px; margin-bottom: 20px; border: 1px solid var(--fcc-border); }\n#fence-calc-wrapper .fcc-subtitle { font-size: 0.9rem; color: var(--fcc-text-light); margin: 0 0 20px 0; }\n#fence-calc-wrapper .fcc-label { display: block; font-weight: 600; font-size: 0.9rem; color: var(--fcc-text); margin-bottom: 5px; }\n#fence-calc-wrapper .fcc-input-row { display: flex; gap: 10px; align-items: stretch; margin-bottom: 18px; }\n#fence-calc-wrapper .fcc-input-field { flex: 1; padding: 12px 14px; border: 2px solid var(--fcc-border); border-radius: 6px; font-size: 1rem; color: #2c3e50; background: #f9fafb; outline: none; width: 100%; }\n#fence-calc-wrapper .fcc-input-field:focus { border-color: #9486f7; background: #fff; color: #2c3e50; }\n#fence-calc-wrapper .fcc-unit-toggle { display: flex; background: #f1f5f9; border-radius: 6px; overflow: hidden; border: 2px solid var(--fcc-border); flex-wrap: wrap; }\n#fence-calc-wrapper .fcc-unit-btn { padding: 8px 14px; font-size: 0.85rem; font-weight: 600; cursor: pointer; border: none; background: transparent; color: var(--fcc-text-light); }\n#fence-calc-wrapper .fcc-unit-btn:focus, #fence-calc-wrapper .fcc-unit-btn:active { outline: 2px solid #9486f7; outline-offset: -2px; color: var(--fcc-text-light); }\n#fence-calc-wrapper .fcc-unit-btn.fcc-active { background: linear-gradient(135deg, #1ecad3, #9486f7); color: #fff; }\n#fence-calc-wrapper .fcc-preset-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }\n#fence-calc-wrapper .fcc-preset-btn { padding: 6px 13px; font-size: 0.78rem; font-weight: 600; border-radius: 20px; border: 1.5px solid var(--fcc-border); background: #fff; color: var(--fcc-text-light); cursor: pointer; }\n#fence-calc-wrapper .fcc-preset-btn:focus, #fence-calc-wrapper .fcc-preset-btn:active { outline: 2px solid #9486f7; outline-offset: 1px; color: var(--fcc-text-light); }\n#fence-calc-wrapper .fcc-preset-btn.fcc-active { border-color: #9486f7; background: #f5f3ff; color: #2c3e50; }\n#fence-calc-wrapper .fcc-btn-row { display: flex; gap: 12px; max-width: 420px; margin: 26px auto 0; flex-wrap: wrap; }\n#fence-calc-wrapper .fcc-calculate-btn { display: block; flex: 1; min-width: 160px; padding: 14px 30px; background: linear-gradient(135deg, #1ecad3, #9486f7); color: #fff; border: none; border-radius: 999px; font-size: 16px; font-weight: 600; letter-spacing: .5px; cursor: pointer; transition: all .2s; }\n#fence-calc-wrapper .fcc-calculate-btn:hover { background: linear-gradient(135deg, #169fa6, #7b6be0); color: #fff; transform: translateY(-1px); box-shadow: 0 6px 16px rgba(148,134,247,.35); }\n#fence-calc-wrapper .fcc-calculate-btn:focus, #fence-calc-wrapper .fcc-calculate-btn:active { color: #fff; outline: none; box-shadow: 0 0 0 3px rgba(148,134,247,.45); }\n#fence-calc-wrapper .fcc-reset-btn { display: block; flex: 1; min-width: 120px; padding: 14px 20px; background: #fff; color: #5a6c7d; border: 2px solid #d1e8ea; border-radius: 999px; font-size: 16px; font-weight: 600; letter-spacing: .5px; cursor: pointer; transition: all .2s; }\n#fence-calc-wrapper .fcc-reset-btn:hover { background: #f0f7f8; border-color: #1ecad3; color: #0f8c94; }\n#fence-calc-wrapper .fcc-reset-btn:focus, #fence-calc-wrapper .fcc-reset-btn:active { background: #fff; outline: none; border-color: #9486f7; color: #0f8c94; }\n#fence-calc-wrapper .fcc-error-msg { color: #dc2626; font-size: 0.85rem; font-weight: 600; text-align: center; margin-top: 10px; display: none; }\n#fence-calc-wrapper .fcc-error-msg.fcc-visible { display: block; }\n#fence-calc-wrapper .fcc-result-area { display: none; margin-top: 25px; }\n#fence-calc-wrapper .fcc-result-area.fcc-visible { display: block; animation: fccFade 0.4s ease; }\n@keyframes fccFade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }\n#fence-calc-wrapper .fcc-result-grid { display: flex; gap: 14px; flex-wrap: wrap; }\n#fence-calc-wrapper .fcc-result-card { flex: 1; min-width: 220px; background: linear-gradient(135deg, #f5f3ff 0%, #e8fafa 100%); border: 2px solid #9486f7; border-radius: 10px; padding: 22px 18px; text-align: center; }\n#fence-calc-wrapper .fcc-result-label { font-size: 0.82rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: #5b4ab8; margin: 0 0 8px; }\n#fence-calc-wrapper .fcc-result-amount { font-size: 2.4rem; font-weight: 800; color: #17a8b0; line-height: 1.15; }\n#fence-calc-wrapper .fcc-result-amount .fcc-unit-label { font-size: 1.1rem; }\n#fence-calc-wrapper .fcc-result-sub { margin: 6px 0 0; color: var(--fcc-text-light); font-size: 0.88rem; }\n#fence-calc-wrapper .fcc-acid-line { margin-top: 12px; padding: 8px 12px; background: #fff; border: 1px solid var(--fcc-border); border-radius: 6px; font-size: 0.82rem; color: var(--fcc-text); }\n#fence-calc-wrapper .fcc-warn { display: none; margin-top: 12px; padding: 10px 14px; background: #fff7ed; border: 1px solid #fed7aa; border-radius: 6px; color: #9a3412; font-size: 0.82rem; text-align: left; }\n#fence-calc-wrapper .fcc-warn.fcc-visible { display: block; }\n#fence-calc-wrapper .fcc-toggle-row { display: flex; justify-content: center; align-items: center; gap: 10px; margin-top: 20px; font-size: 0.85rem; color: var(--fcc-text-light); flex-wrap: wrap; }\n#fence-calc-wrapper .fcc-algebra { margin: 14px 0 0; font-size: 0.78rem; color: #8899a6; text-align: center; }\n#fence-calc-wrapper .fcc-next { margin: 14px 0 0; font-size: 0.85rem; color: var(--fcc-text-light); text-align: center; }\n#fence-calc-wrapper .fcc-next a { color: var(--fcc-teal-dark); font-weight: 600; text-decoration: none; }\n#fence-calc-wrapper .fcc-next a:hover { text-decoration: underline; }\n#fence-calc-wrapper .fcc-info-section { display: none; margin-top: 20px; }\n#fence-calc-wrapper .fcc-info-section.fcc-visible { display: block; }\n#fence-calc-wrapper .fcc-info-card { background: #fff; border: 1px solid var(--fcc-border); border-radius: 10px; padding: 20px; font-size: 0.9rem; }\n#fence-calc-wrapper .fcc-info-title { font-weight: 700; font-size: 1rem; margin-bottom: 10px; }\n#fence-calc-wrapper ol.fcc-howto-list { margin: 0; padding: 0 0 0 20px; }\n#fence-calc-wrapper ol.fcc-howto-list li { margin-bottom: 6px; }\n@media (max-width: 600px) { #fence-calc-wrapper .fcc-btn-row { flex-direction: column; max-width: 280px; } #fence-calc-wrapper .fcc-reset-btn { padding: 12px 20px; font-size: 14px; } }\n@media (max-width: 500px) { #fence-calc-wrapper .fcc-input-row { flex-direction: column; } }\n\n#fence-calc-wrapper .fcc-hide { display: none !important; }\n#fence-calc-wrapper .fcc-field { margin-bottom: 18px; }\n#fence-calc-wrapper .fcc-two-col { display: flex; gap: 14px; }\n#fence-calc-wrapper .fcc-two-col > .fcc-field { flex: 1; min-width: 0; }\n#fence-calc-wrapper .fcc-hint { font-size: 0.78rem; color: #8899a6; margin: 4px 0 0; }\n#fence-calc-wrapper .fcc-group { border: 1px solid var(--fcc-border); border-radius: 12px; padding: 18px 16px 4px; margin: 0 0 18px; background: #fcfdfe; }\n#fence-calc-wrapper .fcc-group-title { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: #5b4ab8; margin: 0 0 14px; }\n#fence-calc-wrapper .fcc-input-field, #fence-calc-wrapper select.fcc-input-field { height: auto; margin: 0; }\n#fence-calc-wrapper .fcc-run { margin-bottom: 12px; }\n#fence-calc-wrapper .fcc-run-ctl { display: flex; gap: 10px; align-items: stretch; }\n#fence-calc-wrapper .fcc-run-del { padding: 8px 14px; font-size: 0.8rem; font-weight: 600; border-radius: 6px; border: 2px solid var(--fcc-border); background: #fff; color: var(--fcc-text-light); cursor: pointer; }\n#fence-calc-wrapper .fcc-run-del:hover { border-color: #dc2626; color: #dc2626; }\n#fence-calc-wrapper .fcc-run-del:focus, #fence-calc-wrapper .fcc-run-del:active { outline: 2px solid #9486f7; outline-offset: 1px; color: var(--fcc-text-light); background: #fff; }\n#fence-calc-wrapper .fcc-link-btn { background: none; border: none; padding: 4px 0; margin: 0 0 12px; color: #17a8b0; font-size: 0.88rem; font-weight: 700; cursor: pointer; }\n#fence-calc-wrapper .fcc-link-btn:hover { text-decoration: underline; color: #0f8c94; }\n#fence-calc-wrapper .fcc-link-btn:focus, #fence-calc-wrapper .fcc-link-btn:active { outline: 2px solid #9486f7; outline-offset: 2px; background: none; color: #17a8b0; }\n#fence-calc-wrapper .fcc-check { display: flex; align-items: center; gap: 8px; font-size: 0.88rem; color: var(--fcc-text); margin: 0 0 18px; cursor: pointer; }\n#fence-calc-wrapper .fcc-check input { width: 18px; height: 18px; accent-color: #9486f7; flex-shrink: 0; margin: 0; }\n#fence-calc-wrapper .fcc-unit-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }\n#fence-calc-wrapper .fcc-unit-row .fcc-label { margin: 0; }\n#fence-calc-wrapper details.fcc-prices { border: 1px solid var(--fcc-border); border-radius: 8px; padding: 10px 14px; margin: 0 0 18px; background: #fff; }\n#fence-calc-wrapper details.fcc-prices summary { cursor: pointer; font-weight: 600; font-size: 0.9rem; color: var(--fcc-text); }\n#fence-calc-wrapper .fcc-price-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; margin-top: 14px; }\n#fence-calc-wrapper .fcc-price-label { display: block; font-size: 0.78rem; font-weight: 600; color: var(--fcc-text-light); margin-bottom: 3px; }\n#fence-calc-wrapper .fcc-price-row .fcc-input-field { padding: 8px 10px; font-size: 0.9rem; }\n#fence-calc-wrapper .fcc-postline { margin: 16px 0 12px; font-size: 0.9rem; color: var(--fcc-text); text-align: center; font-weight: 600; }\n#fence-calc-wrapper .fcc-list { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--fcc-border); border-radius: 12px; }\n#fence-calc-wrapper .fcc-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; min-width: 520px; }\n#fence-calc-wrapper .fcc-table thead th { background: linear-gradient(135deg, #1ecad3, #9486f7); color: #fff; font-weight: 600; font-size: 0.74rem; text-transform: uppercase; letter-spacing: 0.05em; padding: 10px; text-align: left; white-space: nowrap; }\n#fence-calc-wrapper .fcc-table tbody td { padding: 10px; border-bottom: 1px solid #eef1f5; vertical-align: top; color: var(--fcc-text); }\n#fence-calc-wrapper .fcc-table tbody tr:nth-child(even) { background: #fafcfd; }\n#fence-calc-wrapper .fcc-qty { font-weight: 800; color: #0f8c94; white-space: nowrap; }\n#fence-calc-wrapper .fcc-spec { color: var(--fcc-text-light); font-size: 0.8rem; }\n#fence-calc-wrapper .fcc-price { white-space: nowrap; text-align: right; }\n#fence-calc-wrapper tr.fcc-total-row td { font-weight: 700; text-align: right; background: #f5f3ff; }\n#fence-calc-wrapper .fcc-warn span { display: block; margin-top: 6px; }\n#fence-calc-wrapper .fcc-warn span:first-child { margin-top: 0; }\n#fence-calc-wrapper .fcc-jump { margin: 14px 0 0; font-size: 0.85rem; text-align: center; color: var(--fcc-text-light); }\n#fence-calc-wrapper .fcc-jump a { color: var(--fcc-teal-dark); font-weight: 600; text-decoration: none; }\n@media (max-width: 500px) { #fence-calc-wrapper .fcc-two-col { flex-direction: column; gap: 0; } #fence-calc-wrapper .fcc-price-grid { grid-template-columns: 1fr; } #fence-calc-wrapper .fcc-run-ctl { flex-direction: row; } }\n<\/style>\n<div id=\"fence-calc-wrapper\">\n    <p class=\"fcc-intro\">This fence calculator works out the posts, rails, pickets or panels, concrete and cost for a wood, vinyl, aluminum or chain link fence. Enter each side of your fence, add gates, and get a full shopping list with a price estimate.<\/p>\n    <div class=\"fcc-card\">\n        <p class=\"fcc-subtitle\">Pick your fence type and enter the sides. The starting values describe a 100 ft, 6 ft tall wood privacy fence, so you can press Calculate to see an example.<\/p>\n\n        <div class=\"fcc-field\">\n            <label class=\"fcc-label\" for=\"fcc-type\">Fence Type<\/label>\n            <select id=\"fcc-type\" class=\"fcc-input-field\"><option value=\"picket\" selected>Wood picket fence (built on site)<\/option><option value=\"wpanel\">Wood panel fence (prefab panels)<\/option><option value=\"vinyl\">Vinyl fence (panels)<\/option><option value=\"alum\">Aluminum \/ ornamental fence (panels)<\/option><option value=\"chain\">Chain link fence<\/option><\/select>\n        <\/div>\n        <div class=\"fcc-unit-row\">\n            <span class=\"fcc-label\">Units<\/span>\n            <div class=\"fcc-unit-toggle\" id=\"fcc-unit-toggle\">\n                <button type=\"button\" class=\"fcc-unit-btn fcc-active\" data-unit=\"imperial\">Feet and inches<\/button>\n                <button type=\"button\" class=\"fcc-unit-btn\" data-unit=\"metric\">Metres and cm<\/button>\n            <\/div>\n        <\/div>\n\n        <div class=\"fcc-group\">\n            <p class=\"fcc-group-title\">Fence layout<\/p>\n            <div id=\"fcc-runs\"><\/div>\n            <button type=\"button\" id=\"fcc-add-run\" class=\"fcc-link-btn\">+ Add another side<\/button>\n            <label class=\"fcc-check\"><input type=\"checkbox\" id=\"fcc-closed\"> The fence closes a loop (the last side returns to the first)<\/label>\n            <div class=\"fcc-two-col\">\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-label\" for=\"fcc-gates\">Number of Gates<\/label>\n                    <select id=\"fcc-gates\" class=\"fcc-input-field\"><option value=\"0\" selected>0<\/option><option value=\"1\">1<\/option><option value=\"2\">2<\/option><option value=\"3\">3<\/option><option value=\"4\">4<\/option><option value=\"5\">5<\/option><\/select>\n                <\/div>\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-label\" for=\"fcc-gatew\">Gate Width (<span class=\"fcc-u-len\">ft<\/span>)<\/label>\n                    <input type=\"number\" id=\"fcc-gatew\" class=\"fcc-input-field\" value=\"4\" min=\"0\" step=\"any\">\n                <\/div>\n            <\/div>\n            <p class=\"fcc-hint\">Include the gate openings in your side lengths. The calculator takes them out of the fence run and adds the gate posts.<\/p>\n            <div class=\"fcc-field\">\n                <label class=\"fcc-label\" for=\"fcc-attach\">Ends Attached to a House, Wall or Existing Fence<\/label>\n                <select id=\"fcc-attach\" class=\"fcc-input-field\"><option value=\"0\" selected>None, both ends get a post<\/option><option value=\"1\">One end<\/option><option value=\"2\">Both ends<\/option><\/select>\n            <\/div>\n        <\/div>\n\n        <div class=\"fcc-group\">\n            <p class=\"fcc-group-title\">Fence style<\/p>\n            <div class=\"fcc-field\">\n                <label class=\"fcc-label\" for=\"fcc-height\">Fence Height (<span class=\"fcc-u-len\">ft<\/span>)<\/label>\n                <input type=\"number\" id=\"fcc-height\" class=\"fcc-input-field\" value=\"6\" min=\"0\" step=\"any\">\n            <\/div>\n            <div class=\"fcc-preset-row\" id=\"fcc-height-presets\"><\/div>\n            <div class=\"fcc-two-col\">\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-label\" for=\"fcc-spacing\">Post Spacing or Panel Width (<span class=\"fcc-u-len\">ft<\/span>)<\/label>\n                    <input type=\"number\" id=\"fcc-spacing\" class=\"fcc-input-field\" value=\"8\" min=\"0\" step=\"any\">\n                <\/div>\n                <div class=\"fcc-field\" data-show=\"picket,wpanel\">\n                    <label class=\"fcc-label\" for=\"fcc-postsel\">Wood Post Size<\/label>\n                    <select id=\"fcc-postsel\" class=\"fcc-input-field\"><\/select>\n                <\/div>\n            <\/div>\n            <div class=\"fcc-two-col\" data-show=\"picket\">\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-label\" for=\"fcc-rails\">Rails per Section<\/label>\n                    <select id=\"fcc-rails\" class=\"fcc-input-field\"><option value=\"2\">2 rails<\/option><option value=\"3\" selected>3 rails<\/option><option value=\"4\">4 rails<\/option><\/select>\n                <\/div>\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-label\" for=\"fcc-layout\">Picket Layout<\/label>\n                    <select id=\"fcc-layout\" class=\"fcc-input-field\"><option value=\"spaced\" selected>Spaced or butted pickets<\/option><option value=\"bob\">Board on board (1 in overlap)<\/option><\/select>\n                <\/div>\n            <\/div>\n            <div class=\"fcc-two-col\" data-show=\"picket\">\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-label\" for=\"fcc-pw\">Picket Width (<span class=\"fcc-u-in\">in<\/span>)<\/label>\n                    <input type=\"number\" id=\"fcc-pw\" class=\"fcc-input-field\" value=\"5.5\" min=\"0\" step=\"any\">\n                <\/div>\n                <div class=\"fcc-field\" id=\"fcc-gap-field\">\n                    <label class=\"fcc-label\" for=\"fcc-gap\">Gap Between Pickets (<span class=\"fcc-u-in\">in<\/span>)<\/label>\n                    <input type=\"number\" id=\"fcc-gap\" class=\"fcc-input-field\" value=\"0.5\" min=\"0\" step=\"any\">\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"fcc-group\">\n            <p class=\"fcc-group-title\">Post footing<\/p>\n            <div class=\"fcc-two-col\">\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-label\" for=\"fcc-hole\">Hole Diameter (<span class=\"fcc-u-in\">in<\/span>)<\/label>\n                    <input type=\"number\" id=\"fcc-hole\" class=\"fcc-input-field\" value=\"10\" min=\"0\" step=\"any\">\n                <\/div>\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-label\" for=\"fcc-depth\">Hole Depth (<span class=\"fcc-u-in\">in<\/span>)<\/label>\n                    <input type=\"number\" id=\"fcc-depth\" class=\"fcc-input-field\" value=\"24\" min=\"0\" step=\"any\">\n                <\/div>\n            <\/div>\n            <p class=\"fcc-hint\">Depth follows your fence height (about one third of it, never under 24 in). Enter your local frost depth if it is deeper.<\/p>\n            <div class=\"fcc-two-col\">\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-label\" for=\"fcc-bag\">Concrete Bag Size<\/label>\n                    <select id=\"fcc-bag\" class=\"fcc-input-field\"><\/select>\n                <\/div>\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-check\"><input type=\"checkbox\" id=\"fcc-gravel\" checked> Add a 6 in (15 cm) gravel base<\/label>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"fcc-group\">\n            <p class=\"fcc-group-title\">Cost and extras<\/p>\n            <label class=\"fcc-check\"><input type=\"checkbox\" id=\"fcc-cost\" checked> Include a cost estimate<\/label>\n            <div id=\"fcc-cost-box\">\n                <details class=\"fcc-prices\">\n                    <summary>Edit prices (typical US store prices, replace with yours)<\/summary>\n                    <div class=\"fcc-price-grid\" id=\"fcc-prices\"><\/div>\n                <\/details>\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-label\" for=\"fcc-labor\">Installation Labor, per <span class=\"fcc-u-len\">ft<\/span> (optional)<\/label>\n                    <input type=\"number\" id=\"fcc-labor\" class=\"fcc-input-field\" placeholder=\"Leave empty for materials only\" min=\"0\" step=\"any\">\n                <\/div>\n            <\/div>\n            <div class=\"fcc-two-col\">\n                <div class=\"fcc-field\" data-show=\"picket\">\n                    <label class=\"fcc-label\" for=\"fcc-waste\">Extra for Waste<\/label>\n                    <select id=\"fcc-waste\" class=\"fcc-input-field\"><option value=\"0\">None<\/option><option value=\"5\">5%<\/option><option value=\"10\" selected>10%<\/option><option value=\"15\">15% (sloped yard)<\/option><\/select>\n                <\/div>\n                <div class=\"fcc-field\">\n                    <label class=\"fcc-check\"><input type=\"checkbox\" id=\"fcc-pool\"> This fence encloses a swimming pool<\/label>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <div class=\"fcc-btn-row\">\n            <button type=\"button\" id=\"fcc-calculate-btn\" class=\"fcc-calculate-btn\">Calculate<\/button>\n            <button type=\"button\" id=\"fcc-reset-btn\" class=\"fcc-reset-btn\">Reset<\/button>\n        <\/div>\n        <p id=\"fcc-error-msg\" class=\"fcc-error-msg\"><\/p>\n\n        <div id=\"fcc-result-area\" class=\"fcc-result-area\">\n            <div class=\"fcc-result-grid\" id=\"fcc-result-grid\"><\/div>\n            <p class=\"fcc-postline\" id=\"fcc-postline\"><\/p>\n            <div class=\"fcc-list\" id=\"fcc-list\"><\/div>\n            <div id=\"fcc-warn\" class=\"fcc-warn\"><\/div>\n            <p class=\"fcc-algebra\" id=\"fcc-algebra\"><\/p>\n            <div class=\"fcc-info-card\">\n                <div class=\"fcc-info-title\">Before You Dig or Buy<\/div>\n                <ol class=\"fcc-howto-list\"><li>Call 811 (US) or your local utility-locating service a few days before digging. It is free and the lines are marked for you.<\/li><li>Check permits, height limits, setbacks and any HOA rules, and confirm where your property line is before you set posts.<\/li><li>Mark every post position with a string line and stakes, then re-check the spacing before you dig the first hole.<\/li><\/ol>\n            <\/div>\n        <\/div>\n    <\/div>\n    <p class=\"fcc-jump\">Need a quick number? <a href=\"#fence-reference-table\">Jump to the fence materials chart by length<\/a>.<\/p>\n<\/div>\n<script>(function() {\nvar T = {\"sideLabel\": \"Side {n} length ({u})\", \"runPh\": \"e.g., 50\", \"remove\": \"Remove\", \"removeAria\": \"Remove this side\", \"postS_imp\": \"4x4 (3.5 in actual)\", \"postL_imp\": \"6x6 (5.5 in actual)\", \"postS_met\": \"100 x 100 mm\", \"postL_met\": \"150 x 150 mm\", \"p_post\": \"Post (each)\", \"p_rail\": \"Rail (each)\", \"p_picket\": \"Picket (each)\", \"p_fasteners\": \"Screw or nail (each)\", \"p_concrete\": \"Concrete bag (each)\", \"p_gravel\": \"Gravel bag, 0.5 cu ft (each)\", \"p_gate\": \"Gate (each)\", \"p_panel\": \"Panel (each)\", \"p_lpost\": \"Line post (each)\", \"p_tpost\": \"Terminal post (each)\", \"p_fabric\": \"Fabric roll, 50 ft (each)\", \"p_tbar\": \"Tension bar (each)\", \"p_tband\": \"Tension band (each)\", \"p_bband\": \"Brace band (each)\", \"p_cap\": \"Post cap (each)\", \"p_ties\": \"Tie wire (each)\", \"p_strut\": \"Strut (each)\", \"p_wire\": \"Tension wire (each)\", \"err_length\": \"Enter the length of at least one side of your fence.\", \"err_height\": \"Enter the fence height.\", \"err_spacing\": \"Enter the post spacing (or panel width).\", \"err_gatew\": \"Enter the gate width.\", \"err_gates\": \"The gate openings are as long as the whole fence. Increase the fence length or reduce the gates.\", \"err_hole\": \"The post hole must be wider than the post. Increase the hole diameter.\", \"err_depth\": \"The post hole must be deeper than the gravel base. Increase the hole depth or untick the gravel base.\", \"err_picket\": \"Enter the picket width.\", \"estCost\": \"Estimated Cost\", \"matOnly\": \"Materials only, at the prices you entered\", \"matLabor\": \"Materials {a} + labor {b}\", \"costPerFt\": \"Cost Per Foot\", \"costPerM\": \"Cost Per Metre\", \"forLen\": \"for {n} {u} of fence\", \"cardPosts\": \"Fence Posts\", \"cardSections\": \"Sections\", \"cardPanels\": \"Panels\", \"cardBetween\": \"between posts, gates not included\", \"pLine\": \"{n} line\", \"pCorner\": \"{n} corner\", \"pEnd\": \"{n} end\", \"pGate\": \"{n} gate\", \"gatesOne\": \" plus {n} gate opening\", \"gatesMany\": \" plus {n} gate openings\", \"postLine\": \"Posts: {total} in total ({parts}). {sections} sections{gates}.\", \"thItem\": \"Item\", \"thQty\": \"Qty\", \"thDetails\": \"Details\", \"thEach\": \"Each\", \"thCost\": \"Cost\", \"matSub\": \"Materials subtotal\", \"labor\": \"Labor\", \"total\": \"Total\", \"postType_vinyl\": \"5x5 vinyl\", \"postType_alum\": \"2 in aluminum\", \"postType_wpanel\": \"\", \"postType_picket\": \"\", \"postType_chain\": \"\", \"railPreImp\": \"2x4 \", \"railPreMet\": \"\", \"l_post\": \"Fence posts\", \"s_post\": \"{post} posts, {len} long ({depth} in the ground)\", \"l_lpost\": \"Line posts\", \"s_lpost\": \"Round posts, {len} long ({depth} in the ground)\", \"l_tpost\": \"Terminal posts\", \"s_tpost\": \"End, corner and gate posts, {len} long\", \"l_toprail\": \"Top rail\", \"s_toprail\": \"10.5 ft lengths\", \"l_rail\": \"Rails\", \"s_rail\": \"{pre}rails {len} long, {n} per section\", \"l_picket\": \"Pickets\", \"s_bob\": \"Board on board, {w} wide with 1 in (2.5 cm) overlap\", \"s_picket\": \"{w} wide with {g} gap\", \"l_fasteners\": \"Screws or nails\", \"s_fasteners\": \"2 per picket per rail\", \"l_panel\": \"Panels\", \"s_panel\": \"{w} wide, {h} tall (one per section)\", \"l_fabric\": \"Chain link fabric\", \"s_fabric\": \"50 ft (15 m) rolls, {h} tall\", \"l_tbar\": \"Tension bars\", \"s_tbar\": \"One at each fabric end\", \"l_tband\": \"Tension bands\", \"s_tband\": \"{n} per tension bar\", \"l_bband\": \"Brace bands and rail ends\", \"s_bband\": \"One per tension bar\", \"l_strut\": \"Struts\", \"s_strut\": \"One per terminal post side\", \"l_wire\": \"Tension wire\", \"s_wire\": \"{n} lines along the fence, 50 m rolls\", \"l_cap\": \"Post caps\", \"s_cap\": \"Loop caps on line posts, dome caps on terminal posts\", \"l_ties\": \"Fabric ties\", \"s_ties\": \"Every 24 in on the rail, every 12 in on posts\", \"s_ties_eu\": \"Binding wire, 50 m rolls\", \"l_concrete\": \"Concrete mix\", \"s_concrete\": \"{bag} bags, {vol} of concrete (post volume deducted)\", \"l_gravel\": \"Gravel base\", \"s_gravel\": \"6 in (15 cm) under each post, {vol}\", \"l_gate\": \"Gates\", \"s_gate\": \"{w} wide each, with hinges and latch\", \"w_waste\": \"Pickets, rails and screws include {n}% extra for cuts and mistakes. Posts, panels and concrete are counted as whole units.\", \"w_tall\": \"Fences taller than 6 ft (1.8 m) often need a permit or a variance. Check your local rules before you buy.\", \"w_spacing\": \"Post spacing over 8 ft (2.4 m) lets 2x4 rails sag. Use 6 to 8 ft (1.8 to 2.4 m) for a wood picket fence.\", \"w_gate\": \"Gates wider than 4 ft (1.2 m) put real load on the hinge post. Use a 6x6 (150 x 150 mm) post or a steel post there, and set it in extra concrete.\", \"w_attach1\": \"The end you attach to a house or wall needs a bracket or a nailer board fixed to the wall instead of a post.\", \"w_attach2\": \"The ends you attach to a house or wall need a bracket or a nailer board fixed to the wall instead of a post.\", \"w_shallow\": \"A hole shallower than 24 in (60 cm) can lean on a fence this tall. In cold climates set posts below the frost line.\", \"w_pool\": \"Pool barrier: most codes require at least 48 in (1.2 m) of height, openings smaller than 4 in (10 cm), and a self-closing, self-latching gate that opens away from the pool. Confirm the rules with your local building department.\", \"w_poolLow\": \"Your fence is under 48 in (1.2 m).\", \"w_poolGap\": \"Your picket gap is 4 in (10 cm) or more.\", \"algebra\": \"Each side is divided by the {sp} spacing and rounded up to whole sections{gates} = {sections} sections. Posts = {segments} segments {loop}{wall} = {posts}.\", \"alg_gates\": \" (gate openings taken out of the longest sides)\", \"alg_loop\": \"(closed loop, so no extra end post)\", \"alg_wall1\": \" - {n} wall end\", \"alg_wall2\": \" - {n} wall ends\"};\nvar LOC = {\"locale\": \"en-US\", \"currency\": \"USD\", \"metricOnly\": false, \"nbsp\": false, \"tallFt\": 6, \"maxSpacingFt\": 8, \"wideGateFt\": 4, \"poolMinM\": 1.2192, \"poolGapCm\": 10.16};\nvar FENCE_MODEL = (function () {\n    var PI = Math.PI;\n    var EPS = 1e-9;\n\n    \/\/ grp: which option group the type uses. postSq: square posts (else round).\n    var TYPES = {\n        picket: { name: 'Wood picket fence (built on site)', grp: 'picket', spacing: 8, spacingM: 2.4, wood: true },\n        wpanel: { name: 'Wood panel fence (prefab panels)', grp: 'panel', spacing: 8, spacingM: 2.4, wood: true },\n        vinyl: { name: 'Vinyl fence (panels)', grp: 'panel', spacing: 8, spacingM: 2.4, postW: 5, holeD: 12 },\n        alum: { name: 'Aluminum \/ ornamental fence (panels)', grp: 'panel', spacing: 6, spacingM: 1.8, postW: 2, holeD: 8 },\n        chain: { name: 'Chain link fence', grp: 'chain', spacing: 10, spacingM: 3, holeD: 10 }\n    };\n    var POST_STD = {\n        picket: [6, 8, 10, 12, 14, 16], wpanel: [6, 8, 10, 12, 14, 16], vinyl: [7, 8, 9, 10, 12],\n        alum: [4, 5, 6, 7, 8, 9, 10], chain: [5, 6, 7, 8, 9, 10, 12]\n    };\n    var POST_STD_M = [1.5, 1.8, 2.1, 2.4, 2.7, 3, 3.6, 4.2, 4.8].map(function (m) { return m \/ 0.3048; });\n    var RAIL_STD = [8, 10, 12, 16];\n    var RAIL_STD_M = [2.4, 3, 3.6, 4.8].map(function (m) { return m \/ 0.3048; });\n    \/\/ concrete bag yield in cubic feet (80 lb = 0.6 ft3, about 2.135 kg per litre for the metric bags)\n    var BAGS_IMP = [{ v: '50', label: '50 lb', y: 0.375 }, { v: '60', label: '60 lb', y: 0.45 }, { v: '80', label: '80 lb', y: 0.6 }];\n    var BAGS_MET = [{ v: '20', label: '20 kg', y: 9.37 \/ 28.3168 }, { v: '25', label: '25 kg', y: 11.71 \/ 28.3168 }, { v: '40', label: '40 kg', y: 18.74 \/ 28.3168 }];\n    var WOOD_POST_IN = { s: 3.5, l: 5.5 };\n    var WOOD_POST_IN_MET = { s: 3.94, l: 5.91 };\n    var GRAVEL_IN = 6;\n    \/\/ locale overrides (EU pages): typeOv, woodPostMet, chainLine\/chainTerm (in), rollFt, postStdM, railStdM, eu\n    var L = { eu: false, woodPostMet: WOOD_POST_IN_MET, chainLine: 2.375, chainTerm: 2.875, rollFt: 50, railLen: 10.5 };\n    function setLocale(loc) {\n        for (var k in loc) { if (k !== 'typeOv') L[k] = loc[k]; }\n        if (loc.typeOv) { for (var t in loc.typeOv) { for (var f in loc.typeOv[t]) TYPES[t][f] = loc.typeOv[t][f]; } }\n        if (loc.postStdM) POST_STD_M = loc.postStdM.map(function (m) { return m \/ 0.3048; });\n        if (loc.railStdM) RAIL_STD_M = loc.railStdM.map(function (m) { return m \/ 0.3048; });\n    }\n    function woodPostIn(metric, sel) { return metric ? L.woodPostMet[sel] : WOOD_POST_IN[sel]; }\n\n    function nextStd(x, arr) {\n        for (var i = 0; i < arr.length; i++) { if (arr[i] >= x - 1e-6) return arr[i]; }\n        return arr[arr.length - 1];\n    }\n    function defDepthIn(hFt) { return Math.max(24, Math.ceil(hFt * 12 \/ 3 \/ 6 - EPS) * 6); }\n    function defRails(hFt) { return hFt <= 4 + EPS ? 2 : (hFt <= 6 + EPS ? 3 : 4); }\n    function defHoleIn(type, large) {\n        if (TYPES[type].wood) return large ? 12 : 10;\n        return TYPES[type].holeD;\n    }\n    function postBuyFt(type, hFt, depthIn, metric) {\n        return nextStd(hFt + depthIn \/ 12, metric ? POST_STD_M : POST_STD[type]);\n    }\n    function railBuyFt(spacingFt, metric) { return nextStd(spacingFt, metric ? RAIL_STD_M : RAIL_STD); }\n    function r25(x) { return Math.round(x * 4) \/ 4; }\n\n    \/\/ Typical US big-box style estimates. Editable in the calculator.\n    function defaultPrices(type, hFt, o) {\n        var p = { concrete: r25(o.bagYield * 11.5), gravel: 5.5 };\n        var pf = o.postBuyFt, s = o.spacingFt;\n        if (L.eu) return euPrices(type, hFt, o);\n        if (type === 'picket') {\n            p.post = r25(pf * (o.large ? 4.2 : 2)); p.rail = r25(o.railBuyFt * 0.75); p.picket = r25(0.6 * hFt);\n            p.fasteners = 0.04; p.gate = 75;\n        } else if (type === 'wpanel') {\n            p.post = r25(pf * (o.large ? 4.2 : 2)); p.panel = r25(15 * hFt * s \/ 8); p.gate = 110;\n        } else if (type === 'vinyl') {\n            p.post = r25(pf * 5); p.panel = r25(22 * hFt * s \/ 8); p.gate = 220;\n        } else if (type === 'alum') {\n            p.post = r25(pf * 3.4); p.panel = r25(18 * hFt * s \/ 6); p.gate = 180;\n        } else {\n            p.lpost = r25(pf * 3.2); p.tpost = r25(pf * 4.5); p.rail = 15; p.fabric = r25(28 * hFt);\n            p.tbar = 6; p.tband = 1.25; p.bband = 1.5; p.cap = 1.75; p.ties = 0.12; p.gate = r25(25 * hFt);\n        }\n        return p;\n    }\n    \/\/ Typical EU store prices in EUR (heights\/lengths converted to metres)\n    function euPrices(type, hFt, o) {\n        var hM = hFt * 0.3048, sM = o.spacingFt * 0.3048, pM = o.postBuyFt * 0.3048;\n        var p = { concrete: Math.round(o.bagYield * 9.5 * 4) \/ 4, gravel: 4 };\n        if (type === 'picket') {\n            p.post = r25(pM * (o.large ? 10.5 : 5)); p.rail = r25(o.railBuyFt * 0.3048 * 1.7); p.picket = r25(1.8 * hM);\n            p.fasteners = 0.05; p.gate = 120;\n        } else if (type === 'wpanel') {\n            p.post = r25(pM * (o.large ? 10.5 : 5)); p.panel = r25(23 * hM * sM); p.gate = 140;\n        } else if (type === 'vinyl') {\n            p.post = r25(pM * 12); p.panel = r25(43 * hM * sM); p.gate = 250;\n        } else if (type === 'alum') {\n            p.post = r25(pM * 4.5); p.panel = r25(16.5 * hM * sM); p.gate = 150;\n        } else {\n            p.lpost = r25(pM * 3); p.tpost = r25(pM * 4.2); p.strut = 6; p.fabric = r25(29 * hM);\n            p.wire = 12; p.ties = 6; p.cap = 1.25; p.gate = 110;\n        }\n        return p;\n    }\n    var PRICE_KEYS = {\n        picket: ['post', 'rail', 'picket', 'fasteners', 'concrete', 'gravel', 'gate'],\n        wpanel: ['post', 'panel', 'concrete', 'gravel', 'gate'],\n        vinyl: ['post', 'panel', 'concrete', 'gravel', 'gate'],\n        alum: ['post', 'panel', 'concrete', 'gravel', 'gate'],\n        chain: ['lpost', 'tpost', 'rail', 'fabric', 'tbar', 'tband', 'bband', 'cap', 'ties', 'concrete', 'gravel', 'gate']\n    };\n    function priceKeys(type) {\n        if (L.eu) {\n            if (type === 'chain') return ['lpost', 'tpost', 'strut', 'fabric', 'wire', 'ties', 'cap', 'concrete', 'gravel', 'gate'];\n        }\n        return PRICE_KEYS[type];\n    }\n\n    \/\/ c: all lengths in feet, all small dimensions in inches.\n    function model(c) {\n        var T = TYPES[c.type];\n        var runs = c.runs.filter(function (x) { return x > 0; });\n        if (!runs.length) return { err: 'length' };\n        if (!(c.hFt > 0)) return { err: 'height' };\n        var s = c.spacingFt;\n        if (!(s > 0)) return { err: 'spacing' };\n        var gates = c.gates || 0;\n        if (gates > 0) {\n            if (!(c.gateW > 0)) return { err: 'gatew' };\n        }\n        var totalLen = 0;\n        runs.forEach(function (r) { totalLen += r; });\n        var G = gates * (c.gateW || 0);\n        if (G >= totalLen - EPS) return { err: 'gates' };\n        var netLen = totalLen - G;\n\n        \/\/ place each gate in the longest remaining side, then round every side up to whole sections\n        var rem = runs.slice();\n        for (var gi = 0; gi < gates; gi++) {\n            var mi = 0;\n            for (var ri = 1; ri < rem.length; ri++) { if (rem[ri] > rem[mi]) mi = ri; }\n            rem[mi] = Math.max(0, rem[mi] - c.gateW);\n        }\n        var sumN = 0;\n        rem.forEach(function (r) { sumN += Math.ceil(r \/ s - EPS); });\n        var sections = Math.max(1, sumN);\n        var closed = runs.length >= 3 ? !!c.closed : false;\n        var segments = sections + gates;\n        var corners = closed ? runs.length : runs.length - 1;\n        var attach = closed ? 0 : Math.min(c.attach || 0, 2);\n        var totalPosts = closed ? segments : segments + 1 - attach;\n        var endP = Math.min(closed ? 0 : 2 - attach, totalPosts);\n        var cornP = Math.min(corners, totalPosts - endP);\n        var gateP = Math.min(gates * 2, totalPosts - endP - cornP);\n        var lineP = totalPosts - endP - cornP - gateP;\n\n        var dIn = c.holeDIn, depthIn = c.depthIn;\n        var gIn = c.gravel ? GRAVEL_IN : 0;\n        var wMax = T.grp === 'chain' ? L.chainTerm : (c.postWIn || 0);\n        if (!(dIn > wMax)) return { err: 'hole' };\n        var cH = depthIn - gIn;\n        if (!(cH > 0)) return { err: 'depth' };\n        var holeArea = PI \/ 4 * dIn * dIn;\n        function perPost(w, sq) { return (holeArea - (sq ? w * w : PI \/ 4 * w * w)) * cH; }\n        var conc;\n        if (T.grp === 'chain') conc = lineP * perPost(L.chainLine, false) + (totalPosts - lineP) * perPost(L.chainTerm, false);\n        else conc = totalPosts * perPost(c.postWIn, true);\n        var concFt3 = conc \/ 1728;\n        var bags = Math.ceil(concFt3 \/ c.bagYield - EPS);\n        var gravelFt3 = c.gravel ? totalPosts * holeArea * gIn \/ 1728 : 0;\n        var gravelBags = c.gravel ? Math.ceil(gravelFt3 \/ 0.5 - EPS) : 0;\n        var postFt = c.hFt + depthIn \/ 12;\n        var buyFt = postBuyFt(c.type, c.hFt, depthIn, c.metric);\n\n        var items = [];\n        function add(key, qty, extra) {\n            var it = { key: key, qty: qty };\n            for (var k in extra) it[k] = extra[k];\n            items.push(it);\n        }\n        var waste = 1 + (c.wastePct || 0) \/ 100;\n        var info = { buyFt: buyFt, postFt: postFt };\n        if (T.grp === 'picket') {\n            var rails = Math.ceil(c.rails * sections * waste - EPS);\n            var peff = c.bob ? Math.max(1, c.pwIn - 1) : c.pwIn + c.gapIn;\n            if (!(c.pwIn > 0) || !(peff > 0)) return { err: 'picket' };\n            var picketsBase = Math.ceil(netLen * 12 \/ peff - EPS);\n            var pickets = Math.ceil(picketsBase * waste - EPS);\n            info.railBuyFt = railBuyFt(s, c.metric);\n            info.peff = peff;\n            add('post', totalPosts, {});\n            add('rail', rails, {});\n            add('picket', pickets, {});\n            add('fasteners', pickets * c.rails * 2, {});\n        } else if (T.grp === 'panel') {\n            add('post', totalPosts, {});\n            add('panel', sections, {});\n        } else if (L.eu) {\n            var struts = endP + 2 * cornP + gateP;\n            var lines = c.hFt * 0.3048 > 1.0 + EPS ? 3 : 2;\n            add('lpost', lineP, {});\n            add('tpost', totalPosts - lineP, {});\n            add('strut', struts, {});\n            add('fabric', Math.max(1, Math.ceil(netLen \/ L.rollFt - EPS)), {});\n            add('wire', Math.max(1, Math.ceil(lines * netLen * 0.3048 \/ 50 - EPS)), { lines: lines });\n            add('ties', Math.max(1, Math.ceil(netLen * 0.3048 \/ 50 - EPS)), {});\n            add('cap', totalPosts, {});\n        } else {\n            var tbars = endP + 2 * cornP + gateP;\n            var tbandEach = Math.max(2, Math.ceil(c.hFt - EPS) - 1);\n            var terminals = totalPosts - lineP;\n            add('lpost', lineP, {});\n            add('tpost', terminals, {});\n            add('rail', Math.ceil(netLen \/ 10.5 - EPS), {});\n            add('fabric', Math.max(1, Math.ceil(netLen \/ L.rollFt - EPS)), {});\n            add('tbar', tbars, {});\n            add('tband', tbars * tbandEach, {});\n            add('bband', tbars, {});\n            add('cap', totalPosts, {});\n            add('ties', Math.ceil(netLen \/ 2 - EPS) + lineP * Math.ceil(c.hFt - EPS), {});\n        }\n        add('concrete', bags, { ft3: concFt3 });\n        if (c.gravel) add('gravel', gravelBags, { ft3: gravelFt3 });\n        if (gates > 0) add('gate', gates, {});\n\n        var pr = c.prices || {};\n        var materials = 0;\n        items.forEach(function (it) {\n            it.price = Number(pr[it.key]) || 0;\n            it.cost = it.price * it.qty;\n            materials += it.cost;\n        });\n        var labor = (Number(c.laborPerFt) || 0) * totalLen;\n        var total = materials + labor;\n        return {\n            err: null, items: items, info: info,\n            totalLen: totalLen, netLen: netLen, sumN: sumN, sections: sections, segments: segments, closed: closed,\n            posts: { total: totalPosts, line: lineP, corner: cornP, end: endP, gate: gateP },\n            concFt3: concFt3, bags: bags, perPostBags: (conc \/ totalPosts \/ 1728) \/ c.bagYield,\n            materials: materials, labor: labor, total: total, perFt: total \/ totalLen\n        };\n    }\n\n    return {\n        TYPES: TYPES, PRICE_KEYS: PRICE_KEYS, priceKeys: priceKeys, setLocale: setLocale, woodPostIn: woodPostIn,\n        BAGS_IMP: BAGS_IMP, BAGS_MET: BAGS_MET, GRAVEL_IN: GRAVEL_IN,\n        defDepthIn: defDepthIn, defRails: defRails, defHoleIn: defHoleIn, postBuyFt: postBuyFt, railBuyFt: railBuyFt,\n        defaultPrices: defaultPrices, model: model, nextStd: nextStd\n    };\n})();\n\n    \/\/ T (texts) and LOC (locale settings) are defined above this code by the page builder\n    var get = function (id) { return document.getElementById(id); };\n    var M = FENCE_MODEL;\n    if (LOC.model) M.setLocale(LOC.model);\n    var FT = 0.3048, CM = 2.54;\n    var S = { metric: !!LOC.metricOnly, type: 'picket', touched: {}, pTouched: {}, pVals: {} };\n    var NB = LOC.nbsp ? '\u00a0' : ' ';\n    var PRESETS_FT = LOC.presetsM ? LOC.presetsM.map(function (m) { return m \/ FT; }) : [4, 5, 6, 8];\n\n    var t = function (key, vars) {\n        var s = T[key];\n        if (s === undefined) return key;\n        if (vars) { for (var k in vars) { s = s.split('{' + k + '}').join(vars[k]); } }\n        return s;\n    };\n    var rnd = function (n, d) { var p = Math.pow(10, d); return Math.round(n * p) \/ p; };\n    var nf = function (n, max) { return Number(n).toLocaleString(LOC.locale, { maximumFractionDigits: max === undefined ? 2 : max }); };\n    var num = function (n) { return Number(n).toLocaleString(LOC.locale); };\n    var curFmt = function (d) { return new Intl.NumberFormat(LOC.locale, { style: 'currency', currency: LOC.currency, minimumFractionDigits: d, maximumFractionDigits: d }); };\n    var money = function (n) { return curFmt(2).format(n); };\n    var money0 = function (n) { return curFmt(0).format(Math.round(n)); };\n    var val = function (id) { var v = parseFloat(get(id).value); return isNaN(v) ? NaN : v; };\n\n    \/\/ unit helpers: lengths are ft (US) or m, small dimensions are in (US) or cm\n    var toFt = function (v) { return S.metric ? v \/ FT : v; };\n    var toIn = function (v) { return S.metric ? v \/ CM : v; };\n    var roundCm5 = function (inch) { return Math.round(inch * CM \/ 5) * 5; };\n    var fLen = function (ft) { return S.metric ? nf(rnd(ft * FT, 2)) + NB + 'm' : rnd(ft, 1) + ' ft'; };\n    var fIn = function (inch) { return S.metric ? Math.round(inch * CM) + NB + 'cm' : rnd(inch, 1) + ' in'; };\n\n    var curType = function () { return M.TYPES[S.type]; };\n    var isLarge = function () { return get('fcc-postsel').value === 'l'; };\n    var postWIn = function () {\n        var T0 = curType();\n        if (T0.wood) return M.woodPostIn(S.metric, get('fcc-postsel').value);\n        return T0.postW || 0;\n    };\n    var bagList = function () { return S.metric ? M.BAGS_MET : M.BAGS_IMP; };\n    var bagYield = function () {\n        var v = get('fcc-bag').value, l = bagList();\n        for (var i = 0; i < l.length; i++) { if (l[i].v === v) return l[i].y; }\n        return l[l.length - 1].y;\n    };\n    var bagLabel = function () {\n        var v = get('fcc-bag').value, l = bagList();\n        for (var i = 0; i < l.length; i++) { if (l[i].v === v) return l[i].label; }\n        return '';\n    };\n\n    \/\/ ---------------------------------------------------------------- sides (runs)\n    var runsEl = get('fcc-runs');\n    var runRows = function () { return Array.prototype.slice.call(runsEl.querySelectorAll('.fcc-run')); };\n    var renumberRuns = function () {\n        var rows = runRows();\n        rows.forEach(function (row, i) {\n            var inp = row.querySelector('.fcc-run-in'), lab = row.querySelector('.fcc-run-label');\n            inp.id = 'fcc-run-' + (i + 1);\n            lab.htmlFor = inp.id;\n            lab.textContent = t('sideLabel', { n: i + 1, u: S.metric ? 'm' : 'ft' });\n            row.querySelector('.fcc-run-del').classList.toggle('fcc-hide', rows.length < 2);\n        });\n        var closed = get('fcc-closed');\n        closed.disabled = rows.length < 3;\n        if (rows.length < 3) closed.checked = false;\n        get('fcc-add-run').classList.toggle('fcc-hide', rows.length >= 12);\n    };\n    var addRun = function (v) {\n        var row = document.createElement('div');\n        row.className = 'fcc-run';\n        row.innerHTML = '<label class=\"fcc-run-label\"><\/label>' +\n            '<div class=\"fcc-run-ctl\"><input type=\"number\" class=\"fcc-input-field fcc-run-in\" min=\"0\" step=\"any\" placeholder=\"' + t('runPh') + '\">' +\n            '<button type=\"button\" class=\"fcc-run-del\" aria-label=\"' + t('removeAria') + '\">' + t('remove') + '<\/button><\/div>';\n        if (v !== undefined) { if (v !== null) row.querySelector('.fcc-run-in').value = v; }\n        runsEl.appendChild(row);\n        renumberRuns();\n        return row;\n    };\n    runsEl.addEventListener('click', function (e) {\n        if (!e.target.classList.contains('fcc-run-del')) return;\n        runsEl.removeChild(e.target.closest('.fcc-run'));\n        renumberRuns();\n    });\n    get('fcc-add-run').onclick = function () { addRun('').querySelector('.fcc-run-in').focus(); };\n\n    \/\/ ---------------------------------------------------------------- defaults \/ visibility\n    var heightFt = function () { var h = val('fcc-height'); return isNaN(h) ? NaN : toFt(h); };\n    var setSelectOptions = function (sel, list, keep, dflt) {\n        var cur = sel.value;\n        sel.innerHTML = '';\n        list.forEach(function (o) {\n            var op = document.createElement('option');\n            op.value = o.v; op.textContent = o.label;\n            sel.appendChild(op);\n        });\n        var has = keep ? list.some(function (o) { return o.v === cur; }) : false;\n        sel.value = has ? cur : (dflt || list[list.length - 1].v);\n    };\n    var presetLabel = function (ft) { return S.metric ? nf(rnd(ft * FT, 1), 1) + NB + 'm' : ft + ' ft'; };\n    var buildPresets = function () {\n        var box = get('fcc-height-presets');\n        box.innerHTML = '';\n        PRESETS_FT.forEach(function (ft) {\n            var b = document.createElement('button');\n            b.type = 'button'; b.className = 'fcc-preset-btn'; b.dataset.ft = String(ft);\n            box.appendChild(b);\n        });\n    };\n    var syncUnitLabels = function () {\n        Array.prototype.forEach.call(document.querySelectorAll('#fence-calc-wrapper .fcc-u-len'), function (el) { el.textContent = S.metric ? 'm' : 'ft'; });\n        Array.prototype.forEach.call(document.querySelectorAll('#fence-calc-wrapper .fcc-u-in'), function (el) { el.textContent = S.metric ? 'cm' : 'in'; });\n        Array.prototype.forEach.call(get('fcc-height-presets').children, function (b) { b.textContent = presetLabel(parseFloat(b.dataset.ft)); });\n        setSelectOptions(get('fcc-postsel'), S.metric ?\n            [{ v: 's', label: T.postS_met }, { v: 'l', label: T.postL_met }] :\n            [{ v: 's', label: T.postS_imp }, { v: 'l', label: T.postL_imp }], true);\n        setSelectOptions(get('fcc-bag'), bagList(), true, S.metric ? (LOC.bagDefM || '25') : '80');\n        if (!LOC.metricOnly) {\n            get('fcc-unit-toggle').children[0].classList.toggle('fcc-active', !S.metric);\n            get('fcc-unit-toggle').children[1].classList.toggle('fcc-active', S.metric);\n        }\n        renumberRuns();\n    };\n    var syncPresets = function () {\n        var h = heightFt();\n        Array.prototype.forEach.call(get('fcc-height-presets').children, function (b) {\n            b.classList.toggle('fcc-active', Math.abs(parseFloat(b.dataset.ft) - h) < 0.15);\n        });\n    };\n    var showGroups = function () {\n        Array.prototype.forEach.call(document.querySelectorAll('#fence-calc-wrapper [data-show]'), function (el) {\n            el.classList.toggle('fcc-hide', el.dataset.show.split(',').indexOf(S.type) < 0);\n        });\n    };\n    \/\/ values that follow the fence height \/ type until the user edits them\n    var applyAuto = function () {\n        var hFt = heightFt();\n        if (isNaN(hFt) || hFt <= 0) return;\n        if (!S.touched['fcc-depth']) { var dIn = M.defDepthIn(hFt); get('fcc-depth').value = S.metric ? roundCm5(dIn) : dIn; }\n        if (!S.touched['fcc-rails']) get('fcc-rails').value = String(M.defRails(hFt));\n        if (!S.touched['fcc-hole']) { var hIn = M.defHoleIn(S.type, isLarge()); get('fcc-hole').value = S.metric ? roundCm5(hIn) : hIn; }\n    };\n    var setTypeDefaults = function () {\n        var T0 = curType();\n        get('fcc-spacing').value = S.metric ? T0.spacingM : T0.spacing;\n        S.touched['fcc-spacing'] = false; S.touched['fcc-hole'] = false;\n        S.pTouched = {}; S.pVals = {};\n        showGroups();\n        applyAuto();\n        renderPrices();\n    };\n\n    \/\/ ---------------------------------------------------------------- prices\n    var renderPrices = function () {\n        var hFt = heightFt(), sp = toFt(val('fcc-spacing')), dIn = toIn(val('fcc-depth'));\n        if (isNaN(hFt) || hFt <= 0 || isNaN(sp) || sp <= 0 || isNaN(dIn) || dIn <= 0) return;\n        var def = M.defaultPrices(S.type, hFt, {\n            postBuyFt: M.postBuyFt(S.type, hFt, dIn, S.metric), large: isLarge(), spacingFt: sp,\n            railBuyFt: M.railBuyFt(sp, S.metric), bagYield: bagYield()\n        });\n        var box = get('fcc-prices');\n        box.innerHTML = '';\n        M.priceKeys(S.type).forEach(function (k) {\n            var v = S.pTouched[k] ? S.pVals[k] : def[k];\n            var row = document.createElement('div');\n            row.className = 'fcc-price-row';\n            row.innerHTML = '<label class=\"fcc-price-label\" for=\"fcc-p-' + k + '\">' + t('p_' + k) + '<\/label>' +\n                '<input type=\"number\" class=\"fcc-input-field fcc-price-in\" id=\"fcc-p-' + k + '\" data-key=\"' + k + '\" min=\"0\" step=\"0.01\">';\n            box.appendChild(row);\n            row.querySelector('input').value = v;\n        });\n    };\n    get('fcc-prices').addEventListener('input', function (e) {\n        var k = e.target.dataset.key;\n        if (!k) return;\n        S.pTouched[k] = true;\n        S.pVals[k] = e.target.value;\n    });\n    var readPrices = function () {\n        var o = {};\n        Array.prototype.forEach.call(get('fcc-prices').querySelectorAll('.fcc-price-in'), function (el) { o[el.dataset.key] = parseFloat(el.value) || 0; });\n        return o;\n    };\n\n    \/\/ ---------------------------------------------------------------- events\n    ['fcc-depth', 'fcc-rails', 'fcc-hole', 'fcc-spacing'].forEach(function (id) {\n        get(id).addEventListener('input', function () { S.touched[id] = true; if (id !== 'fcc-rails') renderPrices(); });\n    });\n    get('fcc-rails').addEventListener('change', function () { S.touched['fcc-rails'] = true; });\n    get('fcc-height').addEventListener('input', function () { applyAuto(); syncPresets(); renderPrices(); });\n    get('fcc-height-presets').addEventListener('click', function (e) {\n        if (!e.target.dataset.ft) return;\n        var ft = parseFloat(e.target.dataset.ft);\n        get('fcc-height').value = S.metric ? rnd(ft * FT, 1) : ft;\n        applyAuto(); syncPresets(); renderPrices();\n    });\n    get('fcc-postsel').addEventListener('change', function () { applyAuto(); renderPrices(); });\n    get('fcc-bag').addEventListener('change', renderPrices);\n    get('fcc-type').addEventListener('change', function () { S.type = get('fcc-type').value; setTypeDefaults(); hideResults(); });\n    get('fcc-layout').addEventListener('change', function () { get('fcc-gap-field').classList.toggle('fcc-hide', get('fcc-layout').value === 'bob'); });\n    get('fcc-cost').addEventListener('change', function () { get('fcc-cost-box').classList.toggle('fcc-hide', !get('fcc-cost').checked); });\n\n    if (!LOC.metricOnly) get('fcc-unit-toggle').onclick = function (e) {\n        var m = e.target.dataset.unit;\n        if (!m) return;\n        var toMetric = m === 'metric';\n        if (toMetric === S.metric) return;\n        var lenFn = toMetric ? function (v) { return rnd(v * FT, 2); } : function (v) { return rnd(v \/ FT, 1); };\n        var inFn = toMetric ? function (v) { return rnd(v * CM, 1); } : function (v) { return rnd(v \/ CM, 2); };\n        var conv = function (id, fn) { var el = get(id), v = parseFloat(el.value); if (!isNaN(v)) el.value = fn(v); };\n        \/\/ fields that still hold the starting value switch to the starting value of the other system\n        var pairs = { 'fcc-gatew': [4, 1.2], 'fcc-pw': [5.5, 14], 'fcc-gap': [0.5, 1] };\n        Object.keys(pairs).forEach(function (id) {\n            var el = get(id), v = parseFloat(el.value), p = pairs[id];\n            if (isNaN(v)) return;\n            if (Math.abs(v - p[S.metric ? 1 : 0]) < 1e-6) el.value = p[toMetric ? 1 : 0];\n            else el.value = (id === 'fcc-gatew' ? lenFn : inFn)(v);\n        });\n        var h = heightFt();\n        var hp = null;\n        PRESETS_FT.forEach(function (ft) { if (Math.abs(ft - h) < 0.15) hp = ft; });\n        if (hp !== null) get('fcc-height').value = toMetric ? rnd(hp * FT, 1) : hp;\n        else conv('fcc-height', lenFn);\n        Array.prototype.forEach.call(document.querySelectorAll('#fcc-runs .fcc-run-in'), function (el) { var v = parseFloat(el.value); if (!isNaN(v)) el.value = lenFn(v); });\n        var spTouched = S.touched['fcc-spacing'];\n        if (spTouched) conv('fcc-spacing', lenFn);\n        ['fcc-hole', 'fcc-depth'].forEach(function (id) { if (S.touched[id]) conv(id, inFn); });\n        S.metric = toMetric;\n        if (!spTouched) get('fcc-spacing').value = toMetric ? curType().spacingM : curType().spacing;\n        syncUnitLabels();\n        applyAuto();\n        syncPresets(); renderPrices(); hideResults();\n    };\n\n    \/\/ ---------------------------------------------------------------- results\n    var hideResults = function () { get('fcc-result-area').classList.remove('fcc-visible'); };\n    var showError = function (msg) {\n        var err = get('fcc-error-msg');\n        err.textContent = msg;\n        err.classList.add('fcc-visible');\n        hideResults();\n    };\n    var card = function (label, amount, sub) {\n        return '<div class=\"fcc-result-card\"><p class=\"fcc-result-label\">' + label + '<\/p><div class=\"fcc-result-amount\">' + amount + '<\/div><p class=\"fcc-result-sub\">' + sub + '<\/p><\/div>';\n    };\n\n    var readCfg = function () {\n        var runs = Array.prototype.map.call(document.querySelectorAll('#fcc-runs .fcc-run-in'), function (el) { var v = parseFloat(el.value); return isNaN(v) ? 0 : toFt(v); });\n        var labor = parseFloat(get('fcc-labor').value) || 0;\n        return {\n            type: S.type, runs: runs, closed: get('fcc-closed').checked,\n            gates: parseInt(get('fcc-gates').value, 10) || 0, gateW: toFt(val('fcc-gatew')),\n            attach: parseInt(get('fcc-attach').value, 10) || 0,\n            hFt: heightFt(), spacingFt: toFt(val('fcc-spacing')),\n            postWIn: postWIn(), holeDIn: toIn(val('fcc-hole')), depthIn: toIn(val('fcc-depth')),\n            gravel: get('fcc-gravel').checked, bagYield: bagYield(),\n            rails: parseInt(get('fcc-rails').value, 10) || 2,\n            pwIn: toIn(val('fcc-pw')), gapIn: toIn(isNaN(val('fcc-gap')) ? 0 : val('fcc-gap')), bob: get('fcc-layout').value === 'bob',\n            wastePct: parseFloat(get('fcc-waste').value) || 0, metric: S.metric,\n            laborPerFt: get('fcc-cost').checked ? (S.metric ? labor * FT : labor) : 0,\n            prices: get('fcc-cost').checked ? readPrices() : {}\n        };\n    };\n\n    var postLabel = function () {\n        var T0 = curType();\n        if (T0.wood) return S.metric ? (isLarge() ? T.postL_met : T.postS_met) : (isLarge() ? '6x6' : '4x4');\n        return t('postType_' + S.type);\n    };\n    var itemRow = function (it, r, c) {\n        var spec = '', label = '';\n        var buy = r.info.buyFt;\n        var vol = function (ft3) { return S.metric ? nf(rnd(ft3 * 28.3168, 0), 0) + NB + 'L' : rnd(ft3, 1) + ' cu ft'; };\n        if (it.key === 'post') {\n            label = t('l_post');\n            spec = t('s_post', { post: postLabel(), len: fLen(buy), depth: fIn(c.depthIn) });\n        } else if (it.key === 'lpost') { label = t('l_lpost'); spec = t('s_lpost', { len: fLen(buy), depth: fIn(c.depthIn) });\n        } else if (it.key === 'tpost') { label = t('l_tpost'); spec = t('s_tpost', { len: fLen(buy) });\n        } else if (it.key === 'rail') {\n            label = S.type === 'chain' ? t('l_toprail') : t('l_rail');\n            spec = S.type === 'chain' ? t('s_toprail') : t('s_rail', { pre: S.metric ? T.railPreMet : T.railPreImp, len: fLen(r.info.railBuyFt), n: c.rails });\n        } else if (it.key === 'picket') {\n            label = t('l_picket');\n            spec = c.bob ? t('s_bob', { w: fIn(c.pwIn) }) : t('s_picket', { w: fIn(c.pwIn), g: fIn(c.gapIn) });\n        } else if (it.key === 'fasteners') { label = t('l_fasteners'); spec = t('s_fasteners');\n        } else if (it.key === 'panel') { label = t('l_panel'); spec = t('s_panel', { w: fLen(c.spacingFt), h: fLen(c.hFt) });\n        } else if (it.key === 'fabric') { label = t('l_fabric'); spec = t('s_fabric', { h: fLen(c.hFt) });\n        } else if (it.key === 'tbar') { label = t('l_tbar'); spec = t('s_tbar');\n        } else if (it.key === 'tband') { label = t('l_tband'); spec = t('s_tband', { n: Math.max(2, Math.ceil(c.hFt - 0.001) - 1) });\n        } else if (it.key === 'bband') { label = t('l_bband'); spec = t('s_bband');\n        } else if (it.key === 'strut') { label = t('l_strut'); spec = t('s_strut');\n        } else if (it.key === 'wire') { label = t('l_wire'); spec = t('s_wire', { n: it.lines });\n        } else if (it.key === 'cap') { label = t('l_cap'); spec = t('s_cap');\n        } else if (it.key === 'ties') { label = t('l_ties'); var euChain = LOC.model ? LOC.model.eu : false; spec = S.type === 'chain' ? (euChain ? t('s_ties_eu') : t('s_ties')) : t('s_ties');\n        } else if (it.key === 'concrete') { label = t('l_concrete'); spec = t('s_concrete', { bag: bagLabel(), vol: vol(it.ft3) });\n        } else if (it.key === 'gravel') { label = t('l_gravel'); spec = t('s_gravel', { vol: vol(it.ft3) });\n        } else if (it.key === 'gate') { label = t('l_gate'); spec = t('s_gate', { w: fLen(c.gateW) }); }\n        return { label: label, spec: spec };\n    };\n\n    var calc = function () {\n        var err = get('fcc-error-msg');\n        err.classList.remove('fcc-visible');\n        err.textContent = '';\n        var c = readCfg();\n        var r = M.model(c);\n        if (r.err) { showError(t('err_' + r.err)); return; }\n        var cost = get('fcc-cost').checked;\n\n        \/\/ cost \/ summary cards\n        var grid = get('fcc-result-grid');\n        var unitLen = S.metric ? 'm' : 'ft';\n        var totalDisp = S.metric ? rnd(r.totalLen * FT, 1) : rnd(r.totalLen, 1);\n        var forLen = t('forLen', { n: nf(totalDisp, 1), u: unitLen });\n        if (cost) {\n            var perDisp = S.metric ? r.perFt \/ FT : r.perFt;\n            var subCost = c.laborPerFt > 0 ? t('matLabor', { a: money0(r.materials), b: money0(r.labor) }) : t('matOnly');\n            grid.innerHTML = card(t('estCost'), '<span>' + money0(r.total) + '<\/span>', subCost) +\n                card(S.metric ? t('costPerM') : t('costPerFt'), '<span>' + money(perDisp) + '<\/span>', forLen);\n        } else {\n            grid.innerHTML = card(t('cardPosts'), '<span>' + num(r.posts.total) + '<\/span>', forLen) +\n                card(S.type === 'picket' || S.type === 'chain' ? t('cardSections') : t('cardPanels'), '<span>' + num(r.sections) + '<\/span>', t('cardBetween'));\n        }\n\n        \/\/ post breakdown\n        var pb = [];\n        if (r.posts.line) pb.push(t('pLine', { n: r.posts.line }));\n        if (r.posts.corner) pb.push(t('pCorner', { n: r.posts.corner }));\n        if (r.posts.end) pb.push(t('pEnd', { n: r.posts.end }));\n        if (r.posts.gate) pb.push(t('pGate', { n: r.posts.gate }));\n        var gtxt = c.gates ? t(c.gates > 1 ? 'gatesMany' : 'gatesOne', { n: c.gates }) : '';\n        get('fcc-postline').textContent = t('postLine', { total: num(r.posts.total), parts: pb.join(', '), sections: num(r.sections), gates: gtxt });\n\n        \/\/ shopping list\n        var head = '<tr><th>' + t('thItem') + '<\/th><th>' + t('thQty') + '<\/th><th>' + t('thDetails') + '<\/th>' + (cost ? '<th>' + t('thEach') + '<\/th><th>' + t('thCost') + '<\/th>' : '') + '<\/tr>';\n        var body = r.items.map(function (it) {\n            var d = itemRow(it, r, c);\n            return '<tr><td><strong>' + d.label + '<\/strong><\/td><td class=\"fcc-qty\">' + num(it.qty) + '<\/td><td class=\"fcc-spec\">' + d.spec + '<\/td>' +\n                (cost ? '<td class=\"fcc-price\">' + money(it.price) + '<\/td><td class=\"fcc-price\">' + money(it.cost) + '<\/td>' : '') + '<\/tr>';\n        }).join('');\n        var foot = '';\n        if (cost) {\n            var span = 4;\n            foot = '<tr class=\"fcc-total-row\"><td colspan=\"' + span + '\">' + t('matSub') + '<\/td><td class=\"fcc-price\">' + money(r.materials) + '<\/td><\/tr>';\n            if (r.labor > 0) foot += '<tr class=\"fcc-total-row\"><td colspan=\"' + span + '\">' + t('labor') + '<\/td><td class=\"fcc-price\">' + money(r.labor) + '<\/td><\/tr>' +\n                '<tr class=\"fcc-total-row\"><td colspan=\"' + span + '\">' + t('total') + '<\/td><td class=\"fcc-price\">' + money(r.total) + '<\/td><\/tr>';\n        }\n        get('fcc-list').innerHTML = '<table class=\"fcc-table\"><thead>' + head + '<\/thead><tbody>' + body + foot + '<\/tbody><\/table>';\n\n        \/\/ notes and warnings\n        var w = [];\n        var hM = c.hFt * FT;\n        if (S.type === 'picket') { if (c.wastePct > 0) w.push(t('w_waste', { n: c.wastePct })); }\n        if (c.hFt > LOC.tallFt + 0.01) w.push(t('w_tall'));\n        if (S.type === 'picket') { if (c.spacingFt > LOC.maxSpacingFt + 0.01) w.push(t('w_spacing')); }\n        if (c.gates > 0) { if (c.gateW > LOC.wideGateFt + 0.01) w.push(t('w_gate')); }\n        if (c.attach > 0) w.push(t(c.attach > 1 ? 'w_attach2' : 'w_attach1'));\n        var shallow = c.depthIn < 23.5;\n        if (shallow) shallow = c.hFt >= 4;\n        if (shallow) w.push(t('w_shallow'));\n        if (get('fcc-pool').checked) {\n            var pool = t('w_pool');\n            var low = LOC.poolMinM ? hM < LOC.poolMinM - 0.005 : false;\n            if (low) pool = t('w_poolLow', { h: nf(LOC.poolMinM, 2) }) + ' ' + pool;\n            var wideGap = S.type === 'picket' ? !c.bob : false;\n            if (wideGap) wideGap = c.gapIn * CM >= LOC.poolGapCm - 0.05;\n            if (wideGap) pool = t('w_poolGap') + ' ' + pool;\n            w.push(pool);\n        }\n        var wb = get('fcc-warn');\n        wb.innerHTML = w.map(function (m) { return '<span>' + m + '<\/span>'; }).join('');\n        wb.classList.toggle('fcc-visible', w.length > 0);\n\n        get('fcc-algebra').textContent = t('algebra', {\n            sp: fLen(c.spacingFt), gates: c.gates ? t('alg_gates') : '', sections: r.sections, segments: r.segments,\n            loop: r.closed ? t('alg_loop') : '+ 1', wall: c.attach ? t(c.attach > 1 ? 'alg_wall2' : 'alg_wall1', { n: c.attach }) : '', posts: r.posts.total\n        });\n\n        get('fcc-result-area').classList.add('fcc-visible');\n        get('fcc-result-area').scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n    };\n\n    \/\/ ---------------------------------------------------------------- reset\n    var resetAll = function () {\n        S.metric = !!LOC.metricOnly; S.type = 'picket'; S.touched = {}; S.pTouched = {}; S.pVals = {};\n        get('fcc-type').value = 'picket';\n        runsEl.innerHTML = '';\n        addRun(S.metric ? (LOC.runDefM || 30) : 100);\n        get('fcc-closed').checked = false;\n        get('fcc-gates').value = '0';\n        get('fcc-gatew').value = S.metric ? (LOC.gateWM || 1.2) : '4';\n        get('fcc-attach').value = '0';\n        get('fcc-height').value = S.metric ? (LOC.hDefM || 1.8) : '6';\n        get('fcc-layout').value = 'spaced';\n        get('fcc-pw').value = S.metric ? '14' : '5.5';\n        get('fcc-gap').value = S.metric ? '1' : '0.5';\n        get('fcc-gap-field').classList.remove('fcc-hide');\n        get('fcc-gravel').checked = true;\n        get('fcc-waste').value = '10';\n        get('fcc-pool').checked = false;\n        get('fcc-cost').checked = true;\n        get('fcc-cost-box').classList.remove('fcc-hide');\n        get('fcc-labor').value = '';\n        get('fcc-postsel').innerHTML = '';\n        get('fcc-bag').innerHTML = '';\n        syncUnitLabels();\n        get('fcc-postsel').value = 's';\n        setTypeDefaults();\n        syncPresets();\n        var err = get('fcc-error-msg');\n        err.classList.remove('fcc-visible');\n        err.textContent = '';\n        get('fcc-warn').classList.remove('fcc-visible');\n        hideResults();\n    };\n\n    get('fcc-calculate-btn').onclick = calc;\n    get('fcc-reset-btn').onclick = function () { resetAll(); var f = get('fcc-run-1'); if (f) f.focus(); };\n    buildPresets();\n    resetAll();\n\n})();<\/script>\n\n\n\n<style>\n  #fence-reference-table { max-width: 860px; margin: 2.5rem auto; font-family: 'Inter', system-ui, sans-serif; color: #2c3e50; scroll-margin-top: 80px; }\n  #fence-reference-table h2 { font-size: 1.5rem; font-weight: 700; color: #17a8b0; margin: 0 0 8px; }\n  #fence-reference-table h3 { font-size: 1.1rem; font-weight: 700; color: #5b4ab8; margin: 28px 0 6px; }\n  #fence-reference-table .fct-subtitle { font-size: 0.9rem; color: #5a6c7d; margin: 0 0 16px; line-height: 1.5; }\n  #fence-reference-table .fct-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid #e0e5eb; border-radius: 14px; box-shadow: 0 4px 16px rgba(0,0,0,0.04); }\n  #fence-reference-table .fct-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; min-width: 520px; }\n  #fence-reference-table .fct-table thead th { background: linear-gradient(135deg, #1ecad3, #9486f7); color: #fff; font-weight: 600; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em; padding: 12px 10px; text-align: center; white-space: nowrap; }\n  #fence-reference-table .fct-table thead th:first-child { border-radius: 13px 0 0 0; text-align: left; }\n  #fence-reference-table .fct-table thead th:last-child { border-radius: 0 13px 0 0; }\n  #fence-reference-table .fct-table tbody td { padding: 10px; border-bottom: 1px solid #eef1f5; vertical-align: middle; text-align: center; }\n  #fence-reference-table .fct-table tbody tr:nth-child(even) { background: #fafcfd; }\n  #fence-reference-table .fct-table tbody tr:hover { background: #e8fafb; }\n  #fence-reference-table .fct-vol { font-weight: 600; color: #2c3e50; white-space: nowrap; text-align: left; }\n  #fence-reference-table .fct-num { font-weight: 700; color: #0f8c94; white-space: nowrap; }\n  #fence-reference-table .fct-acid { font-weight: 600; color: #5b4ab8; white-space: nowrap; }\n  #fence-reference-table .fct-note { margin-top: 12px; font-size: 0.8rem; color: #8899a6; line-height: 1.5; }\n  @media (max-width: 500px) {\n    #fence-reference-table { padding: 0 6px; }\n    #fence-reference-table .fct-table { font-size: 0.78rem; min-width: 460px; }\n    #fence-reference-table .fct-table thead th { padding: 8px 6px; font-size: 0.65rem; }\n    #fence-reference-table .fct-table tbody td { padding: 7px 6px; }\n  }\n<\/style>\n<div id=\"fence-reference-table\">\n  <h2>Fence Materials Chart: Posts, Pickets and Concrete by Fence Length<\/h2>\n  <p class=\"fct-subtitle\">Look up your fence length for a quick count. Every chart uses the same rules as the calculator above, for a straight fence with a post at each end, no gates and no extra for waste. For corners, gates or your own sizes, use the calculator.<\/p>\n\n  <h3>How many posts, rails and pickets for a fence, by length (6 ft wood privacy fence)<\/h3>\n  <div class=\"fct-table-wrap\">\n    <table class=\"fct-table\">\n      <thead><tr><th>Fence Length<\/th><th>Sections<\/th><th>Posts<\/th><th>Rails (2&#215;4, 8 ft)<\/th><th>Pickets (5.5 in)<\/th><th>Concrete (80 lb bags)<\/th><\/tr><\/thead>\n      <tbody>\n        <tr><td class=\"fct-vol\">25 ft<\/td><td class=\"fct-num\">4<\/td><td class=\"fct-num\">5<\/td><td class=\"fct-num\">12<\/td><td class=\"fct-num\">50<\/td><td class=\"fct-acid\">6<\/td><\/tr><tr><td class=\"fct-vol\">50 ft<\/td><td class=\"fct-num\">7<\/td><td class=\"fct-num\">8<\/td><td class=\"fct-num\">21<\/td><td class=\"fct-num\">100<\/td><td class=\"fct-acid\">10<\/td><\/tr><tr><td class=\"fct-vol\">75 ft<\/td><td class=\"fct-num\">10<\/td><td class=\"fct-num\">11<\/td><td class=\"fct-num\">30<\/td><td class=\"fct-num\">150<\/td><td class=\"fct-acid\">13<\/td><\/tr><tr><td class=\"fct-vol\">100 ft<\/td><td class=\"fct-num\">13<\/td><td class=\"fct-num\">14<\/td><td class=\"fct-num\">39<\/td><td class=\"fct-num\">200<\/td><td class=\"fct-acid\">17<\/td><\/tr><tr><td class=\"fct-vol\">125 ft<\/td><td class=\"fct-num\">16<\/td><td class=\"fct-num\">17<\/td><td class=\"fct-num\">48<\/td><td class=\"fct-num\">250<\/td><td class=\"fct-acid\">20<\/td><\/tr><tr><td class=\"fct-vol\">150 ft<\/td><td class=\"fct-num\">19<\/td><td class=\"fct-num\">20<\/td><td class=\"fct-num\">57<\/td><td class=\"fct-num\">300<\/td><td class=\"fct-acid\">24<\/td><\/tr><tr><td class=\"fct-vol\">200 ft<\/td><td class=\"fct-num\">25<\/td><td class=\"fct-num\">26<\/td><td class=\"fct-num\">75<\/td><td class=\"fct-num\">400<\/td><td class=\"fct-acid\">30<\/td><\/tr><tr><td class=\"fct-vol\">250 ft<\/td><td class=\"fct-num\">32<\/td><td class=\"fct-num\">33<\/td><td class=\"fct-num\">96<\/td><td class=\"fct-num\">500<\/td><td class=\"fct-acid\">38<\/td><\/tr><tr><td class=\"fct-vol\">300 ft<\/td><td class=\"fct-num\">38<\/td><td class=\"fct-num\">39<\/td><td class=\"fct-num\">114<\/td><td class=\"fct-num\">600<\/td><td class=\"fct-acid\">45<\/td><\/tr>\n      <\/tbody>\n    <\/table>\n  <\/div>\n  <p class=\"fct-note\">Based on 8 ft post spacing, 3 rails per section, 5.5 in pickets with a 0.5 in gap, and a 10 in hole 24 in deep with a 6 in gravel base. Add about 10% to pickets and rails for cuts.<\/p>\n\n  <h3>How many fence posts do you need for a length of fence, by post spacing<\/h3>\n  <div class=\"fct-table-wrap\">\n    <table class=\"fct-table\">\n      <thead><tr><th>Fence Length<\/th><th>4 ft Spacing<\/th><th>6 ft Spacing<\/th><th>8 ft Spacing<\/th><th>10 ft Spacing<\/th><th>12 ft Spacing<\/th><\/tr><\/thead>\n      <tbody>\n        <tr><td class=\"fct-vol\">20 ft<\/td><td class=\"fct-num\">6<\/td><td class=\"fct-num\">5<\/td><td class=\"fct-num\">4<\/td><td class=\"fct-num\">3<\/td><td class=\"fct-num\">3<\/td><\/tr><tr><td class=\"fct-vol\">25 ft<\/td><td class=\"fct-num\">8<\/td><td class=\"fct-num\">6<\/td><td class=\"fct-num\">5<\/td><td class=\"fct-num\">4<\/td><td class=\"fct-num\">4<\/td><\/tr><tr><td class=\"fct-vol\">30 ft<\/td><td class=\"fct-num\">9<\/td><td class=\"fct-num\">6<\/td><td class=\"fct-num\">5<\/td><td class=\"fct-num\">4<\/td><td class=\"fct-num\">4<\/td><\/tr><tr><td class=\"fct-vol\">40 ft<\/td><td class=\"fct-num\">11<\/td><td class=\"fct-num\">8<\/td><td class=\"fct-num\">6<\/td><td class=\"fct-num\">5<\/td><td class=\"fct-num\">5<\/td><\/tr><tr><td class=\"fct-vol\">50 ft<\/td><td class=\"fct-num\">14<\/td><td class=\"fct-num\">10<\/td><td class=\"fct-num\">8<\/td><td class=\"fct-num\">6<\/td><td class=\"fct-num\">6<\/td><\/tr><tr><td class=\"fct-vol\">75 ft<\/td><td class=\"fct-num\">20<\/td><td class=\"fct-num\">14<\/td><td class=\"fct-num\">11<\/td><td class=\"fct-num\">9<\/td><td class=\"fct-num\">8<\/td><\/tr><tr><td class=\"fct-vol\">100 ft<\/td><td class=\"fct-num\">26<\/td><td class=\"fct-num\">18<\/td><td class=\"fct-num\">14<\/td><td class=\"fct-num\">11<\/td><td class=\"fct-num\">10<\/td><\/tr><tr><td class=\"fct-vol\">150 ft<\/td><td class=\"fct-num\">39<\/td><td class=\"fct-num\">26<\/td><td class=\"fct-num\">20<\/td><td class=\"fct-num\">16<\/td><td class=\"fct-num\">14<\/td><\/tr><tr><td class=\"fct-vol\">200 ft<\/td><td class=\"fct-num\">51<\/td><td class=\"fct-num\">35<\/td><td class=\"fct-num\">26<\/td><td class=\"fct-num\">21<\/td><td class=\"fct-num\">18<\/td><\/tr><tr><td class=\"fct-vol\">250 ft<\/td><td class=\"fct-num\">64<\/td><td class=\"fct-num\">43<\/td><td class=\"fct-num\">33<\/td><td class=\"fct-num\">26<\/td><td class=\"fct-num\">22<\/td><\/tr><tr><td class=\"fct-vol\">300 ft<\/td><td class=\"fct-num\">76<\/td><td class=\"fct-num\">51<\/td><td class=\"fct-num\">39<\/td><td class=\"fct-num\">31<\/td><td class=\"fct-num\">26<\/td><\/tr><tr><td class=\"fct-vol\">500 ft<\/td><td class=\"fct-num\">126<\/td><td class=\"fct-num\">85<\/td><td class=\"fct-num\">64<\/td><td class=\"fct-num\">51<\/td><td class=\"fct-num\">43<\/td><\/tr>\n      <\/tbody>\n    <\/table>\n  <\/div>\n  <p class=\"fct-note\">Posts = fence length divided by spacing, rounded up, plus one. Wood privacy and picket fences use 6 to 8 ft spacing, most vinyl and wood panels are 6 or 8 ft wide, and chain link line posts go every 10 ft.<\/p>\n\n  <h3>How much concrete per fence post: bags by hole size<\/h3>\n  <div class=\"fct-table-wrap\">\n    <table class=\"fct-table\">\n      <thead><tr><th>Post<\/th><th>Hole (diameter x depth)<\/th><th>Concrete (cu ft)<\/th><th>50 lb Bags<\/th><th>60 lb Bags<\/th><th>80 lb Bags<\/th><\/tr><\/thead>\n      <tbody>\n        <tr><td class=\"fct-vol\">4&#215;4 post<\/td><td class=\"fct-num\">8 in x 24 in<\/td><td class=\"fct-num\">0.40<\/td><td class=\"fct-acid\">1.1<\/td><td class=\"fct-acid\">0.9<\/td><td class=\"fct-acid\">0.7<\/td><\/tr><tr><td class=\"fct-vol\">4&#215;4 post<\/td><td class=\"fct-num\">10 in x 24 in<\/td><td class=\"fct-num\">0.69<\/td><td class=\"fct-acid\">1.8<\/td><td class=\"fct-acid\">1.5<\/td><td class=\"fct-acid\">1.2<\/td><\/tr><tr><td class=\"fct-vol\">4&#215;4 post<\/td><td class=\"fct-num\">10 in x 30 in<\/td><td class=\"fct-num\">0.92<\/td><td class=\"fct-acid\">2.5<\/td><td class=\"fct-acid\">2.0<\/td><td class=\"fct-acid\">1.5<\/td><\/tr><tr><td class=\"fct-vol\">4&#215;4 post<\/td><td class=\"fct-num\">12 in x 30 in<\/td><td class=\"fct-num\">1.40<\/td><td class=\"fct-acid\">3.7<\/td><td class=\"fct-acid\">3.1<\/td><td class=\"fct-acid\">2.3<\/td><\/tr><tr><td class=\"fct-vol\">4&#215;4 post<\/td><td class=\"fct-num\">12 in x 36 in<\/td><td class=\"fct-num\">1.75<\/td><td class=\"fct-acid\">4.7<\/td><td class=\"fct-acid\">3.9<\/td><td class=\"fct-acid\">2.9<\/td><\/tr><tr><td class=\"fct-vol\">6&#215;6 post<\/td><td class=\"fct-num\">12 in x 30 in<\/td><td class=\"fct-num\">1.15<\/td><td class=\"fct-acid\">3.1<\/td><td class=\"fct-acid\">2.6<\/td><td class=\"fct-acid\">1.9<\/td><\/tr><tr><td class=\"fct-vol\">6&#215;6 post<\/td><td class=\"fct-num\">12 in x 36 in<\/td><td class=\"fct-num\">1.44<\/td><td class=\"fct-acid\">3.8<\/td><td class=\"fct-acid\">3.2<\/td><td class=\"fct-acid\">2.4<\/td><\/tr><tr><td class=\"fct-vol\">6&#215;6 post<\/td><td class=\"fct-num\">14 in x 36 in<\/td><td class=\"fct-num\">2.15<\/td><td class=\"fct-acid\">5.7<\/td><td class=\"fct-acid\">4.8<\/td><td class=\"fct-acid\">3.6<\/td><\/tr><tr><td class=\"fct-vol\">6&#215;6 post<\/td><td class=\"fct-num\">16 in x 42 in<\/td><td class=\"fct-num\">3.56<\/td><td class=\"fct-acid\">9.5<\/td><td class=\"fct-acid\">7.9<\/td><td class=\"fct-acid\">5.9<\/td><\/tr>\n      <\/tbody>\n    <\/table>\n  <\/div>\n  <p class=\"fct-note\">Bags per post for one hole, with the volume of the post taken out and a 6 in gravel base under it. An 80 lb bag makes about 0.6 cu ft, a 60 lb bag 0.45 cu ft and a 50 lb bag 0.375 cu ft. Round the total up when you buy for the whole fence. Without a gravel base, a 4&#215;4 in a 10 in by 24 in hole takes about 1.5 bags of 80 lb.<\/p>\n\n  <h3>How deep should fence posts be, and how long should they be, by fence height<\/h3>\n  <div class=\"fct-table-wrap\">\n    <table class=\"fct-table\">\n      <thead><tr><th>Fence Height<\/th><th>Hole Depth<\/th><th>Post Length Needed<\/th><th>Standard Post to Buy<\/th><th>Rails per Section<\/th><\/tr><\/thead>\n      <tbody>\n        <tr><td class=\"fct-vol\">3 ft<\/td><td class=\"fct-num\">24 in<\/td><td class=\"fct-num\">5 ft<\/td><td class=\"fct-num\">6 ft<\/td><td class=\"fct-acid\">2<\/td><\/tr><tr><td class=\"fct-vol\">4 ft<\/td><td class=\"fct-num\">24 in<\/td><td class=\"fct-num\">6 ft<\/td><td class=\"fct-num\">6 ft<\/td><td class=\"fct-acid\">2<\/td><\/tr><tr><td class=\"fct-vol\">5 ft<\/td><td class=\"fct-num\">24 in<\/td><td class=\"fct-num\">7 ft<\/td><td class=\"fct-num\">8 ft<\/td><td class=\"fct-acid\">3<\/td><\/tr><tr><td class=\"fct-vol\">6 ft<\/td><td class=\"fct-num\">24 in<\/td><td class=\"fct-num\">8 ft<\/td><td class=\"fct-num\">8 ft<\/td><td class=\"fct-acid\">3<\/td><\/tr><tr><td class=\"fct-vol\">8 ft<\/td><td class=\"fct-num\">36 in<\/td><td class=\"fct-num\">11 ft<\/td><td class=\"fct-num\">12 ft<\/td><td class=\"fct-acid\">4<\/td><\/tr>\n      <\/tbody>\n    <\/table>\n  <\/div>\n  <p class=\"fct-note\">Depth is about one third of the fence height and never under 24 in. Post length is the fence height plus the hole depth. In cold climates set the depth below your local frost line. Standard lengths are the nearest size sold for wood posts.<\/p>\n\n  <h3>Fence cost by length and type (materials only, 6 ft tall)<\/h3>\n  <div class=\"fct-table-wrap\">\n    <table class=\"fct-table\">\n      <thead><tr><th>Fence Length<\/th><th>Wood picket<\/th><th>Wood panel<\/th><th>Vinyl<\/th><th>Aluminum<\/th><th>Chain link<\/th><\/tr><\/thead>\n      <tbody>\n        <tr><td class=\"fct-vol\">50 ft<\/td><td class=\"fct-num\">$726<\/td><td class=\"fct-num\">$856<\/td><td class=\"fct-num\">$1,374<\/td><td class=\"fct-num\">$1,330<\/td><td class=\"fct-num\">$539<\/td><\/tr><tr><td class=\"fct-vol\">100 ft<\/td><td class=\"fct-num\">$1,369<\/td><td class=\"fct-num\">$1,557<\/td><td class=\"fct-num\">$2,491<\/td><td class=\"fct-num\">$2,470<\/td><td class=\"fct-num\">$985<\/td><\/tr><tr><td class=\"fct-vol\">150 ft<\/td><td class=\"fct-num\">$2,013<\/td><td class=\"fct-num\">$2,259<\/td><td class=\"fct-num\">$3,613<\/td><td class=\"fct-num\">$3,611<\/td><td class=\"fct-num\">$1,429<\/td><\/tr><tr><td class=\"fct-vol\">200 ft<\/td><td class=\"fct-num\">$2,655<\/td><td class=\"fct-num\">$2,959<\/td><td class=\"fct-num\">$4,736<\/td><td class=\"fct-num\">$4,900<\/td><td class=\"fct-num\">$1,873<\/td><\/tr><tr><td class=\"fct-vol\">250 ft<\/td><td class=\"fct-num\">$3,339<\/td><td class=\"fct-num\">$3,773<\/td><td class=\"fct-num\">$6,044<\/td><td class=\"fct-num\">$6,041<\/td><td class=\"fct-num\">$2,310<\/td><\/tr><tr><td class=\"fct-vol\">300 ft<\/td><td class=\"fct-num\">$3,988<\/td><td class=\"fct-num\">$4,480<\/td><td class=\"fct-num\">$7,167<\/td><td class=\"fct-num\">$7,176<\/td><td class=\"fct-num\">$2,749<\/td><\/tr>\n      <\/tbody>\n    <\/table>\n  <\/div>\n  <p class=\"fct-note\">Materials only, for a straight fence with no gates, using the default prices in the calculator (typical US store prices, so real prices will differ by region and season). Labor is not included. Enter your own prices in the calculator for a local estimate.<\/p>\n\n  <h3>Fence materials by length for metric fences (1.8 m wood privacy fence)<\/h3>\n  <div class=\"fct-table-wrap\">\n    <table class=\"fct-table\">\n      <thead><tr><th>Fence Length<\/th><th>Sections<\/th><th>Posts<\/th><th>Rails (3 per section)<\/th><th>Pickets (14 cm)<\/th><th>Concrete (25 kg bags)<\/th><\/tr><\/thead>\n      <tbody>\n        <tr><td class=\"fct-vol\">10 m<\/td><td class=\"fct-num\">5<\/td><td class=\"fct-num\">6<\/td><td class=\"fct-num\">15<\/td><td class=\"fct-num\">67<\/td><td class=\"fct-acid\">9<\/td><\/tr><tr><td class=\"fct-vol\">20 m<\/td><td class=\"fct-num\">9<\/td><td class=\"fct-num\">10<\/td><td class=\"fct-num\">27<\/td><td class=\"fct-num\">134<\/td><td class=\"fct-acid\">15<\/td><\/tr><tr><td class=\"fct-vol\">30 m<\/td><td class=\"fct-num\">13<\/td><td class=\"fct-num\">14<\/td><td class=\"fct-num\">39<\/td><td class=\"fct-num\">200<\/td><td class=\"fct-acid\">21<\/td><\/tr><tr><td class=\"fct-vol\">40 m<\/td><td class=\"fct-num\">17<\/td><td class=\"fct-num\">18<\/td><td class=\"fct-num\">51<\/td><td class=\"fct-num\">267<\/td><td class=\"fct-acid\">27<\/td><\/tr><tr><td class=\"fct-vol\">50 m<\/td><td class=\"fct-num\">21<\/td><td class=\"fct-num\">22<\/td><td class=\"fct-num\">63<\/td><td class=\"fct-num\">334<\/td><td class=\"fct-acid\">33<\/td><\/tr><tr><td class=\"fct-vol\">75 m<\/td><td class=\"fct-num\">32<\/td><td class=\"fct-num\">33<\/td><td class=\"fct-num\">96<\/td><td class=\"fct-num\">500<\/td><td class=\"fct-acid\">50<\/td><\/tr><tr><td class=\"fct-vol\">100 m<\/td><td class=\"fct-num\">42<\/td><td class=\"fct-num\">43<\/td><td class=\"fct-num\">126<\/td><td class=\"fct-num\">667<\/td><td class=\"fct-acid\">65<\/td><\/tr>\n      <\/tbody>\n    <\/table>\n  <\/div>\n  <p class=\"fct-note\">Based on 2.4 m post spacing, 100 x 100 mm posts, 14 cm pickets with a 1 cm gap, and a 25 cm hole 60 cm deep with a 15 cm gravel base.<\/p>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">How This Fence Calculator Counts Materials<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>Sections.<\/strong> Each side of the fence is divided by the post spacing and rounded up to whole sections, so a 100 ft side at 8 ft spacing is 12.5, which becomes 13 sections. Gate openings are taken out of the longest sides first.<\/li><li><strong>Posts.<\/strong> A fence that does not close a loop needs one more post than it has sections. A closed loop needs exactly one post per section. Every gate adds two gate posts, and an end fixed to a wall needs no post.<\/li><li><strong>Post length and depth.<\/strong> Hole depth is about one third of the fence height and never under 24 in. Post length is the fence height plus that depth, rounded up to the next standard length.<\/li><li><strong>Pickets and rails.<\/strong> Pickets are the fence length minus the gates, divided by the picket width plus the gap, rounded up. Rails are the rails per section times the sections.<\/li><li><strong>Concrete.<\/strong> Each hole is a cylinder, and the volume of the post is taken out. A gravel base takes the bottom 6 in of the hole, so the concrete fills the rest. Bags are rounded up for the whole fence.<\/li><li><strong>Cost.<\/strong> Every quantity is multiplied by the price you see in the price editor, and labor per foot is added if you enter it.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Fence Calculator FAQs<\/h2>\n\n\n\n<div class=\"schema-faq wp-block-yoast-faq-block\"><div class=\"schema-faq-section\" id=\"faq-question-1790200000000\"><strong class=\"schema-faq-question\">How do corners and fence shape change the number of posts?<\/strong> <p class=\"schema-faq-answer\">Shape matters because every side rounds up to whole sections on its own. A straight 100 ft fence at 8 ft spacing needs 14 posts, but the same 100 ft built as a closed 25 ft by 25 ft square needs 16. Enter each side separately in the calculator, and tick the loop box if the fence comes back to where it started.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1790200017311\"><strong class=\"schema-faq-question\">Do all fence posts need concrete?<\/strong> <p class=\"schema-faq-answer\">Corner, end and gate posts should always be set in concrete because they carry the pull of the fence or the swing of a gate. Line posts in firm, well-drained soil can be set in tamped gravel, but concrete is the safer choice in sandy or soft soil, on tall solid privacy fences that catch the wind, and for vinyl and chain link terminal posts. The calculator prices every post in concrete, so it gives the higher figure.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1790200034622\"><strong class=\"schema-faq-question\">How deep should fence posts be in cold climates?<\/strong> <p class=\"schema-faq-answer\">Set them below the local frost line, which ranges from a few inches in the far south to 4 ft or more in northern states. Frost that grips a shallow post lifts it a little every winter. Enter your frost depth in the hole depth box, and keep the 6 in gravel base so water drains away from the bottom of the post. Your building department can tell you the frost depth.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1790200051933\"><strong class=\"schema-faq-question\">How much does a fence cost per foot?<\/strong> <p class=\"schema-faq-answer\">The calculator shows materials at the prices in the price editor, so enter what your local store charges for posts, pickets or panels and concrete. Add a labor rate per foot if you have a quote. A contractor&#8217;s price can also cover permits, removing an old fence, hauling, and extra work on sloped or rocky ground, which this estimate does not include.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1790200069244\"><strong class=\"schema-faq-question\">What gap should I leave between fence pickets?<\/strong> <p class=\"schema-faq-answer\">For a solid privacy fence leave 1\/4 to 1\/2 in, because wet lumber shrinks as it dries and opens the gaps. A classic spaced picket fence uses a gap of about 1.5 to 3.5 in. For a board-on-board fence, choose that layout in the calculator, which assumes each board overlaps its neighbour by 1 in. A pool barrier must not have openings of 4 in or more.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1790200086555\"><strong class=\"schema-faq-question\">How do I build a fence on a sloped yard?<\/strong> <p class=\"schema-faq-answer\">Measure each side along the ground with a tape, not across the air. Then choose one of two methods. Racking lets the panels follow the slope, and stepping holds each panel level and leaves a wedge gap under the high side. For a steep slope, pick the 15% waste option, and buy posts one length longer for the downhill end because the gap to the ground grows there.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1790200103866\"><strong class=\"schema-faq-question\">What is the difference between line, corner, end and gate posts?<\/strong> <p class=\"schema-faq-answer\">Line posts hold the fence between other posts. Corner and end posts take the pull from the fence on one side, so they need the deepest footing, and on chain link they are heavier terminal posts. Gate posts carry the gate&#8217;s weight and swing. For a gate wider than 4 ft, use a 6&#215;6 or steel post, and set it in extra concrete to stop it from sagging.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1790200121177\"><strong class=\"schema-faq-question\">What are the requirements for a pool fence?<\/strong> <p class=\"schema-faq-answer\">Most codes follow the 2021 International Residential Code and International Swimming Pool and Spa Code. They require a barrier at least 48 in high, with openings smaller than 4 in and a gap under the fence of no more than 2 in, and no toeholds or climbable features. The gate must be self-closing, self-latching and open away from the pool. Some areas require more, so confirm with your local building department. Tick the pool box for a reminder with your result.<\/p> <\/div> <div class=\"schema-faq-section\" id=\"faq-question-1790200138488\"><strong class=\"schema-faq-question\">Do I need a permit, or to call 811, before building a fence?<\/strong> <p class=\"schema-faq-answer\">In the US, call 811 before you dig, at least a few business days ahead in most states. It is free and buried utilities are marked for you. Many towns also require a fence permit and set height limits, and many limit front-yard fences to about 4 ft and back-yard fences to about 6 ft, but the rules vary widely. Check setbacks and your HOA, and confirm your property line before you set posts.<\/p> <\/div><\/div>\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\/paver-calculator\/\" class=\"aiper-tl-tag\">Paver Calculator<\/a>\n<a href=\"https:\/\/aiper.com\/blogs\/decking-calculator\/\" class=\"aiper-tl-tag\">Decking 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>\n\n\n<p class=\"has-text-align-center aiper-last-updated has-small-font-size wp-block-paragraph\"><time datetime=\"2026-09-30\">Last updated: September 30, 2026<\/time><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This fence calculator works out the posts, rails, pickets or panels, concrete and cost for a wood, vinyl, aluminum or chain link fence. Enter each side of your fence, add gates, and get a full shopping list with a price estimate. Pick your fence type and enter the sides. The starting values describe a 100&#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-2908","page","type-page","status-publish","hentry"],"lang":"en","translations":{"en":2908,"es":2915,"de":2910,"fr":2913},"_links":{"self":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/2908","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=2908"}],"version-history":[{"count":11,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/2908\/revisions"}],"predecessor-version":[{"id":11869,"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/pages\/2908\/revisions\/11869"}],"wp:attachment":[{"href":"https:\/\/aiper.com\/blogs\/wp-json\/wp\/v2\/media?parent=2908"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}