{"id":120,"date":"2026-04-27T18:30:03","date_gmt":"2026-04-27T18:30:03","guid":{"rendered":"https:\/\/www.divetalking.com\/oceanseye\/?page_id=120"},"modified":"2026-05-04T22:42:40","modified_gmt":"2026-05-04T22:42:40","slug":"dive-calculator","status":"publish","type":"page","link":"https:\/\/www.divetalking.com\/oceanseye\/dive-calculator\/","title":{"rendered":"Dive Calculator"},"content":{"rendered":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>DTDL Dive Calculator<\/title>\n<style>\n*{box-sizing:border-box;margin:0;padding:0}\n\n\/* \u2500\u2500 DESIGN TOKENS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n:root{\n  --blue:#0369a1;--blue-dk:#0c4a6e;--blue-lt:#e0f2fe;\n  --green:#15803d;--green-lt:#dcfce7;\n  --amber:#b45309;--amber-lt:#fef9c3;\n  --red:#dc2626;--red-lt:#fee2e2;\n  --radius:8px;\n\n  \/* Light theme surfaces *\/\n  --bg-page:#eef4ff;\n  --bg-panel:#ffffff;\n  --bg-panel-hdr:#f1f5f9;\n  --bg-input:#f8fafc;\n  --border-color:#e2e8f0;\n  --text-primary:#1e293b;\n  --text-secondary:#475569;\n  --text-hint:#94a3b8;\n  --text-val:#0c4a6e;\n  --disc-bg:#fffbeb;\n  --disc-border:#fde047;\n  --disc-text:#78350f;\n  --tod-warn-bg:#fef9c3;\n  --tod-warn-border:#fde047;\n  --tod-warn-text:#854d0e;\n  --help-sb-bg:#f8fafc;\n  --help-sb-border:#e2e8f0;\n  --help-h3-border:#f0f0f0;\n  --help-th-bg:#f1f5f9;\n  --help-th-border:#e2e8f0;\n  --help-td-border:#f5f5f5;\n  --help-tip-bg:#f0f9ff;\n  --help-tip-text:#0c4a6e;\n  --help-warn-bg:#fffbeb;\n  --help-warn-text:#78350f;\n  --help-danger-bg:#fef2f2;\n  --help-danger-text:#7f1d1d;\n  --help-example-bg:#f0fdf4;\n  --help-example-border:#86efac;\n  --help-example-text:#14532d;\n  --help-btn2-hover:#f1f5f9;\n  --help-btn2-text:#374151;\n  --gfcard-border:#e2e8f0;\n  --gfcard-text:#475569;\n  --comp-th-bg:#f1f5f9;\n  --comp-td-border:#f0f0f0;\n  --tbl-row-alt:#f8fafc;\n  --modal-bg:#ffffff;\n  --toggle-bg:rgba(255,255,255,.12);\n  --toggle-color:rgba(255,255,255,.85);\n  --toggle-border:rgba(255,255,255,.25);\n}\n\n\/* \u2500\u2500 DARK THEME OVERRIDES \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n[data-theme=\"dark\"]{\n  --bg-page:#0f172a;\n  --bg-panel:#1e293b;\n  --bg-panel-hdr:#0f172a;\n  --bg-input:#0f172a;\n  --border-color:#334155;\n  --text-primary:#cbd5e1;\n  --text-secondary:#64748b;\n  --text-hint:#475569;\n  --text-val:#38bdf8;\n  --disc-bg:#1c1917;\n  --disc-border:#44403c;\n  --disc-text:#a8a29e;\n  --tod-warn-bg:#451a03;\n  --tod-warn-border:#92400e;\n  --tod-warn-text:#fcd34d;\n  --help-sb-bg:#0f172a;\n  --help-sb-border:#334155;\n  --help-h3-border:#1e293b;\n  --help-th-bg:#0f172a;\n  --help-th-border:#334155;\n  --help-td-border:#1e293b;\n  --help-tip-bg:#0c2440;\n  --help-tip-text:#7dd3fc;\n  --help-warn-bg:#451a03;\n  --help-warn-text:#fcd34d;\n  --help-danger-bg:#3b0a0a;\n  --help-danger-text:#fca5a5;\n  --help-example-bg:#052e16;\n  --help-example-border:#166534;\n  --help-example-text:#4ade80;\n  --help-btn2-hover:#1e293b;\n  --help-btn2-text:#94a3b8;\n  --gfcard-border:#334155;\n  --gfcard-text:#94a3b8;\n  --comp-th-bg:#0f172a;\n  --comp-td-border:#1e293b;\n  --tbl-row-alt:#1a2742;\n  --modal-bg:#1e293b;\n  --toggle-bg:rgba(255,255,255,.08);\n  --toggle-color:rgba(255,255,255,.6);\n  --toggle-border:rgba(255,255,255,.15);\n  --green:#4ade80;--green-lt:#052e16;\n  --amber:#fcd34d;--amber-lt:#451a03;\n  --red:#f87171;--red-lt:#3b0a0a;\n  --blue-lt:#164e63;\n  --blue-dk:#38bdf8;\n}\n\n\/* \u2500\u2500 LAYOUT \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\nbody{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;font-size:13px;background:var(--bg-page);color:var(--text-primary);min-height:100vh;transition:background .25s,color .25s}\nheader{background:var(--blue-dk);color:#fff;padding:12px 20px;display:flex;align-items:center;gap:12px}\n[data-theme=\"dark\"] header{background:#020617}\nheader h1{font-size:15px;font-weight:600;flex:1}\nheader .hdr-note{font-size:11px;color:rgba(255,255,255,.45)}\n.help-btn{padding:5px 14px;background:var(--toggle-bg);color:var(--toggle-color);border:1px solid var(--toggle-border);border-radius:5px;font-size:11px;font-weight:600;cursor:pointer}\n.help-btn.active{background:rgba(255,255,255,.9);color:#0c4a6e}\n.theme-btn{padding:5px 14px;background:var(--toggle-bg);color:var(--toggle-color);border:1px solid var(--toggle-border);border-radius:20px;font-size:11px;font-weight:600;cursor:pointer;white-space:nowrap}\n.app{display:grid;grid-template-columns:290px 1fr;gap:12px;padding:12px;max-width:1100px;margin:0 auto}\n.panel{background:var(--bg-panel);border-radius:var(--radius);border:1px solid var(--border-color);overflow:hidden;transition:background .25s,border-color .25s}\n.panel-hdr{background:var(--bg-panel-hdr);border-bottom:1px solid var(--border-color);padding:8px 14px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--text-secondary)}\n.inputs{padding:12px 14px;display:flex;flex-direction:column;gap:10px}\n.field{display:flex;flex-direction:column;gap:3px}\n.field label{font-size:11px;color:var(--text-secondary);font-weight:500}\n.field input,.field select{padding:6px 8px;border:1px solid var(--border-color);border-radius:5px;font-size:12px;font-family:inherit;width:100%;background:var(--bg-input);color:var(--text-primary);transition:background .25s,border-color .25s,color .25s}\n.field input:focus,.field select:focus{outline:none;border-color:var(--blue)}\n.field .hint{font-size:10px;color:var(--text-hint)}\n.row2{display:grid;grid-template-columns:1fr 1fr;gap:8px}\n.grp-label{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--blue);padding:4px 0 2px;border-bottom:1px solid var(--blue-lt);margin-top:4px}\n.algo-grid{display:flex;flex-direction:column;gap:5px}\n.algo-check{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:5px;border:1px solid var(--border-color);cursor:pointer;background:var(--bg-panel)}\n.algo-check input{width:14px;height:14px;accent-color:var(--blue)}\n.algo-check .aname{font-size:12px;font-weight:500;color:var(--text-primary)}\n.algo-check .atag{margin-left:auto;font-size:9px;padding:1px 6px;border-radius:10px;font-weight:600}\n.results-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:8px;padding:12px 14px}\n.rc{border-radius:6px;padding:10px 12px;text-align:center;border:1px solid var(--border-color);background:var(--bg-input)}\n.rc .rl{font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--text-secondary);margin-bottom:4px}\n.rc .rv{font-size:20px;font-weight:600;line-height:1;color:var(--text-val)}\n.rc .ru{font-size:11px;color:var(--text-hint)}\n.rc .rs{font-size:10px;color:var(--text-hint);margin-top:2px}\n.rc.warn{background:var(--amber-lt);border-color:var(--amber)}\n.rc.warn .rv{color:var(--amber)}\n.rc.danger{background:var(--red-lt);border-color:var(--red)}\n.rc.danger .rv{color:var(--red)}\n.rc.ok{background:var(--green-lt);border-color:var(--green)}\n.rc.ok .rv{color:var(--green)}\n.comp-wrap{padding:12px 14px;overflow-x:auto}\ntable.comp{width:100%;border-collapse:collapse;font-size:12px}\ntable.comp th{background:var(--comp-th-bg);padding:7px 10px;text-align:left;font-weight:600;border-bottom:2px solid var(--border-color);white-space:nowrap;color:var(--text-secondary)}\ntable.comp td{padding:7px 10px;border-bottom:1px solid var(--comp-td-border);vertical-align:middle;color:var(--text-primary)}\n.badge{display:inline-block;padding:2px 7px;border-radius:10px;font-size:10px;font-weight:600}\n.bc{background:#fee2e2;color:#991b1b}\n.bm{background:#fef9c3;color:#854d0e}\n.bl{background:#dcfce7;color:#166534}\n[data-theme=\"dark\"] .bc{background:#3b0a0a;color:#fca5a5}\n[data-theme=\"dark\"] .bm{background:#451a03;color:#fcd34d}\n[data-theme=\"dark\"] .bl{background:#052e16;color:#4ade80}\n.nv{font-weight:600;font-size:13px}\n.nok{color:var(--green)}.nwarn{color:var(--amber)}.nzero{color:var(--red)}\n.aname2{font-weight:600;color:var(--text-val)}\n.asub{font-size:10px;color:var(--text-hint)}\n.full-row{grid-column:1\/-1}\n.disc{background:var(--disc-bg);border:1px solid var(--disc-border);border-radius:var(--radius);padding:10px 14px;font-size:11px;color:var(--disc-text);line-height:1.6}\n.tod-warn{display:none;background:var(--tod-warn-bg);border:1px solid var(--tod-warn-border);border-radius:5px;padding:5px 8px;font-size:10px;color:var(--tod-warn-text);margin-top:4px}\n\n\/* \u2500\u2500 HELP MODAL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.help-overlay{display:none;position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,.6)}\n.help-modal{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:780px;max-width:97vw;max-height:90vh;border-radius:12px;overflow:hidden;box-shadow:0 24px 64px rgba(0,0,0,.5);background:var(--modal-bg);display:flex;flex-direction:column;border:1px solid var(--border-color)}\n.help-modal-hdr{background:var(--blue-dk);padding:10px 16px;display:flex;align-items:center;justify-content:space-between;flex-shrink:0}\n[data-theme=\"dark\"] .help-modal-hdr{background:#020617}\n.help-modal-hdr span{font-size:13px;font-weight:600;color:#fff}\n.help-modal-hdr button{background:none;border:none;color:rgba(255,255,255,.7);font-size:20px;cursor:pointer;line-height:1;padding:0}\n.help-body{display:flex;flex:1;overflow:hidden}\n.help-sb{width:210px;flex-shrink:0;background:var(--help-sb-bg);border-right:1px solid var(--help-sb-border);overflow-y:auto;padding:6px 0}\n.help-grp{padding:7px 12px 2px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--text-hint);margin-top:4px}\n.help-btn2{display:block;width:100%;text-align:left;padding:6px 12px 6px 16px;border:none;border-left:3px solid transparent;background:none;cursor:pointer;font-size:11px;color:var(--help-btn2-text);line-height:1.3;font-family:inherit}\n.help-btn2:hover{background:var(--help-btn2-hover);color:var(--blue)}\n.help-btn2.on{background:var(--help-btn2-hover);color:var(--blue);border-left-color:var(--blue);font-weight:600}\n.help-content{flex:1;overflow-y:auto;padding:18px 22px;line-height:1.75;font-size:12px;color:var(--text-primary)}\n.help-content h2{font-size:14px;font-weight:700;color:var(--blue);margin:0 0 8px;padding-bottom:6px;border-bottom:2px solid var(--blue-lt)}\n.help-content h3{font-size:11px;font-weight:700;color:var(--text-primary);margin:16px 0 5px;text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--help-h3-border);padding-bottom:3px}\n.help-content p{margin:0 0 8px;color:var(--text-primary)}\n.help-content ul,.help-content ol{margin:0 0 8px 18px;color:var(--text-primary)}\n.help-content li{margin-bottom:5px;line-height:1.6}\n.help-content table{width:100%;border-collapse:collapse;margin:6px 0 12px;font-size:11px}\n.help-content th{background:var(--help-th-bg);padding:5px 8px;text-align:left;font-weight:600;border-bottom:1px solid var(--help-th-border);color:var(--text-secondary)}\n.help-content td{padding:5px 8px;border-bottom:1px solid var(--help-td-border);vertical-align:top;color:var(--text-primary)}\n.help-content .tip{background:var(--help-tip-bg);border-left:3px solid #38bdf8;padding:8px 12px;border-radius:0 5px 5px 0;margin:10px 0;color:var(--help-tip-text);line-height:1.6}\n.help-content .warn{background:var(--help-warn-bg);border-left:3px solid #f59e0b;padding:8px 12px;border-radius:0 5px 5px 0;margin:10px 0;color:var(--help-warn-text);line-height:1.6}\n.help-content .danger{background:var(--help-danger-bg);border-left:3px solid #dc2626;padding:8px 12px;border-radius:0 5px 5px 0;margin:10px 0;color:var(--help-danger-text);line-height:1.6}\n.help-content .formula{background:#0f172a;color:#38bdf8;padding:8px 12px;border-radius:5px;margin:8px 0;font-family:monospace;font-size:11px;line-height:1.8;white-space:pre-wrap}\n.help-content .example{background:var(--help-example-bg);border:1px solid var(--help-example-border);border-radius:5px;padding:10px 12px;margin:8px 0;color:var(--help-example-text);line-height:1.7}\n.help-content .gfrow{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:8px 0}\n.help-content .gfcard{border-radius:6px;padding:10px;border:1px solid var(--gfcard-border)}\n.help-content .gfcard h4{margin:0 0 4px;font-size:11px;color:var(--text-primary)}\n.help-content .gfcard p{margin:0;font-size:11px;color:var(--gfcard-text)}\n<\/style>\n<\/head>\n<body>\n<header>\n  <h1>&#9881; DTDL Dive Calculator<\/h1>\n  <span class=\"hdr-note\">Educational reference only &mdash; not for dive planning<\/span>\n  <button class=\"theme-btn\" id=\"theme-btn\" onclick=\"calcThemeToggle()\">&#9790; Dark<\/button>\n  <button class=\"help-btn\" id=\"calc-help-btn\" onclick=\"calcHelpToggle()\">? Help<\/button>\n<\/header>\n\n<div class=\"app\">\n\n  <!-- LEFT: INPUTS -->\n  <div class=\"panel\" style=\"grid-row:1\/4\">\n    <div class=\"panel-hdr\">Dive Parameters<\/div>\n    <div class=\"inputs\">\n\n      <div class=\"grp-label\">Depth &amp; Time<\/div>\n      <div class=\"field\">\n        <label>Depth<\/label>\n        <input type=\"number\" id=\"c-depth\" value=\"60\" min=\"0\" max=\"500\">\n      <\/div>\n      <div class=\"field\">\n        <label>Bottom Time (min)<\/label>\n        <input type=\"number\" id=\"c-time\" value=\"45\" min=\"1\" max=\"300\">\n      <\/div>\n      <div class=\"field\">\n        <label>Units<\/label>\n        <select id=\"c-units\">\n          <option value=\"imperial\" selected>Imperial (ft \/ PSI)<\/option>\n          <option value=\"metric\">Metric (m \/ bar)<\/option>\n        <\/select>\n      <\/div>\n\n      <div class=\"grp-label\">Gas Mix<\/div>\n      <div class=\"row2\">\n        <div class=\"field\">\n          <label>O2 %<\/label>\n          <input type=\"number\" id=\"c-o2\" value=\"21\" min=\"16\" max=\"100\">\n        <\/div>\n        <div class=\"field\">\n          <label>He %<\/label>\n          <input type=\"number\" id=\"c-he\" value=\"0\" min=\"0\" max=\"80\">\n        <\/div>\n      <\/div>\n\n      <div class=\"grp-label\">PO2 Planning Limits<\/div>\n      <div class=\"field\">\n        <label>TOD PO2 &mdash; Target Operating Depth<\/label>\n        <input type=\"number\" id=\"c-todpo2\" value=\"1.2\" min=\"0.5\" max=\"2.0\" step=\"0.05\">\n        <span class=\"hint\">Your planned dive depth limit (typically 1.2 bar)<\/span>\n      <\/div>\n      <div class=\"field\">\n        <label>MOD PO2 &mdash; Max Operating Depth<\/label>\n        <input type=\"number\" id=\"c-maxpo2\" value=\"1.4\" min=\"0.5\" max=\"2.0\" step=\"0.05\">\n        <span class=\"hint\">Working limit (1.4 bar standard). Must be >= TOD PO2<\/span>\n      <\/div>\n      <div class=\"field\">\n        <label>Contingency PO2<\/label>\n        <input type=\"number\" id=\"c-contpo2\" value=\"1.6\" min=\"0.5\" max=\"2.0\" step=\"0.05\">\n        <span class=\"hint\">Absolute ceiling (1.6 bar). Emergency reference only.<\/span>\n      <\/div>\n      <div class=\"tod-warn\" id=\"tod-warn\">\n        Warning: TOD PO2 exceeds MOD PO2. TOD should be less than or equal to MOD.\n      <\/div>\n\n      <div class=\"grp-label\">Tank &amp; Consumption<\/div>\n      <div class=\"row2\">\n        <div class=\"field\">\n          <label>Pressure Start<\/label>\n          <input type=\"number\" id=\"c-pstart\" value=\"3000\" min=\"0\">\n        <\/div>\n        <div class=\"field\">\n          <label>Pressure End<\/label>\n          <input type=\"number\" id=\"c-pend\" value=\"1200\" min=\"0\">\n        <\/div>\n      <\/div>\n      <div class=\"row2\">\n        <div class=\"field\">\n          <label>Tank Size (cu ft)<\/label>\n          <input type=\"number\" id=\"c-tanksize\" value=\"80\" min=\"1\">\n        <\/div>\n        <div class=\"field\">\n          <label>Working PSI<\/label>\n          <input type=\"number\" id=\"c-workpsi\" value=\"3000\" min=\"1\">\n        <\/div>\n      <\/div>\n\n      <div class=\"grp-label\">Algorithm Settings<\/div>\n      <div class=\"row2\">\n        <div class=\"field\">\n          <label>GF Low<\/label>\n          <input type=\"number\" id=\"c-gflo\" value=\"40\" min=\"10\" max=\"100\">\n        <\/div>\n        <div class=\"field\">\n          <label>GF High<\/label>\n          <input type=\"number\" id=\"c-gfhi\" value=\"85\" min=\"10\" max=\"100\">\n        <\/div>\n      <\/div>\n      <div class=\"field\">\n        <span class=\"hint\">Gradient Factors apply to Buhlmann ZHL-16C only<\/span>\n      <\/div>\n\n    <\/div>\n  <\/div>\n\n  <!-- RIGHT TOP: RESULTS -->\n  <div class=\"panel\">\n    <div class=\"panel-hdr\">Results<\/div>\n    <div class=\"results-grid\" id=\"results-grid\"><\/div>\n  <\/div>\n\n  <!-- RIGHT MIDDLE: ALGO SELECTION -->\n  <div class=\"panel\">\n    <div class=\"panel-hdr\">Algorithms to Compare<\/div>\n    <div style=\"padding:10px 14px;display:grid;grid-template-columns:repeat(5,1fr);gap:6px;\">\n      <label class=\"algo-check\" style=\"min-width:0\">\n        <input type=\"checkbox\" class=\"algo-cb\" value=\"buhlmann\" checked>\n        <div><div class=\"aname\">Buhlmann ZHL-16C<\/div><div style=\"font-size:9px;color:#94a3b8\">with Gradient Factors<\/div><\/div>\n        <span class=\"atag bm\">Moderate<\/span>\n      <\/label>\n      <label class=\"algo-check\" style=\"min-width:0\">\n        <input type=\"checkbox\" class=\"algo-cb\" value=\"dsat\" checked>\n        <div><div class=\"aname\">DSAT \/ PADI RDP<\/div><div style=\"font-size:9px;color:#94a3b8\">Recreational no-stop<\/div><\/div>\n        <span class=\"atag bl\">Liberal<\/span>\n      <\/label>\n      <label class=\"algo-check\" style=\"min-width:0\">\n        <input type=\"checkbox\" class=\"algo-cb\" value=\"rgbm\" checked>\n        <div><div class=\"aname\">RGBM (Suunto)<\/div><div style=\"font-size:9px;color:#94a3b8\">Bubble model<\/div><\/div>\n        <span class=\"atag bc\">Conservative<\/span>\n      <\/label>\n      <label class=\"algo-check\" style=\"min-width:0\">\n        <input type=\"checkbox\" class=\"algo-cb\" value=\"vpmb\">\n        <div><div class=\"aname\">VPM-B<\/div><div style=\"font-size:9px;color:#94a3b8\">Variable Permeability<\/div><\/div>\n        <span class=\"atag bc\">Conservative<\/span>\n      <\/label>\n      <label class=\"algo-check\" style=\"min-width:0\">\n        <input type=\"checkbox\" class=\"algo-cb\" value=\"dciem\">\n        <div><div class=\"aname\">DCIEM<\/div><div style=\"font-size:9px;color:#94a3b8\">Canadian military<\/div><\/div>\n        <span class=\"atag bc\">Conservative<\/span>\n      <\/label>\n    <\/div>\n  <\/div>\n\n  <!-- RIGHT BOTTOM: COMPARISON -->\n  <div class=\"panel\">\n    <div class=\"panel-hdr\">Algorithm NDL Comparison<\/div>\n    <div class=\"comp-wrap\">\n      <table class=\"comp\">\n        <thead>\n          <tr>\n            <th>Algorithm<\/th>\n            <th>Philosophy<\/th>\n            <th>NDL at Depth<\/th>\n            <th>Conservatism<\/th>\n            <th>Notes<\/th>\n          <\/tr>\n        <\/thead>\n        <tbody id=\"comp-body\"><\/tbody>\n      <\/table>\n    <\/div>\n  <\/div>\n\n  <!-- DISCLAIMER -->\n  <div class=\"disc full-row\">\n    <strong>Important:<\/strong> This calculator is an educational reference tool only.\n    NDL values are simplified approximations and are <strong>not<\/strong> certified for\n    actual dive planning. Always use a certified dive computer. Decompression sickness\n    can occur even within calculated limits.\n  <\/div>\n\n<\/div><!-- .app -->\n\n<!-- HELP OVERLAY -->\n<div class=\"help-overlay\" id=\"help-overlay\" onclick=\"if(event.target===this)calcHelpClose()\">\n  <div class=\"help-modal\">\n    <div class=\"help-modal-hdr\">\n      <span>&#9881; Dive Calculator Help<\/span>\n      <button onclick=\"calcHelpClose()\">&#10005;<\/button>\n    <\/div>\n    <div class=\"help-body\">\n      <div class=\"help-sb\" id=\"help-sb\"><\/div>\n      <div class=\"help-content\" id=\"help-content\"><\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n\/\/ ============================================================\n\/\/ CALCULATOR ENGINE\n\/\/ ============================================================\n\n\/\/ Buhlmann ZHL-16C tissue compartments [half-time-N2, a, b]\nvar ZHL16C = [\n  [4,   1.2599, 0.5050], [5,   1.2195, 0.6514], [8,   1.1747, 0.7222],\n  [12.5,1.1225, 0.7825], [18.5,1.0765, 0.8126], [27,  1.0305, 0.8434],\n  [38.3,0.9895, 0.8693], [54.3,0.9553, 0.8910], [77,  0.9249, 0.9092],\n  [109, 0.8945, 0.9222], [146, 0.8678, 0.9319], [187, 0.8478, 0.9403],\n  [239, 0.8279, 0.9477], [305, 0.8090, 0.9544], [390, 0.7917, 0.9602],\n  [498, 0.7756, 0.9653]\n];\n\n\/\/ DSAT NDL table (depth metres -> NDL minutes)\nvar DSAT_NDL = [\n  {d:10,n:219},{d:12,n:147},{d:14,n:98},{d:16,n:72},\n  {d:18,n:56},{d:20,n:45},{d:22,n:37},{d:25,n:29},\n  {d:30,n:20},{d:35,n:14},{d:40,n:9}\n];\n\n\/\/ DCIEM NDL table (depth metres -> NDL minutes)\nvar DCIEM_NDL = [\n  {d:9,n:200},{d:12,n:100},{d:15,n:60},{d:18,n:50},\n  {d:21,n:40},{d:24,n:30},{d:27,n:25},{d:30,n:20},\n  {d:33,n:15},{d:36,n:12},{d:39,n:10}\n];\n\nfunction getDepthM() {\n  var d = parseFloat(document.getElementById('c-depth').value) || 0;\n  return document.getElementById('c-units').value === 'imperial' ? d * 0.3048 : d;\n}\n\nfunction getPressures() {\n  var u = document.getElementById('c-units').value;\n  var s = parseFloat(document.getElementById('c-pstart').value) || 0;\n  var e = parseFloat(document.getElementById('c-pend').value) || 0;\n  var w = parseFloat(document.getElementById('c-workpsi').value) || 3000;\n  if (u === 'metric') { s *= 14.5038; e *= 14.5038; w *= 14.5038; }\n  return {start:s, end:e, work:w};\n}\n\nfunction depthUnit() {\n  return document.getElementById('c-units').value === 'imperial' ? 'ft' : 'm';\n}\n\nfunction ata(dm) { return 1 + dm \/ 10; }\n\nfunction calcMOD(o2pct, po2limit) {\n  if (o2pct <= 0) return 9999;\n  return ((po2limit \/ (o2pct \/ 100)) - 1) * 10;\n}\n\nfunction calcBestMix(dm, po2limit) {\n  var mix = (po2limit \/ ata(dm)) * 100;\n  return Math.min(100, Math.max(16, mix));\n}\n\nfunction calcCNS(o2pct, dm, tmin) {\n  var po2 = (o2pct \/ 100) * ata(dm);\n  var lims = [\n    {p:1.6,l:45},{p:1.55,l:120},{p:1.5,l:150},{p:1.45,l:180},\n    {p:1.4,l:210},{p:1.35,l:240},{p:1.3,l:270},{p:1.25,l:300},\n    {p:1.2,l:360},{p:1.1,l:450},{p:1.0,l:570},{p:0.9,l:720}\n  ];\n  if (po2 < 0.5) return 0;\n  var lim = 720;\n  for (var i = 0; i < lims.length; i++) {\n    if (po2 >= lims[i].p) { lim = lims[i].l; break; }\n  }\n  return Math.min(100, (tmin \/ lim) * 100);\n}\n\nfunction calcSAC(dm, tmin, pstart, pend, tankft, workpsi) {\n  var used = pstart - pend;\n  var cap  = tankft \/ workpsi;\n  var cuft = used * cap;\n  return cuft \/ (ata(dm) * tmin);\n}\n\nfunction buhlmannNDL(dm, o2pct, hepct, gflo, gfhi) {\n  var n2frac = (100 - o2pct - hepct) \/ 100;\n  var amb    = ata(dm) * 1.01325;\n  var n2pp   = amb * n2frac;\n  var tis    = ZHL16C.map(function() { return 0.7902; });\n  var dt     = 0.1;\n  var ndl    = 0;\n  for (var t = 0; t < 300; t += dt) {\n    tis = tis.map(function(ti, i) {\n      var k = Math.LN2 \/ ZHL16C[i][0];\n      return ti + (n2pp - ti) * (1 - Math.exp(-k * dt));\n    });\n    var ceil = 0;\n    for (var i = 0; i < 16; i++) {\n      var a = ZHL16C[i][1], b = ZHL16C[i][2];\n      var gf = gflo \/ 100;\n      var mv = (a + amb \/ b) * gf + amb * (1 - gf);\n      if (tis[i] > mv) { ceil = 3; break; }\n    }\n    if (ceil > 0) { ndl = Math.round(t); break; }\n    ndl = Math.round(t);\n  }\n  return Math.min(ndl, 300);\n}\n\nfunction tableNDL(tbl, dm) {\n  if (dm < tbl[0].d) return tbl[0].n;\n  if (dm > tbl[tbl.length - 1].d) return 0;\n  for (var i = 0; i < tbl.length - 1; i++) {\n    if (dm >= tbl[i].d && dm <= tbl[i+1].d) {\n      var f = (dm - tbl[i].d) \/ (tbl[i+1].d - tbl[i].d);\n      return Math.max(0, Math.round(tbl[i].n + f * (tbl[i+1].n - tbl[i].n)));\n    }\n  }\n  return 0;\n}\n\nfunction f1(n) { return (isNaN(n) || !isFinite(n)) ? '--' : n.toFixed(1); }\nfunction f0(n) { return (isNaN(n) || !isFinite(n)) ? '--' : Math.round(n); }\n\nfunction cardClass(v, warn, danger) {\n  if (v >= danger) return 'danger';\n  if (v >= warn)   return 'warn';\n  return 'ok';\n}\n\nfunction renderResults() {\n  var dm      = getDepthM();\n  var o2      = parseFloat(document.getElementById('c-o2').value) || 21;\n  var he      = parseFloat(document.getElementById('c-he').value) || 0;\n  var todpo2  = parseFloat(document.getElementById('c-todpo2').value) || 1.2;\n  var maxpo2  = parseFloat(document.getElementById('c-maxpo2').value) || 1.4;\n  var contpo2 = parseFloat(document.getElementById('c-contpo2').value) || 1.6;\n  var tmin    = parseFloat(document.getElementById('c-time').value) || 45;\n  var gflo    = parseFloat(document.getElementById('c-gflo').value) || 40;\n  var gfhi    = parseFloat(document.getElementById('c-gfhi').value) || 85;\n  var prs     = getPressures();\n  var tsize   = parseFloat(document.getElementById('c-tanksize').value) || 80;\n  var units   = document.getElementById('c-units').value;\n\n  var ddsp = units === 'imperial'\n    ? parseFloat(document.getElementById('c-depth').value)\n    : dm;\n\n  \/\/ TOD warning\n  document.getElementById('tod-warn').style.display = todpo2 > maxpo2 ? 'block' : 'none';\n\n  \/\/ Calculations\n  var absBar    = ata(dm);\n  var po2actual = (o2 \/ 100) * absBar;\n\n  var todM    = calcMOD(o2, todpo2);\n  var modM    = calcMOD(o2, maxpo2);\n  var contM   = calcMOD(o2, contpo2);\n  var todDsp  = units === 'imperial' ? todM \/ 0.3048 : todM;\n  var modDsp  = units === 'imperial' ? modM \/ 0.3048 : modM;\n  var contDsp = units === 'imperial' ? contM \/ 0.3048 : contM;\n\n  var bmix    = calcBestMix(dm, maxpo2);\n  var ndlMain = buhlmannNDL(dm, o2, he, gflo, gfhi);\n  var cnsVal  = calcCNS(o2, dm, tmin);\n  var sacVal  = calcSAC(dm, tmin, prs.start, prs.end, tsize, prs.work);\n  var sacOk   = !isNaN(sacVal) && isFinite(sacVal);\n  var rmv     = sacOk ? sacVal * 28.317 : null;\n\n  var tClass = tmin > ndlMain ? 'danger' : tmin > ndlMain * 0.8 ? 'warn' : 'ok';\n  var todCls = ddsp > todDsp && ddsp <= modDsp ? 'warn' : ddsp > contDsp ? 'danger' : '';\n  var modCls = ddsp > modDsp && ddsp <= contDsp ? 'warn' : ddsp > contDsp ? 'danger' : '';\n  var conCls = ddsp > contDsp ? 'danger' : ddsp > modDsp ? 'warn' : '';\n\n  var cards = [\n    {l:'Abs. Pressure', v:f1(absBar),    u:'ATA',       s:'at '+f0(ddsp)+' '+depthUnit(), c:''},\n    {l:'Actual PO2',    v:f1(po2actual), u:'bar',       s:'O2 '+o2+'% at depth',\n     c: po2actual > 1.6 ? 'danger' : po2actual > 1.4 ? 'warn' : 'ok'},\n    {l:'TOD',           v:f0(todDsp),    u:depthUnit(), s:'PO2 '+todpo2+' bar - target',   c:todCls},\n    {l:'MOD',           v:f0(modDsp),    u:depthUnit(), s:'PO2 '+maxpo2+' bar - limit',    c:modCls},\n    {l:'Contingency',   v:f0(contDsp),   u:depthUnit(), s:'PO2 '+contpo2+' bar - ceiling', c:conCls},\n    {l:'Best Mix',      v:f1(bmix),      u:'% O2',      s:'for '+f0(ddsp)+' '+depthUnit(), c:''},\n    {l:'NDL (Buhlmann)',v:ndlMain,       u:'min',       s:'GF '+gflo+'\/'+gfhi,             c:tClass},\n    {l:'CNS O2',        v:f1(cnsVal),    u:'%',         s:tmin+' min at depth',\n     c:cardClass(cnsVal, 75, 100)},\n    {l:'SAC Rate',      v:sacOk ? f1(sacVal) : '--', u:'cu ft\/min', s:'surface equiv.',\n     c:sacOk ? (sacVal > 1.2 ? 'danger' : sacVal > 0.9 ? 'warn' : 'ok') : ''},\n    {l:'RMV',           v:rmv ? f1(rmv) : '--', u:'L\/min', s:'surface equiv.', c:''}\n  ];\n\n  var grid = document.getElementById('results-grid');\n  grid.innerHTML = cards.map(function(c) {\n    return '<div class=\"rc ' + c.c + '\">' +\n      '<div class=\"rl\">' + c.l + '<\/div>' +\n      '<div class=\"rv\">' + c.v + '<\/div>' +\n      '<div class=\"ru\">' + c.u + '<\/div>' +\n      '<div class=\"rs\">' + c.s + '<\/div>' +\n    '<\/div>';\n  }).join('');\n\n  \/\/ Comparison table\n  var sel = [];\n  document.querySelectorAll('.algo-cb:checked').forEach(function(cb) {\n    sel.push(cb.value);\n  });\n\n  var algos = {\n    buhlmann: {\n      name:'Buhlmann ZHL-16C', sub:'GF '+gflo+'\/'+gfhi,\n      phil:'Dissolved gas + Gradient Factors',\n      cons:'<span class=\"badge bm\">Moderate<\/span>',\n      note:'Industry standard for technical diving.',\n      ndl:buhlmannNDL(dm, o2, he, gflo, gfhi)\n    },\n    dsat: {\n      name:'DSAT \/ PADI RDP', sub:'Recreational no-stop',\n      phil:'Haldane dissolved gas, 14 compartments',\n      cons:'<span class=\"badge bl\">Liberal<\/span>',\n      note:'Designed for recreational no-decompression diving.',\n      ndl:tableNDL(DSAT_NDL, dm)\n    },\n    rgbm: {\n      name:'RGBM (Suunto)', sub:'Bubble model',\n      phil:'Reduced gradient bubble mechanics',\n      cons:'<span class=\"badge bc\">Conservative<\/span>',\n      note:'More conservative on repetitive and multi-day diving.',\n      ndl:Math.max(0, Math.round(buhlmannNDL(dm, o2, he, gflo, gfhi) * 0.78))\n    },\n    vpmb: {\n      name:'VPM-B', sub:'Variable Permeability',\n      phil:'Bubble mechanics, deeper first stops',\n      cons:'<span class=\"badge bc\">Conservative<\/span>',\n      note:'Tends toward deeper shorter decompression stops.',\n      ndl:Math.max(0, Math.round(buhlmannNDL(dm, o2, he, 30, 70) * 0.82))\n    },\n    dciem: {\n      name:'DCIEM', sub:'Canadian military',\n      phil:'Empirical dissolved gas model',\n      cons:'<span class=\"badge bc\">Conservative<\/span>',\n      note:'Based on extensive empirical human testing.',\n      ndl:tableNDL(DCIEM_NDL, dm)\n    }\n  };\n\n  var tbody = document.getElementById('comp-body');\n  tbody.innerHTML = sel.map(function(key) {\n    var a   = algos[key];\n    var ndl = a.ndl;\n    var cls = ndl <= 0 ? 'nzero' : ndl < 10 ? 'nwarn' : 'nok';\n    var str = ndl <= 0 ? 'DECO REQ.' : ndl + ' min';\n    var ovr = (tmin > ndl && ndl > 0)\n      ? '<br><span style=\"font-size:10px;color:#dc2626\">Time exceeds NDL by ' + (tmin-ndl) + ' min<\/span>'\n      : '';\n    return '<tr>' +\n      '<td><div class=\"aname2\">' + a.name + '<\/div><div class=\"asub\">' + a.sub + '<\/div><\/td>' +\n      '<td style=\"font-size:11px;color:#475569\">' + a.phil + '<\/td>' +\n      '<td><span class=\"nv ' + cls + '\">' + str + '<\/span>' + ovr + '<\/td>' +\n      '<td>' + a.cons + '<\/td>' +\n      '<td style=\"font-size:11px;color:#475569\">' + a.note + '<\/td>' +\n    '<\/tr>';\n  }).join('');\n}\n\n\/\/ Wire up all inputs\ndocument.querySelectorAll('input, select').forEach(function(el) {\n  el.addEventListener('input', renderResults);\n  el.addEventListener('change', renderResults);\n});\ndocument.querySelectorAll('.algo-cb').forEach(function(cb) {\n  cb.addEventListener('change', renderResults);\n});\n\n\/\/ Run on load\nrenderResults();\n\n\/\/ ============================================================\n\/\/ HELP SYSTEM\n\/\/ ============================================================\n\nvar HELP_TOPICS = {\n  acronyms: {\n    label: 'Acronyms and Terms',\n    group: 'Diving Physics Foundation',\n    html: function() {\n      return '<h2>Acronyms and Terms<\/h2>' +\n        '<p>These acronyms appear throughout this calculator and its help system. They are standard across recreational and technical diving worldwide. Familiarise yourself with them before reading further.<\/p>' +\n        '<table>' +\n        '<tr><th style=\"width:80px\">Acronym<\/th><th>Definition<\/th><\/tr>' +\n        '<tr><td><strong>FO<\/strong><\/td><td>Fraction of Oxygen - the percentage of oxygen in your gas mix, expressed as a decimal. 21% = 0.21, 32% = 0.32<\/td><\/tr>' +\n        '<tr><td><strong>FN<\/strong><\/td><td>Fraction of Nitrogen - the percentage of nitrogen in your gas mix<\/td><\/tr>' +\n        '<tr><td><strong>FHe<\/strong><\/td><td>Fraction of Helium - the percentage of helium in your gas mix (trimix and heliox)<\/td><\/tr>' +\n        '<tr><td><strong>PP<\/strong><\/td><td>Partial Pressure - the pressure contribution of a single gas in a mixture<\/td><\/tr>' +\n        '<tr><td><strong>PPO<\/strong><\/td><td>Partial Pressure of Oxygen - the actual oxygen pressure your body experiences at depth<\/td><\/tr>' +\n        '<tr><td><strong>PPN<\/strong><\/td><td>Partial Pressure of Nitrogen - the actual nitrogen pressure at depth<\/td><\/tr>' +\n        '<tr><td><strong>PPHe<\/strong><\/td><td>Partial Pressure of Helium - the actual helium pressure at depth<\/td><\/tr>' +\n        '<tr><td><strong>TOD<\/strong><\/td><td>Target Operating Depth - the maximum depth you plan to dive to. Your planned limit.<\/td><\/tr>' +\n        '<tr><td><strong>MOD<\/strong><\/td><td>Maximum Operating Depth - the deepest permissible depth for a given gas mix without exceeding safe PPO<\/td><\/tr>' +\n        '<tr><td><strong>PSI<\/strong><\/td><td>Pounds per Square Inch - Imperial unit of pressure<\/td><\/tr>' +\n        '<tr><td><strong>AT<\/strong><\/td><td>Atmosphere - 1 unit of atmospheric pressure at sea level (14.7 PSI)<\/td><\/tr>' +\n        '<tr><td><strong>ATA<\/strong><\/td><td>Atmosphere Absolute - total pressure at depth including both water column and air column<\/td><\/tr>' +\n        '<tr><td><strong>cf<\/strong><\/td><td>Cubic Feet - unit of gas volume (Imperial)<\/td><\/tr>' +\n        '<tr><td><strong>fsw<\/strong><\/td><td>Feet of Sea Water - depth in salt water<\/td><\/tr>' +\n        '<tr><td><strong>ffw<\/strong><\/td><td>Feet of Fresh Water - depth in fresh water (slightly less pressure per foot than sea water)<\/td><\/tr>' +\n        '<tr><td><strong>bar<\/strong><\/td><td>Metric unit of pressure. 1 bar is approximately 1 atmosphere at sea level<\/td><\/tr>' +\n        '<tr><td><strong>~<\/strong><\/td><td>Approximately equal to<\/td><\/tr>' +\n        '<\/table>' +\n        '<div class=\"tip\"><strong>Imperial vs Metric:<\/strong> This calculator defaults to Imperial (feet, PSI). Switch to Metric (metres, bar) using the Units selector. All results recalculate instantly. PPO values and O2 percentages are the same in both systems - they are dimensionless ratios.<\/div>';\n    }\n  },\n\n  boyles: {\n    label: \"Boyle&#39;s Law\",\n    group: 'Diving Physics Foundation',\n    html: function() {\n      return '<h2>Boyle&#39;s Law<\/h2>' +\n        '<p>Boyle&#39;s Law is the single most important piece of physics in diving. It describes what happens to a gas when pressure is applied or removed, at constant temperature.<\/p>' +\n        '<h3>The Rule<\/h3>' +\n        '<ul>' +\n        '<li>As pressure <strong>increases<\/strong> - gas volume <strong>decreases<\/strong> and density <strong>increases<\/strong><\/li>' +\n        '<li>As pressure <strong>decreases<\/strong> - gas volume <strong>increases<\/strong> and density <strong>decreases<\/strong><\/li>' +\n        '<li>As pressure increases, the partial pressure of every gas in the mix increases proportionally<\/li>' +\n        '<li>As pressure decreases, the partial pressure of every gas decreases proportionally<\/li>' +\n        '<\/ul>' +\n        '<h3>What This Means Underwater<\/h3>' +\n        '<p>Every time you descend, the weight of water above you increases the pressure on the gas you are breathing. That pressure compresses the gas - the same number of molecules now occupy a smaller space, making the gas denser. When you inhale at depth, you take in the same physical volume of gas as at the surface, but that volume contains far more molecules packed together under pressure.<\/p>' +\n        '<div class=\"example\"><strong>Practical consequence:<\/strong><br>' +\n        'A tank that lasts 60 minutes at the surface might only last 20 minutes at 66 feet.<br>' +\n        'At 66 feet the pressure is 3 ATA - each breath consumes 3 times as many molecules as the same breath at the surface.<br>' +\n        'The same Boyle&#39;s Law effect is why you must never hold your breath during ascent - expanding gas will rupture lung tissue.<\/div>' +\n        '<h3>Boyle&#39;s Law and Your Dive Computer<\/h3>' +\n        '<p>Every decompression algorithm in this calculator - Buhlmann, DSAT, RGBM, VPM-B, DCIEM - is built on top of Boyle&#39;s Law. The algorithms track how much nitrogen dissolves into your tissues at each depth (where pressure is high and gas is dense) and how it comes back out on ascent (where pressure drops and gas expands). Understanding Boyle&#39;s Law is understanding why decompression exists at all.<\/p>';\n    }\n  },\n\n  charles: {\n    label: \"Charles&#39; Law\",\n    group: 'Diving Physics Foundation',\n    html: function() {\n      return '<h2>Charles&#39; Law<\/h2>' +\n        '<p>Charles&#39; Law adds temperature to Boyle&#39;s Law. It states that at constant pressure, the volume of a gas is directly proportional to its temperature. In plain terms:<\/p>' +\n        '<ul>' +\n        '<li>An <strong>increase<\/strong> in temperature causes gas volume to <strong>increase<\/strong><\/li>' +\n        '<li>A <strong>decrease<\/strong> in temperature causes gas volume to <strong>decrease<\/strong><\/li>' +\n        '<\/ul>' +\n        '<h3>Why We Set It Aside for Dive Planning<\/h3>' +\n        '<p>Temperature does affect gas behaviour in diving - a tank filled in the hot sun will show a higher pressure gauge reading than the same tank cooled in the water. However, the effect of water pressure (Boyle&#39;s Law) is far larger and more immediate than the effect of temperature change during a typical dive. For this reason, dive tables and most dive computers use Boyle&#39;s Law and treat temperature as constant for decompression calculations.<\/p>' +\n        '<h3>Where Charles&#39; Law Does Affect Divers<\/h3>' +\n        '<ul>' +\n        '<li><strong>Tank filling:<\/strong> Tanks are typically filled at ambient temperature. If a tank is filled warm and then cools in the water, the pressure reading will drop slightly - the gas contracts as it cools.<\/li>' +\n        '<li><strong>Cold water diving:<\/strong> Breathing cold dense gas increases breathing effort and affects gas consumption rates.<\/li>' +\n        '<li><strong>Drysuit inflation:<\/strong> Air in a drysuit expands as you ascend (Boyle&#39;s Law) and also expands if you enter warmer water (Charles&#39; Law).<\/li>' +\n        '<\/ul>' +\n        '<div class=\"tip\">For all practical dive planning and the calculations in this calculator, Boyle&#39;s Law governs. Charles&#39; Law is noted here for completeness and because it explains some real-world behaviours divers observe with their equipment.<\/div>';\n    }\n  },\n\n  ata: {\n    label: 'Atmosphere Absolute (ATA)',\n    group: 'Diving Physics Foundation',\n    html: function() {\n      return '<h2>Atmosphere Absolute (ATA)<\/h2>' +\n        '<h3>What Is ATA?<\/h3>' +\n        '<p>ATA stands for Atmospheres Absolute - the total pressure acting on you at any depth. It counts two things together:<\/p>' +\n        '<ul>' +\n        '<li>The pressure from the column of water above you (increases with every foot of depth)<\/li>' +\n        '<li>The pressure from the atmosphere of air above the ocean surface (always 1 atmosphere = 14.7 PSI at sea level)<\/li>' +\n        '<\/ul>' +\n        '<p>The word Absolute means we are counting everything. At the surface you are at 1.0 ATA - just air, no water above you. Every 33 feet of sea water adds exactly 1 more atmosphere of pressure.<\/p>' +\n        '<h3>The Formula<\/h3>' +\n        '<div class=\"formula\">ATA = ( Depth in feet \/ 33 ) + 1<br><br>The \/33 converts feet of sea water to atmospheres of water pressure.<br>The +1 adds the 1 atmosphere of air always present above the surface.<\/div>' +\n        '<h3>Worked Examples<\/h3>' +\n        '<table>' +\n        '<tr><th>Depth<\/th><th>Calculation<\/th><th>ATA<\/th><th>What It Means<\/th><\/tr>' +\n        '<tr><td>Surface (0 ft)<\/td><td>(0\/33)+1<\/td><td>1.0<\/td><td>Air pressure only<\/td><\/tr>' +\n        '<tr><td>33 ft<\/td><td>(33\/33)+1<\/td><td>2.0<\/td><td>Pressure doubled. Gas is twice as dense.<\/td><\/tr>' +\n        '<tr><td>66 ft<\/td><td>(66\/33)+1<\/td><td>3.0<\/td><td>Three times surface pressure.<\/td><\/tr>' +\n        '<tr><td>99 ft<\/td><td>(99\/33)+1<\/td><td>4.0<\/td><td>Four times. Each breath takes 4x the gas.<\/td><\/tr>' +\n        '<tr><td>100 ft<\/td><td>(100\/33)+1<\/td><td>4.03<\/td><td>The calculator shows this in the Abs. Pressure card.<\/td><\/tr>' +\n        '<tr><td>132 ft<\/td><td>(132\/33)+1<\/td><td>5.0<\/td><td>Five atmospheres. Oxygen toxicity becomes a serious concern.<\/td><\/tr>' +\n        '<\/table>' +\n        '<h3>Calculating PSI at Depth<\/h3>' +\n        '<div class=\"formula\">PSI at depth = ( ( Depth \/ 33 ) + 1 ) x 14.7<br>Or: PSI at depth = ( Depth x 0.445 ) + 14.7<br><br>Example at 46 feet:<br>( (46\/33) + 1 ) x 14.7 = 2.39 x 14.7 = 35.13 PSI<\/div>' +\n        '<div class=\"tip\">The calculator uses the metric equivalent internally: ATA = 1 + (depth in metres \/ 10). For example 30 metres = 1 + (30\/10) = 4.0 ATA - identical to the Imperial formula. The Abs. Pressure result card shows this value for your entered depth.<\/div>';\n    }\n  },\n\n  ppo: {\n    label: 'Partial Pressure of Oxygen (PPO)',\n    group: 'Diving Physics Foundation',\n    html: function() {\n      return '<h2>Partial Pressure of Oxygen (PPO)<\/h2>' +\n        '<h3>What Is PPO?<\/h3>' +\n        '<p>The air you breathe is a mixture of gases - 21% oxygen and 79% nitrogen. At the surface, each gas exerts its own share of the total pressure. Oxygen contributes 21% of 14.7 PSI = about 3.1 PSI. That is its partial pressure at the surface.<\/p>' +\n        '<p>As you descend and total pressure increases (Boyle&#39;s Law), the partial pressure of every gas increases proportionally. The percentage of oxygen in your tank does not change - but the pressure each oxygen molecule exerts on your body increases with every foot of depth.<\/p>' +\n        '<h3>The Formula<\/h3>' +\n        '<div class=\"formula\">PPO = ATA x FO<br><br>Where FO is the Fraction of Oxygen (O2% as a decimal)<br>21% oxygen = FO of 0.21<br>32% oxygen = FO of 0.32<\/div>' +\n        '<h3>PPO of Air (21% O2) at Various Depths<\/h3>' +\n        '<table>' +\n        '<tr><th>Depth<\/th><th>ATA<\/th><th>Calculation<\/th><th>PPO<\/th><th>Equivalent O2 %<\/th><\/tr>' +\n        '<tr><td>Surface<\/td><td>1.0<\/td><td>1.0 x 0.21<\/td><td>0.21<\/td><td>21% - normal<\/td><\/tr>' +\n        '<tr><td>33 ft<\/td><td>2.0<\/td><td>2.0 x 0.21<\/td><td>0.42<\/td><td>42% equivalent<\/td><\/tr>' +\n        '<tr><td>66 ft<\/td><td>3.0<\/td><td>3.0 x 0.21<\/td><td>0.63<\/td><td>63% equivalent<\/td><\/tr>' +\n        '<tr><td>99 ft<\/td><td>4.0<\/td><td>4.0 x 0.21<\/td><td>0.84<\/td><td>84% equivalent<\/td><\/tr>' +\n        '<tr><td>132 ft<\/td><td>5.0<\/td><td>5.0 x 0.21<\/td><td>1.05<\/td><td>105% - exceeds 100%!<\/td><\/tr>' +\n        '<\/table>' +\n        '<h3>Why Does PPO Matter?<\/h3>' +\n        '<p>Too much oxygen under pressure becomes toxic to the central nervous system (CNS). This is called CNS oxygen toxicity. Symptoms can include vision disturbances, ringing in the ears, nausea, muscle twitching, and in severe cases convulsions underwater with little or no warning.<\/p>' +\n        '<div class=\"warn\"><strong>PPO limits:<\/strong><br>' +\n        'Working limit: PPO must not exceed <strong>1.4<\/strong> during normal diving (PADI standard).<br>' +\n        'Contingency: <strong>1.6<\/strong> is the absolute maximum - brief exposure only.<br>' +\n        'The Actual PO2 result card turns AMBER above 1.4 and RED above 1.6.<\/div>' +\n        '<h3>How an Open Circuit Diver Controls PPO<\/h3>' +\n        '<p>Two controls only:<\/p>' +\n        '<ul>' +\n        '<li><strong>O2 percentage in the tank<\/strong> - set at fill time. Higher O2 % raises PPO at any given depth.<\/li>' +\n        '<li><strong>Depth<\/strong> - deeper means higher PPO. Ascending reduces PPO. Rising in the water column is how an open circuit diver immediately reduces oxygen exposure.<\/li>' +\n        '<\/ul>' +\n        '<p>This is why enriched air nitrox has a shallower MOD than air - the higher oxygen fraction reaches the PPO limit at a shallower depth. More bottom time, but a stricter depth ceiling.<\/p>';\n    }\n  },\n\n  depthformulas: {\n    label: 'TOD, MOD and Depth Limit Formulas',\n    group: 'Diving Physics Foundation',\n    html: function() {\n      return '<h2>TOD, MOD and Depth Limit Formulas<\/h2>' +\n        '<p>Now that you understand ATA and PPO, you can calculate the three depth limits for any gas mix. These are the numbers you need to know before every dive.<\/p>' +\n        '<h3>The Three Limits<\/h3>' +\n        '<ul>' +\n        '<li><strong>TOD<\/strong> - Target Operating Depth. The depth you plan to dive to. Set at PPO 1.2 - comfortable, conservative, with room to spare. Brief your buddy on this number.<\/li>' +\n        '<li><strong>MOD<\/strong> - Maximum Operating Depth. The hard boundary you must not cross. Set at PPO 1.4. This is not a target - it is a limit.<\/li>' +\n        '<li><strong>Contingency<\/strong> - The absolute physiological ceiling. Set at PPO 1.6. Emergency reference only - not a planning depth.<\/li>' +\n        '<\/ul>' +\n        '<h3>The Formula<\/h3>' +\n        '<div class=\"formula\">Depth (feet) = ( ( PPO_limit \/ FO ) - 1 ) x 33<br><br>TOD:         PPO_limit = 1.2<br>MOD:         PPO_limit = 1.4<br>Contingency: PPO_limit = 1.6<br><br>In metric (metres): Depth = ( ( PPO_limit \/ FO ) - 1 ) x 10<\/div>' +\n        '<h3>Complete Example - EAN32 (32% Oxygen, FO = 0.32)<\/h3>' +\n        '<div class=\"example\"><strong>EAN32 - the three depths you must know before diving:<\/strong><br><br>' +\n        'TOD at PPO 1.2: ( (1.2\/0.32) - 1 ) x 33 = (3.75-1) x 33 = 2.75 x 33 = 90 feet<br>' +\n        'Brief your buddy: we are going to 90 feet on EAN32.<br><br>' +\n        'MOD at PPO 1.4: ( (1.4\/0.32) - 1 ) x 33 = (4.375-1) x 33 = 3.375 x 33 = 111 feet<br>' +\n        'Hard limit. If you find yourself at 111 feet on EAN32 - ascend immediately.<br><br>' +\n        'Contingency at PPO 1.6: ( (1.6\/0.32) - 1 ) x 33 = (5.0-1) x 33 = 4.0 x 33 = 132 feet<br>' +\n        'Absolute physiological ceiling. Below this on EAN32 is an oxygen emergency.<\/div>' +\n        '<h3>Common Gas Mixes - Quick Reference<\/h3>' +\n        '<table>' +\n        '<tr><th>Gas Mix<\/th><th>TOD (PPO 1.2)<\/th><th>MOD (PPO 1.4)<\/th><th>Contingency (PPO 1.6)<\/th><th>N2 %<\/th><\/tr>' +\n        '<tr><td>Air (21%)<\/td><td>134 ft<\/td><td>185 ft<\/td><td>224 ft<\/td><td>79%<\/td><\/tr>' +\n        '<tr><td>EAN28<\/td><td>109 ft<\/td><td>132 ft<\/td><td>157 ft<\/td><td>72%<\/td><\/tr>' +\n        '<tr><td>EAN32<\/td><td>90 ft<\/td><td>111 ft<\/td><td>132 ft<\/td><td>68%<\/td><\/tr>' +\n        '<tr><td>EAN36<\/td><td>77 ft<\/td><td>95 ft<\/td><td>114 ft<\/td><td>64%<\/td><\/tr>' +\n        '<tr><td>EAN40<\/td><td>66 ft<\/td><td>82 ft<\/td><td>99 ft<\/td><td>60%<\/td><\/tr>' +\n        '<\/table>' +\n        '<h3>Verifying PPO at Any Depth<\/h3>' +\n        '<p>Always verify using the forward formula: PPO = ATA x FO<\/p>' +\n        '<div class=\"formula\">Check EAN32 at 111 feet:<br>ATA = (111\/33) + 1 = 3.36 + 1 = 4.36<br>PPO = 4.36 x 0.32 = 1.40 - confirms MOD is correct<\/div>' +\n        '<div class=\"warn\"><strong>Know these numbers BEFORE you enter the water.<\/strong> Calculate TOD, MOD, and Contingency at the surface during your pre-dive briefing. Brief your buddy. Mark your MOD depth on your SPG slate or set a depth alarm on your dive computer. The calculator shows all three automatically in the Results panel once you enter your O2 percentage.<\/div>';\n    }\n  },\n\n  overview: {\n    label: 'Overview',\n    group: 'Getting Started',\n    html: function() { return '<h2>Overview<\/h2><p>The DTDL Dive Calculator computes key dive planning values in real time as you change inputs. Fill in the left panel and all results update instantly.<\/p><h3>What It Calculates<\/h3><ul><li><strong>Absolute Pressure (ATA)<\/strong> - how pressure multiplies at depth<\/li><li><strong>Actual PO2<\/strong> - your oxygen exposure at depth<\/li><li><strong>TOD \/ MOD \/ Contingency<\/strong> - three layered depth limits from your gas mix<\/li><li><strong>Best Mix<\/strong> - optimal nitrox blend for your planned depth<\/li><li><strong>NDL<\/strong> - no-decompression limit from five algorithms side by side<\/li><li><strong>CNS O2 %<\/strong> - oxygen toxicity exposure<\/li><li><strong>SAC Rate and RMV<\/strong> - gas consumption efficiency<\/li><\/ul><div class=\"tip\">Set your Units first to match your dive computer, then enter depth and gas mix. Results appear immediately.<\/div>'; }\n  },\n  units: {\n    label: 'Units',\n    group: 'Getting Started',\n    html: function() { return '<h2>Units<\/h2><p>Select Imperial (ft \/ PSI) or Metric (m \/ bar) from the Units dropdown. All depth, pressure, and volume fields update to match.<\/p><h3>What Converts<\/h3><table><tr><th>Field<\/th><th>Imperial<\/th><th>Metric<\/th><\/tr><tr><td>Depth<\/td><td>feet<\/td><td>metres<\/td><\/tr><tr><td>Pressure<\/td><td>PSI<\/td><td>bar<\/td><\/tr><tr><td>SAC rate<\/td><td>cu ft\/min<\/td><td>L\/min<\/td><\/tr><\/table><p>PO2 values, O2 %, He %, and algorithm settings are the same in both unit systems.<\/p>'; }\n  },\n  depth: {\n    label: 'Depth and Bottom Time',\n    group: 'Input Fields',\n    html: function() { return '<h2>Depth and Bottom Time<\/h2><h3>Depth<\/h3><p>Enter the maximum depth you plan to reach. This drives absolute pressure, which drives every other calculation. At 30m (99ft) the pressure is 4 ATA - every litre of nitrogen dissolves four times faster than at the surface.<\/p><h3>Bottom Time<\/h3><p>Enter the total dive time in minutes from descent to beginning of ascent. Used for CNS oxygen tracking and for comparing against the NDL results. When your entered time approaches or exceeds an algorithm NDL, that result card changes colour.<\/p>'; }\n  },\n  gas: {\n    label: 'Gas Mix - O2, He, N2',\n    group: 'Input Fields',\n    html: function() { return '<h2>Gas Mix<\/h2><h3>O2 %<\/h3><p>Oxygen percentage of your breathing gas. Air is 21%. EAN32 nitrox is 32%. Higher O2 means less nitrogen, which gives longer NDLs at recreational depths - but also a shallower MOD due to oxygen toxicity risk.<\/p><div class=\"example\"><strong>Nitrox advantage example:<\/strong><br>Air 21% at 60ft: NDL approximately 51 min<br>EAN32 at 60ft: NDL approximately 88 min<br>That is 37 extra minutes on the same dive.<\/div><h3>He %<\/h3><p>Helium percentage for trimix or heliox. Reduces narcosis and modifies decompression. Leave at 0 for all recreational and nitrox diving.<\/p>'; }\n  },\n  tod: {\n    label: 'TOD, MOD and Contingency',\n    group: 'Input Fields',\n    html: function() {\n      return '<h2>TOD, MOD and Contingency - In the Calculator<\/h2>' +\n        '<p>For the complete explanation of what TOD, MOD, and Contingency mean, how the formulas work, and a full table of depth limits for common gas mixes, see <strong>TOD, MOD and Depth Limit Formulas<\/strong> in the Diving Physics Foundation section at the top of the sidebar.<\/p>' +\n        '<h3>How the Calculator Uses These Three Limits<\/h3>' +\n        '<p>Set your three PO2 values in the left panel under PO2 Planning Limits. The calculator instantly shows the corresponding depth for each limit based on your O2 percentage.<\/p>' +\n        '<ul>' +\n        '<li><strong>TOD PO2<\/strong> (default 1.2) - your planned dive depth. The number you brief your buddy on.<\/li>' +\n        '<li><strong>MOD PO2<\/strong> (default 1.4) - the working limit. Must be greater than or equal to TOD PO2.<\/li>' +\n        '<li><strong>Contingency PO2<\/strong> (default 1.6) - the absolute physiological ceiling. Emergency reference only.<\/li>' +\n        '<\/ul>' +\n        '<h3>Result Card Colours<\/h3>' +\n        '<ul>' +\n        '<li><strong>TOD card amber<\/strong> - your entered depth is between TOD and MOD. Deeper than your target. Consider ascending.<\/li>' +\n        '<li><strong>MOD card amber<\/strong> - your entered depth is between MOD and Contingency. At the working limit. Ascend.<\/li>' +\n        '<li><strong>Contingency card red<\/strong> - your entered depth exceeds the absolute oxygen ceiling. Emergency.<\/li>' +\n        '<\/ul>' +\n        '<div class=\"warn\">If you set TOD PO2 higher than MOD PO2 the calculator shows a warning. TOD must always be less than or equal to MOD PO2 - your target depth cannot exceed your maximum operating limit.<\/div>'; }\n  },\n  tank: {\n    label: 'Tank and Consumption',\n    group: 'Input Fields',\n    html: function() { return '<h2>Tank and Consumption<\/h2><h3>Pressure Start and End<\/h3><p>Enter tank pressure when you entered the water and when you surfaced. Used only for SAC and RMV calculation. Has no effect on NDL or depth limits.<\/p><h3>Tank Size<\/h3><p>Rated volume in cubic feet. Common sizes: AL80=80, AL63=63, HP100=100, HP120=120.<\/p><h3>Working PSI<\/h3><p>The rated working pressure of your cylinder. Standard aluminium AL80 is 3000 PSI. Steel HP tanks are typically 3440-3500 PSI.<\/p><div class=\"formula\">Water capacity (cu ft per PSI) = Tank Size \/ Working PSI\\nAL80 example: 80 \/ 3000 = 0.0267 cu ft per PSI<\/div>'; }\n  },\n  gf: {\n    label: 'Gradient Factors GF Lo \/ GF Hi',\n    group: 'Input Fields',\n    html: function() { return '<h2>Gradient Factors - The Most Misunderstood Setting in Diving<\/h2><p>Gradient Factors are a way of making Buhlmann ZHL-16C more conservative. They express how close to the theoretical tissue nitrogen limit (M-value) you are allowed to approach.<\/p><h3>The Problem They Solve<\/h3><p>The raw Buhlmann algorithm calculates the maximum dissolved nitrogen your tissues can hold at any pressure - the M-value. Diving right to the M-value leaves zero safety margin. Gradient Factors say: use only a fraction of the M-value. That fraction is the Gradient Factor.<\/p><h3>GF High - Controls the Surface<\/h3><p>GF High controls how close to the M-value you are allowed to approach at the shallowest stop and surface. GF Hi 85 means tissues reach only 85% of the theoretical limit when you surface.<\/p><div class=\"gfrow\"><div class=\"gfcard\" style=\"background:#f0fdf4;border-color:#86efac\"><h4 style=\"color:#166534\">GF Hi 70 - Conservative<\/h4><p>Surfaces at 70% of M-value. Longer ascent. Best for cold, dehydration, repetitive days.<\/p><\/div><div class=\"gfcard\" style=\"background:#fef9c3;border-color:#fde047\"><h4 style=\"color:#854d0e\">GF Hi 85 - Moderate<\/h4><p>Industry standard. Reasonable margin. Good default for most technical diving.<\/p><\/div><div class=\"gfcard\" style=\"background:#fff7ed;border-color:#fed7aa\"><h4 style=\"color:#9a3412\">GF Hi 95 - Liberal<\/h4><p>Very close to the M-value. Only for ideal conditions, well rested and hydrated.<\/p><\/div><div class=\"gfcard\" style=\"background:#fef2f2;border-color:#fca5a5\"><h4 style=\"color:#7f1d1d\">GF Hi 100 - No Buffer<\/h4><p>Pure Buhlmann, no safety margin. Not recommended for actual diving.<\/p><\/div><\/div><h3>GF Low - Controls the First Stop<\/h3><p>GF Low controls how close to the M-value you approach at the deepest decompression stop. Lower GF Lo means a deeper first stop and more conservative early ascent.<\/p><h3>Reading a GF Setting: GF 40\/85<\/h3><p>GF Lo 40 means the first deco stop allows only 40% of M-value. GF Hi 85 means the surface allows 85%. The ascent ramps linearly between them.<\/p><div class=\"example\"><strong>Concrete example at 40m, 25 min, air:<\/strong><br>GF 40\/85: First stop at 21m, ~18 min total deco, surfaces at 85% M-value. Conservative.<br>GF 80\/90: First stop at 6m, ~6 min total deco, surfaces at 90% M-value. Aggressive.<br>12 minutes difference. Over a 5-day trip that conservatism compounds significantly.<\/div><h3>Common Real-World GF Settings<\/h3><table><tr><th>Setting<\/th><th>Conservatism<\/th><th>Used for<\/th><\/tr><tr><td>GF 20\/70<\/td><td>Very conservative<\/td><td>Cave diving, cold water, extreme depths<\/td><\/tr><tr><td>GF 30\/70<\/td><td>Conservative<\/td><td>Technical diving, repetitive deep dives<\/td><\/tr><tr><td>GF 40\/85<\/td><td>Moderate<\/td><td>General technical diving default. Shearwater factory setting.<\/td><\/tr><tr><td>GF 55\/80<\/td><td>Moderate<\/td><td>Popular balance. Ratio Computers default.<\/td><\/tr><tr><td>GF 80\/90<\/td><td>Liberal<\/td><td>Recreational only, shallow, ideal conditions<\/td><\/tr><tr><td>GF 100\/100<\/td><td>None<\/td><td>Pure Buhlmann. Research and comparison only.<\/td><\/tr><\/table><div class=\"tip\">If you are new to GF settings, start with GF 40\/85. It is the most widely accepted moderate default used by instructors and manufacturers. When in doubt, be more conservative - it costs minutes; DCS costs much more.<\/div>'; }\n  },\n  results: {\n    label: 'Reading the Results',\n    group: 'Results Explained',\n    html: function() { return '<h2>Reading the Results<\/h2><p>Each result card shows a value, its unit, and a subtitle. Cards change colour based on safety status:<\/p><table><tr><th>Colour<\/th><th>Meaning<\/th><\/tr><tr><td style=\"background:#dcfce7;color:#166534;font-weight:600\">Green<\/td><td>Within safe limits<\/td><\/tr><tr><td style=\"background:#fef9c3;color:#854d0e;font-weight:600\">Amber<\/td><td>Approaching a limit - be aware<\/td><\/tr><tr><td style=\"background:#fee2e2;color:#991b1b;font-weight:600\">Red<\/td><td>Limit exceeded - do not proceed<\/td><\/tr><\/table><h3>Specific Thresholds<\/h3><ul><li><strong>Actual PO2<\/strong> - green below 1.4, amber 1.4 to 1.6, red above 1.6<\/li><li><strong>TOD<\/strong> - amber when depth is between TOD and MOD<\/li><li><strong>MOD<\/strong> - amber when depth is between MOD and Contingency<\/li><li><strong>Contingency<\/strong> - red when depth exceeds the contingency ceiling<\/li><li><strong>NDL<\/strong> - amber when bottom time is within 20% of NDL, red when exceeded<\/li><li><strong>CNS O2<\/strong> - amber above 75%, red at 100%<\/li><\/ul>'; }\n  },\n  sac: {\n    label: 'SAC Rate and RMV',\n    group: 'Results Explained',\n    html: function() { return '<h2>SAC Rate and RMV<\/h2><h3>Why Raw Pressure Drop Does Not Compare Fairly<\/h3><p>At 30m the pressure is 4 ATA. Every breath draws 4x more gas from the tank than the same breath at the surface. To compare consumption across dives at different depths you must correct for pressure. SAC and RMV do this correction.<\/p><h3>SAC - Surface Air Consumption<\/h3><p>How much gas you would have consumed per minute if diving at the surface. Expressed in cu ft\/min (imperial) or L\/min (metric).<\/p><div class=\"formula\">Gas used (cu ft) = Pressure Used x (Tank Size \/ Working PSI)\\nSAC = Gas Used \/ (ATA x Bottom Time)\\n\\nExample: AL80, start 3000, end 1200, 60ft, 45min\\nGas used: 1800 x (80\/3000) = 48 cu ft\\nATA at 60ft: 1 + (18\/10) = 2.8\\nSAC: 48 \/ (2.8 x 45) = 0.38 cu ft\/min - excellent<\/div><h3>RMV - Respiratory Minute Volume<\/h3><p>The actual volume your lungs move per minute at surface pressure, in L\/min. This is what your Shearwater computer reports. Typical values: under 10 L\/min excellent, 10-16 good, 16-20 fair, over 20 needs improvement.<\/p>'; }\n  },\n  buhlmann: {\n    label: 'Buhlmann ZHL-16C',\n    group: 'The Algorithms',\n    html: function() { return '<h2>Buhlmann ZHL-16C Algorithm<\/h2><p>Developed by Dr. Albert Buhlmann at the University of Zurich. The most widely used decompression algorithm in the world. Used by Shearwater, Ratio, Apeks, ScubaPro, Deepblu, and most technical dive computers.<\/p><h3>How It Works<\/h3><p>The algorithm models 16 hypothetical tissue compartments with different nitrogen half-times (the time to reach half saturation). Each compartment has an M-value - the maximum nitrogen partial pressure the algorithm considers safe before a stop is required.<\/p><table><tr><th>Compartment<\/th><th>Half-time<\/th><th>Represents<\/th><\/tr><tr><td>1<\/td><td>4 min<\/td><td>Fast - blood, CNS<\/td><\/tr><tr><td>8<\/td><td>54 min<\/td><td>Medium - most recreational dives governed here<\/td><\/tr><tr><td>16<\/td><td>498 min<\/td><td>Slowest - fat, bone, relevant for multi-day diving<\/td><\/tr><\/table><p>Gradient Factors reduce the allowed M-value fraction, adding a safety buffer. See the GF Lo\/Hi topic for a complete explanation.<\/p>'; }\n  },\n  mvalue: {\n    label: 'M-Value Explained',\n    group: 'The Algorithms',\n    html: function() { return '<h2>M-Value - The Maximum Value<\/h2>' +\n      '<p>M-Value stands for Maximum Value. It is the maximum partial pressure of dissolved nitrogen that a specific tissue compartment can tolerate at a given ambient pressure without a decompression stop being required. Every tissue compartment in the Buhlmann model has its own M-value, and every M-value changes with depth.<\/p>' +\n      '<h3>Where M-Values Come From<\/h3>' +\n      '<p>Dr. Buhlmann derived M-values empirically from decades of experimental diving data combined with mathematical modeling. Each of the 16 tissue compartments has two coefficients - called <strong>a<\/strong> and <strong>b<\/strong> - that define a straight line relationship between ambient pressure and the maximum tolerable tissue nitrogen pressure at that ambient pressure.<\/p>' +\n      '<div class=\"formula\">M-value at any depth = a + (ambient pressure \/ b)<br><br>Example - Compartment 5 (half-time 18.5 min), a=1.0765, b=0.8126:<br>&nbsp;&nbsp;At surface (1 bar ambient): M = 1.0765 + (1.0 \/ 0.8126) = 2.307 bar N2<br>&nbsp;&nbsp;At 10m (2 bar ambient):     M = 1.0765 + (2.0 \/ 0.8126) = 3.538 bar N2<br>&nbsp;&nbsp;At 30m (4 bar ambient):     M = 1.0765 + (4.0 \/ 0.8126) = 6.000 bar N2<\/div>' +\n      '<h3>What M-Value Means Practically<\/h3>' +\n      '<p>Think of M-value as the gas station that is about to overflow. Your tissue compartment is a tank filling with dissolved nitrogen. The M-value is how full the tank can get before bubbles form and the decompression sickness risk becomes unacceptable. As long as the dissolved nitrogen in every compartment stays below its M-value at the current depth, the algorithm says you can continue ascending.<\/p>' +\n      '<h3>Why M-Values Increase With Depth<\/h3>' +\n      '<p>This is counterintuitive but important. At 30m the M-value is higher than at 10m. This is because at 30m the ambient pressure is also higher, which actually suppresses bubble formation. The same dissolved nitrogen that would cause bubbles at the surface can be held safely in solution at depth because the surrounding pressure keeps it dissolved. As you ascend and ambient pressure drops, your tissues must off-gas nitrogen fast enough to stay below the M-value at each shallower depth.<\/p>' +\n      '<h3>The Critical Moment - Surfacing<\/h3>' +\n      '<p>The most dangerous transition is the final ascent from the safety stop to the surface. Ambient pressure drops from about 1.5 bar (at 5m) to 1.0 bar (surface) - a 33% pressure reduction in the last few metres. The M-value at the surface is the lowest of all - the tissues must have off-gassed enough nitrogen to stay below it at 1.0 bar ambient. This is why GF High is so important - it controls exactly how close to the surface M-value you are allowed to get.<\/p>' +\n      '<h3>M-Value vs Gradient Factor<\/h3>' +\n      '<table><tr><th>Concept<\/th><th>What It Is<\/th><th>Who Sets It<\/th><\/tr>' +\n      '<tr><td>M-value<\/td><td>The theoretical maximum - the hard limit from Buhlmann research<\/td><td>Fixed by algorithm - you cannot change it<\/td><\/tr>' +\n      '<tr><td>Gradient Factor<\/td><td>The fraction of the M-value you are actually allowed to use<\/td><td>Set by the diver on their computer<\/td><\/tr><\/table>' +\n      '<p>GF 100 means diving right to the M-value - the theoretical limit with no buffer. GF 85 means stopping at 85% of the M-value - a 15% safety margin. GF 40 at the first stop means starting the ascent at only 40% of the deep M-value - very conservative.<\/p>' +\n      '<h3>Which Compartment Controls the Stop<\/h3>' +\n      '<p>At any given moment during your ascent, the compartment closest to its M-value is the <strong>controlling compartment<\/strong>. This changes as you ascend. During the first minutes of ascent, faster compartments (low half-times like 4-8 minutes) are usually well under their M-value. Slower compartments (longer half-times like 77-187 minutes) that accumulated nitrogen throughout the dive are typically the controlling compartments during decompression stops.<\/p>' +\n      '<div class=\"tip\">Understanding M-values helps you understand why decompression algorithms behave as they do. A diver who ascends too fast does not violate a rule - they violate physics. They allow tissue nitrogen to exceed its M-value, and supersaturated gas comes out of solution as bubbles. That is decompression sickness.<\/div>'; }\n  },\n  dsat: {\n    label: 'DSAT \/ PADI RDP',\n    group: 'The Algorithms',\n    html: function() { return '<h2>DSAT \/ PADI RDP Algorithm<\/h2><p>Developed by Diving Science and Technology for PADI in the late 1980s. A Haldane dissolved-gas model with 14 tissue compartments, designed specifically for recreational no-decompression diving.<\/p><p>DSAT is the most permissive (liberal) algorithm in this calculator. It consistently shows the longest NDLs and smallest safety margins. Many technical divers consider it too permissive for repetitive or multi-day diving.<\/p><p>In this calculator the DSAT NDL is computed by table interpolation from the published PADI RDP no-stop times.<\/p>'; }\n  },\n  rgbm: {\n    label: 'RGBM (Suunto)',\n    group: 'The Algorithms',\n    html: function() { return '<h2>RGBM - Reduced Gradient Bubble Model<\/h2><p>Developed by Dr. Bruce Wienke. Used primarily by Suunto dive computers. A hybrid model combining dissolved gas theory with bubble mechanics.<\/p><p>RGBM is particularly conservative on repetitive dives, multi-day diving, and short surface intervals - because it tracks the cumulative bubble load from previous dives. A Suunto diver who did three dives yesterday will have a shorter NDL today than someone using Buhlmann with the same surface interval.<\/p><p>In this calculator RGBM is modeled as Buhlmann NDL x 0.78, reflecting the algorithm\\'s typical conservatism relative to Buhlmann at recreational depths.<\/p>'; }\n  },\n  vpmb: {\n    label: 'VPM-B',\n    group: 'The Algorithms',\n    html: function() { return '<h2>VPM-B - Variable Permeability Model<\/h2><p>Developed by David Yount at the University of Hawaii. A pure bubble mechanics model that tracks the radii of gas micronuclei in tissues rather than dissolved nitrogen concentration.<\/p><p>VPM-B typically produces a deeper first decompression stop and shorter shallow stops compared to Buhlmann - based on the theory that bubble formation is best minimized early in the ascent.<\/p><p>In this calculator VPM-B is modeled as Buhlmann (GF 30\/70) x 0.82, reflecting the algorithm\\'s conservative tendency at recreational depths.<\/p>'; }\n  },\n  dciem: {\n    label: 'DCIEM',\n    group: 'The Algorithms',\n    html: function() { return '<h2>DCIEM - Defence and Civil Institute of Environmental Medicine<\/h2><p>A Canadian military decompression model developed through extensive empirical testing on human subjects rather than pure mathematical modeling. Thousands of actual chamber and open-water dives validated the tables.<\/p><p>DCIEM is notably conservative, especially at shallower depths, and applies significant penalties for repetitive diving. Reflects the military requirement that decompression sickness be avoided even when evacuation and treatment are not immediately available.<\/p><p>In this calculator DCIEM NDL is computed by interpolation from the published Canadian DCIEM dive tables.<\/p>'; }\n  },\n  comparing: {\n    label: 'Comparing Algorithms',\n    group: 'The Algorithms',\n    html: function() { return '<h2>Comparing Algorithms<\/h2><p>Check or uncheck algorithms in the left panel. The comparison table updates instantly showing each algorithm\\'s NDL at your entered depth and gas mix side by side.<\/p><div class=\"example\"><strong>Air at 60ft \/ 18m, GF 40\/85:<\/strong><br>DSAT\/PADI: 56 min (most liberal)<br>Buhlmann GF 40\/85: 51 min (moderate)<br>RGBM: 40 min (conservative)<br>VPM-B: 42 min (conservative)<br>DCIEM: 50 min (conservative)<br><br>The 16-minute spread between most liberal and most conservative matters for dive planning. A diver whose computer uses DSAT gets 56 minutes; a Suunto RGBM diver gets 40.<\/div><p>Always follow the algorithm in your actual dive computer. Use this calculator to understand why the numbers differ, not to override your computer\\'s limits.<\/p>'; }\n  },\n  safety: {\n    label: 'Limitations and Safety',\n    group: 'Safety',\n    html: function() { return '<h2>Limitations and Safety<\/h2><div class=\"danger\">This calculator is an educational reference tool. It is NOT certified for dive planning and must NOT be used as a substitute for a calibrated dive computer.<\/div><h3>Why These Values Are Approximations<\/h3><ul><li><strong>Square profile<\/strong> - assumes constant depth for the entire bottom time. Real dives vary.<\/li><li><strong>Single dive<\/strong> - assumes fully off-gassed tissues. After any prior dive your NDL will be shorter.<\/li><li><strong>No altitude correction<\/strong> - assumes sea-level diving.<\/li><li><strong>Simplified RGBM and VPM-B<\/strong> - these use multipliers on Buhlmann for comparison. Real manufacturer implementations are full mathematical models.<\/li><\/ul><h3>DCS Can Occur Within Limits<\/h3><p>Decompression sickness can and does occur in divers who stayed within computer limits. No algorithm guarantees immunity. Factors increasing risk: dehydration, alcohol, strenuous exercise, obesity, PFO, cold water, rapid ascent.<\/p><h3>Always<\/h3><ul><li>Dive with a calibrated dive computer programmed with a recognised algorithm<\/li><li>Ascend no faster than 9m \/ 30ft per minute<\/li><li>Always perform a 3-5 minute safety stop at 5m \/ 15ft<\/li><li>Never dive beyond your training and certification level<\/li><li>Contact DAN immediately if you experience any post-dive symptoms<\/li><\/ul>'; }\n  }\n};\n\nvar HELP_GROUPS = ['Diving Physics Foundation','Getting Started','Input Fields','Results Explained','The Algorithms','Safety'];\n\nfunction buildHelpSidebar() {\n  var sb = document.getElementById('help-sb');\n  var html = '';\n  HELP_GROUPS.forEach(function(grp) {\n    html += '<div class=\"help-grp\">' + grp + '<\/div>';\n    Object.keys(HELP_TOPICS).forEach(function(key) {\n      var t = HELP_TOPICS[key];\n      if (t.group === grp) {\n        html += '<button class=\"help-btn2\" data-key=\"' + key + '\" onclick=\"showHelp(\\'' + key + '\\')\">' + t.label + '<\/button>';\n      }\n    });\n  });\n  sb.innerHTML = html;\n}\n\nfunction showHelp(key) {\n  var t = HELP_TOPICS[key];\n  if (!t) return;\n  document.getElementById('help-content').innerHTML = t.html();\n  document.getElementById('help-content').scrollTop = 0;\n  document.querySelectorAll('.help-btn2').forEach(function(b) {\n    b.classList.toggle('on', b.getAttribute('data-key') === key);\n  });\n}\n\nfunction calcHelpToggle() {\n  var ov  = document.getElementById('help-overlay');\n  var btn = document.getElementById('calc-help-btn');\n  var open = ov.style.display !== 'none' && ov.style.display !== '';\n  if (open) {\n    calcHelpClose();\n  } else {\n    buildHelpSidebar();\n    showHelp('overview');\n    ov.style.display = 'block';\n    btn.classList.add('active');\n  }\n}\n\nfunction calcHelpClose() {\n  document.getElementById('help-overlay').style.display = 'none';\n  document.getElementById('calc-help-btn').classList.remove('active');\n}\n\nfunction calcThemeToggle() {\n  var html = document.documentElement;\n  var btn  = document.getElementById('theme-btn');\n  if (html.getAttribute('data-theme') === 'dark') {\n    html.removeAttribute('data-theme');\n    btn.innerHTML = '&#9790; Dark';\n    try { localStorage.setItem('dtdl-calc-theme', 'light'); } catch(e) {}\n  } else {\n    html.setAttribute('data-theme', 'dark');\n    btn.innerHTML = '&#9728; Light';\n    try { localStorage.setItem('dtdl-calc-theme', 'dark'); } catch(e) {}\n  }\n}\n\n(function() {\n  try {\n    if (localStorage.getItem('dtdl-calc-theme') === 'dark') {\n      document.documentElement.setAttribute('data-theme', 'dark');\n      document.addEventListener('DOMContentLoaded', function() {\n        var btn = document.getElementById('theme-btn');\n        if (btn) btn.innerHTML = '&#9728; Light';\n      });\n    }\n  } catch(e) {}\n})();\n<\/script>\n<\/body>\n<\/html>\n\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-120","page","type-page","status-publish"],"_links":{"self":[{"href":"https:\/\/www.divetalking.com\/oceanseye\/wp-json\/wp\/v2\/pages\/120","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.divetalking.com\/oceanseye\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.divetalking.com\/oceanseye\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.divetalking.com\/oceanseye\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.divetalking.com\/oceanseye\/wp-json\/wp\/v2\/comments?post=120"}],"version-history":[{"count":5,"href":"https:\/\/www.divetalking.com\/oceanseye\/wp-json\/wp\/v2\/pages\/120\/revisions"}],"predecessor-version":[{"id":126,"href":"https:\/\/www.divetalking.com\/oceanseye\/wp-json\/wp\/v2\/pages\/120\/revisions\/126"}],"wp:attachment":[{"href":"https:\/\/www.divetalking.com\/oceanseye\/wp-json\/wp\/v2\/media?parent=120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}