{"id":3049,"date":"2026-09-10T10:15:03","date_gmt":"2026-09-10T07:15:03","guid":{"rendered":"https:\/\/oxroastery.com\/?page_id=3049"},"modified":"2026-09-20T12:01:10","modified_gmt":"2026-09-20T09:01:10","slug":"grind-calculator","status":"publish","type":"page","link":"https:\/\/oxroastery.com\/ar\/grind-calculator\/","title":{"rendered":"Grind Calculator"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"3049\" class=\"elementor elementor-3049\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-324a965b e-flex e-con-boxed e-con e-parent\" data-id=\"324a965b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1d57438 elementor-widget elementor-widget-html\" data-id=\"1d57438\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>Coffee Dial-In Widget<\/title>\r\n<\/head>\r\n<body>\r\n\r\n<div id=\"coffee-dial-in-widget\">\r\n    <style>\r\n        #coffee-dial-in-widget {\r\n            --bg-color: #121417;\r\n            --card-bg: #1c2026;\r\n            --primary: #ffffff;\r\n            --accent: #f59e0b;\r\n            --accent-hover: #d97706;\r\n            --accent-light: rgba(245, 158, 11, 0.15);\r\n            --border: #2e353f;\r\n            --text-main: #f3f4f6;\r\n            --text-muted: #9ca3af;\r\n            --radius-lg: 16px;\r\n            --radius-md: 10px;\r\n            --shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.3);\r\n            font-family: 'Plus Jakarta Sans', sans-serif;\r\n            background-color: var(--bg-color);\r\n            color: var(--text-main);\r\n            padding: 20px 10px;\r\n            border-radius: var(--radius-lg);\r\n            box-sizing: border-box;\r\n            width: 100%;\r\n        }\r\n\r\n        #coffee-dial-in-widget * {\r\n            box-sizing: border-box;\r\n        }\r\n\r\n        #coffee-dial-in-widget .container {\r\n            max-width: 650px;\r\n            background: var(--card-bg);\r\n            padding: 25px;\r\n            margin: 0 auto;\r\n            border-radius: var(--radius-lg);\r\n            box-shadow: var(--shadow);\r\n            border: 1px solid var(--border);\r\n        }\r\n\r\n        #coffee-dial-in-widget .header-title {\r\n            font-size: 1.25rem;\r\n            font-weight: 700;\r\n            color: var(--text-muted);\r\n            text-transform: uppercase;\r\n            letter-spacing: 0.05em;\r\n            text-align: center;\r\n            margin-top: 0;\r\n            margin-bottom: 10px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .coffee-heading {\r\n            font-size: 1.8rem;\r\n            font-weight: 700;\r\n            color: var(--primary);\r\n            text-align: center;\r\n            margin-bottom: 20px;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 10px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .config-grid {\r\n            display: grid;\r\n            grid-template-columns: 1fr;\r\n            gap: 12px;\r\n            background: #16191e;\r\n            padding: 15px;\r\n            border-radius: var(--radius-md);\r\n            border: 1px solid var(--border);\r\n            margin-bottom: 20px;\r\n        }\r\n\r\n        @media (min-width: 550px) {\r\n            #coffee-dial-in-widget .config-grid {\r\n                grid-template-columns: repeat(3, 1fr);\r\n            }\r\n        }\r\n\r\n        #coffee-dial-in-widget .field-group label {\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: space-between;\r\n            font-size: 0.7rem;\r\n            font-weight: 700;\r\n            text-transform: uppercase;\r\n            letter-spacing: 0.05em;\r\n            margin-bottom: 4px;\r\n            color: var(--text-muted);\r\n        }\r\n\r\n        #coffee-dial-in-widget .info-btn {\r\n            background: var(--border);\r\n            color: var(--primary);\r\n            border: none;\r\n            width: 16px;\r\n            height: 16px;\r\n            border-radius: 50%;\r\n            font-size: 0.65rem;\r\n            font-weight: 700;\r\n            cursor: pointer;\r\n            display: inline-flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            transition: background 0.2s;\r\n            flex-shrink: 0;\r\n        }\r\n\r\n        #coffee-dial-in-widget .info-btn:hover {\r\n            background: var(--accent);\r\n            color: #121417;\r\n        }\r\n\r\n        #coffee-dial-in-widget .field-group select, \r\n        #coffee-dial-in-widget .field-group input {\r\n            width: 100%;\r\n            padding: 8px 10px;\r\n            border: 1px solid var(--border);\r\n            border-radius: 6px;\r\n            background: #121417;\r\n            font-family: inherit;\r\n            font-size: 0.9rem;\r\n            color: var(--text-main);\r\n        }\r\n\r\n        #coffee-dial-in-widget .field-group select option {\r\n            background: #121417;\r\n            color: var(--text-main);\r\n            padding: 8px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .step-heading {\r\n            display: flex;\r\n            align-items: center;\r\n            gap: 10px;\r\n            font-size: 1rem;\r\n            font-weight: 700;\r\n            color: var(--primary);\r\n            margin: 20px 0 10px 0;\r\n        }\r\n\r\n        #coffee-dial-in-widget .step-number {\r\n            background: var(--accent);\r\n            color: #121417;\r\n            width: 24px;\r\n            height: 24px;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            border-radius: 50%;\r\n            font-size: 0.8rem;\r\n            font-weight: 700;\r\n        }\r\n\r\n        #coffee-dial-in-widget .sub-label {\r\n            font-size: 0.8rem;\r\n            font-weight: 600;\r\n            color: var(--text-muted);\r\n            margin: 12px 0 8px 0;\r\n        }\r\n\r\n        #coffee-dial-in-widget .options-grid {\r\n            display: grid;\r\n            grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));\r\n            gap: 8px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .option-card {\r\n            border: 1px solid var(--border);\r\n            border-radius: 8px;\r\n            padding: 10px 8px;\r\n            text-align: center;\r\n            cursor: pointer;\r\n            background: #16191e;\r\n            transition: all 0.2s ease;\r\n            user-select: none;\r\n            font-size: 0.85rem;\r\n            font-weight: 500;\r\n            color: var(--text-main);\r\n            display: flex;\r\n            flex-direction: column;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 6px;\r\n            position: relative;\r\n        }\r\n\r\n        #coffee-dial-in-widget .option-card-top {\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 6px;\r\n            width: 100%;\r\n        }\r\n\r\n        #coffee-dial-in-widget .option-card input[type=\"checkbox\"] {\r\n            accent-color: var(--accent);\r\n            width: 14px;\r\n            height: 14px;\r\n            cursor: pointer;\r\n            margin: 0;\r\n            flex-shrink: 0;\r\n        }\r\n\r\n        #coffee-dial-in-widget .option-card.active {\r\n            border-color: var(--accent);\r\n            background: var(--accent-light);\r\n            color: var(--accent);\r\n            font-weight: 700;\r\n        }\r\n\r\n        #coffee-dial-in-widget .calculate-btn {\r\n            background: var(--accent);\r\n            color: #121417;\r\n            border: none;\r\n            width: 100%;\r\n            padding: 14px;\r\n            font-size: 1rem;\r\n            font-weight: 700;\r\n            border-radius: var(--radius-md);\r\n            cursor: pointer;\r\n            margin-top: 25px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .calculate-btn:hover {\r\n            background: var(--accent-hover);\r\n        }\r\n\r\n        #coffee-dial-in-widget .result-container {\r\n            margin-top: 5px;\r\n            background: #16191e;\r\n            border: 1px solid var(--border);\r\n            padding: 20px;\r\n            border-radius: var(--radius-md);\r\n        }\r\n\r\n        #coffee-dial-in-widget .meta-row {\r\n            text-align: center;\r\n            border-bottom: 1px solid var(--border);\r\n            padding-bottom: 15px;\r\n            margin-bottom: 15px;\r\n            font-size: 0.85rem;\r\n            color: var(--text-muted);\r\n        }\r\n\r\n        #coffee-dial-in-widget .meta-row strong {\r\n            color: var(--primary);\r\n            display: inline-block;\r\n            font-size: 0.95rem;\r\n        }\r\n\r\n        #coffee-dial-in-widget .recommended-range-text {\r\n            text-align: center;\r\n            font-size: 0.85rem;\r\n            color: var(--text-muted);\r\n            text-transform: uppercase;\r\n            letter-spacing: 0.05em;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 6px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .range-display-big {\r\n            text-align: center;\r\n            font-size: 2.2rem;\r\n            font-weight: 700;\r\n            color: var(--primary);\r\n            margin: 5px 0;\r\n        }\r\n\r\n        #coffee-dial-in-widget .starting-point-box {\r\n            text-align: center;\r\n            background: #121417;\r\n            border: 1px solid var(--border);\r\n            padding: 12px;\r\n            border-radius: 8px;\r\n            max-width: 240px;\r\n            margin: 15px auto;\r\n        }\r\n\r\n        #coffee-dial-in-widget .variation-controls {\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 12px;\r\n            margin-top: 6px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .var-btn {\r\n            background: #2e353f;\r\n            color: var(--primary);\r\n            border: none;\r\n            width: 32px;\r\n            height: 32px;\r\n            border-radius: 6px;\r\n            font-size: 1.1rem;\r\n            font-weight: 700;\r\n            cursor: pointer;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            transition: background 0.2s;\r\n        }\r\n\r\n        #coffee-dial-in-widget .var-btn:hover {\r\n            background: var(--accent);\r\n            color: #121417;\r\n        }\r\n\r\n        #coffee-dial-in-widget .slider-visual {\r\n            margin: 20px 0;\r\n            background: #121417;\r\n            padding: 15px;\r\n            border-radius: 8px;\r\n            border: 1px solid var(--border);\r\n        }\r\n\r\n        #coffee-dial-in-widget .slider-bar {\r\n            height: 12px;\r\n            background: #2e353f;\r\n            border-radius: 6px;\r\n            position: relative;\r\n            margin: 25px 0 10px 0;\r\n        }\r\n\r\n        #coffee-dial-in-widget .slider-range-fill {\r\n            position: absolute;\r\n            top: 0;\r\n            height: 100%;\r\n            background: linear-gradient(90deg, #ef4444 0%, #10b981 50%, #f97316 100%);\r\n            border-radius: 6px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .slider-thumb {\r\n            position: absolute;\r\n            top: -6px;\r\n            width: 24px;\r\n            height: 24px;\r\n            background: var(--primary);\r\n            border: 3px solid var(--accent);\r\n            border-radius: 50%;\r\n            transform: translateX(-50%);\r\n            box-shadow: 0 0 10px rgba(0,0,0,0.5);\r\n            z-index: 3;\r\n        }\r\n\r\n        #coffee-dial-in-widget .chart-container {\r\n            margin-top: 25px;\r\n            background: #121417;\r\n            padding: 15px;\r\n            border-radius: 8px;\r\n            border: 1px solid var(--border);\r\n        }\r\n\r\n        #coffee-dial-in-widget .chart-title {\r\n            font-size: 0.75rem;\r\n            text-transform: uppercase;\r\n            letter-spacing: 0.05em;\r\n            color: var(--text-muted);\r\n            margin-bottom: 12px;\r\n            text-align: center;\r\n        }\r\n\r\n        #coffee-dial-in-widget .bar-item {\r\n            position: relative;\r\n            height: 26px;\r\n            background: rgba(255,255,255,0.05);\r\n            margin-bottom: 6px;\r\n            border-radius: 4px;\r\n            overflow: hidden;\r\n            font-size: 0.75rem;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: space-between;\r\n            padding: 0 10px;\r\n            color: white;\r\n            font-weight: 600;\r\n        }\r\n\r\n        #coffee-dial-in-widget .bar-fill {\r\n            position: absolute;\r\n            left: 0;\r\n            top: 0;\r\n            height: 100%;\r\n            opacity: 0.5;\r\n            z-index: 1;\r\n        }\r\n\r\n        #coffee-dial-in-widget .bar-item .bar-label-text,\r\n        #coffee-dial-in-widget .bar-item .bar-values-text {\r\n            position: relative;\r\n            z-index: 2;\r\n            text-shadow: 0 1px 2px rgba(0,0,0,0.8);\r\n        }\r\n\r\n        #coffee-dial-in-widget .bar-item .bar-values-text {\r\n            font-size: 0.7rem;\r\n            background: rgba(0, 0, 0, 0.4);\r\n            padding: 2px 6px;\r\n            border-radius: 4px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .important-note-box {\r\n            margin-top: 20px;\r\n            background: #121417;\r\n            border: 1px solid var(--border);\r\n            padding: 15px;\r\n            border-radius: 8px;\r\n            font-size: 0.8rem;\r\n            color: var(--text-muted);\r\n            line-height: 1.5;\r\n        }\r\n\r\n        #coffee-dial-in-widget .important-note-box strong {\r\n            color: var(--primary);\r\n            display: block;\r\n            margin-bottom: 4px;\r\n            text-transform: uppercase;\r\n            letter-spacing: 0.05em;\r\n            font-size: 0.75rem;\r\n        }\r\n\r\n        #coffee-dial-in-widget .action-buttons {\r\n            display: flex;\r\n            gap: 10px;\r\n            margin-top: 20px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .action-btn {\r\n            background: #16191e;\r\n            border: 1px solid var(--border);\r\n            color: var(--text-main);\r\n            padding: 12px 10px;\r\n            border-radius: 8px;\r\n            font-size: 0.85rem;\r\n            font-weight: 600;\r\n            cursor: pointer;\r\n            text-align: center;\r\n            text-decoration: none;\r\n            display: flex;\r\n            align-items: center;\r\n            justify-content: center;\r\n            gap: 8px;\r\n            flex: 1;\r\n            white-space: nowrap;\r\n            transition: background 0.2s, border-color 0.2s;\r\n        }\r\n\r\n        #coffee-dial-in-widget .action-btn:hover {\r\n            border-color: var(--accent);\r\n        }\r\n\r\n        #coffee-dial-in-widget .reset-btn {\r\n            background: #374151;\r\n            color: #fff;\r\n            border: none;\r\n        }\r\n\r\n        #coffee-dial-in-widget .reset-btn:hover {\r\n            background: #4b5563;\r\n            border-color: transparent;\r\n        }\r\n\r\n        #coffee-dial-in-widget .modal-overlay {\r\n            display: none;\r\n            position: fixed;\r\n            top: 0;\r\n            left: 0;\r\n            width: 100%;\r\n            height: 100%;\r\n            background: rgba(0, 0, 0, 0.7);\r\n            z-index: 99999;\r\n            align-items: center;\r\n            justify-content: center;\r\n            padding: 15px;\r\n        }\r\n\r\n        #coffee-dial-in-widget .modal-overlay.open {\r\n            display: flex;\r\n        }\r\n\r\n        #coffee-dial-in-widget .modal-content {\r\n            background: var(--card-bg);\r\n            border: 1px solid var(--border);\r\n            border-radius: var(--radius-lg);\r\n            padding: 25px;\r\n            max-width: 450px;\r\n            width: 100%;\r\n            box-shadow: var(--shadow);\r\n        }\r\n\r\n        #coffee-dial-in-widget .modal-title {\r\n            font-size: 1.1rem;\r\n            font-weight: 700;\r\n            color: var(--primary);\r\n            margin-top: 0;\r\n            margin-bottom: 12px;\r\n            text-transform: capitalize;\r\n        }\r\n\r\n        #coffee-dial-in-widget .modal-body {\r\n            font-size: 0.9rem;\r\n            color: var(--text-muted);\r\n            line-height: 1.6;\r\n            margin-bottom: 20px;\r\n            white-space: pre-line;\r\n        }\r\n\r\n        #coffee-dial-in-widget .modal-close-btn {\r\n            background: var(--accent);\r\n            color: #121417;\r\n            border: none;\r\n            width: 100%;\r\n            padding: 10px;\r\n            border-radius: 6px;\r\n            font-weight: 700;\r\n            cursor: pointer;\r\n        }\r\n\r\n        #coffee-dial-in-widget .modal-close-btn:hover {\r\n            background: var(--accent-hover);\r\n        }\r\n    <\/style>\r\n\r\n    <div class=\"container\">\r\n        <div id=\"calculator-view\">\r\n            <form id=\"calc-form\" onsubmit=\"window.coffeeWidget.handleCalculate(event)\">\r\n                <h2 class=\"header-title\">\u2615 Grind Dial-In Calculator<\/h2>\r\n\r\n                <div class=\"config-grid\">\r\n                    <div class=\"field-group\">\r\n                        <label for=\"coffee_type\">Coffee Type<\/label>\r\n                        <select id=\"coffee_type\" name=\"coffee_type\">\r\n                            <!-- Populated dynamically via JS -->\r\n                        <\/select>\r\n                    <\/div>\r\n                    <div class=\"field-group\">\r\n                        <label for=\"grinder_u\">\r\n                            Maximum Grind Setting\r\n                            <button type=\"button\" class=\"info-btn\" onclick=\"window.coffeeWidget.openModal('Maximum Grind Setting', 'The maximum number of clicks\/settings available on your grinder.')\">?<\/button>\r\n                        <\/label>\r\n                        <input type=\"number\" id=\"grinder_u\" name=\"u\" value=\"80\" required>\r\n                    <\/div>\r\n                    <div class=\"field-group\">\r\n                        <label for=\"grinder_direction\">\r\n                            Direction\r\n                            <button type=\"button\" class=\"info-btn\" onclick=\"window.coffeeWidget.openModal('Direction', 'Indicates how grind size changes as the click number increases \u2014 Ascending: higher numbers = coarser; Descending: higher numbers = finer.')\">?<\/button>\r\n                        <\/label>\r\n                        <select id=\"grinder_direction\" name=\"direction\">\r\n                            <option value=\"ascending\">Ascending<\/option>\r\n                            <option value=\"descending\">Descending<\/option>\r\n                        <\/select>\r\n                    <\/div>\r\n                <\/div>\r\n\r\n                <div class=\"step-heading\">\r\n                    <div class=\"step-number\">4<\/div>\r\n                    <span>Adjust the Grind to Your Taste<\/span>\r\n                <\/div>\r\n\r\n                <div class=\"sub-label\">I want more:<\/div>\r\n                <div class=\"options-grid\" id=\"t-options-container\">\r\n                    <!-- Populated dynamically via JS -->\r\n                <\/div>\r\n\r\n                <button type=\"submit\" class=\"calculate-btn\">Calculate Grind Setting<\/button>\r\n            <\/form>\r\n        <\/div>\r\n\r\n        <div id=\"result-view\" style=\"display: none;\">\r\n            <!-- Results rendered dynamically via JS -->\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <div class=\"modal-overlay\" id=\"customModal\" onclick=\"window.coffeeWidget.outsideModalClose(event)\">\r\n        <div class=\"modal-content\">\r\n            <h3 class=\"modal-title\" id=\"modalTitle\">Title<\/h3>\r\n            <div class=\"modal-body\" id=\"modalBody\">Description text goes here...<\/div>\r\n            <button type=\"button\" class=\"modal-close-btn\" onclick=\"window.coffeeWidget.closeModal()\">Got it<\/button>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <script>\r\n        window.coffeeWidget = (function() {\r\n            const defaultCoffeeRanges = {\r\n                'cezve'          : {'label' : 'Cezve \/ Ibrik \/ Turkish', 'min' : 1, 'max' : 3},\r\n                'espresso'       : {'label' : 'Espresso', 'min' : 3, 'max' : 9.5},\r\n                'filter'         : {'label' : 'Filter \/ V60', 'min' : 10.5, 'max' : 18.6},\r\n                'bialetti'       : {'label' : 'Bialetti \/ Moka pot', 'min' : 10, 'max' : 20},\r\n                'aeropress'      : {'label' : 'Aeropress', 'min' : 11, 'max' : 22},\r\n                'cupping'        : {'label' : 'Cupping', 'min' : 22, 'max' : 25.5},\r\n                'chemex'         : {'label' : 'Chemex', 'min' : 27, 'max' : 35},\r\n                'french_press'   : {'label' : 'French Press', 'min' : 29, 'max' : 36.5},\r\n                'electric_maker' : {'label' : 'Electric coffee maker', 'min' : 25.5, 'max' : 33},\r\n                'siphon'         : {'label' : 'Siphon', 'min' : 13.5, 'max' : 14.5},\r\n                'cold_brew'      : {'label' : 'Cold Brew', 'min' : 34.5, 'max' : 40},\r\n                'cold_drip'      : {'label' : 'Cold drip', 'min' : 33.5, 'max' : 40},\r\n                'pour_over'      : {'label' : 'Pour-over', 'min' : 12, 'max' : 38},\r\n                'steep_release'  : {'label' : 'Steep and release', 'min' : 13.5, 'max' : 33}\r\n            };\r\n\r\n            const tOptions = [\r\n                {'label' : 'Acidity', 'val' : -0.50, 'desc' : 'More bright, lively, fruity or citrus-like notes.'},\r\n                {'label' : 'Sweetness', 'val' : -0.25, 'desc' : 'More sugary, such as caramel, fruit, honey or chocolate-like notes.'},\r\n                {'label' : 'Body', 'val' : 0.50, 'desc' : 'More weight, texture and richness in the mouth.'},\r\n                {'label' : 'Clarity', 'val' : -0.25, 'desc' : 'A cleaner cup where individual flavours are easier to distinguish.'},\r\n                {'label' : 'Balanced', 'val' : 0.00, 'desc' : 'A harmonious cup with acidity, sweetness and bitterness working well together.'}\r\n            ];\r\n\r\n            let currentTarget = 0;\r\n            let minRange = 0;\r\n            let maxRange = 100;\r\n            let globalU = 80;\r\n            let globalDirection = 'ascending';\r\n            let globalCoffeeType = 'espresso';\r\n\r\n            function initForm() {\r\n                const selectEl = document.getElementById('coffee_type');\r\n                if (!selectEl) return;\r\n                \r\n                selectEl.innerHTML = '';\r\n                for (const [key, data] of Object.entries(defaultCoffeeRanges)) {\r\n                    const opt = document.createElement('option');\r\n                    opt.value = key;\r\n                    opt.textContent = data.label;\r\n                    if (key === 'espresso') opt.selected = true;\r\n                    selectEl.appendChild(opt);\r\n                }\r\n\r\n                const tContainer = document.getElementById('t-options-container');\r\n                if (tContainer) {\r\n                    tContainer.innerHTML = '';\r\n                    tOptions.forEach(opt => {\r\n                        tContainer.appendChild(createOptionCard(opt, 't_vals[]'));\r\n                    });\r\n                }\r\n            }\r\n\r\n            function createOptionCard(opt, inputName) {\r\n                const label = document.createElement('label');\r\n                label.className = 'option-card';\r\n                \r\n                const topDiv = document.createElement('div');\r\n                topDiv.className = 'option-card-top';\r\n\r\n                const checkbox = document.createElement('input');\r\n                checkbox.type = 'checkbox';\r\n                checkbox.name = inputName;\r\n                checkbox.value = opt.val;\r\n                checkbox.addEventListener('change', function() {\r\n                    if (this.checked) {\r\n                        label.classList.add('active');\r\n                    } else {\r\n                        label.classList.remove('active');\r\n                    }\r\n                });\r\n\r\n                const span = document.createElement('span');\r\n                span.textContent = opt.label;\r\n\r\n                const infoBtn = document.createElement('button');\r\n                infoBtn.type = 'button';\r\n                infoBtn.className = 'info-btn';\r\n                infoBtn.textContent = '?';\r\n                infoBtn.onclick = (e) => {\r\n                    e.preventDefault();\r\n                    window.coffeeWidget.openModal(opt.label, opt.desc);\r\n                };\r\n\r\n                topDiv.appendChild(checkbox);\r\n                topDiv.appendChild(span);\r\n                topDiv.appendChild(infoBtn);\r\n                label.appendChild(topDiv);\r\n\r\n                return label;\r\n            }\r\n\r\n            function handleCalculate(e) {\r\n                e.preventDefault();\r\n                \r\n                globalCoffeeType = document.getElementById('coffee_type').value;\r\n                globalU = parseFloat(document.getElementById('grinder_u').value) || 80.0;\r\n                globalDirection = document.getElementById('grinder_direction').value;\r\n\r\n                const rangeData = defaultCoffeeRanges[globalCoffeeType] || {'min': 3, 'max': 9.5};\r\n                const rmin = rangeData.min;\r\n                const rmax = rangeData.max;\r\n\r\n                const selectedT = Array.from(document.querySelectorAll('#coffee-dial-in-widget input[name=\"t_vals[]\"]:checked')).map(el => parseFloat(el.value));\r\n\r\n                \/\/ Since \"My coffee tastes\" section was removed, cVal is defaulted to balanced (0.00)\r\n                let tVal = selectedT.length > 0 ? selectedT.reduce((a, b) => a + b, 0) \/ selectedT.length : 0;\r\n                let cVal = 0.00;\r\n\r\n                const term = 0.50 + 0.25 * (0.30 * tVal + 0.70 * cVal);\r\n                const baseCalc = (globalU \/ 40.0) * (rmin + (rmax - rmin) * term);\r\n\r\n                const baseMin = (globalU \/ 40.0) * rmin;\r\n                const baseMax = (globalU \/ 40.0) * rmax;\r\n\r\n                let result, minUserRange, maxUserRange;\r\n                if (globalDirection === 'descending') {\r\n                    result = globalU - baseCalc;\r\n                    minUserRange = globalU - baseMax;\r\n                    maxUserRange = globalU - baseMin;\r\n                } else {\r\n                    result = baseCalc;\r\n                    minUserRange = baseMin;\r\n                    maxUserRange = baseMax;\r\n                }\r\n\r\n                renderResult(Math.round(minUserRange), Math.round(maxUserRange), Math.round(result));\r\n            }\r\n\r\n            function renderResult(rMinVal, rMaxVal, targetVal) {\r\n                minRange = rMinVal;\r\n                maxRange = rMaxVal;\r\n                currentTarget = targetVal;\r\n                const spanVal = Math.max(1, maxRange - minRange);\r\n                const initialPercent = Math.min(100, Math.max(0, ((currentTarget - minRange) \/ spanVal) * 100));\r\n\r\n                document.getElementById('calculator-view').style.display = 'none';\r\n                const resultView = document.getElementById('result-view');\r\n                resultView.style.display = 'block';\r\n\r\n                const coffeeLabel = (defaultCoffeeRanges[globalCoffeeType]?.label || globalCoffeeType).toUpperCase();\r\n\r\n                let chartHtml = '';\r\n                const colors = ['#ec4899', '#f97316', '#eab308', '#10b981', '#06b6d4', '#8b5cf6', '#3b82f6', '#14b8a6', '#f43f5e', '#84cc16'];\r\n                let i = 0;\r\n                for (const [key, data] of Object.entries(defaultCoffeeRanges)) {\r\n                    const cMinBase = (globalU \/ 40.0) * data.min;\r\n                    const cMaxBase = (globalU \/ 40.0) * data.max;\r\n\r\n                    let cUserMin, cUserMax;\r\n                    if (globalDirection === 'descending') {\r\n                        cUserMin = globalU - cMaxBase;\r\n                        cUserMax = globalU - cMinBase;\r\n                    } else {\r\n                        cUserMin = cMinBase;\r\n                        cUserMax = cMaxBase;\r\n                    }\r\n\r\n                    const pStart = (cUserMin \/ globalU) * 100;\r\n                    const pWidth = ((cUserMax - cUserMin) \/ globalU) * 100;\r\n\r\n                    const displayMin = Math.round(cUserMin);\r\n                    const displayMax = Math.round(cUserMax);\r\n                    const bg = colors[i % colors.length];\r\n                    i++;\r\n\r\n                    chartHtml += `\r\n                        <div class=\"bar-item\">\r\n                            <div class=\"bar-fill\" style=\"left: ${Math.max(0, Math.min(100, pStart))}%; width: ${Math.max(2, Math.min(100, pWidth))}%; background: ${bg};\"><\/div>\r\n                            <span class=\"bar-label-text\">${data.label}<\/span>\r\n                            <span class=\"bar-values-text\">${displayMin} \u2013 ${displayMax} clicks<\/span>\r\n                        <\/div>\r\n                    `;\r\n                }\r\n\r\n                resultView.innerHTML = `\r\n                    <div class=\"result-container\">\r\n                        <div class=\"header-title\" style=\"margin-bottom: 5px;\">Your Recommended Grind<\/div>\r\n                        <div class=\"coffee-heading\">\u2615 ${coffeeLabel}<\/div>\r\n\r\n                        <div class=\"meta-row\">\r\n                            Your Grinder: <strong>${Math.floor(globalU)} Clicks<\/strong> (${globalDirection.charAt(0).toUpperCase() + globalDirection.slice(1)})\r\n                        <\/div>\r\n\r\n                        <div class=\"recommended-range-text\">\r\n                            Recommended Range (Your Grinder)\r\n                            <button type=\"button\" class=\"info-btn\" onclick=\"window.coffeeWidget.openModal('Finer & Coarser Adjustments', 'Finer \u2192 go Finer when you want higher extraction, richer body, and more sweetness.\\\\n\\\\nCoarser \u2192 go Coarser when you want lower extraction, higher clarity, and more brightness.')\">?<\/button>\r\n                        <\/div>\r\n                        <div class=\"range-display-big\"><span id=\"range-min-val\">${minRange}<\/span> \u2013 <span id=\"range-max-val\">${maxRange}<\/span> <span style=\"font-size: 1.1rem; font-weight: 500;\">clicks<\/span><\/div>\r\n\r\n                        <div class=\"starting-point-box\">\r\n                            <div style=\"font-size: 0.8rem; font-weight: 700; color: var(--primary); text-transform: uppercase; letter-spacing: 0.05em;\">Starting Point: <span id=\"starting-target-label\">${currentTarget}<\/span><\/div>\r\n                            <div class=\"variation-controls\">\r\n                                <button type=\"button\" class=\"var-btn\" onclick=\"window.coffeeWidget.adjustClicks(-1)\">-<\/button>\r\n                                <div style=\"font-size: 1.3rem; font-weight: 700; color: var(--accent);\"><span id=\"target-click-display\">${currentTarget}<\/span> <span style=\"font-size:0.8rem;\">clicks<\/span><\/div>\r\n                                <button type=\"button\" class=\"var-btn\" onclick=\"window.coffeeWidget.adjustClicks(1)\">+<\/button>\r\n                            <\/div>\r\n                        <\/div>\r\n\r\n                        <div class=\"slider-visual\">\r\n                            <div style=\"display: flex; justify-content: space-between; font-size: 0.75rem; color: var(--text-muted);\">\r\n                                <span><span id=\"slider-label-min\">${minRange}<\/span> clicks<\/span>\r\n                                <span style=\"color: var(--accent); font-weight: 700;\">Target: <span id=\"slider-label-target\">${currentTarget}<\/span><\/span>\r\n                                <span><span id=\"slider-label-max\">${maxRange}<\/span> clicks<\/span>\r\n                            <\/div>\r\n                            <div class=\"slider-bar\">\r\n                                <div class=\"slider-range-fill\" style=\"left: 0%; width: 100%;\"><\/div>\r\n                                <div class=\"slider-thumb\" id=\"slider-thumb-el\" style=\"left: ${initialPercent}%;\"><\/div>\r\n                            <\/div>\r\n                        <\/div>\r\n\r\n                        <div class=\"chart-container\">\r\n                            <div class=\"chart-title\">Grind range (Customized for your grinder)<\/div>\r\n                            ${chartHtml}\r\n                        <\/div>\r\n\r\n                        <div class=\"important-note-box\">\r\n                            <strong>Important Note<\/strong>\r\n                            Recommendations normalized to standard reference grind charts. Actual results may vary depending on burr calibration and coffee bean properties.\r\n                        <\/div>\r\n\r\n                        <div class=\"action-buttons\">\r\n                            <button type=\"button\" class=\"action-btn reset-btn\" onclick=\"window.coffeeWidget.resetForm()\">\ud83d\udd04 Dial-In Again<\/button>\r\n                            <a href=\"#\" class=\"action-btn\" onclick=\"window.coffeeWidget.shareWhatsApp(event)\">\ud83d\udcac Share WhatsApp<\/a>\r\n                        <\/div>\r\n                    <\/div>\r\n                `;\r\n            }\r\n\r\n            function shareWhatsApp(e) {\r\n                if (e) e.preventDefault();\r\n                const coffeeLabel = (defaultCoffeeRanges[globalCoffeeType]?.label || globalCoffeeType).toUpperCase();\r\n                const text = `\u2615 Coffee Dial-In Results:\\nCoffee: ${coffeeLabel}\\nGrinder Max: ${Math.floor(globalU)} Clicks (${globalDirection})\\nRecommended Range: ${minRange} - ${maxRange} clicks\\nTarget Starting Point: ${currentTarget} clicks`;\r\n                const url = `https:\/\/api.whatsapp.com\/send?text=${encodeURIComponent(text)}`;\r\n                window.open(url, '_blank');\r\n            }\r\n\r\n            function adjustClicks(delta) {\r\n                currentTarget += delta;\r\n                currentTarget = Math.max(0, Math.min(globalU, currentTarget));\r\n\r\n                const spanVal = Math.max(1, maxRange - minRange);\r\n                const percent = Math.min(100, Math.max(0, ((currentTarget - minRange) \/ spanVal) * 100));\r\n\r\n                const targetEl1 = document.getElementById('target-click-display');\r\n                const targetEl2 = document.getElementById('slider-label-target');\r\n                const targetEl3 = document.getElementById('starting-target-label');\r\n                const thumbEl = document.getElementById('slider-thumb-el');\r\n\r\n                if (targetEl1) targetEl1.textContent = currentTarget;\r\n                if (targetEl2) targetEl2.textContent = currentTarget;\r\n                if (targetEl3) targetEl3.textContent = currentTarget;\r\n                if (thumbEl) thumbEl.style.left = percent + '%';\r\n            }\r\n\r\n            function resetForm() {\r\n                document.getElementById('result-view').style.display = 'none';\r\n                document.getElementById('calculator-view').style.display = 'block';\r\n                const form = document.getElementById('calc-form');\r\n                if (form) form.reset();\r\n                initForm();\r\n            }\r\n\r\n            function openModal(title, body) {\r\n                document.getElementById('modalTitle').textContent = title;\r\n                document.getElementById('modalBody').textContent = body;\r\n                document.getElementById('customModal').classList.add('open');\r\n            }\r\n\r\n            function closeModal() {\r\n                document.getElementById('customModal').classList.remove('open');\r\n            }\r\n\r\n            function outsideModalClose(e) {\r\n                if (e.target.id === 'customModal') {\r\n                    closeModal();\r\n                }\r\n            }\r\n\r\n            if (document.readyState === 'loading') {\r\n                document.addEventListener('DOMContentLoaded', initForm);\r\n            } else {\r\n                initForm();\r\n            }\r\n\r\n            return {\r\n                handleCalculate,\r\n                adjustClicks,\r\n                resetForm,\r\n                shareWhatsApp,\r\n                openModal,\r\n                closeModal,\r\n                outsideModalClose\r\n            };\r\n        })();\r\n    <\/script>\r\n<\/div>\r\n\r\n<\/body>\r\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-1cd374a e-flex e-con-boxed e-con e-parent\" data-id=\"1cd374a\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-25096f9 elementor-widget elementor-widget-text-editor\" data-id=\"25096f9\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>OX Grind Calculator \u2014 Coffee Grind Adjustment Calculator<br \/>OX Grind Calculator is a specialized interactive calculator for adjusting coffee grind size, designed to help the user reach a suitable starting point for grinding according to the desired brewing method (among 14 selected brewing methods), and according to the user&#8217;s flavor preferences.<br \/>How the Calculator Works<br \/>The user first selects the brewing method, and based on this, the calculator determines the grind range. After that, the user enters the maximum setting of the grinder they are using and selects the direction of its scale, whether ascending or descending, because in some grinders number 1 gives the finest grind, while in others it gives the coarsest grind.<br \/>The calculator determines the grind position within the reference range, then converts this position into the user&#8217;s grinder scale based on a complex algorithm developed by the team of OX Specialty Coffee Roastery, so the user gets the appropriate number for their grinder, customized according to their taste and the brewing method they desire. This allows the concept to be applied to different grinders, whether manual or electric.<br \/>Customizing the Result<br \/>After determining the basic setting, the user can customize the result according to their sensory preferences, such as:<br \/>Sweetness<br \/>Acidity<br \/>Clarity<br \/>Body<br \/>Result<br \/>In the end, the calculator provides a suggested grind setting as a starting point, rather than a fixed number for all cases. After tasting, the user can adjust the grind based on the extraction result and taste.<br \/>It also provides a comprehensive result for all brewing methods in the form of a graphic. For example, if the user selects V60 as the brewing method, the result will not be limited to the appropriate grind number for V60 only, but the user will receive the result for all brewing methods related to coffee and mentioned in the calculator&#8217;s brewing methods.<br \/>The Basic Idea of the Calculator:<br \/>Selecting the brewing method \u2b05\ufe0f Selecting the number of grinder clicks \/ settings \u2b05\ufe0f Selecting the desired result according to taste \u2b05\ufe0f Suggested grind setting \u2b05\ufe0f Adjusting based on the result in the cup.<br \/>Brewing Methods Supported by the Calculator:<br \/>Cezve \/ Ibrik \/ Turkish<br \/>Espresso<br \/>Filter \/ V60<br \/>Bialetti \/ Moka Pot<br \/>Aeropress<br \/>Cupping<br \/>Chemex<br \/>French Press<br \/>Electric Coffee Maker<br \/>Siphon<br \/>Cold Brew<br \/>Cold Drip<br \/>Pour-Over<br \/>Steep and Release<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Coffee Dial-In Widget \u2615 Grind Dial-In Calculator Coffee Type Maximum Grind Setting ? Direction ? AscendingDescending 4 Adjust the Grind to Your Taste I want more: Calculate Grind Setting Title Description text goes here&#8230; Got it OX Grind Calculator \u2014 Coffee Grind Adjustment CalculatorOX Grind Calculator is a specialized interactive calculator for adjusting coffee grind [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-3049","page","type-page","status-publish","hentry"],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/oxroastery.com\/ar\/wp-json\/wp\/v2\/pages\/3049","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oxroastery.com\/ar\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/oxroastery.com\/ar\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/oxroastery.com\/ar\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/oxroastery.com\/ar\/wp-json\/wp\/v2\/comments?post=3049"}],"version-history":[{"count":32,"href":"https:\/\/oxroastery.com\/ar\/wp-json\/wp\/v2\/pages\/3049\/revisions"}],"predecessor-version":[{"id":3123,"href":"https:\/\/oxroastery.com\/ar\/wp-json\/wp\/v2\/pages\/3049\/revisions\/3123"}],"wp:attachment":[{"href":"https:\/\/oxroastery.com\/ar\/wp-json\/wp\/v2\/media?parent=3049"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}