{"id":4181,"date":"2026-05-14T16:35:14","date_gmt":"2026-05-14T16:35:14","guid":{"rendered":"https:\/\/primetoolhub.com\/?page_id=4181"},"modified":"2026-08-08T11:30:45","modified_gmt":"2026-08-08T11:30:45","slug":"free-recipe-nutrition-calculator","status":"publish","type":"page","link":"https:\/\/schoolict.net\/tools\/free-recipe-nutrition-calculator\/","title":{"rendered":"Free Recipe Nutrition Calculator (Auto-Scale &amp; Convert)"},"content":{"rendered":"<div class=\"pth-hero-section\">\n<div class=\"pth-hero-content\">\n<h2><b data-path-to-node=\"1,1,0\" data-index-in-node=\"0\">Smart Recipe Calculator<\/b> | Instant Nutrition Breakdown, Food Costing &amp; Automatic Unit Conversion<\/h2>\n<p>Easily analyze your meals with our free recipe nutrition calculator. Auto-scale servings, track macros (protein, carbs, fat), and calculate recipe costs instantly in your browser.<\/p>\n<div id=\"pth-toc-placeholder\">\u00a0<\/div>\n<\/div>\n<div class=\"pth-hero-image\"><img decoding=\"async\" src=\"https:\/\/schoolict.net\/tools\/wp-content\/uploads\/2026\/05\/Recipe-Nutrition-Calculator-800x447.jpeg\" alt=\"Recipe Nutrition Calculator\" width=\"450\" height=\"253\" data-no-lazy=\"1\" \/><\/div>\n<\/div>\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li><a href=\"#\ud83d\udd34-what-you-can-work-out-with-it\">\ud83d\udd34\u00a0What you can work out with it<\/a><\/li><li><a href=\"#\ud83d\udfe1-from-ingredient-list-to-cost-and-nutrition\">\ud83d\udfe1\u00a0From ingredient list to cost and nutrition<\/a><\/li><li><a href=\"#\ud83d\udfe2-making-the-numbers-accurate\">\ud83d\udfe2\u00a0Making the numbers accurate<\/a><\/li><\/ul><\/nav><\/div>\n\n\n<!-- ================================================================\r\n  RECIPE NUTRITION & COST STUDIO v8.0  (PrimeToolHub #58)\r\n  Slug: free-recipe-nutrition-calculator\r\n  100% offline, self-contained (built-in ingredient database, no external fetch).\r\n  Scoped to #pth-recipecalc-wrap. Woody HTML snippet - HTML + Vanilla JS (ES5) + scoped CSS.\r\n  Meal-planning intentionally NOT included (that is tool #57) - cross-linked instead (rule E5).\r\n================================================================= -->\r\n\r\n<style>\r\n#pth-recipecalc-wrap *, #pth-recipecalc-wrap *::before, #pth-recipecalc-wrap *::after { box-sizing: border-box; min-width: 0; }\r\n#pth-recipecalc-wrap { font-family: 'Inter', system-ui, -apple-system, \"Segoe UI\", sans-serif; color: #1e293b; font-weight: 500; line-height: 1.6; max-width: 1480px; margin: 0 auto; padding: 0 20px; }\r\n#pth-recipecalc-wrap .pth-rc-topbar { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; padding: 16px 22px; margin-bottom: 16px; }\r\n#pth-recipecalc-wrap .pth-rc-brand { display: flex; align-items: center; gap: 14px; }\r\n#pth-recipecalc-wrap .pth-rc-icon { width: 46px; height: 46px; border-radius: 11px; background: #ea580c; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 24px; flex: 0 0 auto; }\r\n#pth-recipecalc-wrap .pth-rc-title { font-size: 1.4rem; font-weight: 800; color: #0f172a; margin: 0; }\r\n#pth-recipecalc-wrap .pth-rc-sub { font-size: 0.8rem; color: #334155; font-weight: 600; margin: 2px 0 0; }\r\n#pth-recipecalc-wrap .pth-rc-badges { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }\r\n#pth-recipecalc-wrap .pth-rc-badge { font-size: 0.72rem; font-weight: 800; padding: 5px 11px; border-radius: 20px; border: 1px solid #e2e8f0; color: #334155; background: #f8fafc; }\r\n#pth-recipecalc-wrap .pth-rc-badge.off { color: #047857; border-color: #a7f3d0; background: #ecfdf5; }\r\n#pth-recipecalc-wrap .pth-rc-badge.ver { color: #c2410c; border-color: #fed7aa; background: #fff7ed; }\r\n\r\n#pth-recipecalc-wrap .pth-rc-tabs { display: flex; gap: 6px; background: #f1f5f9; border: 1px solid #e2e8f0; border-radius: 12px; padding: 5px; margin-bottom: 18px; flex-wrap: wrap; }\r\n#pth-recipecalc-wrap .pth-rc-tab { flex: 1 1 auto; min-width: 130px; padding: 11px 14px; border: none; cursor: pointer; border-radius: 8px; background: transparent; color: #334155; font-family: inherit; font-size: 0.9rem; font-weight: 700; }\r\n#pth-recipecalc-wrap .pth-rc-tab:hover { color: #0f172a; }\r\n#pth-recipecalc-wrap .pth-rc-tab.active { background: #ea580c; color: #fff; }\r\n\r\n#pth-recipecalc-wrap .pth-rc-panel { display: none; }\r\n#pth-recipecalc-wrap .pth-rc-panel.active { display: block; }\r\n#pth-recipecalc-wrap .pth-rc-layout { display: grid; grid-template-columns: 1.7fr 1fr; gap: 18px; align-items: start; }\r\n#pth-recipecalc-wrap.full .pth-rc-layout { grid-template-columns: 1fr; }\r\n#pth-recipecalc-wrap .pth-rc-card { background: #fff; border: 1px solid #e2e8f0; border-radius: 14px; padding: 20px; margin-bottom: 16px; }\r\n#pth-recipecalc-wrap .pth-rc-ctitle { font-size: 0.72rem; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; color: #c2410c; margin: 0 0 14px; }\r\n\r\n#pth-recipecalc-wrap .pth-rc-meta { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 10px; margin-bottom: 14px; }\r\n#pth-recipecalc-wrap .pth-rc-fg { display: flex; flex-direction: column; gap: 5px; }\r\n#pth-recipecalc-wrap .pth-rc-label { font-size: 0.72rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px; color: #334155; }\r\n#pth-recipecalc-wrap .pth-rc-input, #pth-recipecalc-wrap .pth-rc-select { width: 100%; border: 1px solid #e2e8f0; border-radius: 8px; padding: 9px 11px; background: #f8fafc; font-family: inherit; font-size: 0.88rem; font-weight: 600; color: #1e293b; outline: none; }\r\n#pth-recipecalc-wrap .pth-rc-input:focus, #pth-recipecalc-wrap .pth-rc-select:focus { border-color: #ea580c; background: #fff; }\r\n\r\n#pth-recipecalc-wrap .pth-rc-ing-head, #pth-recipecalc-wrap .pth-rc-ing { display: grid; grid-template-columns: 2fr 0.9fr 0.9fr 1fr auto; gap: 8px; align-items: center; }\r\n#pth-recipecalc-wrap .pth-rc-ing-head { font-size: 0.68rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.5px; color: #64748b; padding: 0 4px 6px; }\r\n#pth-recipecalc-wrap .pth-rc-ing { padding: 6px 4px; border-bottom: 1px solid #f1f5f9; }\r\n#pth-recipecalc-wrap .pth-rc-ing .nm { font-size: 0.88rem; font-weight: 700; color: #0f172a; }\r\n#pth-recipecalc-wrap .pth-rc-ing input { width: 100%; border: 1px solid #e2e8f0; border-radius: 6px; padding: 6px 8px; font-family: inherit; font-size: 0.84rem; }\r\n#pth-recipecalc-wrap .pth-rc-ing select { width: 100%; border: 1px solid #e2e8f0; border-radius: 6px; padding: 6px 4px; font-family: inherit; font-size: 0.8rem; background: #fff; }\r\n#pth-recipecalc-wrap .pth-rc-x { cursor: pointer; border: none; background: transparent; color: #dc2626; font-weight: 800; font-size: 1rem; padding: 2px 6px; }\r\n\r\n#pth-recipecalc-wrap .pth-rc-btn { display: inline-flex; align-items: center; gap: 7px; padding: 10px 16px; border-radius: 8px; border: 1px solid transparent; font-family: inherit; font-size: 0.88rem; font-weight: 700; cursor: pointer; }\r\n#pth-recipecalc-wrap .pth-rc-btn:disabled { opacity: 0.5; cursor: not-allowed; }\r\n#pth-recipecalc-wrap .pth-rc-btn.sm { padding: 7px 12px; font-size: 0.8rem; }\r\n#pth-recipecalc-wrap .pth-rc-primary { background: #ea580c; color: #fff; }\r\n#pth-recipecalc-wrap .pth-rc-primary:hover:not(:disabled) { background: #c2410c; }\r\n#pth-recipecalc-wrap .pth-rc-blue { background: #2563eb; color: #fff; }\r\n#pth-recipecalc-wrap .pth-rc-blue:hover:not(:disabled) { background: #1d4ed8; }\r\n#pth-recipecalc-wrap .pth-rc-green { background: #059669; color: #fff; }\r\n#pth-recipecalc-wrap .pth-rc-green:hover:not(:disabled) { filter: brightness(0.94); }\r\n#pth-recipecalc-wrap .pth-rc-ghost { background: #f8fafc; color: #334155; border-color: #e2e8f0; }\r\n#pth-recipecalc-wrap .pth-rc-ghost:hover:not(:disabled) { background: #f1f5f9; color: #0f172a; }\r\n#pth-recipecalc-wrap .pth-rc-danger { background: #fef2f2; color: #991b1b; border-color: #fecaca; }\r\n#pth-recipecalc-wrap .pth-rc-danger:hover:not(:disabled) { background: #fee2e2; }\r\n#pth-recipecalc-wrap .pth-rc-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }\r\n\r\n#pth-recipecalc-wrap .pth-rc-summary { border: 1px solid #e2e8f0; border-radius: 10px; background: #f8fafc; padding: 16px; }\r\n#pth-recipecalc-wrap .pth-rc-row { display: flex; justify-content: space-between; align-items: baseline; padding: 7px 0; border-bottom: 1px dashed #e2e8f0; }\r\n#pth-recipecalc-wrap .pth-rc-row:last-child { border-bottom: none; }\r\n#pth-recipecalc-wrap .pth-rc-row span { font-size: 0.84rem; font-weight: 700; color: #334155; }\r\n#pth-recipecalc-wrap .pth-rc-row b { font-size: 1rem; font-weight: 800; color: #0f172a; }\r\n#pth-recipecalc-wrap .pth-rc-row b.big { font-size: 1.5rem; color: #c2410c; }\r\n#pth-recipecalc-wrap .pth-rc-cost b.big { color: #047857; }\r\n#pth-recipecalc-wrap .pth-rc-hint { font-size: 0.78rem; color: #64748b; margin-top: 10px; }\r\n\r\n\/* nutrition label *\/\r\n#pth-recipecalc-wrap .pth-rc-label-box { border: 2px solid #0f172a; border-radius: 6px; background: #fff; padding: 12px 14px; max-width: 320px; font-family: 'Inter', system-ui, sans-serif; color: #0f172a; }\r\n#pth-recipecalc-wrap .pth-rc-label-box .lt { font-size: 1.5rem; font-weight: 900; letter-spacing: -0.5px; border-bottom: 8px solid #0f172a; padding-bottom: 2px; margin: 0; }\r\n#pth-recipecalc-wrap .pth-rc-label-box .sv { font-size: 0.8rem; display: flex; justify-content: space-between; border-bottom: 1px solid #0f172a; padding: 3px 0; }\r\n#pth-recipecalc-wrap .pth-rc-label-box .cal { display: flex; justify-content: space-between; align-items: flex-end; border-bottom: 4px solid #0f172a; padding: 2px 0; }\r\n#pth-recipecalc-wrap .pth-rc-label-box .cal .l { font-size: 0.95rem; font-weight: 900; }\r\n#pth-recipecalc-wrap .pth-rc-label-box .cal .v { font-size: 1.6rem; font-weight: 900; }\r\n#pth-recipecalc-wrap .pth-rc-label-box .dvh { text-align: right; font-size: 0.68rem; font-weight: 700; border-bottom: 1px solid #0f172a; padding: 2px 0; }\r\n#pth-recipecalc-wrap .pth-rc-label-box .lr { display: flex; justify-content: space-between; font-size: 0.8rem; border-bottom: 1px solid #cbd5e1; padding: 3px 0; }\r\n#pth-recipecalc-wrap .pth-rc-label-box .lr .n { font-weight: 400; }\r\n#pth-recipecalc-wrap .pth-rc-label-box .lr b { font-weight: 800; }\r\n#pth-recipecalc-wrap .pth-rc-label-box .foot { font-size: 0.62rem; color: #475569; margin-top: 6px; line-height: 1.3; }\r\n\r\n#pth-recipecalc-wrap .pth-rc-side-title { font-size: 0.95rem; font-weight: 800; color: #0f172a; margin: 0 0 10px; }\r\n#pth-recipecalc-wrap .pth-rc-side-text { font-size: 0.86rem; color: #334155; margin: 0 0 10px; }\r\n#pth-recipecalc-wrap .pth-rc-side-list { margin: 0; padding-left: 18px; font-size: 0.85rem; color: #334155; }\r\n#pth-recipecalc-wrap .pth-rc-side-list li { margin-bottom: 6px; }\r\n#pth-recipecalc-wrap .pth-rc-xlink { color: #c2410c; font-weight: 700; text-decoration: none; }\r\n#pth-recipecalc-wrap .pth-rc-xlink:hover { text-decoration: underline; }\r\n#pth-recipecalc-wrap .pth-rc-tags { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 10px; }\r\n#pth-recipecalc-wrap .pth-rc-tag { font-size: 0.7rem; font-weight: 700; padding: 3px 9px; border-radius: 20px; background: #ecfdf5; color: #047857; border: 1px solid #a7f3d0; }\r\n\r\n#pth-recipecalc-wrap .pth-rc-cmp { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; }\r\n#pth-recipecalc-wrap .pth-rc-cmp-col { border: 1px solid #e2e8f0; border-radius: 10px; padding: 14px; background: #fff; }\r\n#pth-recipecalc-wrap .pth-rc-cmp-col h4 { margin: 0 0 10px; font-size: 0.95rem; color: #0f172a; }\r\n#pth-recipecalc-wrap .pth-rc-cmp-col .cr { display: flex; justify-content: space-between; font-size: 0.82rem; padding: 4px 0; border-bottom: 1px dashed #f1f5f9; }\r\n#pth-recipecalc-wrap .pth-rc-cmp-col .cr b { color: #0f172a; }\r\n\r\n#pth-recipecalc-wrap textarea.pth-rc-notes { width: 100%; min-height: 200px; resize: vertical; border: 1px solid #e2e8f0; border-radius: 10px; padding: 14px; font-family: inherit; font-size: 0.92rem; line-height: 1.6; color: #1e293b; background: #f8fafc; outline: none; }\r\n#pth-recipecalc-wrap textarea.pth-rc-notes:focus { border-color: #ea580c; background: #fff; }\r\n#pth-recipecalc-wrap .pth-rc-saved { display: flex; flex-direction: column; gap: 6px; }\r\n#pth-recipecalc-wrap .pth-rc-saved-item { display: flex; justify-content: space-between; align-items: center; gap: 8px; border: 1px solid #e2e8f0; border-radius: 8px; padding: 8px 12px; font-size: 0.86rem; }\r\n\r\n#pth-recipecalc-wrap .pth-rc-modal { position: fixed; inset: 0; background: rgba(15,23,42,0.5); z-index: 999998; display: none; align-items: flex-start; justify-content: center; padding: 40px 16px; overflow: auto; }\r\n#pth-recipecalc-wrap .pth-rc-modal.show { display: flex; }\r\n#pth-recipecalc-wrap .pth-rc-modal-box { background: #fff; border-radius: 14px; padding: 20px; width: 100%; max-width: 540px; }\r\n#pth-recipecalc-wrap .pth-rc-modal-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }\r\n#pth-recipecalc-wrap .pth-rc-modal-head h3 { margin: 0; font-size: 1.05rem; color: #0f172a; font-weight: 800; }\r\n#pth-recipecalc-wrap .pth-rc-list { max-height: 320px; overflow: auto; margin-top: 10px; }\r\n#pth-recipecalc-wrap .pth-rc-li { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 9px 10px; border: 1px solid #e2e8f0; border-radius: 8px; margin-bottom: 6px; }\r\n#pth-recipecalc-wrap .pth-rc-li .info b { color: #0f172a; display: block; font-size: 0.88rem; }\r\n#pth-recipecalc-wrap .pth-rc-li .info span { font-size: 0.78rem; color: #64748b; }\r\n\r\n#pth-recipecalc-wrap .pth-rc-toast { position: fixed; bottom: 22px; right: 22px; z-index: 999999; display: none; padding: 13px 18px; border-radius: 10px; color: #fff; font-family: 'Inter', system-ui, sans-serif; font-size: 0.9rem; font-weight: 700; box-shadow: 0 8px 24px rgba(15,23,42,0.2); max-width: 320px; }\r\n#pth-recipecalc-wrap .pth-rc-toast.show { display: block; }\r\n\r\n@media (max-width: 768px) {\r\n  #pth-recipecalc-wrap { padding: 0 10px; }\r\n  #pth-recipecalc-wrap .pth-rc-layout { grid-template-columns: 1fr; }\r\n  #pth-recipecalc-wrap .pth-rc-meta { grid-template-columns: 1fr; }\r\n  #pth-recipecalc-wrap .pth-rc-ing-head { display: none; }\r\n  #pth-recipecalc-wrap .pth-rc-ing { grid-template-columns: 1fr 1fr; grid-auto-rows: auto; gap: 6px; }\r\n  #pth-recipecalc-wrap .pth-rc-ing .nm { grid-column: 1 \/ -1; }\r\n}\r\n@media print {\r\n  body * { visibility: hidden; }\r\n  #pth-recipecalc-wrap #pth-rc-print, #pth-recipecalc-wrap #pth-rc-print * { visibility: visible; }\r\n  #pth-recipecalc-wrap #pth-rc-print { position: absolute; left: 0; top: 0; }\r\n}\r\n<\/style>\r\n\r\n<div id=\"pth-recipecalc-wrap\">\r\n\r\n  <div class=\"pth-rc-topbar\">\r\n    <div class=\"pth-rc-brand\">\r\n      <div class=\"pth-rc-icon\" aria-hidden=\"true\">&#127858;<\/div>\r\n      <div>\r\n        <h2 class=\"pth-rc-title\">Recipe Nutrition &amp; Cost Studio<\/h2>\r\n        <p class=\"pth-rc-sub\">Nutrition facts, cost per serving &amp; recipe comparison &mdash; fully offline<\/p>\r\n      <\/div>\r\n    <\/div>\r\n    <div class=\"pth-rc-badges\">\r\n      <span class=\"pth-rc-badge ver\">v8.0<\/span>\r\n      <span class=\"pth-rc-badge off\">&#128274; 100% Offline<\/span>\r\n      <button type=\"button\" class=\"pth-rc-btn pth-rc-ghost sm\" data-action=\"sample\">&#128161; Sample<\/button>\r\n      <button type=\"button\" class=\"pth-rc-btn pth-rc-ghost sm\" data-action=\"wide\">&#9906; Wide<\/button>\r\n      <button type=\"button\" class=\"pth-rc-btn pth-rc-danger sm\" data-action=\"clear\">&#128465;&#65039; Clear<\/button>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div class=\"pth-rc-tabs\" role=\"tablist\">\r\n    <button type=\"button\" class=\"pth-rc-tab active\" data-tab=\"build\" role=\"tab\">&#129365; Build &amp; Cost<\/button>\r\n    <button type=\"button\" class=\"pth-rc-tab\" data-tab=\"label\" role=\"tab\">&#127991;&#65039; Nutrition Label<\/button>\r\n    <button type=\"button\" class=\"pth-rc-tab\" data-tab=\"compare\" role=\"tab\">&#9878;&#65039; Compare<\/button>\r\n    <button type=\"button\" class=\"pth-rc-tab\" data-tab=\"notes\" role=\"tab\">&#128221; Notes &amp; Saved<\/button>\r\n  <\/div>\r\n\r\n  <div id=\"pth-rc-print\">\r\n  <!-- ===== BUILD & COST ===== -->\r\n  <div class=\"pth-rc-panel active\" data-panel=\"build\">\r\n    <div class=\"pth-rc-layout\">\r\n      <div class=\"pth-rc-card\">\r\n        <p class=\"pth-rc-ctitle\">Recipe<\/p>\r\n        <div class=\"pth-rc-meta\">\r\n          <div class=\"pth-rc-fg\"><label class=\"pth-rc-label\" for=\"rc-name\">Recipe name<\/label><input id=\"rc-name\" class=\"pth-rc-input\" type=\"text\" placeholder=\"e.g. Chicken curry\"><\/div>\r\n          <div class=\"pth-rc-fg\"><label class=\"pth-rc-label\" for=\"rc-servings\">Servings<\/label><input id=\"rc-servings\" class=\"pth-rc-input\" type=\"number\" min=\"1\" max=\"50\" value=\"4\"><\/div>\r\n          <div class=\"pth-rc-fg\"><label class=\"pth-rc-label\" for=\"rc-currency\">Currency<\/label>\r\n            <select id=\"rc-currency\" class=\"pth-rc-select\">\r\n              <option value=\"USD\">$ USD<\/option><option value=\"EUR\">&euro; EUR<\/option><option value=\"GBP\">&pound; GBP<\/option>\r\n              <option value=\"INR\">&#8377; INR<\/option><option value=\"LKR\">Rs LKR<\/option><option value=\"AUD\">A$ AUD<\/option><option value=\"CAD\">C$ CAD<\/option>\r\n            <\/select><\/div>\r\n        <\/div>\r\n        <p class=\"pth-rc-ctitle\" style=\"margin-top:8px;\">Ingredients<\/p>\r\n        <div class=\"pth-rc-ing-head\">\r\n          <div>Ingredient<\/div><div>Amount<\/div><div>Unit<\/div><div>Price<\/div><div><\/div>\r\n        <\/div>\r\n        <div id=\"rc-ing-list\"><\/div>\r\n        <div class=\"pth-rc-actions\">\r\n          <button type=\"button\" class=\"pth-rc-btn pth-rc-primary sm\" data-action=\"open-picker\">&#43; Add ingredient<\/button>\r\n          <button type=\"button\" class=\"pth-rc-btn pth-rc-ghost sm\" data-action=\"custom-ing\">&#43; Custom<\/button>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <aside>\r\n        <div class=\"pth-rc-card\">\r\n          <p class=\"pth-rc-ctitle\">Per serving<\/p>\r\n          <div class=\"pth-rc-summary\" id=\"rc-summary\">\r\n            <div class=\"pth-rc-row\"><span>Calories<\/span><b class=\"big\" id=\"rc-cal\">0<\/b><\/div>\r\n            <div class=\"pth-rc-row\"><span>Protein<\/span><b id=\"rc-p\">0 g<\/b><\/div>\r\n            <div class=\"pth-rc-row\"><span>Carbs<\/span><b id=\"rc-c\">0 g<\/b><\/div>\r\n            <div class=\"pth-rc-row\"><span>Fat<\/span><b id=\"rc-f\">0 g<\/b><\/div>\r\n            <div class=\"pth-rc-row\"><span>Fiber<\/span><b id=\"rc-fb\">0 g<\/b><\/div>\r\n          <\/div>\r\n        <\/div>\r\n        <div class=\"pth-rc-card pth-rc-cost\">\r\n          <p class=\"pth-rc-ctitle\">Cost<\/p>\r\n          <div class=\"pth-rc-summary\">\r\n            <div class=\"pth-rc-row\"><span>Per serving<\/span><b class=\"big\" id=\"rc-cps\">0<\/b><\/div>\r\n            <div class=\"pth-rc-row\"><span>Whole recipe<\/span><b id=\"rc-ctot\">0<\/b><\/div>\r\n            <div class=\"pth-rc-row\"><span>Per 100 kcal<\/span><b id=\"rc-c100\">0<\/b><\/div>\r\n          <\/div>\r\n          <p class=\"pth-rc-hint\">Add a price to each ingredient to see budgeting figures. Prices are the cost of the amount you entered.<\/p>\r\n        <\/div>\r\n        <div class=\"pth-rc-card\">\r\n          <button type=\"button\" class=\"pth-rc-btn pth-rc-green sm\" data-action=\"save-recipe\" style=\"width:100%;justify-content:center;\">&#128190; Save this recipe<\/button>\r\n        <\/div>\r\n      <\/aside>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- ===== NUTRITION LABEL ===== -->\r\n  <div class=\"pth-rc-panel\" data-panel=\"label\">\r\n    <div class=\"pth-rc-card\">\r\n      <p class=\"pth-rc-ctitle\">Nutrition facts (per serving)<\/p>\r\n      <div id=\"rc-label\"><\/div>\r\n      <div class=\"pth-rc-actions\">\r\n        <button type=\"button\" class=\"pth-rc-btn pth-rc-green sm\" data-action=\"copy-label\">&#128203; Copy as text<\/button>\r\n        <button type=\"button\" class=\"pth-rc-btn pth-rc-blue sm\" data-action=\"export-csv\">&#128229; CSV<\/button>\r\n        <button type=\"button\" class=\"pth-rc-btn pth-rc-blue sm\" data-action=\"export-json\">&#128229; JSON<\/button>\r\n        <button type=\"button\" class=\"pth-rc-btn pth-rc-ghost sm\" data-action=\"print\">&#128424;&#65039; Print<\/button>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- ===== COMPARE ===== -->\r\n  <div class=\"pth-rc-panel\" data-panel=\"compare\">\r\n    <div class=\"pth-rc-card\">\r\n      <p class=\"pth-rc-ctitle\">Compare saved recipes<\/p>\r\n      <p class=\"pth-rc-side-text\">Save a few recipes on the Build tab, then compare their per-serving nutrition and cost side by side.<\/p>\r\n      <div id=\"rc-compare\"><\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <!-- ===== NOTES & SAVED ===== -->\r\n  <div class=\"pth-rc-panel\" data-panel=\"notes\">\r\n    <div class=\"pth-rc-layout\">\r\n      <div class=\"pth-rc-card\">\r\n        <p class=\"pth-rc-ctitle\">Recipe notes<\/p>\r\n        <textarea id=\"rc-notes\" class=\"pth-rc-notes\" placeholder=\"Method, tweaks, timings, substitutions...\"><\/textarea>\r\n        <div class=\"pth-rc-actions\">\r\n          <button type=\"button\" class=\"pth-rc-btn pth-rc-green sm\" data-action=\"save-notes\">&#128190; Save notes<\/button>\r\n          <button type=\"button\" class=\"pth-rc-btn pth-rc-ghost sm\" data-action=\"copy-notes\">&#128203; Copy<\/button>\r\n        <\/div>\r\n      <\/div>\r\n      <div class=\"pth-rc-card\">\r\n        <p class=\"pth-rc-ctitle\">Saved recipes<\/p>\r\n        <div id=\"rc-saved\" class=\"pth-rc-saved\"><\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n  <\/div><!-- \/print -->\r\n\r\n  <!-- SIDEBAR (always visible under build via layout; here a persistent tips card outside tabs) -->\r\n  <div class=\"pth-rc-card\">\r\n    <p class=\"pth-rc-side-title\">&#128279; Related tools<\/p>\r\n    <ul class=\"pth-rc-side-list\">\r\n      <li>Planning several days of meals? Use the <a class=\"pth-rc-xlink\" href=\"https:\/\/schoolict.net\/tools\/free-offline-weight-loss-meal-planner\/\" target=\"_blank\" rel=\"noopener\">7-day Meal Plan Studio<\/a>.<\/li>\r\n      <li><a class=\"pth-rc-xlink\" href=\"https:\/\/schoolict.net\/tools\/csv-to-label-maker\/\" target=\"_blank\" rel=\"noopener\">CSV to Label Maker<\/a> for printable labels.<\/li>\r\n    <\/ul>\r\n    <p class=\"pth-rc-side-text\" style=\"margin-top:10px;font-size:0.78rem;color:#64748b;\">Nutrition values are estimates from a general ingredient database and will vary by brand and preparation.<\/p>\r\n  <\/div>\r\n\r\n  <!-- INGREDIENT PICKER MODAL -->\r\n  <div class=\"pth-rc-modal\" id=\"rc-modal\">\r\n    <div class=\"pth-rc-modal-box\">\r\n      <div class=\"pth-rc-modal-head\">\r\n        <h3>Add ingredient<\/h3>\r\n        <button type=\"button\" class=\"pth-rc-btn pth-rc-ghost sm\" data-action=\"modal-close\">&#10005;<\/button>\r\n      <\/div>\r\n      <input id=\"rc-search\" class=\"pth-rc-input\" type=\"text\" placeholder=\"Search ingredients...\">\r\n      <div class=\"pth-rc-list\" id=\"rc-food-list\"><\/div>\r\n    <\/div>\r\n  <\/div>\r\n\r\n  <div id=\"pth-rc-toast\" class=\"pth-rc-toast\" role=\"status\" aria-live=\"polite\"><\/div>\r\n<\/div>\r\n\r\n<script data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\">\r\n(function () {\r\n  'use strict';\r\n  if (window.pthRecipeCalcApp) { return; }\r\n\r\n  var STORE_R = 'pthRecipesV8';\r\n  var STORE_N = 'pthRecipeNotesV8';\r\n\r\n  \/* Ingredient database - values per 100 g. *\/\r\n  var DB = [\r\n    { name: 'Chicken breast', kcal: 165, protein: 31, carbs: 0, fat: 4, fiber: 0, tags: ['halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Beef mince (lean)', kcal: 217, protein: 26, carbs: 0, fat: 12, fiber: 0, tags: ['halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Salmon fillet', kcal: 208, protein: 20, carbs: 0, fat: 13, fiber: 0, tags: ['halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Tuna (canned in water)', kcal: 116, protein: 26, carbs: 0, fat: 1, fiber: 0, tags: ['halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Prawns', kcal: 99, protein: 24, carbs: 0, fat: 1, fiber: 0, tags: ['halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Egg', kcal: 143, protein: 13, carbs: 1, fat: 10, fiber: 0, tags: ['veg', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Tofu (firm)', kcal: 121, protein: 12, carbs: 3, fat: 7, fiber: 1, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Lentils (cooked)', kcal: 116, protein: 9, carbs: 20, fat: 0, fiber: 8, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Chickpeas (cooked)', kcal: 164, protein: 9, carbs: 27, fat: 3, fiber: 8, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Black beans (cooked)', kcal: 132, protein: 9, carbs: 24, fat: 1, fiber: 9, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'White rice (cooked)', kcal: 130, protein: 3, carbs: 28, fat: 0, fiber: 0, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Brown rice (cooked)', kcal: 111, protein: 3, carbs: 23, fat: 1, fiber: 2, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Pasta (cooked)', kcal: 158, protein: 6, carbs: 31, fat: 1, fiber: 2, tags: ['veg', 'vegan', 'halal', 'dairyfree'] },\r\n    { name: 'Bread (wholemeal)', kcal: 247, protein: 13, carbs: 41, fat: 3, fiber: 7, tags: ['veg', 'vegan', 'halal', 'dairyfree'] },\r\n    { name: 'Potato', kcal: 77, protein: 2, carbs: 17, fat: 0, fiber: 2, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Sweet potato', kcal: 86, protein: 2, carbs: 20, fat: 0, fiber: 3, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Oats', kcal: 389, protein: 17, carbs: 66, fat: 7, fiber: 11, tags: ['veg', 'vegan', 'halal', 'dairyfree'] },\r\n    { name: 'Onion', kcal: 40, protein: 1, carbs: 9, fat: 0, fiber: 2, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Tomato', kcal: 18, protein: 1, carbs: 4, fat: 0, fiber: 1, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Carrot', kcal: 41, protein: 1, carbs: 10, fat: 0, fiber: 3, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Broccoli', kcal: 34, protein: 3, carbs: 7, fat: 0, fiber: 3, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Spinach', kcal: 23, protein: 3, carbs: 4, fat: 0, fiber: 2, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Bell pepper', kcal: 31, protein: 1, carbs: 6, fat: 0, fiber: 2, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Garlic', kcal: 149, protein: 6, carbs: 33, fat: 1, fiber: 2, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Mushrooms', kcal: 22, protein: 3, carbs: 3, fat: 0, fiber: 1, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Coconut milk', kcal: 230, protein: 2, carbs: 6, fat: 24, fiber: 0, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Milk (whole)', kcal: 61, protein: 3, carbs: 5, fat: 3, fiber: 0, tags: ['veg', 'halal', 'glutenfree'] },\r\n    { name: 'Greek yogurt', kcal: 59, protein: 10, carbs: 4, fat: 0, fiber: 0, tags: ['veg', 'halal', 'glutenfree'] },\r\n    { name: 'Cheddar cheese', kcal: 402, protein: 25, carbs: 1, fat: 33, fiber: 0, tags: ['veg', 'halal', 'glutenfree'] },\r\n    { name: 'Butter', kcal: 717, protein: 1, carbs: 0, fat: 81, fiber: 0, tags: ['veg', 'halal', 'glutenfree'] },\r\n    { name: 'Olive oil', kcal: 884, protein: 0, carbs: 0, fat: 100, fiber: 0, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Flour (plain)', kcal: 364, protein: 10, carbs: 76, fat: 1, fiber: 3, tags: ['veg', 'vegan', 'halal', 'dairyfree'] },\r\n    { name: 'Sugar', kcal: 387, protein: 0, carbs: 100, fat: 0, fiber: 0, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Almonds', kcal: 579, protein: 21, carbs: 22, fat: 50, fiber: 12, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Peanut butter', kcal: 588, protein: 25, carbs: 20, fat: 50, fiber: 6, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Banana', kcal: 89, protein: 1, carbs: 23, fat: 0, fiber: 3, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Apple', kcal: 52, protein: 0, carbs: 14, fat: 0, fiber: 2, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Avocado', kcal: 160, protein: 2, carbs: 9, fat: 15, fiber: 7, tags: ['veg', 'vegan', 'halal', 'glutenfree', 'dairyfree'] },\r\n    { name: 'Honey', kcal: 304, protein: 0, carbs: 82, fat: 0, fiber: 0, tags: ['veg', 'halal', 'glutenfree', 'dairyfree'] }\r\n  ];\r\n\r\n  var UNIT_G = { g: 1, kg: 1000, oz: 28.35, lb: 453.59, ml: 1, l: 1000, cup: 240, tbsp: 15, tsp: 5 };\r\n  var CUR = { USD: '$', EUR: '\\u20AC', GBP: '\\u00A3', INR: '\\u20B9', LKR: 'Rs ', AUD: 'A$', CAD: 'C$' };\r\n  var DV = { fat: 78, carbs: 275, fiber: 28, protein: 50 };\r\n\r\n  var App = {\r\n    initialized: false, root: null,\r\n    ings: [], currency: 'USD',\r\n\r\n    init: function () {\r\n      this.root = document.getElementById('pth-recipecalc-wrap');\r\n      if (!this.root) { return; }\r\n      this.loadNotes();\r\n      this.loadSaved();\r\n      this.attach();\r\n      this.renderIngs();\r\n      this.recompute();\r\n    },\r\n\r\n    attach: function () {\r\n      var self = this;\r\n      this.root.addEventListener('click', function (e) {\r\n        var el = e.target;\r\n        while (el && el !== self.root && !el.getAttribute('data-action') && !el.getAttribute('data-tab')) { el = el.parentNode; }\r\n        if (!el || el === self.root) { return; }\r\n        if (el.getAttribute('data-tab')) { self.switchTab(el.getAttribute('data-tab')); return; }\r\n        var a = el.getAttribute('data-action');\r\n        if (!a) { return; }\r\n        try { self.handle(a, el); } catch (err) { self.toast('Something went wrong. Please try again.', 'error'); if (window.console) { console.error('[RecipeCalc]', err); } }\r\n      });\r\n      this.root.addEventListener('input', function (e) {\r\n        var t = e.target;\r\n        if (t.id === 'rc-search') { self.renderFoodList(); return; }\r\n        if (t.id === 'rc-servings' || t.id === 'rc-name') { self.recompute(); return; }\r\n        if (t.id === 'rc-currency') { self.currency = t.value; self.recompute(); return; }\r\n        var idx = t.getAttribute && t.getAttribute('data-ing');\r\n        if (idx !== null && idx !== undefined && idx !== '') {\r\n          var i = parseInt(idx, 10);\r\n          var field = t.getAttribute('data-field');\r\n          if (this && self.ings[i]) { self.ings[i][field] = (field === 'unit') ? t.value : (parseFloat(t.value) || 0); self.recompute(); }\r\n        }\r\n      });\r\n      this.root.addEventListener('change', function (e) {\r\n        var t = e.target;\r\n        if (t.id === 'rc-currency') { self.currency = t.value; self.recompute(); }\r\n        var idx = t.getAttribute && t.getAttribute('data-ing');\r\n        if (idx !== null && idx !== undefined && idx !== '' && t.getAttribute('data-field') === 'unit') {\r\n          self.ings[parseInt(idx, 10)].unit = t.value; self.recompute();\r\n        }\r\n      });\r\n    },\r\n\r\n    handle: function (a, el) {\r\n      switch (a) {\r\n        case 'sample': this.loadSample(); break;\r\n        case 'wide': this.root.className = this.root.className.indexOf('full') > -1 ? '' : 'full'; break;\r\n        case 'clear': this.clearAll(); break;\r\n        case 'open-picker': this.openModal(); break;\r\n        case 'modal-close': this.closeModal(); break;\r\n        case 'custom-ing': this.customIng(); break;\r\n        case 'del-ing': this.delIng(el); break;\r\n        case 'save-recipe': this.saveRecipe(); break;\r\n        case 'save-notes': this.saveNotes(); break;\r\n        case 'copy-notes': this.copyNotes(); break;\r\n        case 'copy-label': this.copyLabel(); break;\r\n        case 'export-csv': this.exportCSV(); break;\r\n        case 'export-json': this.exportJSON(); break;\r\n        case 'print': window.print(); break;\r\n        case 'load-saved': this.loadRecipe(el); break;\r\n        case 'del-saved': this.delSaved(el); break;\r\n      }\r\n    },\r\n\r\n    switchTab: function (name) {\r\n      var tabs = this.root.querySelectorAll('.pth-rc-tab'), i;\r\n      for (i = 0; i < tabs.length; i++) { tabs[i].className = 'pth-rc-tab' + (tabs[i].getAttribute('data-tab') === name ? ' active' : ''); }\r\n      var panels = this.root.querySelectorAll('.pth-rc-panel');\r\n      for (i = 0; i < panels.length; i++) { panels[i].className = 'pth-rc-panel' + (panels[i].getAttribute('data-panel') === name ? ' active' : ''); }\r\n      if (name === 'label') { this.renderLabel(); }\r\n      if (name === 'compare') { this.renderCompare(); }\r\n      if (name === 'notes') { this.renderSaved(); }\r\n    },\r\n\r\n    \/* ---------- ingredients ---------- *\/\r\n    renderIngs: function () {\r\n      var host = document.getElementById('rc-ing-list');\r\n      if (!host) { return; }\r\n      host.innerHTML = '';\r\n      if (!this.ings.length) {\r\n        var p = document.createElement('p'); p.className = 'pth-rc-side-text'; p.textContent = 'No ingredients yet. Press \"Add ingredient\" to begin.';\r\n        host.appendChild(p); return;\r\n      }\r\n      for (var i = 0; i < this.ings.length; i++) { host.appendChild(this.ingRow(i)); }\r\n    },\r\n\r\n    ingRow: function (i) {\r\n      var ing = this.ings[i];\r\n      var row = document.createElement('div'); row.className = 'pth-rc-ing';\r\n      var nm = document.createElement('div'); nm.className = 'nm'; nm.textContent = ing.name; row.appendChild(nm);\r\n\r\n      var amt = document.createElement('input'); amt.type = 'number'; amt.min = '0'; amt.value = String(ing.amount);\r\n      amt.setAttribute('data-ing', String(i)); amt.setAttribute('data-field', 'amount'); amt.setAttribute('aria-label', 'Amount of ' + ing.name);\r\n      row.appendChild(amt);\r\n\r\n      var unit = document.createElement('select'); unit.setAttribute('data-ing', String(i)); unit.setAttribute('data-field', 'unit'); unit.setAttribute('aria-label', 'Unit for ' + ing.name);\r\n      var uk = ['g', 'kg', 'oz', 'lb', 'ml', 'l', 'cup', 'tbsp', 'tsp'];\r\n      for (var u = 0; u < uk.length; u++) { var o = document.createElement('option'); o.value = uk[u]; o.textContent = uk[u]; if (uk[u] === ing.unit) { o.selected = true; } unit.appendChild(o); }\r\n      row.appendChild(unit);\r\n\r\n      var price = document.createElement('input'); price.type = 'number'; price.min = '0'; price.step = '0.01'; price.value = ing.price ? String(ing.price) : '';\r\n      price.placeholder = '0.00'; price.setAttribute('data-ing', String(i)); price.setAttribute('data-field', 'price'); price.setAttribute('aria-label', 'Price of ' + ing.name);\r\n      row.appendChild(price);\r\n\r\n      var x = document.createElement('button'); x.type = 'button'; x.className = 'pth-rc-x'; x.setAttribute('data-action', 'del-ing'); x.setAttribute('data-idx', String(i)); x.textContent = '\\u00D7';\r\n      row.appendChild(x);\r\n      return row;\r\n    },\r\n\r\n    grams: function (ing) { return (ing.amount || 0) * (UNIT_G[ing.unit] || 1); },\r\n\r\n    totals: function () {\r\n      var t = { kcal: 0, protein: 0, carbs: 0, fat: 0, fiber: 0, cost: 0 };\r\n      for (var i = 0; i < this.ings.length; i++) {\r\n        var ing = this.ings[i], f = this.grams(ing) \/ 100;\r\n        t.kcal += ing.kcal * f; t.protein += ing.protein * f; t.carbs += ing.carbs * f; t.fat += ing.fat * f; t.fiber += ing.fiber * f;\r\n        t.cost += (ing.price || 0);\r\n      }\r\n      return t;\r\n    },\r\n\r\n    servings: function () { var s = parseInt((document.getElementById('rc-servings') || {}).value, 10); return (s && s > 0) ? s : 1; },\r\n\r\n    recompute: function () {\r\n      var t = this.totals(), s = this.servings();\r\n      var sym = CUR[this.currency] || '';\r\n      this.setTxt('rc-cal', Math.round(t.kcal \/ s));\r\n      this.setTxt('rc-p', (t.protein \/ s).toFixed(1) + ' g');\r\n      this.setTxt('rc-c', (t.carbs \/ s).toFixed(1) + ' g');\r\n      this.setTxt('rc-f', (t.fat \/ s).toFixed(1) + ' g');\r\n      this.setTxt('rc-fb', (t.fiber \/ s).toFixed(1) + ' g');\r\n      this.setTxt('rc-cps', t.cost ? (sym + (t.cost \/ s).toFixed(2)) : (sym + '0.00'));\r\n      this.setTxt('rc-ctot', sym + t.cost.toFixed(2));\r\n      var per100 = t.kcal > 0 ? (t.cost \/ (t.kcal \/ 100)) : 0;\r\n      this.setTxt('rc-c100', t.cost ? (sym + per100.toFixed(3)) : (sym + '0.00'));\r\n    },\r\n\r\n    setTxt: function (id, v) { var e = document.getElementById(id); if (e) { e.textContent = String(v); } },\r\n\r\n    \/* ---------- picker ---------- *\/\r\n    openModal: function () { document.getElementById('rc-search').value = ''; this.renderFoodList(); document.getElementById('rc-modal').className = 'pth-rc-modal show'; },\r\n    closeModal: function () { document.getElementById('rc-modal').className = 'pth-rc-modal'; },\r\n\r\n    renderFoodList: function () {\r\n      var host = document.getElementById('rc-food-list'); if (!host) { return; }\r\n      var q = (document.getElementById('rc-search').value || '').toLowerCase();\r\n      host.innerHTML = ''; var self = this;\r\n      for (var i = 0; i < DB.length; i++) {\r\n        var fd = DB[i];\r\n        if (q && fd.name.toLowerCase().indexOf(q) === -1) { continue; }\r\n        host.appendChild(this.pickRow(fd));\r\n      }\r\n    },\r\n\r\n    pickRow: function (fd) {\r\n      var self = this;\r\n      var row = document.createElement('div'); row.className = 'pth-rc-li';\r\n      var info = document.createElement('div'); info.className = 'info';\r\n      var b = document.createElement('b'); b.textContent = fd.name; info.appendChild(b);\r\n      var sp = document.createElement('span'); sp.textContent = 'per 100 g: ' + fd.kcal + ' kcal, P' + fd.protein + ' C' + fd.carbs + ' F' + fd.fat; info.appendChild(sp);\r\n      var add = document.createElement('button'); add.type = 'button'; add.className = 'pth-rc-btn pth-rc-primary sm'; add.textContent = '+ Add';\r\n      add.onclick = function () { self.addIng(fd); };\r\n      row.appendChild(info); row.appendChild(add);\r\n      return row;\r\n    },\r\n\r\n    addIng: function (fd) {\r\n      this.ings.push({ name: fd.name, kcal: fd.kcal, protein: fd.protein, carbs: fd.carbs, fat: fd.fat, fiber: fd.fiber, tags: fd.tags || [], amount: 100, unit: 'g', price: 0 });\r\n      this.renderIngs(); this.recompute();\r\n      this.toast(fd.name + ' added.', 'success');\r\n    },\r\n\r\n    customIng: function () {\r\n      var name = window.prompt('Ingredient name:'); if (!name) { return; }\r\n      var kcal = parseFloat(window.prompt('Calories per 100 g:')); if (isNaN(kcal)) { this.toast('Enter a valid number.', 'error'); return; }\r\n      var p = parseFloat(window.prompt('Protein per 100 g (g):')) || 0;\r\n      var c = parseFloat(window.prompt('Carbs per 100 g (g):')) || 0;\r\n      var f = parseFloat(window.prompt('Fat per 100 g (g):')) || 0;\r\n      this.ings.push({ name: name, kcal: kcal, protein: p, carbs: c, fat: f, fiber: 0, tags: [], amount: 100, unit: 'g', price: 0 });\r\n      this.renderIngs(); this.recompute(); this.closeModal();\r\n      this.toast('Custom ingredient added.', 'success');\r\n    },\r\n\r\n    delIng: function (el) { this.ings.splice(parseInt(el.getAttribute('data-idx'), 10), 1); this.renderIngs(); this.recompute(); },\r\n\r\n    \/* ---------- nutrition label ---------- *\/\r\n    renderLabel: function () {\r\n      var host = document.getElementById('rc-label'); if (!host) { return; }\r\n      var t = this.totals(), s = this.servings();\r\n      if (!this.ings.length) { host.innerHTML = ''; var p = document.createElement('p'); p.className = 'pth-rc-side-text'; p.textContent = 'Add ingredients on the Build tab to generate a label.'; host.appendChild(p); return; }\r\n      var per = { kcal: t.kcal \/ s, protein: t.protein \/ s, carbs: t.carbs \/ s, fat: t.fat \/ s, fiber: t.fiber \/ s };\r\n      host.innerHTML = '';\r\n      var box = document.createElement('div'); box.className = 'pth-rc-label-box';\r\n      box.appendChild(this.mk('p', 'lt', 'Nutrition Facts'));\r\n      var sv = this.mk('div', 'sv', ''); sv.appendChild(this.mk('span', '', s + ' servings per recipe')); box.appendChild(sv);\r\n      var cal = document.createElement('div'); cal.className = 'cal';\r\n      cal.appendChild(this.mk('span', 'l', 'Calories')); cal.appendChild(this.mk('span', 'v', String(Math.round(per.kcal)))); box.appendChild(cal);\r\n      box.appendChild(this.mk('div', 'dvh', '% Daily Value *'));\r\n      box.appendChild(this.labelRow('Total Fat', per.fat, 'g', DV.fat));\r\n      box.appendChild(this.labelRow('Total Carbohydrate', per.carbs, 'g', DV.carbs));\r\n      box.appendChild(this.labelRow('Dietary Fiber', per.fiber, 'g', DV.fiber, true));\r\n      box.appendChild(this.labelRow('Protein', per.protein, 'g', DV.protein));\r\n      box.appendChild(this.mk('div', 'foot', '* Percent Daily Values are based on a 2,000 calorie diet. Values are estimates from a general ingredient database and vary by brand and preparation.'));\r\n      host.appendChild(box);\r\n    },\r\n\r\n    labelRow: function (name, val, unit, dv, indent) {\r\n      var r = document.createElement('div'); r.className = 'lr';\r\n      var left = document.createElement('span');\r\n      if (indent) { left.className = 'n'; left.style.paddingLeft = '14px'; var bb = document.createElement('b'); bb.style.fontWeight = '400'; }\r\n      var strong = document.createElement('b'); strong.textContent = name + ' ';\r\n      var amt = document.createElement('span'); amt.textContent = val.toFixed(1) + unit;\r\n      if (indent) { left.appendChild(document.createTextNode(name + ' ' + val.toFixed(1) + unit)); }\r\n      else { left.appendChild(strong); left.appendChild(amt); }\r\n      var pct = document.createElement('b'); pct.textContent = Math.round((val \/ dv) * 100) + '%';\r\n      r.appendChild(left); r.appendChild(pct);\r\n      return r;\r\n    },\r\n\r\n    mk: function (tag, cls, txt) { var e = document.createElement(tag); if (cls) { e.className = cls; } if (txt) { e.textContent = txt; } return e; },\r\n\r\n    \/* ---------- save \/ load ---------- *\/\r\n    currentRecipe: function () {\r\n      return { name: (document.getElementById('rc-name') || {}).value || 'Untitled recipe', servings: this.servings(), currency: this.currency, ings: JSON.parse(JSON.stringify(this.ings)) };\r\n    },\r\n\r\n    saveRecipe: function () {\r\n      if (!this.ings.length) { this.toast('Add ingredients before saving.', 'error'); return; }\r\n      var list = this.getSaved();\r\n      list.push(this.currentRecipe());\r\n      try { localStorage.setItem(STORE_R, JSON.stringify(list)); } catch (e) {}\r\n      this.toast('Recipe saved.', 'success');\r\n      this.renderSaved();\r\n    },\r\n\r\n    getSaved: function () { try { return JSON.parse(localStorage.getItem(STORE_R)) || []; } catch (e) { return []; } },\r\n    loadSaved: function () { this.saved = this.getSaved(); },\r\n\r\n    renderSaved: function () {\r\n      var host = document.getElementById('rc-saved'); if (!host) { return; }\r\n      var list = this.getSaved(); host.innerHTML = '';\r\n      if (!list.length) { var p = document.createElement('p'); p.className = 'pth-rc-side-text'; p.textContent = 'No saved recipes yet.'; host.appendChild(p); return; }\r\n      for (var i = 0; i < list.length; i++) {\r\n        var row = document.createElement('div'); row.className = 'pth-rc-saved-item';\r\n        var nm = document.createElement('span'); nm.textContent = list[i].name + ' (' + list[i].servings + ' servings)';\r\n        var wrap = document.createElement('span');\r\n        var ld = document.createElement('button'); ld.type = 'button'; ld.className = 'pth-rc-btn pth-rc-ghost sm'; ld.setAttribute('data-action', 'load-saved'); ld.setAttribute('data-idx', String(i)); ld.textContent = 'Load';\r\n        var dl = document.createElement('button'); dl.type = 'button'; dl.className = 'pth-rc-btn pth-rc-danger sm'; dl.setAttribute('data-action', 'del-saved'); dl.setAttribute('data-idx', String(i)); dl.textContent = '\\u00D7'; dl.style.marginLeft = '6px';\r\n        wrap.appendChild(ld); wrap.appendChild(dl);\r\n        row.appendChild(nm); row.appendChild(wrap);\r\n        host.appendChild(row);\r\n      }\r\n    },\r\n\r\n    loadRecipe: function (el) {\r\n      var r = this.getSaved()[parseInt(el.getAttribute('data-idx'), 10)]; if (!r) { return; }\r\n      this.ings = JSON.parse(JSON.stringify(r.ings)); this.currency = r.currency || 'USD';\r\n      var nm = document.getElementById('rc-name'); if (nm) { nm.value = r.name; }\r\n      var sv = document.getElementById('rc-servings'); if (sv) { sv.value = r.servings; }\r\n      var cu = document.getElementById('rc-currency'); if (cu) { cu.value = this.currency; }\r\n      this.renderIngs(); this.recompute(); this.switchTab('build');\r\n      this.toast('Loaded \"' + r.name + '\".', 'success');\r\n    },\r\n\r\n    delSaved: function (el) {\r\n      var list = this.getSaved(); list.splice(parseInt(el.getAttribute('data-idx'), 10), 1);\r\n      try { localStorage.setItem(STORE_R, JSON.stringify(list)); } catch (e) {}\r\n      this.renderSaved();\r\n    },\r\n\r\n    renderCompare: function () {\r\n      var host = document.getElementById('rc-compare'); if (!host) { return; }\r\n      var list = this.getSaved(); host.innerHTML = '';\r\n      if (list.length < 2) { var p = document.createElement('p'); p.className = 'pth-rc-side-text'; p.textContent = 'Save at least two recipes to compare them here.'; host.appendChild(p); return; }\r\n      var grid = document.createElement('div'); grid.className = 'pth-rc-cmp';\r\n      var self = this;\r\n      for (var i = 0; i < list.length; i++) {\r\n        var r = list[i], col = document.createElement('div'); col.className = 'pth-rc-cmp-col';\r\n        var h = document.createElement('h4'); h.textContent = r.name; col.appendChild(h);\r\n        var t = { kcal: 0, protein: 0, carbs: 0, fat: 0, cost: 0 };\r\n        for (var j = 0; j < r.ings.length; j++) { var ing = r.ings[j], f = ((ing.amount || 0) * (UNIT_G[ing.unit] || 1)) \/ 100; t.kcal += ing.kcal * f; t.protein += ing.protein * f; t.carbs += ing.carbs * f; t.fat += ing.fat * f; t.cost += (ing.price || 0); }\r\n        var s = r.servings || 1, sym = CUR[r.currency] || '';\r\n        col.appendChild(this.cmpRow('Calories', Math.round(t.kcal \/ s)));\r\n        col.appendChild(this.cmpRow('Protein', (t.protein \/ s).toFixed(1) + ' g'));\r\n        col.appendChild(this.cmpRow('Carbs', (t.carbs \/ s).toFixed(1) + ' g'));\r\n        col.appendChild(this.cmpRow('Fat', (t.fat \/ s).toFixed(1) + ' g'));\r\n        col.appendChild(this.cmpRow('Cost\/serving', t.cost ? (sym + (t.cost \/ s).toFixed(2)) : '-'));\r\n        grid.appendChild(col);\r\n      }\r\n      host.appendChild(grid);\r\n    },\r\n\r\n    cmpRow: function (label, val) { var r = document.createElement('div'); r.className = 'cr'; var s = document.createElement('span'); s.textContent = label; var b = document.createElement('b'); b.textContent = String(val); r.appendChild(s); r.appendChild(b); return r; },\r\n\r\n    \/* ---------- export ---------- *\/\r\n    labelText: function () {\r\n      var t = this.totals(), s = this.servings(), sym = CUR[this.currency] || '';\r\n      var name = (document.getElementById('rc-name') || {}).value || 'Recipe';\r\n      var L = [];\r\n      L.push(name + ' - Nutrition (per serving, ' + s + ' servings)');\r\n      L.push('Calories: ' + Math.round(t.kcal \/ s));\r\n      L.push('Protein: ' + (t.protein \/ s).toFixed(1) + ' g');\r\n      L.push('Carbs: ' + (t.carbs \/ s).toFixed(1) + ' g');\r\n      L.push('Fat: ' + (t.fat \/ s).toFixed(1) + ' g');\r\n      L.push('Fiber: ' + (t.fiber \/ s).toFixed(1) + ' g');\r\n      if (t.cost) { L.push('Cost\/serving: ' + sym + (t.cost \/ s).toFixed(2)); }\r\n      return L.join('\\n');\r\n    },\r\n\r\n    copyLabel: function () {\r\n      var self = this, txt = this.labelText();\r\n      if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(txt).then(function () { self.toast('Copied.', 'success'); })['catch'](function () { self.toast('Copy blocked.', 'error'); }); }\r\n      else { this.toast('Copy blocked by browser.', 'error'); }\r\n    },\r\n\r\n    exportCSV: function () {\r\n      if (!this.ings.length) { this.toast('Nothing to export.', 'error'); return; }\r\n      var rows = [['Ingredient', 'Amount', 'Unit', 'Grams', 'Calories', 'Protein', 'Carbs', 'Fat', 'Fiber', 'Price']];\r\n      for (var i = 0; i < this.ings.length; i++) { var ing = this.ings[i], f = this.grams(ing) \/ 100; rows.push([ing.name, ing.amount, ing.unit, Math.round(this.grams(ing)), Math.round(ing.kcal * f), (ing.protein * f).toFixed(1), (ing.carbs * f).toFixed(1), (ing.fat * f).toFixed(1), (ing.fiber * f).toFixed(1), ing.price || 0]); }\r\n      var csv = '';\r\n      for (var r = 0; r < rows.length; r++) { var line = []; for (var c = 0; c < rows[r].length; c++) { line.push('\"' + String(rows[r][c]).replace(\/\"\/g, '\"\"') + '\"'); } csv += line.join(',') + '\\r\\n'; }\r\n      this.download(csv, 'recipe.csv', 'text\/csv'); this.toast('CSV downloaded.', 'success');\r\n    },\r\n\r\n    exportJSON: function () {\r\n      if (!this.ings.length) { this.toast('Nothing to export.', 'error'); return; }\r\n      this.download(JSON.stringify(this.currentRecipe(), null, 2), 'recipe.json', 'application\/json'); this.toast('JSON downloaded.', 'success');\r\n    },\r\n\r\n    download: function (data, fname, mime) {\r\n      var blob = new Blob([data], { type: mime }); var url = URL.createObjectURL(blob);\r\n      var a = document.createElement('a'); a.href = url; a.download = fname; document.body.appendChild(a); a.click(); document.body.removeChild(a);\r\n      setTimeout(function () { URL.revokeObjectURL(url); }, 1500);\r\n    },\r\n\r\n    \/* ---------- notes ---------- *\/\r\n    loadNotes: function () { try { var n = localStorage.getItem(STORE_N); if (n) { var ta = document.getElementById('rc-notes'); if (ta) { ta.value = n; } } } catch (e) {} },\r\n    saveNotes: function () { try { localStorage.setItem(STORE_N, (document.getElementById('rc-notes') || {}).value || ''); this.toast('Notes saved.', 'success'); } catch (e) { this.toast('Could not save.', 'error'); } },\r\n    copyNotes: function () {\r\n      var self = this, txt = (document.getElementById('rc-notes') || {}).value || '';\r\n      if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(txt).then(function () { self.toast('Copied.', 'success'); })['catch'](function () {}); }\r\n    },\r\n\r\n    \/* ---------- misc ---------- *\/\r\n    loadSample: function () {\r\n      this.ings = [\r\n        { name: 'Chicken breast', kcal: 165, protein: 31, carbs: 0, fat: 4, fiber: 0, tags: [], amount: 500, unit: 'g', price: 4.50 },\r\n        { name: 'Coconut milk', kcal: 230, protein: 2, carbs: 6, fat: 24, fiber: 0, tags: [], amount: 400, unit: 'ml', price: 1.20 },\r\n        { name: 'Onion', kcal: 40, protein: 1, carbs: 9, fat: 0, fiber: 2, tags: [], amount: 150, unit: 'g', price: 0.30 },\r\n        { name: 'White rice (cooked)', kcal: 130, protein: 3, carbs: 28, fat: 0, fiber: 0, tags: [], amount: 600, unit: 'g', price: 0.80 }\r\n      ];\r\n      var nm = document.getElementById('rc-name'); if (nm) { nm.value = 'Chicken & coconut rice'; }\r\n      var sv = document.getElementById('rc-servings'); if (sv) { sv.value = 4; }\r\n      this.renderIngs(); this.recompute(); this.switchTab('build');\r\n    },\r\n\r\n    clearAll: function () {\r\n      this.ings = [];\r\n      var nm = document.getElementById('rc-name'); if (nm) { nm.value = ''; }\r\n      this.renderIngs(); this.recompute(); this.toast('Workspace cleared.', 'info');\r\n    },\r\n\r\n    toast: function (msg, type) {\r\n      var t = document.getElementById('pth-rc-toast'); if (!t) { return; }\r\n      var colors = { success: '#059669', error: '#dc2626', info: '#ea580c' };\r\n      t.style.background = colors[type] || colors.info; t.textContent = msg; t.className = 'pth-rc-toast show';\r\n      if (this._tt) { clearTimeout(this._tt); }\r\n      this._tt = setTimeout(function () { t.className = 'pth-rc-toast'; }, 3000);\r\n    }\r\n  };\r\n\r\n  window.pthRecipeCalcApp = App;\r\n\r\n  function runInit() {\r\n    if (!window.pthRecipeCalcApp.initialized && document.getElementById('pth-recipecalc-wrap')) {\r\n      window.pthRecipeCalcApp.initialized = true;\r\n      window.pthRecipeCalcApp.init();\r\n    }\r\n  }\r\n  runInit();\r\n  if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', runInit); }\r\n  window.addEventListener('load', function () { setTimeout(runInit, 50); });\r\n  if (!window.pthRecipeCalcApp.initialized && typeof MutationObserver !== 'undefined') {\r\n    var obs = new MutationObserver(function () { if (document.getElementById('pth-recipecalc-wrap')) { obs.disconnect(); runInit(); } });\r\n    obs.observe(document.body || document.documentElement, { childList: true, subtree: true });\r\n    setTimeout(function () { obs.disconnect(); }, 10000);\r\n  }\r\n})();\r\n<\/script>\n\n\n\n<style>\n.pth-container{max-width:1480px;margin:0 auto;padding:0 20px;box-sizing:border-box}\n.pth-feature-wrap{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px;margin-bottom:40px}\n.pth-feat-box{border:1px solid #e2e8f0;background:#fff;padding:24px;border-radius:12px;box-shadow:0 4px 6px -1px rgba(0,0,0,0.02)}\n.pth-feat-title{font-size:1.05rem;font-weight:800;color:#0f172a;margin:0 0 10px;display:flex;align-items:center;gap:10px}\n.pth-feat-text{font-size:.9rem;color:#1e293b;line-height:1.6;margin:0;font-weight:500}\n.pth-steps-wrap{border:1px solid #e2e8f0;background:#fff;padding:40px 30px;border-radius:16px;text-align:center;box-shadow:0 4px 6px -1px rgba(0,0,0,0.02);margin-bottom:40px;width:100%;box-sizing:border-box}\n.pth-steps-title{font-size:1.2rem;font-weight:800;color:#0f172a;text-transform:uppercase;margin:0 0 35px;letter-spacing:1px}\n.pth-steps-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:30px}\n.pth-step-item{display:flex;flex-direction:column;align-items:center}\n.pth-step-num{width:45px;height:45px;background:#ea580c;color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:1.2rem;margin-bottom:15px;box-shadow:0 4px 10px rgba(234,88,12,.3)}\n.pth-step-name{font-weight:800;color:#0f172a;margin:0 0 8px;font-size:1rem}\n.pth-step-desc{font-size:.9rem;color:#1e293b;line-height:1.5;margin:0;font-weight:500}\n<\/style>\n<div class=\"pth-container\">\n  <div class=\"pth-feature-wrap\">\n    <div class=\"pth-feat-box\">\n      <p class=\"pth-feat-title\"><span aria-hidden=\"true\">&#128176;<\/span> Cost Per Serving<\/p>\n      <p class=\"pth-feat-text\">Add a price to each ingredient and the studio works out what one serving actually costs, plus the whole-recipe total and a cost-per-100-calories figure that makes budget cooking easy to compare.<\/p>\n    <\/div>\n    <div class=\"pth-feat-box\">\n      <p class=\"pth-feat-title\"><span aria-hidden=\"true\">&#127991;&#65039;<\/span> Nutrition Facts Label<\/p>\n      <p class=\"pth-feat-text\">Every recipe generates a clean, FDA-style nutrition label per serving with calories, macros, fiber, and % Daily Values, ready to copy, print, or export as CSV or JSON.<\/p>\n    <\/div>\n    <div class=\"pth-feat-box\">\n      <p class=\"pth-feat-title\"><span aria-hidden=\"true\">&#128207;<\/span> Units, Scaling &amp; Compare<\/p>\n      <p class=\"pth-feat-text\">Enter amounts in grams, ounces, cups, or spoons and it converts them for you. Change the serving count to rescale instantly, and line up saved recipes side by side.<\/p>\n    <\/div>\n  <\/div>\n  <div class=\"pth-steps-wrap\">\n    <p class=\"pth-steps-title\">How to Use the Recipe Nutrition &amp; Cost Studio<\/p>\n    <div class=\"pth-steps-grid\">\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">1<\/div>\n        <p class=\"pth-step-name\">Name it<\/p>\n        <p class=\"pth-step-desc\">Enter your recipe name, how many servings it makes, and your currency.<\/p>\n      <\/div>\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">2<\/div>\n        <p class=\"pth-step-name\">Add ingredients<\/p>\n        <p class=\"pth-step-desc\">Pick from the database or add custom, then set the amount, unit, and price for each.<\/p>\n      <\/div>\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">3<\/div>\n        <p class=\"pth-step-name\">Read the numbers<\/p>\n        <p class=\"pth-step-desc\">See per-serving calories, macros, and cost update live as you type.<\/p>\n      <\/div>\n      <div class=\"pth-step-item\">\n        <div class=\"pth-step-num\" aria-hidden=\"true\">4<\/div>\n        <p class=\"pth-step-name\">Label or export<\/p>\n        <p class=\"pth-step-desc\">Open the Nutrition Label tab to copy, print, or export CSV and JSON.<\/p>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n\n<div id=\"start-seo-article\"><\/div>\n\n\n<p class=\"wp-block-paragraph\">Last updated: August 2026<\/p>\n\n\n\n<h2 id=\"\ud83d\udd34-what-you-can-work-out-with-it\" class=\"wp-block-heading\">\ud83d\udd34&nbsp;<strong>What you can work out with it<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This recipe nutrition calculator answers two questions at once that usually take two separate tools: what is in a dish, and what it costs. Home cooks use it to see the calories and protein in a family meal, meal-preppers use it to keep a batch on budget, and small food sellers use it to price a dish with a real margin instead of a guess. Everything runs in your browser, so your recipes and prices stay on your own device with nothing uploaded.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you are planning several days of meals rather than costing one dish, the&nbsp;<a href=\"https:\/\/schoolict.net\/tools\/free-offline-weight-loss-meal-planner\/\">7-day Meal Plan Studio<\/a>&nbsp;is the better fit, and the two work well together: build and cost a recipe here, then drop the dish into your week there.<\/p>\n\n\n\n<h2 id=\"\ud83d\udfe1-from-ingredient-list-to-cost-and-nutrition\" class=\"wp-block-heading\">\ud83d\udfe1&nbsp;<strong>From ingredient list to cost and nutrition<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Start on the Build tab and add ingredients one at a time. For each, set the amount and choose a unit \u2014 grams, ounces, pounds, millilitres, cups, tablespoons, or teaspoons \u2014 and the tool converts everything to a common weight behind the scenes so the nutrition maths lines up. Add the price you paid for that amount, and it totals the recipe cost, divides by your servings, and shows a cost-per-serving figure straight away.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Nutrition Label tab turns the same recipe into a per-serving label modelled on the standard&nbsp;<a href=\"https:\/\/www.fda.gov\/food\/nutrition-facts-label\" target=\"_blank\" rel=\"noreferrer noopener\">FDA Nutrition Facts panel<\/a>, with % Daily Values worked out against a 2,000-calorie reference. From there you can copy it as text, export a CSV or JSON, or print it. If you need physical printed labels for jars or packaging, the&nbsp;<a href=\"https:\/\/schoolict.net\/tools\/csv-to-label-maker\/\">CSV to Label Maker<\/a>&nbsp;takes that exported data further.<\/p>\n\n\n\n<h2 id=\"\ud83d\udfe2-making-the-numbers-accurate\" class=\"wp-block-heading\">\ud83d\udfe2&nbsp;<strong>Making the numbers accurate<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A few habits keep the figures honest. Weigh ingredients in grams where you can, since volume units like cups are approximations that vary with how tightly something is packed. Enter prices for the exact amount you actually used, not the whole packet, so the cost reflects the recipe rather than your shopping. And remember the nutrition values come from a general database, so a specific brand or a different cut of meat will shift them slightly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Used this way, this recipe nutrition calculator is close enough for meal planning, budgeting, and everyday label-making. For the reasoning behind keeping a tool like this fully on your device, the&nbsp;<a href=\"https:\/\/schoolict.net\/tools\/secure-offline-web-development-utilities-guide\/\">offline utilities guide<\/a>&nbsp;explains the privacy case. And if you want the maths spelled out, the companion article on&nbsp;<a href=\"https:\/\/schoolict.net\/tools\/how-to-calculate-recipe-cost\/\">how to calculate recipe cost per serving<\/a>&nbsp;walks through every step.<\/p>\n\n\n\n<style>\n.pth-faq-wrap{max-width:1480px;margin:0 auto;padding:0 20px;box-sizing:border-box}\n.pth-faq-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}\n.pth-faq-card{border:1px solid #e2e8f0;background:#fff;border-radius:12px;padding:18px}\n.pth-faq-q{font-weight:800;color:#0f172a;margin:0 0 8px;font-size:1rem}\n.pth-faq-a{color:#1e293b;font-weight:500;line-height:1.6;margin:0;font-size:.92rem}\n@media(max-width:1024px){.pth-faq-grid{grid-template-columns:repeat(2,1fr)}}\n@media(max-width:640px){.pth-faq-grid{grid-template-columns:1fr}}\n<\/style>\n<div class=\"pth-faq-wrap\">\n  <div class=\"pth-faq-grid\">\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Is it free, offline, and private?<\/p>\n      <p class=\"pth-faq-a\">Yes. It runs entirely in your browser, so your recipes and prices never leave your device. There is no account and no upload, and it keeps working after the page has loaded even without a connection.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">How is cost per serving calculated?<\/p>\n      <p class=\"pth-faq-a\">It adds up the price you entered for every ingredient to get the total recipe cost, then divides by the number of servings. It also shows cost per 100 calories, which is handy for comparing value.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Can it make a nutrition label?<\/p>\n      <p class=\"pth-faq-a\">Yes. The Nutrition Label tab builds a per-serving, FDA-style Nutrition Facts panel with calories, macros, fiber, and % Daily Values that you can copy, print, or export.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">What units can I use?<\/p>\n      <p class=\"pth-faq-a\">Grams, kilograms, ounces, pounds, millilitres, litres, cups, tablespoons, and teaspoons. The tool converts them to a common weight so the nutrition maths stays consistent.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">How accurate are the numbers?<\/p>\n      <p class=\"pth-faq-a\">They are solid estimates. Nutrition comes from a general ingredient database, so brand and preparation shift things a little. Weighing in grams and pricing the exact amount used gives the closest result.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Can I compare recipes?<\/p>\n      <p class=\"pth-faq-a\">Yes. Save a few recipes and the Compare tab lines up their per-serving calories, macros, and cost side by side, so you can see which dish is leaner or cheaper at a glance.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Can I save and export my work?<\/p>\n      <p class=\"pth-faq-a\">Recipes save in this browser, and you can export any recipe as CSV or JSON, copy the label as text, or print it. Your notes are saved locally too.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">I want to plan a whole week, not one dish.<\/p>\n      <p class=\"pth-faq-a\">Then use the Meal Plan Studio, which handles a full seven-day plan with targets and a grocery list. This tool focuses on costing and labelling individual recipes.<\/p>\n    <\/div>\n    <div class=\"pth-faq-card\">\n      <p class=\"pth-faq-q\">Does it work on a phone?<\/p>\n      <p class=\"pth-faq-a\">Yes. The layout stacks into a single column on small screens, so you can build a recipe and read its cost and nutrition from a phone.<\/p>\n    <\/div>\n  <\/div>\n<\/div>\n \n","protected":false},"excerpt":{"rendered":"<p>Smart Recipe Calculator | Instant Nutrition Breakdown, Food Costing &amp; Automatic Unit Conversion Easily analyze your meals with our free recipe nutrition calculator. Auto-scale servings, track macros (protein, carbs, fat), and calculate recipe costs instantly in your browser. \u00a0 &#128176; Cost Per Serving Add a price to each ingredient and the studio works out what &#8230; <a title=\"Free Recipe Nutrition Calculator (Auto-Scale &amp; Convert)\" class=\"read-more\" href=\"https:\/\/schoolict.net\/tools\/free-recipe-nutrition-calculator\/\" aria-label=\"Read more about Free Recipe Nutrition Calculator (Auto-Scale &amp; Convert)\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":4192,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-4181","page","type-page","status-publish","has-post-thumbnail"],"_links":{"self":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/4181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/comments?post=4181"}],"version-history":[{"count":2,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/4181\/revisions"}],"predecessor-version":[{"id":6974,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/4181\/revisions\/6974"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media\/4192"}],"wp:attachment":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media?parent=4181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}