{"id":133,"date":"2026-03-14T13:18:56","date_gmt":"2026-03-14T04:18:56","guid":{"rendered":"https:\/\/tanakacoffeelab.com\/english\/?p=133"},"modified":"2026-03-14T13:23:39","modified_gmt":"2026-03-14T04:23:39","slug":"roast_calc","status":"publish","type":"post","link":"https:\/\/tanakacoffeelab.com\/english\/roast_calc\/","title":{"rendered":"Coffee Roast Level Calculator: Determine Roast Degree by Weight Loss"},"content":{"rendered":"\n<style>\n  \/* \u30b9\u30bf\u30a4\u30eb\u306f\u5143\u306e\u30c7\u30b6\u30a4\u30f3\u3092\u7dad\u6301 *\/\n  .container{\n    max-width:560px;\n    margin:0 auto;\n  }\n  .form{\n    background:var(--card);\n    padding:28px 24px;\n    border-radius:14px;\n    border:1px solid var(--brand);\n    box-shadow:0 10px 24px rgba(0,0,0,.08);\n  }\n  .form-title{\n    font-weight:700;\n    font-size:1.4rem;\n    text-align:center;\n    margin:0 0 14px;\n    color:#222;\n  }\n  .form-sub{\n    font-size:.92rem;\n    color:var(--muted);\n    text-align:center;\n    margin:0 0 18px;\n  }\n  .form-grid{\n    display:grid;\n    grid-template-columns:1fr;\n    gap:12px;\n  }\n  @media (min-width:520px){\n    .form-grid{ grid-template-columns:1fr 1fr; }\n  }\n  .form-group{\n    display:flex;\n    flex-direction:column;\n    gap:6px;\n  }\n  label{\n    font-size:.95rem;\n    color:#444;\n  }\n  .row{\n    display:flex;\n    gap:8px;\n    align-items:center;\n  }\n  .unit{\n    white-space:nowrap;\n    font-size:.95rem;\n    color:#555;\n  }\n  .form-input{\n    flex:1;\n    width:100%;\n    padding:10px 12px;\n    border:1px solid #d8dde6;\n    border-radius:10px;\n    background:#fff;\n    box-sizing:border-box;\n    height:40px;\n    transition:border-color .2s, box-shadow .2s;\n  }\n  .form-input:focus{\n    outline:none;\n    border-color:var(--brand);\n    box-shadow:0 0 0 3px rgba(50,161,206,.18);\n  }\n  .action-row{\n    display:flex;\n    gap:10px;\n    margin-top:10px;\n  }\n  .btn{\n    appearance:none;\n    border:none;\n    border-radius:10px;\n    padding:12px 14px;\n    font-weight:700;\n    cursor:pointer;\n    transition:transform .06s ease, background-color .2s ease;\n  }\n  .btn-primary{\n    flex:1;\n    background:var(--brand);\n    color:#fff;\n  }\n  .btn-primary:hover{ background:var(--brand-dark); }\n  .btn:active{ transform:scale(.98); }\n  .btn-ghost{\n    background:#eef6fb;\n    color:var(--brand-dark);\n  }\n  .result-card{\n    margin-top:18px;\n    padding:16px;\n    border-radius:12px;\n    border:1px solid var(--border);\n    background:#fcfdff;\n  }\n  .result-line{\n    display:flex;\n    justify-content:space-between;\n    align-items:baseline;\n    gap:10px;\n    padding:6px 0;\n    border-bottom:1px dashed #e9eef4;\n  }\n  .result-line:last-child{ border-bottom:none; }\n  .result-label{\n    color:#4a5568;\n    font-size:.95rem;\n  }\n  .result-value{\n    font-weight:800;\n    font-size:1.1rem;\n    color:var(--brand-dark);\n  }\n  .badge{\n    display:inline-block;\n    padding:4px 8px;\n    border-radius:999px;\n    font-weight:700;\n    font-size:.85rem;\n    background:#eaf7fc;\n    color:var(--brand-dark);\n  }\n  .note{\n    margin-top:10px;\n    font-size:.9rem;\n    color:#556;\n  }\n  .error{\n    margin-top:10px;\n    color:var(--danger);\n    font-size:.92rem;\n    min-height:1.2em;\n  }\n  .helper{\n    font-size:.85rem;\n    color:#6b7280;\n  }\n<\/style>\n\n<div class=\"container\">\n  <form class=\"form\" id=\"roastForm\" onsubmit=\"event.preventDefault(); calc();\">\n    <p class=\"form-sub\">Calculate the Roast Index and weight loss percentage based on green and roasted coffee weights.<\/p>\n\n    <div class=\"form-grid\">\n      <div class=\"form-group\">\n        <label for=\"wbefore\">Green Bean Weight<\/label>\n        <div class=\"row\">\n          <input type=\"number\" id=\"wbefore\" class=\"form-input\"\n                 inputmode=\"decimal\" step=\"0.1\" min=\"1\" placeholder=\"e.g. 200\" required \/>\n          <span class=\"unit\">g<\/span>\n        <\/div>\n        <div class=\"helper\">Weight before roasting (green)<\/div>\n      <\/div>\n\n      <div class=\"form-group\">\n        <label for=\"wafter\">Roasted Bean Weight<\/label>\n        <div class=\"row\">\n          <input type=\"number\" id=\"wafter\" class=\"form-input\"\n                 inputmode=\"decimal\" step=\"0.1\" min=\"1\" placeholder=\"e.g. 170\" required \/>\n          <span class=\"unit\">g<\/span>\n        <\/div>\n        <div class=\"helper\">Weight after cooling down<\/div>\n      <\/div>\n    <\/div>\n\n    <div class=\"action-row\">\n      <button type=\"submit\" class=\"btn btn-primary\" id=\"calcBtn\">Calculate<\/button>\n      <button type=\"button\" class=\"btn btn-ghost\" id=\"clearBtn\">Clear<\/button>\n    <\/div>\n\n    <div class=\"result-card\" aria-live=\"polite\">\n      <div class=\"result-line\">\n        <span class=\"result-label\">Roast Index<\/span>\n        <span class=\"result-value\" id=\"shisuu\">\u2014<\/span>\n      <\/div>\n      <div class=\"result-line\">\n        <span class=\"result-label\">Weight Loss<\/span>\n        <span class=\"result-value\" id=\"loss\">\u2014<\/span>\n      <\/div>\n      <div class=\"result-line\">\n        <span class=\"result-label\">Estimated Roast Level<\/span>\n        <span class=\"result-value\"><span class=\"badge\" id=\"grade\">\u2014<\/span><\/span>\n      <\/div>\n      <p id=\"error\" class=\"error\"><\/p>\n    <\/div>\n  <\/form>\n<\/div>\n\n<script>\n(function(){\n  const beforeEl = document.getElementById(\"wbefore\");\n  const afterEl  = document.getElementById(\"wafter\");\n  const shisuuEl = document.getElementById(\"shisuu\");\n  const lossEl   = document.getElementById(\"loss\");\n  const gradeEl  = document.getElementById(\"grade\");\n  const errorEl  = document.getElementById(\"error\");\n  const clearBtn = document.getElementById(\"clearBtn\");\n\n  beforeEl.addEventListener(\"input\", autoCalc, {passive:true});\n  afterEl.addEventListener(\"input\", autoCalc, {passive:true});\n\n  clearBtn.addEventListener(\"click\", () => {\n    beforeEl.value = \"\";\n    afterEl.value = \"\";\n    renderResult(null);\n    errorEl.textContent = \"\";\n    beforeEl.focus();\n  });\n\n  function autoCalc(){\n    if(!beforeEl.value || !afterEl.value) { return; }\n    calc();\n  }\n\n  window.calc = function(){\n    const wbefore = parseFloat(beforeEl.value);\n    const wafter  = parseFloat(afterEl.value);\n\n    errorEl.textContent = \"\";\n\n    if(Number.isNaN(wbefore) || Number.isNaN(wafter) || wbefore <= 0 || wafter <= 0){\n      return showError(\"Please enter valid positive numbers.\");\n    }\n    if(wafter >= wbefore){\n      return showError(\"Roasted weight must be less than green weight. Please check your measurements.\");\n    }\n\n    const index = wbefore \/ wafter;\n    const indexDisp = (Math.round(index*1000)\/1000).toFixed(3);\n    const lossPct = (1 - (wafter \/ wbefore)) * 100;\n    const lossDisp = lossPct.toFixed(1) + \"%\";\n\n    if(index < 1.05 || index > 1.35){\n      errorEl.textContent = \"Result is outside the typical range (1.05 - 1.35). Please verify your weights.\";\n    }\n\n    const grade = judge(index);\n    renderResult({ indexDisp, lossDisp, grade });\n  };\n\n  function judge(x){\n    if(x < 1.00){\n      return \"Under-roasted (<1.00)\";\n    } else if(x >= 1.10 && x < 1.125){\n      return \"Light Roast\";\n    } else if(x >= 1.125 && x < 1.150){\n      return \"Cinnamon Roast\";\n    } else if(x >= 1.150 && x < 1.175){\n      return \"Medium Roast\";\n    } else if(x >= 1.175 && x < 1.200){\n      return \"High Roast\";\n    } else if(x >= 1.200 && x < 1.225){\n      return \"City Roast\";\n    } else if(x >= 1.225 && x < 1.250){\n      return \"Full City Roast\";\n    } else if(x >= 1.250 && x < 1.275){\n      return \"French Roast\";\n    } else if(x >= 1.275 && x < 1.300){\n      return \"Italian Roast\";\n    } else if(x >= 1.00 && x < 1.10){\n      return \"Very Light (Verify)\";\n    } else if(x >= 1.300){\n      return \"Very Dark (Verify)\";\n    }\n    return \"N\/A\";\n  }\n\n  function renderResult(payload){\n    if(!payload){\n      shisuuEl.textContent = \"\u2014\";\n      lossEl.textContent = \"\u2014\";\n      gradeEl.textContent = \"\u2014\";\n      return;\n    }\n    shisuuEl.textContent = payload.indexDisp;\n    lossEl.textContent = payload.lossDisp;\n    gradeEl.textContent = payload.grade;\n  }\n\n  function showError(msg){\n    errorEl.textContent = msg;\n    renderResult(null);\n  }\n})();\n<\/script>\n\n\n<div class=\"p-adBox -normal -border-off\" data-id=\"18\" data-ad=\"normal\"><div class=\"p-adBox__body\"><div class=\"p-adBox__img\"><p>\u3010PR\u3011<\/p>\r\n<script async src=\"https:\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-2455376819472767\"\r\n     crossorigin=\"anonymous\"><\/script>\r\n<!-- contents -->\r\n<ins class=\"adsbygoogle\"\r\n     style=\"display:block\"\r\n     data-ad-client=\"ca-pub-2455376819472767\"\r\n     data-ad-slot=\"1764394185\"\r\n     data-ad-format=\"auto\"\r\n     data-full-width-responsive=\"true\"><\/ins>\r\n<script>\r\n     (adsbygoogle = window.adsbygoogle || []).push({});\r\n<\/script><\/div><\/div><\/div>\n\n\n<div class=\"wp-block-group has-border -border01\"><div class=\"wp-block-group__inner-container\">\n<h3 class=\"wp-block-heading\">Understanding the Estimated Roast Level<\/h3>\n\n\n\n<p>The roast level is determined by the <strong>Roast Index (Green Weight \/ Roasted Weight)<\/strong>. As beans are roasted longer, they lose more moisture and organic matter, increasing the index.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>Roast Level<\/strong><\/td><td><strong>Roast Index<\/strong><\/td><td><strong>Characteristics<\/strong><\/td><\/tr><\/thead><tbody><tr><td><strong>Light \/ Cinnamon<\/strong><\/td><td><strong>1.10 \u2013 1.15<\/strong><\/td><td>High acidity, tea-like body. No oils on the surface.<\/td><\/tr><tr><td><strong>Medium \/ High<\/strong><\/td><td><strong>1.15 \u2013 1.20<\/strong><\/td><td>Balanced acidity and sweetness. Standard for many specialty coffees.<\/td><\/tr><tr><td><strong>City \/ Full City<\/strong><\/td><td><strong>1.20 \u2013 1.25<\/strong><\/td><td>Rich body, slight bitterness. Tiny oil droplets may appear in Full City.<\/td><\/tr><tr><td><strong>French \/ Italian<\/strong><\/td><td><strong>1.25 \u2013 1.30+<\/strong><\/td><td>Strong bitterness, smoky aroma. Beans look oily and dark brown\/black.<\/td><\/tr><\/tbody><\/table><\/figure>\n<\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">How to Use the Roast Calculator<\/h2>\n\n\n\n<p>Tracking the weight loss of your coffee beans is one of the most accurate ways to determine the roast level. Use this tool to keep your roasting consistent!<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Green Bean Weight<\/strong>: Enter the weight of the beans before roasting.<\/li>\n\n\n\n<li><strong>Roasted Bean Weight<\/strong>: Enter the weight after roasting (for best results, weigh them after they have cooled down).<\/li>\n\n\n\n<li><strong>Calculate<\/strong>: The tool will automatically calculate the <strong>Roast Index<\/strong> and <strong>Weight Loss %<\/strong>.<\/li>\n\n\n\n<li><strong>Result<\/strong>: Check the &#8220;Estimated Roast Level&#8221; to see if your batch is Light, Medium, or Dark.<\/li>\n<\/ol>\n\n\n<div class=\"p-adBox -normal -border-off\" data-id=\"18\" data-ad=\"normal\"><div class=\"p-adBox__body\"><div class=\"p-adBox__img\"><p>\u3010PR\u3011<\/p>\r\n<script async src=\"https:\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-2455376819472767\"\r\n     crossorigin=\"anonymous\"><\/script>\r\n<!-- contents -->\r\n<ins class=\"adsbygoogle\"\r\n     style=\"display:block\"\r\n     data-ad-client=\"ca-pub-2455376819472767\"\r\n     data-ad-slot=\"1764394185\"\r\n     data-ad-format=\"auto\"\r\n     data-full-width-responsive=\"true\"><\/ins>\r\n<script>\r\n     (adsbygoogle = window.adsbygoogle || []).push({});\r\n<\/script><\/div><\/div><\/div>\n\n\n<h2 class=\"wp-block-heading\">What is the Roast Index?<\/h2>\n\n\n\n<p>The Roast Index is a numerical value representing the degree of roast, calculated by dividing the green weight by the roasted weight.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Typical Range<\/strong>: Usually stays between <strong>1.05 and 1.35<\/strong>.<\/li>\n\n\n\n<li><strong>Weight Loss<\/strong>: Most roasts result in a <strong>12% to 22%<\/strong> weight loss.<\/li>\n<\/ul>\n\n\n<div class=\"p-adBox -normal -border-off\" data-id=\"18\" data-ad=\"normal\"><div class=\"p-adBox__body\"><div class=\"p-adBox__img\"><p>\u3010PR\u3011<\/p>\r\n<script async src=\"https:\/\/pagead2.googlesyndication.com\/pagead\/js\/adsbygoogle.js?client=ca-pub-2455376819472767\"\r\n     crossorigin=\"anonymous\"><\/script>\r\n<!-- contents -->\r\n<ins class=\"adsbygoogle\"\r\n     style=\"display:block\"\r\n     data-ad-client=\"ca-pub-2455376819472767\"\r\n     data-ad-slot=\"1764394185\"\r\n     data-ad-format=\"auto\"\r\n     data-full-width-responsive=\"true\"><\/ins>\r\n<script>\r\n     (adsbygoogle = window.adsbygoogle || []).push({});\r\n<\/script><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>Calculate the Roast Index and weight loss percentage based on green and roasted coffee weights. Green Bean Weight g Weight before roasting (green) Roasted Bean Weight g Weight after cooling down Calculate Clear Roast Index \u2014 Weight Loss \u2014 Estimated Roast Level \u2014 Understanding the Estimated Roast Level The roast level is determined by the Roast Index (Green Weight \/ Roasted Weight). As beans are roasted longer, they lose more moisture and organic matter, increasing the index. Roast Level Roast Index Characteristics Light \/ Cinnamon 1.10 \u2013 1.15 High acidity, tea-like body. No oils on the surface. Medium \/ High 1.15 \u2013 1.20 Balanced acidity and sweetness. Standard for many [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":134,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"swell_btn_cv_data":"","footnotes":""},"categories":[3],"tags":[],"class_list":["post-133","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-random-notes"],"_links":{"self":[{"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/posts\/133","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/comments?post=133"}],"version-history":[{"count":2,"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/posts\/133\/revisions"}],"predecessor-version":[{"id":137,"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/posts\/133\/revisions\/137"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/media\/134"}],"wp:attachment":[{"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/media?parent=133"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/categories?post=133"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tanakacoffeelab.com\/english\/wp-json\/wp\/v2\/tags?post=133"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}