{"id":75203,"date":"2026-03-13T00:27:22","date_gmt":"2026-03-13T00:27:22","guid":{"rendered":"https:\/\/aceworldpgs.com\/?page_id=75203"},"modified":"2026-05-22T16:57:26","modified_gmt":"2026-05-22T16:57:26","slug":"publishing-calculator","status":"publish","type":"post","link":"https:\/\/aceworldpgs.com\/tools\/publishing-calculator\/","title":{"rendered":"Publishing Calculator"},"content":{"rendered":"\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"WebApplication\",\n  \"name\": \"ACEworld Book Publishing Cost Calculator\",\n  \"url\": \"https:\/\/aceworldpgs.com\/tools\/publishing-calculator\/\",\n  \"description\": \"A free online publishing calculator that helps authors estimate the total cost of self-publishing a book. Calculate expenses for editing, cover design, formatting, ISBN registration, printing, and marketing to plan your publishing budget effectively.\",\n  \"applicationCategory\": \"FinanceApplication\",\n  \"operatingSystem\": \"All\",\n  \"browserRequirements\": \"Requires JavaScript\",\n  \"creator\": {\n    \"@type\": \"Organization\",\n    \"name\": \"ACEworld Publishing Services\",\n    \"url\": \"https:\/\/aceworldpgs.com\"\n  },\n  \"offers\": {\n    \"@type\": \"Offer\",\n    \"price\": \"0\",\n    \"priceCurrency\": \"USD\"\n  },\n  \"featureList\": [\n    \"Estimate total self-publishing costs\",\n    \"Calculate editing and proofreading expenses\",\n    \"Estimate cover design and formatting costs\",\n    \"Budget for ISBN registration and distribution\",\n    \"Plan book marketing and promotion expenses\"\n  ],\n  \"keywords\": [\n    \"book publishing calculator\",\n    \"self publishing cost calculator\",\n    \"book production cost estimator\",\n    \"publishing budget calculator\",\n    \"cost of publishing a book\"\n  ],\n  \"aggregateRating\": {\n    \"@type\": \"AggregateRating\",\n    \"ratingValue\": \"5.0\",\n    \"reviewCount\": \"87\"\n  }\n}\n<\/script>\n\n\n<!-- ============================================================\n     ACEWORLD PUBLISHING CALCULATOR \u2014 DYNAMIC (Phase 2)\n     Services rendered from ace_get_sap_services() config.\n     Print production pricing is also dynamic now (Toolkit Settings \u2192\n     Print Pricing tab) \u2014 see ace_get_sap_print_config(). Step 3's HTML\n     controls (trim size, ink, paper, binding, etc.) stay hardcoded;\n     only the underlying matrix\/multiplier\/modifier NUMBERS are editable.\n============================================================ -->\n<style>\n\/* \u2500\u2500 Design tokens \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n:root {\n  --sap-navy:      #0f1c3f;\n  --sap-blue:      #1d4ed8;\n  --sap-blue-lt:   #3b82f6;\n  --sap-blue-pale: #eff6ff;\n  --sap-green:     #166534;\n  --sap-green-lt:  #22c55e;\n  --sap-accent:    #f59e0b;\n  --sap-white:     #ffffff;\n  --sap-gray-50:   #f8fafc;\n  --sap-gray-100:  #f1f5f9;\n  --sap-gray-200:  #e2e8f0;\n  --sap-gray-400:  #94a3b8;\n  --sap-gray-600:  #475569;\n  --sap-gray-800:  #1e293b;\n  --sap-error:     #ef4444;\n  --sap-radius:    12px;\n  --sap-radius-sm: 8px;\n  --sap-shadow:    0 4px 24px rgba(15,28,63,0.08);\n  --sap-shadow-lg: 0 12px 48px rgba(15,28,63,0.14);\n  --sap-trans:     all 0.2s cubic-bezier(0.4,0,0.2,1);\n  --font-display:  'DM Sans', 'Segoe UI', system-ui, sans-serif;\n  --font-mono:     'DM Mono', 'Fira Code', monospace;\n}\n\n@import url('https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&family=DM+Mono:wght@400;500&display=swap');\n\n.sap-calc * { box-sizing: border-box; margin: 0; padding: 0; }\n.sap-calc {\n  font-family: var(--font-display);\n  color: var(--sap-gray-800);\n  background: var(--sap-white);\n  max-width: 1000px;\n  margin: 0 auto;\n  border-radius: 20px;\n  box-shadow: var(--sap-shadow-lg);\n  overflow: hidden;\n  position: relative;\n}\n\n.sap-header {\n  background: linear-gradient(135deg, var(--sap-navy) 0%, #1e3a7a 100%);\n  padding: 28px 32px 24px;\n  position: relative;\n  overflow: hidden;\n}\n.sap-header::after {\n  content: '';\n  position: absolute;\n  right: -60px; top: -60px;\n  width: 240px; height: 240px;\n  border-radius: 50%;\n  background: rgba(59,130,246,0.12);\n  pointer-events: none;\n}\n.sap-header-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }\n.sap-header h2 { color: #fff; font-size: clamp(18px, 3vw, 24px); font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; }\n.sap-header p { color: rgba(255,255,255,0.7); font-size: 13px; margin-top: 4px; font-weight: 400; }\n.sap-checklist-link {\n  display: inline-flex; align-items: center; gap: 6px;\n  background: rgba(255,255,255,0.12); color: #fff; font-size: 11px; font-weight: 600;\n  padding: 6px 12px; border-radius: 20px; text-decoration: none;\n  border: 1px solid rgba(255,255,255,0.2); white-space: nowrap; transition: var(--sap-trans); flex-shrink: 0;\n}\n.sap-checklist-link:hover { background: rgba(255,255,255,0.22); }\n.sap-checklist-link .badge { background: var(--sap-accent); color: #000; font-size: 9px; font-weight: 700; padding: 1px 5px; border-radius: 4px; }\n\n.sap-stepper {\n  display: flex; align-items: center; gap: 0; padding: 0 32px;\n  background: var(--sap-gray-50); border-bottom: 1px solid var(--sap-gray-200);\n  overflow-x: auto; scrollbar-width: none;\n}\n.sap-stepper::-webkit-scrollbar { display: none; }\n.sap-step-item {\n  display: flex; align-items: center; gap: 8px; padding: 14px 16px 14px 0;\n  cursor: pointer; flex-shrink: 0; position: relative; border-bottom: 2px solid transparent;\n  transition: var(--sap-trans); margin-bottom: -1px;\n}\n.sap-step-item:not(:last-child)::after {\n  content: '\u203a'; position: absolute; right: -2px; color: var(--sap-gray-400); font-size: 16px; top: 50%; transform: translateY(-50%);\n}\n.sap-step-num {\n  width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center;\n  font-size: 11px; font-weight: 700; background: var(--sap-gray-200); color: var(--sap-gray-600);\n  transition: var(--sap-trans); flex-shrink: 0;\n}\n.sap-step-label { font-size: 12px; font-weight: 500; color: var(--sap-gray-400); transition: var(--sap-trans); white-space: nowrap; }\n.sap-step-item.active { border-bottom-color: var(--sap-blue); }\n.sap-step-item.active .sap-step-num { background: var(--sap-blue); color: #fff; }\n.sap-step-item.active .sap-step-label { color: var(--sap-blue); font-weight: 600; }\n.sap-step-item.done .sap-step-num { background: var(--sap-green-lt); color: #fff; }\n.sap-step-item.done .sap-step-num::before { content: '\u2713'; }\n.sap-step-item.done .sap-step-label { color: var(--sap-green); }\n\n.sap-body { padding: 28px 32px 0; }\n.sap-step-panel { display: none; }\n.sap-step-panel.active { display: block; animation: sapFadeIn 0.25s ease; }\n@keyframes sapFadeIn { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:translateY(0); } }\n\n.sap-step-heading { font-size: 16px; font-weight: 700; color: var(--sap-navy); margin-bottom: 4px; letter-spacing: -0.01em; }\n.sap-step-sub { font-size: 13px; color: var(--sap-gray-600); margin-bottom: 20px; line-height: 1.5; }\n\n.sap-section-label {\n  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--sap-blue);\n  margin: 22px 0 10px; display: flex; align-items: center; gap: 6px;\n}\n.sap-section-label::after { content: ''; flex: 1; height: 1px; background: var(--sap-gray-200); }\n\n.sap-project-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 20px; }\n@media (max-width: 560px) { .sap-project-row { grid-template-columns: 1fr; } }\n\n.sap-field label { display: block; font-size: 11px; font-weight: 700; color: var(--sap-gray-600); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 6px; }\n.sap-field input[type=\"text\"], .sap-field input[type=\"number\"], .sap-field input[type=\"email\"], .sap-field input[type=\"tel\"], .sap-field select {\n  width: 100%; padding: 10px 13px; border: 1.5px solid var(--sap-gray-200); border-radius: var(--sap-radius-sm);\n  font-size: 14px; font-family: var(--font-display); color: var(--sap-gray-800); background: var(--sap-white);\n  transition: var(--sap-trans); appearance: none; -webkit-appearance: none;\n}\n.sap-field select {\n  background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%2394a3b8' stroke-width='1.5' fill='none' stroke-linecap='round'\/%3E%3C\/svg%3E\");\n  background-repeat: no-repeat; background-position: right 12px center; padding-right: 34px;\n}\n.sap-field input:focus, .sap-field select:focus { outline: none; border-color: var(--sap-blue-lt); box-shadow: 0 0 0 3px rgba(59,130,246,0.12); }\n.sap-field small { display: block; font-size: 11px; color: var(--sap-gray-400); margin-top: 4px; }\n\n.sap-toggle-row {\n  display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 16px;\n  border: 1.5px solid var(--sap-gray-200); border-radius: var(--sap-radius-sm); margin-bottom: 8px;\n  cursor: pointer; transition: var(--sap-trans); background: var(--sap-white);\n}\n.sap-toggle-row:hover { border-color: var(--sap-blue-lt); background: var(--sap-blue-pale); }\n.sap-toggle-row.toggled { border-color: var(--sap-blue); background: var(--sap-blue-pale); }\n.sap-toggle-label { font-size: 14px; font-weight: 500; color: var(--sap-gray-800); display: flex; align-items: center; gap: 8px; }\n.sap-toggle-label .tip { font-size: 11px; background: var(--sap-gray-100); color: var(--sap-gray-600); padding: 2px 7px; border-radius: 10px; font-weight: 500; }\n\n.sap-switch { position:relative; width:44px; height:24px; flex-shrink:0; }\n.sap-switch input { opacity:0; width:0; height:0; position:absolute; }\n.sap-switch-track { position:absolute; inset:0; background: var(--sap-gray-200); border-radius: 12px; transition: var(--sap-trans); cursor: pointer; }\n.sap-switch-track::after { content:''; position:absolute; width:18px; height:18px; left:3px; top:3px; background:#fff; border-radius:50%; transition: var(--sap-trans); box-shadow: 0 1px 4px rgba(0,0,0,0.18); }\n.sap-switch input:checked + .sap-switch-track { background: var(--sap-blue); }\n.sap-switch input:checked + .sap-switch-track::after { transform: translateX(20px); }\n\n.sap-subsection {\n  background: var(--sap-gray-50); border: 1.5px solid var(--sap-gray-200); border-top: none;\n  border-radius: 0 0 var(--sap-radius-sm) var(--sap-radius-sm); padding: 14px 16px; margin-top: -8px; margin-bottom: 8px; display: none;\n}\n.sap-subsection.open { display: block; }\n.sap-subsection label { font-size: 12px; font-weight: 600; color: var(--sap-gray-600); margin-bottom: 6px; display: block; }\n.sap-subsection select, .sap-subsection input[type=\"number\"] {\n  width: 100%; padding: 8px 12px; border: 1.5px solid var(--sap-gray-200); border-radius: 6px; font-size: 13px;\n  font-family: var(--font-display); background: #fff; color: var(--sap-gray-800); appearance: none;\n  background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%2394a3b8' stroke-width='1.5' fill='none' stroke-linecap='round'\/%3E%3C\/svg%3E\");\n  background-repeat: no-repeat; background-position: right 10px center; padding-right: 30px;\n}\n.sap-subsection select:focus, .sap-subsection input:focus { outline: none; border-color: var(--sap-blue-lt); box-shadow: 0 0 0 3px rgba(59,130,246,0.1); }\n\n.sap-radio-grid { display: grid; gap: 10px; margin-bottom: 14px; }\n.sap-radio-grid-2 { grid-template-columns: repeat(2, 1fr); }\n.sap-radio-grid-3 { grid-template-columns: repeat(3, 1fr); }\n.sap-radio-grid-4 { grid-template-columns: repeat(4, 1fr); }\n.sap-radio-grid-5 { grid-template-columns: repeat(5, 1fr); }\n@media (max-width: 560px) {\n  .sap-radio-grid-3 { grid-template-columns: repeat(2, 1fr); }\n  .sap-radio-grid-4 { grid-template-columns: repeat(2, 1fr); }\n  .sap-radio-grid-5 { grid-template-columns: repeat(3, 1fr); }\n}\n@media (max-width: 400px) {\n  .sap-radio-grid-2 { grid-template-columns: 1fr 1fr; }\n  .sap-radio-grid-5 { grid-template-columns: repeat(2, 1fr); }\n}\n\n.sap-radio-card {\n  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; padding: 12px 8px;\n  border: 1.5px solid var(--sap-gray-200); border-radius: var(--sap-radius-sm); cursor: pointer; text-align: center;\n  transition: var(--sap-trans); background: var(--sap-white); position: relative; min-height: 64px;\n}\n.sap-radio-card:hover { border-color: var(--sap-blue-lt); background: var(--sap-blue-pale); }\n.sap-radio-card.selected { border-color: var(--sap-blue); background: var(--sap-blue-pale); box-shadow: 0 0 0 2px rgba(29,78,216,0.15); }\n.sap-radio-card.selected::after { content: '\u2713'; position: absolute; top: 6px; right: 8px; font-size: 10px; font-weight: 700; color: var(--sap-blue); }\n.sap-radio-card input { position: absolute; opacity: 0; width:0; height:0; }\n.sap-radio-card .rc-icon { font-size: 20px; line-height: 1; }\n.sap-radio-card .rc-label { font-size: 11px; font-weight: 600; color: var(--sap-gray-800); line-height: 1.2; }\n.sap-radio-card .rc-sub { font-size: 10px; color: var(--sap-gray-400); font-weight: 400; }\n.sap-radio-card.selected .rc-label { color: var(--sap-blue); }\n\n.sap-radio-card.no-print.selected { border-color: var(--sap-gray-400); background: var(--sap-gray-100); box-shadow: none; }\n.sap-radio-card.no-print.selected::after { display: none; }\n.sap-radio-card.no-print.selected .rc-label { color: var(--sap-gray-600); }\n\n.sap-print-specs { border: 1.5px solid var(--sap-gray-200); border-radius: var(--sap-radius); overflow: hidden; margin-top: 4px; }\n.sap-print-specs-header {\n  display: flex; align-items: center; justify-content: space-between; padding: 13px 16px; background: var(--sap-navy);\n  color: #fff; font-size: 13px; font-weight: 600; cursor: pointer; user-select: none;\n}\n.sap-print-specs-header .chevron { transition: var(--sap-trans); font-size: 16px; }\n.sap-print-specs-header.open .chevron { transform: rotate(180deg); }\n.sap-print-specs-body { padding: 20px 20px 4px; background: var(--sap-gray-50); }\n\n.sap-interior-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin-bottom: 14px; }\n@media (max-width: 600px) { .sap-interior-grid { grid-template-columns: 1fr; gap: 14px; } }\n\n.sap-spec-grid-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px; }\n@media (max-width: 500px) { .sap-spec-grid-2col { grid-template-columns: 1fr; gap: 14px; } }\n\n.sap-custom-copies { display: none; margin-top: 10px; }\n.sap-custom-copies.show { display: block; }\n.sap-custom-copies input { width: 100%; padding: 10px 13px; border: 1.5px solid var(--sap-blue-lt); border-radius: var(--sap-radius-sm); font-size: 14px; font-family: var(--font-display); }\n.sap-custom-copies input:focus { outline: none; box-shadow: 0 0 0 3px rgba(59,130,246,0.12); }\n\n.sap-client-grid { display: grid; grid-template-columns: 1fr 1.5fr 1fr; gap: 14px; margin-bottom: 20px; }\n@media (max-width: 640px) { .sap-client-grid { grid-template-columns: 1fr; } }\n\n.sap-error { font-size: 11px; font-weight: 600; color: var(--sap-error); margin-top: 5px; margin-bottom: 8px; display: none; }\n.sap-error.show { display: block; }\n\n.sap-nav { display: flex; align-items: center; justify-content: space-between; padding: 20px 32px; border-top: 1px solid var(--sap-gray-200); margin-top: 24px; gap: 12px; background: var(--sap-gray-50); }\n.sap-btn { display: inline-flex; align-items: center; gap: 6px; padding: 11px 22px; border-radius: var(--sap-radius-sm); font-size: 14px; font-weight: 600; font-family: var(--font-display); cursor: pointer; border: none; transition: var(--sap-trans); text-decoration: none; }\n.sap-btn-ghost { background: var(--sap-gray-100); color: var(--sap-gray-600); }\n.sap-btn-ghost:hover { background: var(--sap-gray-200); }\n.sap-btn-primary { background: var(--sap-blue); color: #fff; box-shadow: 0 2px 8px rgba(29,78,216,0.25); }\n.sap-btn-primary:hover { background: #1a45c0; box-shadow: 0 4px 16px rgba(29,78,216,0.35); }\n.sap-btn-primary:disabled { background: var(--sap-gray-400); box-shadow: none; cursor: not-allowed; }\n.sap-btn-submit { background: linear-gradient(135deg, #166534 0%, #15803d 100%); color: #fff; box-shadow: 0 2px 8px rgba(22,101,52,0.3); font-size: 14px; }\n.sap-btn-submit:hover { box-shadow: 0 4px 16px rgba(22,101,52,0.4); filter: brightness(1.06); }\n.sap-btn-submit:disabled { background: var(--sap-gray-400); box-shadow:none; cursor:not-allowed; }\n\n.sap-floating-total {\n  position: fixed; bottom: 24px; right: 24px; z-index: 9999; background: var(--sap-navy); color: #fff; border-radius: 50px;\n  padding: 12px 20px; display: flex; align-items: center; gap: 10px; box-shadow: 0 8px 32px rgba(15,28,63,0.35);\n  transition: var(--sap-trans); opacity: 0; pointer-events: none; transform: translateY(10px);\n}\n.sap-floating-total.show { opacity: 1; pointer-events: auto; transform: translateY(0); }\n.sap-float-label { font-size: 11px; color: rgba(255,255,255,0.6); font-weight: 500; }\n.sap-float-value { font-size: 16px; font-weight: 700; font-family: var(--font-mono); color: var(--sap-accent); }\n.sap-float-details { font-size: 11px; font-weight: 600; padding: 5px 12px; background: rgba(255,255,255,0.12); border-radius: 20px; cursor: pointer; border: none; color: #fff; transition: var(--sap-trans); }\n.sap-float-details:hover { background: rgba(255,255,255,0.22); }\n\n.sap-quote-panel { background: var(--sap-gray-50); border: 1.5px solid var(--sap-gray-200); border-radius: var(--sap-radius); overflow: hidden; margin-bottom: 20px; }\n.sap-quote-header { background: linear-gradient(135deg, var(--sap-navy) 0%, #1e3a7a 100%); padding: 16px 20px; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px; }\n.sap-quote-header-left { color: #fff; }\n.sap-quote-header-left .qh-title { font-size: 13px; font-weight: 400; opacity: 0.7; }\n.sap-quote-header-left .qh-book { font-size: 16px; font-weight: 700; }\n.sap-quote-header-left .qh-words { font-size: 12px; opacity: 0.6; margin-top: 2px; }\n.sap-quote-total-badge { background: var(--sap-accent); color: var(--sap-navy); font-size: 22px; font-weight: 800; padding: 8px 18px; border-radius: 10px; letter-spacing: -0.02em; }\n.sap-quote-date { font-size: 11px; color: rgba(255,255,255,0.5); margin-top: 4px; }\n\n.sap-quote-body { padding: 16px 20px; }\n.sap-quote-section-title { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--sap-blue); margin: 16px 0 8px; display: flex; align-items: center; gap: 6px; }\n.sap-quote-section-title::after { content:''; flex:1; height:1px; background:var(--sap-gray-200); }\n.sap-quote-row { display: flex; justify-content: space-between; align-items: center; padding: 7px 0; border-bottom: 1px solid var(--sap-gray-100); font-size: 13px; }\n.sap-quote-row:last-child { border-bottom: none; }\n.sap-quote-row .qr-label { color: var(--sap-gray-600); }\n.sap-quote-row .qr-value { font-weight: 600; color: var(--sap-gray-800); font-family: var(--font-mono); }\n.sap-quote-row.dimmed { opacity: 0.35; }\n.sap-quote-row.total { font-weight: 700; font-size: 14px; padding-top: 10px; border-top: 2px solid var(--sap-gray-200); border-bottom: none; }\n.sap-quote-row.total .qr-value { color: var(--sap-navy); }\n\n.sap-print-card {\n  background: linear-gradient(135deg, var(--sap-blue-pale) 0%, #dbeafe 100%); border: 1.5px solid #bfdbfe; border-radius: var(--sap-radius-sm);\n  padding: 14px 16px; display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin: 8px 0;\n}\n@media (max-width: 480px) { .sap-print-card { flex-direction: column; align-items: flex-start; } .sap-print-card > div:last-child { text-align: left; } }\n.sap-print-card .pc-copies { font-size: 16px; font-weight: 700; color: var(--sap-navy); }\n.sap-print-card .pc-specs { font-size: 10px; text-transform: uppercase; color: var(--sap-gray-400); letter-spacing: 0.07em; margin-top: 2px; }\n.sap-print-card .pc-price { font-size: 15px; font-weight: 700; color: var(--sap-navy); font-family: var(--font-mono); }\n.sap-print-card .pc-each { font-size: 10px; color: var(--sap-gray-400); }\n\n.sap-specs-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; margin: 8px 0; }\n@media (max-width: 560px) { .sap-specs-grid { grid-template-columns: 1fr; gap: 5px; } }\n.sap-spec-pill { background: var(--sap-white); border: 1px solid var(--sap-gray-200); border-radius: 6px; padding: 6px 10px; font-size: 11px; color: var(--sap-gray-600); }\n\n.sap-note { background: #fef9ee; border: 1px solid #fde68a; border-radius: 8px; padding: 10px 14px; font-size: 12px; color: #78350f; margin: 10px 0; line-height: 1.5; }\n\n.sap-clear-link { font-size: 12px; color: var(--sap-gray-400); cursor: pointer; text-decoration: underline; background: none; border: none; padding: 0; font-family: var(--font-display); }\n.sap-clear-link:hover { color: var(--sap-error); }\n\n.sap-tip { position: relative; display: inline-block; cursor: help; color: var(--sap-gray-400); font-size: 11px; font-weight: 700; background: var(--sap-gray-100); border-radius: 50%; width: 16px; height: 16px; text-align: center; line-height: 16px; vertical-align: middle; margin-left: 4px; }\n.sap-tip:hover .sap-tip-text { visibility: visible; opacity: 1; }\n.sap-tip-text {\n  visibility: hidden; opacity: 0; width: 220px; background: var(--sap-navy); color: #fff; font-size: 11px; font-weight: 400;\n  padding: 8px 12px; border-radius: 8px; position: absolute; bottom: 130%; left: 50%; transform: translateX(-50%);\n  line-height: 1.5; z-index: 100; pointer-events: none; transition: opacity 0.15s;\n}\n\n@media print {\n  body * { visibility: hidden !important; }\n  #sap-quote-print-target, #sap-quote-print-target * { visibility: visible !important; }\n  #sap-quote-print-target { position: fixed !important; top: 0 !important; left: 0 !important; width: 100% !important; background: #fff !important; padding: 24px !important; box-shadow: none !important; border: none !important; z-index: 999999 !important; }\n  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }\n  .sap-stepper, .sap-header, .sap-nav, .sap-floating-total, .sap-progress-bar, .sap-btn-submit, .sap-note, .sap-clear-link, #clearFormBtn { display: none !important; visibility: hidden !important; }\n}\n\n.sap-jump { font-size: 12px; color: var(--sap-blue-lt); text-decoration: none; }\n.sap-jump:hover { text-decoration: underline; }\n\n.sap-progress-bar { height: 3px; background: var(--sap-gray-200); position: relative; overflow: hidden; }\n.sap-progress-fill { height: 100%; background: linear-gradient(90deg, var(--sap-blue) 0%, var(--sap-blue-lt) 100%); border-radius: 2px; transition: width 0.4s cubic-bezier(0.4,0,0.2,1); }\n\/* NOTE: fixed an undefined --sap-red variable reference here (pre-existing bug) \u2014 now uses --sap-blue for a solid gradient instead of an invalid fallback. *\/\n<\/style>\n\n<!-- ============================================================\n     MARKUP\n============================================================ -->\n<div class=\"sap-calc\" id=\"sap-calc-root\">\n\n  <div class=\"sap-header\">\n    <div class=\"sap-header-top\">\n      <div>\n        <h2>Publishing Calculator<\/h2>\n        <p>Know how much it costs to publish and print your book. Get instant quotation.<\/p>\n      <\/div>\n      <a href=\"https:\/\/aceworldpgs.com\/acepublishingchecklist\" class=\"sap-checklist-link\">\n        Download Publishing Checklist <span class=\"badge\">\u2b07<\/span>\n      <\/a>\n    <\/div>\n  <\/div>\n\n  <div class=\"sap-progress-bar\"><div class=\"sap-progress-fill\" id=\"sapProgressFill\" style=\"width:20%\"><\/div><\/div>\n\n  <div class=\"sap-stepper\" id=\"sapStepper\">\n    <div class=\"sap-step-item active\" data-step=\"1\" onclick=\"sapGoStep(1)\"><div class=\"sap-step-num\">1<\/div><div class=\"sap-step-label\">Project<\/div><\/div>\n    <div class=\"sap-step-item\" data-step=\"2\" onclick=\"sapGoStep(2)\"><div class=\"sap-step-num\">2<\/div><div class=\"sap-step-label\">Publishing<\/div><\/div>\n    <div class=\"sap-step-item\" data-step=\"3\" onclick=\"sapGoStep(3)\"><div class=\"sap-step-num\">3<\/div><div class=\"sap-step-label\">Print<\/div><\/div>\n    <div class=\"sap-step-item\" data-step=\"4\" onclick=\"sapGoStep(4)\"><div class=\"sap-step-num\">4<\/div><div class=\"sap-step-label\">Quotation<\/div><\/div>\n  <\/div>\n\n  <div class=\"sap-body\" id=\"calculator-form\">\n\n  <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n       STEP 1 \u2014 PROJECT DETAILS (unchanged)\n  \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n  <div class=\"sap-step-panel active\" id=\"sap-step-1\">\n\n    <p class=\"sap-step-heading\">Project Details<\/p>\n    <p class=\"sap-step-sub\">Start with your project basics. Word count drives all editorial cost estimates.<\/p>\n\n    <div class=\"sap-project-row\">\n      <div class=\"sap-field\">\n        <label for=\"bookTitle\">Project Title<\/label>\n        <input type=\"text\" id=\"bookTitle\" name=\"bookTitle\" placeholder=\"My Book Project\" value=\"My Book Project\">\n      <\/div>\n      <div class=\"sap-field\">\n        <label for=\"wordCount\">Word Count <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Total words in your manuscript. Required for editing, typesetting and transcription estimates.<\/span><\/span><\/label>\n        <input type=\"number\" id=\"wordCount\" name=\"wordCount\" min=\"500\" value=\"20000\">\n      <\/div>\n    <\/div>\n\n    <div class=\"sap-section-label\">Your Details<\/div>\n\n    <div class=\"sap-client-grid\">\n      <div class=\"sap-field\">\n        <label for=\"clientName\">Your Name<\/label>\n        <input type=\"text\" id=\"clientName\" name=\"clientName\" placeholder=\"Full name\">\n      <\/div>\n      <div class=\"sap-field\">\n        <label for=\"clientEmail\">Email Address <span style=\"color:var(--sap-error)\">*<\/span><\/label>\n        <input type=\"email\" id=\"clientEmail\" name=\"clientEmail\" placeholder=\"email@example.com\">\n        <div class=\"sap-error\" id=\"emailError\">A valid email address is required.<\/div>\n      <\/div>\n      <div class=\"sap-field\">\n        <label for=\"clientPhone\">Phone \/ WhatsApp<\/label>\n        <input type=\"tel\" id=\"clientPhone\" name=\"clientPhone\" placeholder=\"Optional\">\n      <\/div>\n    <\/div>\n\n  <\/div><!-- \/step 1 -->\n\n\n  <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n       STEP 2 \u2014 PUBLISHING SERVICES (DYNAMIC)\n       Rendered entirely from ace_get_sap_services().\n       To add\/remove\/reprice a service, use\n       Publishing Toolkit \u2192 Settings \u2192 SAP Calculator.\n       No code changes required.\n  \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n  <div class=\"sap-step-panel\" id=\"sap-step-2\">\n\n    <p class=\"sap-step-heading\">Publishing Services<\/p>\n    <p class=\"sap-step-sub\">Toggle any services you need. Prices update live on the next step.<\/p>\n\n        <div class=\"sap-section-label\">\n        Editorial            <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_transcription_active\" data-subsection=\"svc_transcription_details\">\n      <span class=\"sap-toggle-label\">\u270d\ufe0f Manuscript Transcription        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Converting handwritten manuscripts into digital text format.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_transcription_active\" name=\"svc_transcription_active\" class=\"ace-svc-toggle\" data-key=\"transcription\">\n        <label class=\"sap-switch-track\" for=\"svc_transcription_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_transcription_details\">\n\n                <div class=\"sap-error\" id=\"svc_transcription_error\">Requires a word count of 100 or more.<\/div>\n        \n                    <label for=\"svc_transcription_option\">Select Manuscript Language<\/label>\n            <select id=\"svc_transcription_option\" name=\"svc_transcription_option\" class=\"ace-svc-option\">\n                                <option value=\"English\">English<\/option>\n                                <option value=\"Yoruba\">Yoruba<\/option>\n                                <option value=\"Other Languages\">Other Languages<\/option>\n                            <\/select>\n\n        \n    <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_editing_active\" data-subsection=\"svc_editing_details\">\n      <span class=\"sap-toggle-label\">\ud83d\udcdd Editing        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Dev. Editing = structure &amp; ideas. Line Editing = style &amp; clarity. Copy Editing = grammar &amp; consistency.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_editing_active\" name=\"svc_editing_active\" class=\"ace-svc-toggle\" data-key=\"editing\">\n        <label class=\"sap-switch-track\" for=\"svc_editing_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_editing_details\">\n\n                <div class=\"sap-error\" id=\"svc_editing_error\">Requires a word count of 30 or more.<\/div>\n        \n                    <label for=\"svc_editing_option\">Select Level<\/label>\n            <select id=\"svc_editing_option\" name=\"svc_editing_option\" class=\"ace-svc-option\">\n                                <option value=\"Developmental Editing\">Developmental Editing (\u20a610\/word)<\/option>\n                                <option value=\"Line Editing\">Line Editing (\u20a66\/word)<\/option>\n                                <option value=\"Copy Editing\">Copy Editing (\u20a63.2\/word)<\/option>\n                            <\/select>\n\n        \n    <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_proofreading_active\" data-subsection=\"\">\n      <span class=\"sap-toggle-label\">\ud83d\udd0d Proofreading        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Final quality check \u2014 typos, punctuation, and formatting inconsistencies.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_proofreading_active\" name=\"svc_proofreading_active\" class=\"ace-svc-toggle\" data-key=\"proofreading\">\n        <label class=\"sap-switch-track\" for=\"svc_proofreading_active\"><\/label>\n      <\/div>\n    <\/label>\n\n            <div class=\"sap-section-label\">\n        Design            <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_formatting_active\" data-subsection=\"svc_formatting_details\">\n      <span class=\"sap-toggle-label\"> Typesetting &amp; Formatting        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Arranging text for print or digital. Select both Ebook &amp; Print and enjoy a 25% discount.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_formatting_active\" name=\"svc_formatting_active\" class=\"ace-svc-toggle\" data-key=\"formatting\">\n        <label class=\"sap-switch-track\" for=\"svc_formatting_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_formatting_details\">\n\n                <div class=\"sap-error\" id=\"svc_formatting_error\">Requires a word count of 30 or more.<\/div>\n        \n                    <label for=\"svc_formatting_option\">Select Formatting Type<\/label>\n            <select id=\"svc_formatting_option\" name=\"svc_formatting_option\" class=\"ace-svc-option\">\n                                <option value=\"Ebook &amp; Print\">Ebook and Print Formatting<\/option>\n                                <option value=\"Ebook Formatting\">Ebook Formatting<\/option>\n                                <option value=\"Print Layout\">Print Layout<\/option>\n                            <\/select>\n\n        \n    <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_cover_design_active\" data-subsection=\"svc_cover_design_details\">\n      <span class=\"sap-toggle-label\">\ud83c\udfa8 Book Cover        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Full cover (front, back &amp; spine) required for print. Front only for digital distribution.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_cover_design_active\" name=\"svc_cover_design_active\" class=\"ace-svc-toggle\" data-key=\"cover_design\">\n        <label class=\"sap-switch-track\" for=\"svc_cover_design_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_cover_design_details\">\n\n        \n                    <label for=\"svc_cover_design_option\">Select an option<\/label>\n            <select id=\"svc_cover_design_option\" name=\"svc_cover_design_option\" class=\"ace-svc-option\">\n                                <option value=\"Full Cover\">Full Cover (\u20a628,000)<\/option>\n                                <option value=\"Front Cover Only\">Front Cover Only (\u20a616,000)<\/option>\n                            <\/select>\n\n        \n    <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_brochure_design_active\" data-subsection=\"svc_brochure_design_details\">\n      <span class=\"sap-toggle-label\">\ud83d\udcf0 Brochure &amp; Magazine        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Promotional brochure design. Enter the number of pages needed.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_brochure_design_active\" name=\"svc_brochure_design_active\" class=\"ace-svc-toggle\" data-key=\"brochure_design\">\n        <label class=\"sap-switch-track\" for=\"svc_brochure_design_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_brochure_design_details\">\n\n                <div class=\"sap-error\" id=\"svc_brochure_design_error\">Please enter at least 1 page(s).<\/div>\n        \n                    <label for=\"svc_brochure_design_count\">Number of pages<\/label>\n            <input type=\"number\" id=\"svc_brochure_design_count\" name=\"svc_brochure_design_count\" class=\"ace-svc-count\"\n                   min=\"1\" placeholder=\"e.g. 1\">\n\n        \n    <\/div>\n            <div class=\"sap-section-label\">\n        Legal            <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_isbn_active\" data-subsection=\"svc_isbn_details\">\n      <span class=\"sap-toggle-label\">\ud83d\udd22 ISBN        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Each book title &amp; version requires its own ISBN.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_isbn_active\" name=\"svc_isbn_active\" class=\"ace-svc-toggle\" data-key=\"isbn\">\n        <label class=\"sap-switch-track\" for=\"svc_isbn_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_isbn_details\">\n\n        \n                    <label for=\"svc_isbn_option\">Select an option<\/label>\n            <select id=\"svc_isbn_option\" name=\"svc_isbn_option\" class=\"ace-svc-option\">\n                                <option value=\"1isbn\">1 ISBN (\u20a615,500)<\/option>\n                                <option value=\"2isbn\">2 ISBNs (\u20a620,500)<\/option>\n                                <option value=\"3isbn\">3 ISBNs (\u20a625,500)<\/option>\n                                <option value=\"4isbn\">4 ISBNs (\u20a630,500)<\/option>\n                                <option value=\"5isbn\">5 ISBNs (\u20a635,500)<\/option>\n                            <\/select>\n\n        \n    <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_copyright_active\" data-subsection=\"\">\n      <span class=\"sap-toggle-label\">\u00a9\ufe0f Copyright        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Formal legal claim over your content. Recommended for protection.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_copyright_active\" name=\"svc_copyright_active\" class=\"ace-svc-toggle\" data-key=\"copyright\">\n        <label class=\"sap-switch-track\" for=\"svc_copyright_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <label class=\"sap-toggle-row\" for=\"svc_issn_active\" data-subsection=\"svc_issn_details\">\n      <span class=\"sap-toggle-label\">\ud83d\udccb ISSN        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">For serial publications like magazines, journals, and newsletters.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_issn_active\" name=\"svc_issn_active\" class=\"ace-svc-toggle\" data-key=\"issn\">\n        <label class=\"sap-switch-track\" for=\"svc_issn_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_issn_details\">\n\n        \n                    <label for=\"svc_issn_option\">Select an option<\/label>\n            <select id=\"svc_issn_option\" name=\"svc_issn_option\" class=\"ace-svc-option\">\n                                <option value=\"Electronic ISSN\">Electronic ISSN (\u20a629,100)<\/option>\n                                <option value=\"Print ISSN\">Print ISSN (\u20a632,100)<\/option>\n                                <option value=\"Both\">Both (\u20a661,200)<\/option>\n                            <\/select>\n\n        \n    <\/div>\n            <div class=\"sap-section-label\">\n        Publishing                <a href=\"https:\/\/aceworldpgs.com\/sap\/\" target=\"_blank\" class=\"sap-jump\" style=\"margin-left:4px;\">\u2197<\/a>\n            <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_amazon_kindle_active\" data-subsection=\"svc_amazon_kindle_details\">\n      <span class=\"sap-toggle-label\">\ud83d\udce6 Amazon Kindle &amp; Selar        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Your book on Amazon marketplaces in Kindle ebook and print format.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_amazon_kindle_active\" name=\"svc_amazon_kindle_active\" class=\"ace-svc-toggle\" data-key=\"amazon_kindle\">\n        <label class=\"sap-switch-track\" for=\"svc_amazon_kindle_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_amazon_kindle_details\">\n\n        \n                    <label for=\"svc_amazon_kindle_option\">Select an option<\/label>\n            <select id=\"svc_amazon_kindle_option\" name=\"svc_amazon_kindle_option\" class=\"ace-svc-option\">\n                                <option value=\"new_kdp_user\">New KDP User (\u20a625,000)<\/option>\n                                <option value=\"existing_kdp_user\">Existing KDP User (\u20a615,000)<\/option>\n                            <\/select>\n\n        \n    <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_ebook_distribution_active\" data-subsection=\"\">\n      <span class=\"sap-toggle-label\">\ud83c\udf10 Ebook Distribution        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Kobo, Apple Books, Barnes &amp; Noble, Everand, Indigo, and more.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_ebook_distribution_active\" name=\"svc_ebook_distribution_active\" class=\"ace-svc-toggle\" data-key=\"ebook_distribution\">\n        <label class=\"sap-switch-track\" for=\"svc_ebook_distribution_active\"><\/label>\n      <\/div>\n    <\/label>\n\n            <div class=\"sap-section-label\">\n        Marketing                <a href=\"https:\/\/aceworldpgs.com\/marketing\/\" target=\"_blank\" class=\"sap-jump\" style=\"margin-left:4px;\">\u2197<\/a>\n            <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_news_distribution_active\" data-subsection=\"svc_news_distribution_details\">\n      <span class=\"sap-toggle-label\">\ud83d\udce2 News Distribution        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Share the news where the world reads.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_news_distribution_active\" name=\"svc_news_distribution_active\" class=\"ace-svc-toggle\" data-key=\"news_distribution\">\n        <label class=\"sap-switch-track\" for=\"svc_news_distribution_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_news_distribution_details\">\n\n        \n                    <p style=\"font-size:12px; color:var(--sap-gray-600);\">\n                News Distribution has a fully integrated service page.                 <a href=\"https:\/\/aceworldpgs.com\/marketing\/cds\/\" target=\"_blank\">Click here to learn more<\/a>.            <\/p>\n        \n    <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_authors_website_active\" data-subsection=\"svc_authors_website_details\">\n      <span class=\"sap-toggle-label\">\ud83c\udf0d Author&#039;s Website        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Engage your audience with a powerful author website.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_authors_website_active\" name=\"svc_authors_website_active\" class=\"ace-svc-toggle\" data-key=\"authors_website\">\n        <label class=\"sap-switch-track\" for=\"svc_authors_website_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_authors_website_details\">\n\n        \n                    <p style=\"font-size:12px; color:var(--sap-gray-600);\">\n                Website Development has a fully integrated service page.                 <a href=\"https:\/\/aceworldpgs.com\/wds\/\" target=\"_blank\">Click here to learn more<\/a>.            <\/p>\n        \n    <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_social_media_active\" data-subsection=\"svc_social_media_details\">\n      <span class=\"sap-toggle-label\">\ud83d\udcf1 Social Media Management        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">We know how social media algorithms work. Book us now!<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_social_media_active\" name=\"svc_social_media_active\" class=\"ace-svc-toggle\" data-key=\"social_media\">\n        <label class=\"sap-switch-track\" for=\"svc_social_media_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_social_media_details\">\n\n        \n                    <p style=\"font-size:12px; color:var(--sap-gray-600);\">\n                Social Media Management has a fully integrated service page.                 <a href=\"https:\/\/aceworldpgs.com\/sms\/\" target=\"_blank\">Click here to learn more<\/a>.            <\/p>\n        \n    <\/div>\n        <label class=\"sap-toggle-row\" for=\"svc_mdservice_active\" data-subsection=\"svc_mdservice_details\">\n      <span class=\"sap-toggle-label\">\u2712\ufe0f Manuscript Development Service        <span class=\"sap-tip\">?<span class=\"sap-tip-text\">We help you estimate the cost of professionally developing a manuscript based on your project needs.<\/span><\/span>      <\/span>\n      <div class=\"sap-switch\">\n        <input type=\"checkbox\" id=\"svc_mdservice_active\" name=\"svc_mdservice_active\" class=\"ace-svc-toggle\" data-key=\"mdservice\">\n        <label class=\"sap-switch-track\" for=\"svc_mdservice_active\"><\/label>\n      <\/div>\n    <\/label>\n\n        <div class=\"sap-subsection\" id=\"svc_mdservice_details\">\n\n        \n                    <p style=\"font-size:12px; color:var(--sap-gray-600);\">\n                Manuscript Development Service has a fully integrated service page.                 <a href=\"https:\/\/aceworldpgs.com\/tools\/manuscript-development-calculator\/\" target=\"_blank\">Click here to learn more<\/a>.            <\/p>\n        \n    <\/div>\n        \n    \n  <\/div><!-- \/step 2 -->\n\n\n  <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n       STEP 3 \u2014 PRINT SERVICES (unchanged \u2014 ACF driven,\n       gets its own admin tab in a later phase)\n  \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n  <div class=\"sap-step-panel\" id=\"sap-step-3\">\n    <span id=\"printcalc\"><\/span>\n\n    <p class=\"sap-step-heading\">Print Services<\/p>\n    <p class=\"sap-step-sub\">Configure your print run. Select 0 copies if you are not printing.<\/p>\n\n    <div class=\"sap-section-label\">Number of Copies<\/div>\n    <div class=\"sap-radio-grid sap-radio-grid-5\" id=\"copiesGrid\">\n      <label class=\"sap-radio-card no-print selected\" data-group=\"copiesOption\" data-copies=\"0\">\n        <input type=\"radio\" name=\"copiesOption\" value=\"0\" checked>\n        <span class=\"rc-label\">No Print<\/span><span class=\"rc-sub\">0 copies<\/span>\n      <\/label>\n      <label class=\"sap-radio-card\" data-group=\"copiesOption\" data-copies=\"100\"><input type=\"radio\" name=\"copiesOption\" value=\"100\"><span class=\"rc-icon\">\ud83d\udcda<\/span><span class=\"rc-label\">100<\/span><\/label>\n      <label class=\"sap-radio-card\" data-group=\"copiesOption\" data-copies=\"300\"><input type=\"radio\" name=\"copiesOption\" value=\"300\"><span class=\"rc-icon\">\ud83d\udcda<\/span><span class=\"rc-label\">300<\/span><\/label>\n      <label class=\"sap-radio-card\" data-group=\"copiesOption\" data-copies=\"500\"><input type=\"radio\" name=\"copiesOption\" value=\"500\"><span class=\"rc-icon\">\ud83d\udcda<\/span><span class=\"rc-label\">500<\/span><\/label>\n      <label class=\"sap-radio-card\" data-group=\"copiesOption\" data-copies=\"1000\"><input type=\"radio\" name=\"copiesOption\" value=\"1000\"><span class=\"rc-icon\">\ud83d\udcda<\/span><span class=\"rc-label\">1000<\/span><\/label>\n    <\/div>\n    <label class=\"sap-radio-card\" id=\"customCopiesCard\" data-group=\"copiesOption\" style=\"display:flex; flex-direction:row; gap:10px; padding:10px 16px; justify-content:flex-start; margin-bottom:8px;\">\n      <input type=\"radio\" name=\"copiesOption\" value=\"custom\">\n      <span class=\"rc-label\">Custom quantity (20\u20131000)<\/span>\n    <\/label>\n    <div class=\"sap-custom-copies\" id=\"customCopiesInput\">\n      <input type=\"number\" id=\"copies-custom-input\"\n             placeholder=\"Enter copies (20\u20131000)\"\n             min=\"20\"\n             max=\"1000\"\n             value=\"20\">\n      <div class=\"sap-error\" id=\"customCopiesError\">Enter between 20 and 1000 copies.<\/div>\n    <\/div>\n\n    <div id=\"pageCountSection\" style=\"display:none;\">\n      <div class=\"sap-section-label\">Number of Pages<\/div>\n      <div class=\"sap-field\">\n        <input type=\"number\" id=\"pageCount\" name=\"pageCount\" min=\"50\" value=\"100\">\n        <div class=\"sap-error\" id=\"pageCountError\">Minimum 50 pages required for printing.<\/div>\n        <small>Minimum 50 pages for printing. This tool quotes digital printing for under 50 copies; offset for 50+.<\/small>\n      <\/div>\n    <\/div>\n\n    <div id=\"printSpecsSection\" style=\"display:none; margin-top:16px;\">\n      <div class=\"sap-print-specs\">\n        <div class=\"sap-print-specs-header\" id=\"printSpecsToggler\">\n          <span>\u2699\ufe0f Print Specifications<\/span><span class=\"chevron\">\u2304<\/span>\n        <\/div>\n        <div class=\"sap-print-specs-body\" id=\"printSpecsBody\" style=\"display:none;\">\n\n          <div class=\"sap-section-label\">Trim Size <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Physical dimensions of your printed book.<\/span><\/span><\/div>\n          <div class=\"sap-field\" style=\"margin-bottom:14px;\">\n            <select id=\"desiredPrintSize\" name=\"desiredPrintSize\">\n                            <option value=\"A5\">A5 (International Standard)<\/option>\n                            <option value=\"US Trade\">Digest (Compact \/ Novel)<\/option>\n                            <option value=\"B5\">B5 (Large \/ Academic)<\/option>\n                            <option value=\"Pocket\">Pocket \/ Small Trade<\/option>\n                            <option value=\"A6\">A6 (Pocketbook)<\/option>\n                            <option value=\"A4\">A4 (Workbooks \/ Reports)<\/option>\n                            <option value=\"6x9\">6x9 US Trade (Amazon KDP)<\/option>\n                          <\/select>\n          <\/div>\n\n                    <div class=\"sap-section-label\">Paper Finish<\/div>\n          <div class=\"sap-radio-grid sap-radio-grid-2\">\n                            <label class=\"sap-radio-card selected\"\n                     data-group=\"og_paper_finish\" data-val=\"uncoated\">\n                  <input type=\"radio\" name=\"og_paper_finish\" value=\"uncoated\"  checked='checked'>\n                  <span class=\"rc-label\">Uncoated<\/span>\n                                <\/label>\n                            <label class=\"sap-radio-card \"\n                     data-group=\"og_paper_finish\" data-val=\"coated\">\n                  <input type=\"radio\" name=\"og_paper_finish\" value=\"coated\" >\n                  <span class=\"rc-label\">Coated<\/span>\n                  <span class=\"rc-sub\">+\u20a6500<\/span>              <\/label>\n                        <\/div>\n                    <div class=\"sap-section-label\">Paper Color<\/div>\n          <div class=\"sap-radio-grid sap-radio-grid-2\">\n                            <label class=\"sap-radio-card selected\"\n                     data-group=\"og_paper_color\" data-val=\"white\">\n                  <input type=\"radio\" name=\"og_paper_color\" value=\"white\"  checked='checked'>\n                  <span class=\"rc-label\">White<\/span>\n                                <\/label>\n                            <label class=\"sap-radio-card \"\n                     data-group=\"og_paper_color\" data-val=\"cream\">\n                  <input type=\"radio\" name=\"og_paper_color\" value=\"cream\" >\n                  <span class=\"rc-label\">Cream<\/span>\n                  <span class=\"rc-sub\">+\u20a6600<\/span>              <\/label>\n                        <\/div>\n                    <div class=\"sap-section-label\">Interior Ink<\/div>\n          <div class=\"sap-radio-grid sap-radio-grid-2\">\n                            <label class=\"sap-radio-card selected\"\n                     data-group=\"og_interior_ink\" data-val=\"bw\">\n                  <input type=\"radio\" name=\"og_interior_ink\" value=\"bw\"  checked='checked'>\n                  <span class=\"rc-label\">Black and White<\/span>\n                                <\/label>\n                            <label class=\"sap-radio-card \"\n                     data-group=\"og_interior_ink\" data-val=\"colored\">\n                  <input type=\"radio\" name=\"og_interior_ink\" value=\"colored\" >\n                  <span class=\"rc-label\">Colored<\/span>\n                  <span class=\"rc-sub\">+\u20a6600<\/span>              <\/label>\n                        <\/div>\n                    <div class=\"sap-section-label\">Cover Lamination<\/div>\n          <div class=\"sap-radio-grid sap-radio-grid-2\">\n                            <label class=\"sap-radio-card selected\"\n                     data-group=\"og_cover_lamination\" data-val=\"matte\">\n                  <input type=\"radio\" name=\"og_cover_lamination\" value=\"matte\"  checked='checked'>\n                  <span class=\"rc-label\">Matte<\/span>\n                                <\/label>\n                            <label class=\"sap-radio-card \"\n                     data-group=\"og_cover_lamination\" data-val=\"glossy\">\n                  <input type=\"radio\" name=\"og_cover_lamination\" value=\"glossy\" >\n                  <span class=\"rc-label\">Glossy<\/span>\n                  <span class=\"rc-sub\">+\u20a6400<\/span>              <\/label>\n                        <\/div>\n                    <div class=\"sap-section-label\">Binding &amp; Cover Type<\/div>\n          <div class=\"sap-radio-grid sap-radio-grid-2\">\n                            <label class=\"sap-radio-card selected\"\n                     data-group=\"og_binding_cover_type\" data-val=\"paperback\">\n                  <input type=\"radio\" name=\"og_binding_cover_type\" value=\"paperback\"  checked='checked'>\n                  <span class=\"rc-label\">Perfect Binding (Paperback)<\/span>\n                                <\/label>\n                            <label class=\"sap-radio-card \"\n                     data-group=\"og_binding_cover_type\" data-val=\"hardback\">\n                  <input type=\"radio\" name=\"og_binding_cover_type\" value=\"hardback\" >\n                  <span class=\"rc-label\">Case Binding (Hardback)<\/span>\n                  <span class=\"rc-sub\">+\u20a6600<\/span>              <\/label>\n                        <\/div>\n                    <div class=\"sap-section-label\">Cover Title Style<\/div>\n          <div class=\"sap-radio-grid sap-radio-grid-3\">\n                            <label class=\"sap-radio-card selected\"\n                     data-group=\"og_cover_title_style\" data-val=\"normal\">\n                  <input type=\"radio\" name=\"og_cover_title_style\" value=\"normal\"  checked='checked'>\n                  <span class=\"rc-label\">Normal<\/span>\n                                <\/label>\n                            <label class=\"sap-radio-card \"\n                     data-group=\"og_cover_title_style\" data-val=\"embossing_debossing\">\n                  <input type=\"radio\" name=\"og_cover_title_style\" value=\"embossing_debossing\" >\n                  <span class=\"rc-label\">Embossing \/ Debossing<\/span>\n                  <span class=\"rc-sub\">+\u20a6600<\/span>              <\/label>\n                            <label class=\"sap-radio-card \"\n                     data-group=\"og_cover_title_style\" data-val=\"foil\">\n                  <input type=\"radio\" name=\"og_cover_title_style\" value=\"foil\" >\n                  <span class=\"rc-label\">Foil Stamping Embossing<\/span>\n                  <span class=\"rc-sub\">+\u20a6800<\/span>              <\/label>\n                        <\/div>\n          \n                    <div class=\"sap-section-label\">Finishing Add-ons <span class=\"sap-tip\">?<span class=\"sap-tip-text\">Any number can be added together \u2014 unlike the choices above, these stack.<\/span><\/span><\/div>\n                    <label class=\"sap-toggle-row\" for=\"addon_nylon_wrapping_active\">\n              <span class=\"sap-toggle-label\">Nylon Wrapping (per copy) <span class=\"tip\">+\u20a650\/copy<\/span><\/span>\n              <div class=\"sap-switch\">\n                  <input type=\"checkbox\" id=\"addon_nylon_wrapping_active\" class=\"ace-svc-toggle\"  checked='checked'>\n                  <label class=\"sap-switch-track\" for=\"addon_nylon_wrapping_active\"><\/label>\n              <\/div>\n          <\/label>\n                    <label class=\"sap-toggle-row\" for=\"addon_crystal_effect_active\">\n              <span class=\"sap-toggle-label\">Crystal Cover Effect (per copy) <span class=\"tip\">+\u20a61,000\/copy<\/span><\/span>\n              <div class=\"sap-switch\">\n                  <input type=\"checkbox\" id=\"addon_crystal_effect_active\" class=\"ace-svc-toggle\" >\n                  <label class=\"sap-switch-track\" for=\"addon_crystal_effect_active\"><\/label>\n              <\/div>\n          <\/label>\n                    <label class=\"sap-toggle-row\" for=\"addon_sample_proofing_active\">\n              <span class=\"sap-toggle-label\">Physical Proof Copy (per copy) <span class=\"tip\">+\u20a67,000\/copy<\/span><\/span>\n              <div class=\"sap-switch\">\n                  <input type=\"checkbox\" id=\"addon_sample_proofing_active\" class=\"ace-svc-toggle\" >\n                  <label class=\"sap-switch-track\" for=\"addon_sample_proofing_active\"><\/label>\n              <\/div>\n          <\/label>\n                    \n        <\/div>\n      <\/div>\n    <\/div>\n\n  <\/div><!-- \/step 3 -->\n\n\n  <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n       STEP 4 \u2014 QUOTATION (service rows now render\n       into #qServicesBlock dynamically via JS)\n  \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n  <div class=\"sap-step-panel\" id=\"sap-step-4\">\n\n    <p class=\"sap-step-heading\">Your Quotation<\/p>\n    <p class=\"sap-step-sub\">Review your itemised estimate below.<\/p>\n\n    <div id=\"sap-quote-print-target\">\n    <div class=\"sap-quote-panel\">\n      <div class=\"sap-quote-header\">\n        <div class=\"sap-quote-header-left\">\n          <div class=\"qh-title\">ACEworld Publishers Limited<\/div>\n          <div class=\"qh-title\">Publishing Quotation<\/div>\n          <div class=\"qh-book\" id=\"qhBookTitle\">My Book Project<\/div>\n          <div class=\"qh-words\" id=\"qhWords\">20,000 words<\/div>\n          <div class=\"sap-quote-date\" id=\"qhDate\"><\/div>\n        <\/div>\n        <div><div class=\"sap-quote-total-badge\" id=\"qhTotal\">\u20a60<\/div><\/div>\n      <\/div>\n\n      <div class=\"sap-quote-body\">\n\n        <div class=\"sap-quote-section-title\">Publishing Services<\/div>\n        <div id=\"qServicesBlock\"><!-- populated by sapUpdateQuote() --><\/div>\n\n        <div id=\"qPrintBlock\" style=\"display:none;\">\n          <div class=\"sap-quote-section-title\">Print Production<\/div>\n          <div class=\"sap-print-card\" id=\"qPrintCard\">\n            <div>\n              <div class=\"pc-copies\" id=\"qPrintCopies\">0 Copies<\/div>\n              <div class=\"pc-specs\" id=\"qPrintSpecs\">\u2014<\/div>\n            <\/div>\n            <div style=\"text-align:right;\">\n              <div class=\"pc-price\" id=\"qPrintPricePerCopy\">\u20a60<\/div>\/each\n              <div class=\"pc-each\"><\/div>\n            <\/div>\n          <\/div>\n          <div class=\"sap-specs-grid\" id=\"qSpecsGrid\"><\/div>\n        <\/div>\n\n        <div class=\"sap-quote-row total\"><span class=\"qr-label\">Estimated Total<\/span><span class=\"qr-value\" id=\"qGrandTotal\">\u20a60<\/span><\/div>\n\n      <\/div>\n\n      <div class=\"sap-note\">\n        \u2139\ufe0f This is an estimate generated by our calculator. Reach us via call or WhatsApp at <strong>+2348166110313, +2348072349777<\/strong>.\n        Email: <strong>info.myaceworld@gmail.com<\/strong>\n      <\/div>\n    <\/div>\n    <\/div><!-- \/#sap-quote-print-target -->\n\n    <div style=\"text-align:center; margin: 4px 0 12px;\">\n      <button class=\"sap-clear-link\" id=\"clearFormBtn\">Clear all inputs<\/button>\n    <\/div>\n\n  <\/div><!-- \/step 4 -->\n\n  <\/div><!-- \/.sap-body -->\n\n  <div class=\"sap-nav\" id=\"sapNav\">\n    <button class=\"sap-btn sap-btn-ghost\" id=\"sapBtnBack\" style=\"display:none;\" onclick=\"sapNavBack()\">\u2190 Back<\/button>\n    <div style=\"flex:1\"><\/div>\n    <button class=\"sap-btn sap-btn-primary\" id=\"sapBtnNext\" onclick=\"sapNavNext()\">Publishing Services \u2192<\/button>\n    <button class=\"sap-btn sap-btn-submit\" id=\"sapBtnSubmit\" style=\"display:none;\" onclick=\"trackTool('publishing_calculator')\" type=\"button\">\ud83d\udda8\ufe0f Print Quote<\/button>\n  <\/div>\n\n<\/div><!-- \/.sap-calc -->\n\n<div class=\"sap-floating-total\" id=\"sapFloatingTotal\">\n  <div>\n    <div class=\"sap-float-label\">Running Total<\/div>\n    <div class=\"sap-float-value\" id=\"sapFloatValue\">\u20a60<\/div>\n  <\/div>\n  <button class=\"sap-float-details\" onclick=\"sapGoStep(4)\">View \u2192<\/button>\n<\/div>\n\n\n<style>\n\n\/* SHARE SECTION *\/\n\n.share-section{\ntext-align:center;\npadding:28px 0;\nmargin-top:30px;\nborder-top:1px solid #e5e7eb;\n}\n\n\/* COPY LINK BUTTON *\/\n\n.copy-link-btn{\ndisplay:inline-flex;\nalign-items:center;\ngap:6px;\nfont-size:14px;\nfont-weight:600;\ncolor:var(--text-main);\nbackground:#f8fafc;\npadding:6px 12px;\nborder-radius:6px;\ntext-decoration:none;\ncursor:pointer;\ntransition:all .2s ease;\nmargin-bottom:18px;\n}\n\n.copy-link-btn:hover{\nbackground:#eef2f7;\ntransform:translateY(-1px);\n}\n\n\/* SHARE BUTTON ROW *\/\n\n.share-btns{\ndisplay:flex;\njustify-content:center;\ngap:12px;\nflex-wrap:wrap;\n}\n\n\/* SHARE ICON *\/\n\n.share-icon{\nwidth:36px;\nheight:36px;\nborder-radius:50%;\ndisplay:flex;\nalign-items:center;\njustify-content:center;\ncolor:#fff;\nfont-size:14px;\nfont-weight:600;\ntext-decoration:none;\ntransition:all .2s ease;\n}\n\n\/* BRAND COLORS *\/\n\n.wa{background:#25D366;}\n.tw{background:#000;}\n.li{background:#0A66C2;}\n.fb{background:#1877F2;}\n.ml{background:#ef4444;}\n\n\/* HOVER EFFECT *\/\n\n.share-icon:hover{\ntransform:translateY(-2px) scale(1.05);\nopacity:.9;\n}\n\n\/* COPY FEEDBACK *\/\n\n.copy-feedback{\nfont-size:12px;\ncolor:#16a34a;\nmargin-top:10px;\ndisplay:none;\n}\n\n<\/style>\n\n\n<div class=\"share-section\">\n\n<a onclick=\"copyToolLink()\" class=\"copy-link-btn\" id=\"copyBtn\">\n\ud83d\udd17 Copy Page Link\n<\/a>\n\n<div class=\"share-btns\">\n<a href=\"#\" id=\"shareWA\" target=\"_blank\" class=\"share-icon wa\" title=\"Share on WhatsApp\">W<\/a>\n<a href=\"#\" id=\"shareTW\" target=\"_blank\" class=\"share-icon tw\" title=\"Share on X\">X<\/a>\n<a href=\"#\" id=\"shareLI\" target=\"_blank\" class=\"share-icon li\" title=\"Share on LinkedIn\">in<\/a>\n<a href=\"#\" id=\"shareFB\" target=\"_blank\" class=\"share-icon fb\" title=\"Share on Facebook\">f<\/a>\n<a href=\"#\" id=\"shareEmail\" target=\"_blank\" class=\"share-icon ml\" title=\"Share via Email\">M<\/a>\n<\/div>\n\n<div id=\"copyFeedback\" class=\"copy-feedback\">Link copied!<\/div>\n\n<\/div>\n\n\n<script>\n\nfunction copyToolLink(){\n\nconst url = window.location.href;\n\nnavigator.clipboard.writeText(url).then(()=>{\n\nconst f = document.getElementById(\"copyFeedback\");\n\nf.style.display=\"block\";\n\nsetTimeout(()=>{f.style.display=\"none\"},2000);\n\n}).catch(()=>{\n\nalert(\"Copy failed. Please copy the URL manually.\");\n\n});\n\n}\n\nfunction setupShareButtons(){\n\nlet pageUrl=encodeURIComponent(window.location.href)\nlet pageTitle=encodeURIComponent(document.title)\n\ndocument.getElementById(\"shareWA\").href=\n`https:\/\/wa.me\/?text=${pageTitle}%20${pageUrl}`\n\ndocument.getElementById(\"shareTW\").href=\n`https:\/\/twitter.com\/intent\/tweet?text=${pageTitle}&url=${pageUrl}`\n\ndocument.getElementById(\"shareLI\").href=\n`https:\/\/www.linkedin.com\/sharing\/share-offsite\/?url=${pageUrl}`\n\ndocument.getElementById(\"shareFB\").href=\n`https:\/\/www.facebook.com\/sharer\/sharer.php?u=${pageUrl}`\n\ndocument.getElementById(\"shareEmail\").href=\n\"mailto:?subject=\"+encodeURIComponent(document.title)+\n\"&body=\"+encodeURIComponent(\"Check out this page: \"+window.location.href)\n\n}\n\nsetupShareButtons()\n\n<\/script>\n\n\n\n    <style>\n        .ace-feedback-btn {\n            padding: 10px 14px;\n            background: #111827;\n            color: #fff;\n            border: none;\n            border-radius: 8px;\n            cursor: pointer;\n            font-size: 13px;\n            display: block;\n            margin: 20px auto;\n        }\n\n        .ace-feedback-modal {\n            display: none;\n            position: fixed;\n            top: 0; left: 0;\n            width: 100%; height: 100%;\n            background: rgba(0,0,0,0.5);\n            justify-content: center;\n            align-items: center;\n            z-index: 9999;\n        }\n\n        .ace-feedback-box {\n            background: #fff;\n            padding: 20px;\n            width: 100%;\n            max-width: 420px;\n            border-radius: 10px;\n        }\n\n        .ace-feedback-box textarea,\n        .ace-feedback-box input {\n            width: 100%;\n            margin-bottom: 10px;\n            padding: 10px;\n            border: 1px solid #ddd;\n            border-radius: 6px;\n        }\n\n        .ace-feedback-submit {\n            background: #2563eb;\n            color: #fff;\n            padding: 10px;\n            border: none;\n            width: 100%;\n            border-radius: 6px;\n            cursor: pointer;\n        }\n    <\/style>\n\n    <button class=\"ace-feedback-btn\" onclick=\"document.getElementById('aceFeedbackModal').style.display='flex'\">\n        Report Problem \/ Contact Us\n    <\/button>\n\n    <div id=\"aceFeedbackModal\" class=\"ace-feedback-modal\">\n        <div class=\"ace-feedback-box\">\n\n            <h3 style=\"margin-top:0;\">Send Feedback<\/h3>\n\n            <input type=\"email\" id=\"ace_feedback_email\" placeholder=\"Your email (optional)\">\n            <textarea id=\"ace_feedback_message\" rows=\"5\" placeholder=\"Describe your issue or suggestion...\"><\/textarea>\n\n            <button class=\"ace-feedback-submit\" onclick=\"trackTool('toolkit_feedback'); aceSendFeedback()\">\n                Send Message\n            <\/button>\n\n            <button style=\"margin-top:10px; background:#000; padding:8px; border:none; width:100%;\" \n                onclick=\"document.getElementById('aceFeedbackModal').style.display='none'\">\n                Close\n            <\/button>\n\n        <\/div>\n    <\/div>\n\n    <script>\n    function aceSendFeedback() {\n\n        let email = document.getElementById('ace_feedback_email').value;\n        let message = document.getElementById('ace_feedback_message').value;\n\n        fetch('https:\/\/aceworldpgs.com\/tools\/wp-admin\/admin-ajax.php', {\n            method: 'POST',\n            headers: {'Content-Type': 'application\/x-www-form-urlencoded'},\n            body: new URLSearchParams({\n                action: 'ace_send_feedback',\n                email: email,\n                message: message,\n                post_url: 'https:\/\/aceworldpgs.com\/tools\/publishing-calculator\/',\n                post_title: 'Publishing Calculator'\n            })\n        }).then(res => res.json()).then(res => {\n            alert('Thank you! Your feedback has been sent.');\n            document.getElementById('aceFeedbackModal').style.display='none';\n        });\n\n    }\n    <\/script>\n\n    \n\n<style>\n\n\/* SIMILAR TOOLS *\/\n\n.similar-tools{\nmargin-top:40px;\npadding-top:20px;\nborder-top:1px solid #e5e7eb;\n}\n\n.similar-tools h3{\nfont-size:18px;\nfont-weight:700;\nmargin-bottom:16px;\n}\n\n.similar-grid{\ndisplay:grid;\ngrid-template-columns:repeat(3,1fr);\ngap:12px;\nmargin-top: 15px;\nmargin-bottom: 15px;\nmargin-left: 20px;\nmargin-right: 20px;\n}\n\n.similar-card{\ndisplay:flex;\nalign-items:center;\ngap:10px;\npadding:12px;\nborder:1px solid #e5e7eb;\nborder-radius:8px;\ntext-decoration:none;\ncolor:inherit;\nbackground:#fff;\ntransition:all .15s ease;\n}\n\n.similar-card:hover{\nborder-color:#cbd5e1;\nbackground:#f8fafc;\ntransform:translateY(-2px);\n}\n\n\/* icon *\/\n\n.similar-icon{\nwidth:32px;\nheight:32px;\nborder-radius:6px;\nbackground:#eff6ff;\ndisplay:flex;\nalign-items:center;\njustify-content:center;\nfont-size:16px;\nflex-shrink:0;\n}\n\n\/* text *\/\n\n.similar-title{\nfont-size:14px;\nfont-weight:600;\nline-height:1.2;\n}\n\n@media(max-width:700px){\n.similar-grid{\ngrid-template-columns:1fr;\n}\n}\n\n.browse-tools-btn{\n    display:inline-block;\n    padding:10px 18px;\n    border-radius:8px;\n    border:1px solid #e5e7eb;\n    background:#fff;\n    text-decoration:none;\n    font-size:16px;\n    font-weight:600;\n    color:inherit;\n    transition:all .15s ease;\n}\n\n.browse-tools-btn:hover{\n    background:#f8fafc;\n    border-color:#d1d5db;\n    transform:translateY(-1px);\n}\n\n<\/style>\n\n\n<div class=\"similar-tools\">\n\n<h2 style=\"text-align: center;\">Other tools<\/h2>\n\n<div class=\"similar-grid\">\n\n<a href=\"\/tools\/isbn-letter-generator\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">ISBN Letter Generator<\/div>\n<\/a>\n\n<a href=\"\/tools\/manuscript-development-calculator\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">Manusript Development Calculator<\/div>\n<\/a>\n\n<a href=\"\/tools\/publishing-calculator\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">Publishing Calculator<\/div>\n<\/a>\n\n<a href=\"\/tools\/isbn-validator\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">ISBN Validator<\/div>\n<\/a>\n\n<a href=\"\/tools\/bulk-isbn-validator\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">Bulk ISBN Validator<\/div>\n<\/a>\n\n<a href=\"\/tools\/book-cover-calculator\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">Book Cover Calculator<\/div>\n<\/a>\n\n<a href=\"\/tools\/book-metadata-generator\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">Book Metadata Generator<\/div>\n<\/a>\n\n<a href=\"\/tools\/advert-policy-checks\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">Meta Ad Policy Checker<\/div>\n<\/a>\n\n<a href=\"\/tools\/barcode-qr-code-generator\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">Barcode & QR Code Generator<\/div>\n<\/a>\n\n<a href=\"\/tools\/book-royalty-calculator\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">Book Royalty Calculator<\/div>\n<\/a>\n\n<a href=\"\/tools\/book-price-calculator\/\" class=\"similar-card\">\n<div class=\"similar-icon\">#<\/div>\n<div class=\"similar-title\">Book Price Calculator<\/div>\n<\/a>\n\n<\/div>\n\n<p style=\"text-align:center;\"><a href=\"https:\/\/aceworldpgs.com\/tools\/all\/\" class=\"browse-tools-btn\">Browse All Tools \u2192<\/a>\n<\/p>\n\n<\/div>\n\n\n\n\n<!-- ============================================================\n     JAVASCRIPT \u2014 CONFIG-DRIVEN CALCULATION ENGINE\n============================================================ -->\n<script>\n\/\/ \u2500\u2500 1. Dynamic service config \u2014 this IS the pricing engine's data now.\n\/\/    Adding\/removing\/repricing a service in the admin dashboard changes\n\/\/    this array on next page load. No JS edits required.\nconst sapServicesConfig = [{\"key\":\"transcription\",\"label\":\"Manuscript Transcription\",\"group\":\"Editorial\",\"icon\":\"\\u270d\\ufe0f\",\"tooltip\":\"Converting handwritten manuscripts into digital text format.\",\"type\":\"transcription\",\"enabled\":true,\"sort\":10,\"min_word_count\":100,\"divider\":210,\"languages\":[{\"label\":\"English\",\"rate\":700},{\"label\":\"Yoruba\",\"rate\":1000},{\"label\":\"Other Languages\",\"rate\":2000}]},{\"key\":\"editing\",\"label\":\"Editing\",\"group\":\"Editorial\",\"icon\":\"\\ud83d\\udcdd\",\"tooltip\":\"Dev. Editing = structure & ideas. Line Editing = style & clarity. Copy Editing = grammar & consistency.\",\"type\":\"wordcount_variable\",\"enabled\":true,\"sort\":20,\"min_word_count\":30,\"levels\":[{\"label\":\"Developmental Editing\",\"rate_per_word\":10},{\"label\":\"Line Editing\",\"rate_per_word\":6},{\"label\":\"Copy Editing\",\"rate_per_word\":3.2}]},{\"key\":\"proofreading\",\"label\":\"Proofreading\",\"group\":\"Editorial\",\"icon\":\"\\ud83d\\udd0d\",\"tooltip\":\"Final quality check \\u2014 typos, punctuation, and formatting inconsistencies.\",\"type\":\"wordcount_flat\",\"enabled\":true,\"sort\":30,\"min_word_count\":30,\"rate_per_word\":1.7},{\"key\":\"formatting\",\"label\":\"Typesetting & Formatting\",\"group\":\"Design\",\"icon\":\"\",\"tooltip\":\"Arranging text for print or digital. Select both Ebook & Print and enjoy a 25% discount.\",\"type\":\"formatting\",\"enabled\":true,\"sort\":40,\"min_word_count\":30,\"divider\":200,\"base_rate\":180,\"combo_discount\":0.75,\"format_types\":[{\"label\":\"Ebook and Print Formatting\",\"key\":\"Ebook & Print\",\"is_combo\":true},{\"label\":\"Ebook Formatting\",\"key\":\"Ebook Formatting\",\"is_combo\":false},{\"label\":\"Print Layout\",\"key\":\"Print Layout\",\"is_combo\":false}]},{\"key\":\"cover_design\",\"label\":\"Book Cover\",\"group\":\"Design\",\"icon\":\"\\ud83c\\udfa8\",\"tooltip\":\"Full cover (front, back & spine) required for print. Front only for digital distribution.\",\"type\":\"tiered\",\"enabled\":true,\"sort\":50,\"options\":[{\"label\":\"Full Cover\",\"key\":\"Full Cover\",\"price\":28000},{\"label\":\"Front Cover Only\",\"key\":\"Front Cover Only\",\"price\":16000}]},{\"key\":\"brochure_design\",\"label\":\"Brochure & Magazine\",\"group\":\"Design\",\"icon\":\"\\ud83d\\udcf0\",\"tooltip\":\"Promotional brochure design. Enter the number of pages needed.\",\"type\":\"count\",\"enabled\":true,\"sort\":60,\"rate\":5000,\"unit_label\":\"page\",\"min_count\":1},{\"key\":\"isbn\",\"label\":\"ISBN\",\"group\":\"Legal\",\"icon\":\"\\ud83d\\udd22\",\"tooltip\":\"Each book title & version requires its own ISBN.\",\"type\":\"tiered\",\"enabled\":true,\"sort\":70,\"options\":[{\"label\":\"1 ISBN\",\"key\":\"1isbn\",\"price\":15500},{\"label\":\"2 ISBNs\",\"key\":\"2isbn\",\"price\":20500},{\"label\":\"3 ISBNs\",\"key\":\"3isbn\",\"price\":25500},{\"label\":\"4 ISBNs\",\"key\":\"4isbn\",\"price\":30500},{\"label\":\"5 ISBNs\",\"key\":\"5isbn\",\"price\":35500}]},{\"key\":\"copyright\",\"label\":\"Copyright\",\"group\":\"Legal\",\"icon\":\"\\u00a9\\ufe0f\",\"tooltip\":\"Formal legal claim over your content. Recommended for protection.\",\"type\":\"flat\",\"enabled\":true,\"sort\":80,\"price\":18500},{\"key\":\"issn\",\"label\":\"ISSN\",\"group\":\"Legal\",\"icon\":\"\\ud83d\\udccb\",\"tooltip\":\"For serial publications like magazines, journals, and newsletters.\",\"type\":\"tiered\",\"enabled\":true,\"sort\":90,\"options\":[{\"label\":\"Electronic ISSN\",\"key\":\"Electronic ISSN\",\"price\":29100},{\"label\":\"Print ISSN\",\"key\":\"Print ISSN\",\"price\":32100},{\"label\":\"Both\",\"key\":\"Both\",\"price\":61200}]},{\"key\":\"amazon_kindle\",\"label\":\"Amazon Kindle & Selar\",\"group\":\"Publishing\",\"icon\":\"\\ud83d\\udce6\",\"tooltip\":\"Your book on Amazon marketplaces in Kindle ebook and print format.\",\"type\":\"tiered\",\"enabled\":true,\"sort\":100,\"price\":15000,\"options\":[{\"label\":\"New KDP User\",\"key\":\"new_kdp_user\",\"price\":25000},{\"label\":\"Existing KDP User\",\"key\":\"existing_kdp_user\",\"price\":15000}]},{\"key\":\"ebook_distribution\",\"label\":\"Ebook Distribution\",\"group\":\"Publishing\",\"icon\":\"\\ud83c\\udf10\",\"tooltip\":\"Kobo, Apple Books, Barnes & Noble, Everand, Indigo, and more.\",\"type\":\"flat\",\"enabled\":true,\"sort\":110,\"price\":26000},{\"key\":\"news_distribution\",\"label\":\"News Distribution\",\"group\":\"Marketing\",\"icon\":\"\\ud83d\\udce2\",\"tooltip\":\"Share the news where the world reads.\",\"type\":\"link_only\",\"enabled\":true,\"sort\":120,\"url\":\"https:\\\/\\\/aceworldpgs.com\\\/marketing\\\/cds\\\/\",\"description\":\"News Distribution has a fully integrated service page.\"},{\"key\":\"authors_website\",\"label\":\"Author's Website\",\"group\":\"Marketing\",\"icon\":\"\\ud83c\\udf0d\",\"tooltip\":\"Engage your audience with a powerful author website.\",\"type\":\"link_only\",\"enabled\":true,\"sort\":130,\"url\":\"https:\\\/\\\/aceworldpgs.com\\\/wds\\\/\",\"description\":\"Website Development has a fully integrated service page.\"},{\"key\":\"social_media\",\"label\":\"Social Media Management\",\"group\":\"Marketing\",\"icon\":\"\\ud83d\\udcf1\",\"tooltip\":\"We know how social media algorithms work. Book us now!\",\"type\":\"link_only\",\"enabled\":true,\"sort\":140,\"url\":\"https:\\\/\\\/aceworldpgs.com\\\/sms\\\/\",\"description\":\"Social Media Management has a fully integrated service page.\"},{\"key\":\"mdservice\",\"label\":\"Manuscript Development Service\",\"group\":\"Marketing\",\"icon\":\"\\u2712\\ufe0f\",\"tooltip\":\"We help you estimate the cost of professionally developing a manuscript based on your project needs.\",\"type\":\"link_only\",\"enabled\":true,\"url\":\"https:\\\/\\\/aceworldpgs.com\\\/tools\\\/manuscript-development-calculator\\\/\",\"description\":\"Manuscript Development Service has a fully integrated service page.\",\"price\":0}];\n\n\/\/ NOTE: breakdown keys are the raw service key (e.g. bd.transcription, not\n\/\/ bd.transcriptionCost). The SAP admin metabox and project-import handler\n\/\/ read this directly and also handle pre-Phase-2 quotes that still have the\n\/\/ old Cost-suffixed keys in their saved JSON \u2014 see the SAP integration\n\/\/ snippet (aceworld_render_sap_project_specs_box \/ aceworld_fetch_quote_for_project).\n\n\/\/ \u2500\u2500 2. Print pricing data \u2014 now dynamic (Toolkit Settings \u2192 Print\n\/\/    Pricing tab). Matrix rows\/columns, trim sizes, option groups, and\n\/\/    add-ons are all fully add\/remove\/disable\/relabel-able there. \u2500\u2500\nconst sapPrintData = {\n  copyTiers:  [20,50,100,300,500,1000],\n  pageRanges: [{\"key\":\"30-79\",\"min\":30,\"max\":79},{\"key\":\"80-150\",\"min\":80,\"max\":150},{\"key\":\"151-200\",\"min\":151,\"max\":200},{\"key\":\"201-250\",\"min\":201,\"max\":250},{\"key\":\"251-300\",\"min\":251,\"max\":300},{\"key\":\"301-350\",\"min\":301,\"max\":350},{\"key\":\"351-400\",\"min\":351,\"max\":400},{\"key\":\"401-450\",\"min\":401,\"max\":450},{\"key\":\"451-500\",\"min\":451,\"max\":500},{\"key\":\"501-550\",\"min\":501,\"max\":550},{\"key\":\"551-600\",\"min\":551,\"max\":600},{\"key\":\"601-650\",\"min\":601,\"max\":650},{\"key\":\"651-700\",\"min\":651,\"max\":700},{\"key\":\"701-750\",\"min\":701,\"max\":750},{\"key\":\"751-800\",\"min\":751,\"max\":800},{\"key\":\"801-850\",\"min\":801,\"max\":850},{\"key\":\"851-900\",\"min\":851,\"max\":900},{\"key\":\"901-950\",\"min\":901,\"max\":950},{\"key\":\"951-1000\",\"min\":951,\"max\":1000},{\"key\":\"1001+\",\"min\":1001,\"max\":null}],\n  basePricing: {\"30-79\":{\"20\":3500,\"50\":2800,\"100\":2000,\"300\":1600,\"500\":1300,\"1000\":1000},\"80-150\":{\"20\":4300,\"50\":3500,\"100\":2800,\"300\":2000,\"500\":1600,\"1000\":1300},\"151-200\":{\"20\":4700,\"50\":4000,\"100\":3200,\"300\":2500,\"500\":2000,\"1000\":1600},\"201-250\":{\"20\":5400,\"50\":4700,\"100\":4000,\"300\":3300,\"500\":2800,\"1000\":2400},\"251-300\":{\"20\":6400,\"50\":5700,\"100\":5000,\"300\":4300,\"500\":3800,\"1000\":3400},\"301-350\":{\"20\":7500,\"50\":6700,\"100\":6000,\"300\":5300,\"500\":4800,\"1000\":4400},\"351-400\":{\"20\":8400,\"50\":7700,\"100\":7000,\"300\":6300,\"500\":5800,\"1000\":5400},\"401-450\":{\"20\":9400,\"50\":8700,\"100\":8000,\"300\":7300,\"500\":6800,\"1000\":6400},\"451-500\":{\"20\":10400,\"50\":9700,\"100\":9000,\"300\":8300,\"500\":7800,\"1000\":7400},\"501-550\":{\"20\":11400,\"50\":10700,\"100\":10000,\"300\":9300,\"500\":8800,\"1000\":8400},\"551-600\":{\"20\":12400,\"50\":11700,\"100\":11000,\"300\":10300,\"500\":9800,\"1000\":9400},\"601-650\":{\"20\":13400,\"50\":12700,\"100\":12000,\"300\":11300,\"500\":10800,\"1000\":10400},\"651-700\":{\"20\":14400,\"50\":13700,\"100\":13000,\"300\":12300,\"500\":11800,\"1000\":11400},\"701-750\":{\"20\":15400,\"50\":14700,\"100\":14000,\"300\":13300,\"500\":12800,\"1000\":12400},\"751-800\":{\"20\":16400,\"50\":15700,\"100\":15000,\"300\":14300,\"500\":13800,\"1000\":13400},\"801-850\":{\"20\":17400,\"50\":16700,\"100\":16000,\"300\":15300,\"500\":14800,\"1000\":14400},\"851-900\":{\"20\":18400,\"50\":17700,\"100\":17000,\"300\":16300,\"500\":15800,\"1000\":15400},\"901-950\":{\"20\":19400,\"50\":18700,\"100\":18000,\"300\":17300,\"500\":16800,\"1000\":16400},\"951-1000\":{\"20\":20400,\"50\":19700,\"100\":19000,\"300\":18300,\"500\":17800,\"1000\":17400},\"1001+\":{\"20\":21400,\"50\":20700,\"100\":20000,\"300\":19300,\"500\":18800,\"1000\":18400}},\n  printSizeMultipliers: {\"A5\":1,\"US Trade\":1,\"B5\":1.23,\"Pocket\":0.9,\"A6\":0.8,\"A4\":1.8,\"6x9\":1.8},\n  optionGroups: [{\"key\":\"paper_finish\",\"label\":\"Paper Finish\",\"options\":[{\"key\":\"uncoated\",\"label\":\"Uncoated\",\"amount\":0,\"enabled\":true,\"is_default\":true},{\"key\":\"coated\",\"label\":\"Coated\",\"amount\":500,\"enabled\":true,\"is_default\":false}]},{\"key\":\"paper_color\",\"label\":\"Paper Color\",\"options\":[{\"key\":\"white\",\"label\":\"White\",\"amount\":0,\"enabled\":true,\"is_default\":true},{\"key\":\"cream\",\"label\":\"Cream\",\"amount\":600,\"enabled\":true,\"is_default\":false}]},{\"key\":\"interior_ink\",\"label\":\"Interior Ink\",\"options\":[{\"key\":\"bw\",\"label\":\"Black and White\",\"amount\":0,\"enabled\":true,\"is_default\":true},{\"key\":\"colored\",\"label\":\"Colored\",\"amount\":600,\"enabled\":true,\"is_default\":false}]},{\"key\":\"cover_lamination\",\"label\":\"Cover Lamination\",\"options\":[{\"key\":\"matte\",\"label\":\"Matte\",\"amount\":0,\"enabled\":true,\"is_default\":true},{\"key\":\"glossy\",\"label\":\"Glossy\",\"amount\":400,\"enabled\":true,\"is_default\":false}]},{\"key\":\"binding_cover_type\",\"label\":\"Binding & Cover Type\",\"options\":[{\"key\":\"paperback\",\"label\":\"Perfect Binding (Paperback)\",\"amount\":0,\"enabled\":true,\"is_default\":true},{\"key\":\"hardback\",\"label\":\"Case Binding (Hardback)\",\"amount\":600,\"enabled\":true,\"is_default\":false}]},{\"key\":\"cover_title_style\",\"label\":\"Cover Title Style\",\"options\":[{\"key\":\"normal\",\"label\":\"Normal\",\"amount\":0,\"enabled\":true,\"is_default\":true},{\"key\":\"embossing_debossing\",\"label\":\"Embossing \\\/ Debossing\",\"amount\":600,\"enabled\":true,\"is_default\":false},{\"key\":\"foil\",\"label\":\"Foil Stamping Embossing\",\"amount\":800,\"enabled\":true,\"is_default\":false}]}],\n  addons: [{\"key\":\"nylon_wrapping\",\"label\":\"Nylon Wrapping (per copy)\",\"amount\":50,\"enabled\":true,\"default_on\":true},{\"key\":\"crystal_effect\",\"label\":\"Crystal Cover Effect (per copy)\",\"amount\":1000,\"enabled\":true,\"default_on\":false},{\"key\":\"sample_proofing\",\"label\":\"Physical Proof Copy (per copy)\",\"amount\":7000,\"enabled\":true,\"default_on\":false}],\n  constraints: {\"min_pages\":50,\"min_words\":500,\"min_copies\":20,\"max_copies\":1000},\n};\n\nconst sapFmt = new Intl.NumberFormat('en-NG', { style:'currency', currency:'NGN', minimumFractionDigits:0, maximumFractionDigits:0 });\n\nlet sapCurrentStep = 1;\nconst SAP_TOTAL_STEPS = 4;\n\n\/\/ \u2500\u2500 3. Step navigation (unchanged) \u2500\u2500\nfunction sapGoStep(n) {\n  if (n < 1 || n > SAP_TOTAL_STEPS) return;\n  document.querySelectorAll('.sap-step-panel').forEach(p => p.classList.remove('active'));\n  document.getElementById('sap-step-' + n).classList.add('active');\n\n  document.querySelectorAll('.sap-step-item').forEach(item => {\n    const s = parseInt(item.dataset.step);\n    item.classList.remove('active', 'done');\n    if (s === n) item.classList.add('active');\n    else if (s < n) item.classList.add('done');\n  });\n\n  const btnBack = document.getElementById('sapBtnBack');\n  const btnNext = document.getElementById('sapBtnNext');\n  const btnSubmit = document.getElementById('sapBtnSubmit');\n  btnBack.style.display = n > 1 ? 'inline-flex' : 'none';\n  btnNext.style.display = n < SAP_TOTAL_STEPS ? 'inline-flex' : 'none';\n  btnSubmit.style.display = n === SAP_TOTAL_STEPS ? 'inline-flex' : 'none';\n\n  const labels = ['', 'Publishing Services \u2192', 'Print Services \u2192', 'View Quotation \u2192'];\n  if (n < SAP_TOTAL_STEPS) btnNext.textContent = labels[n];\n\n  document.getElementById('sapProgressFill').style.width = (n \/ SAP_TOTAL_STEPS * 100) + '%';\n\n  sapCurrentStep = n;\n  if (n === SAP_TOTAL_STEPS) sapUpdateQuote();\n  window.scrollTo({ top: document.getElementById('sap-calc-root').offsetTop - 20, behavior: 'smooth' });\n}\nfunction sapNavNext() { sapGoStep(sapCurrentStep + 1); }\nfunction sapNavBack() { sapGoStep(sapCurrentStep - 1); }\n\n\/\/ \u2500\u2500 4. Generic toggle binding \u2014 every service toggle row carries a\n\/\/    data-subsection attribute (set by ace_render_sap_service_field()).\n\/\/    One handler covers all services, present and future. \u2500\u2500\ndocument.addEventListener('DOMContentLoaded', () => {\n\n  document.querySelectorAll('.ace-svc-toggle').forEach(cb => {\n    const row = cb.closest('.sap-toggle-row');\n    const subId = row ? row.dataset.subsection : '';\n    const sub = subId ? document.getElementById(subId) : null;\n    function update() {\n      if (cb.checked) { row.classList.add('toggled'); if (sub) sub.classList.add('open'); }\n      else { row.classList.remove('toggled'); if (sub) sub.classList.remove('open'); }\n      sapUpdateFloating();\n    }\n    cb.addEventListener('change', update);\n    update();\n  });\n\n  \/\/ Radio cards \u2014 print specs only (Step 3), unchanged\n  document.querySelectorAll('.sap-radio-card').forEach(card => {\n    card.addEventListener('click', () => {\n      const radio = card.querySelector('input[type=\"radio\"]');\n      if (!radio) return;\n      radio.checked = true;\n      const group = card.dataset.group || radio.name;\n      document.querySelectorAll('[data-group=\"' + group + '\"]').forEach(c => c.classList.remove('selected'));\n      card.classList.add('selected');\n      sapHandleCopiesChange();\n      sapUpdateFloating();\n    });\n  });\n\n  document.getElementById('copies-custom-input').addEventListener('input', () => {\n    sapHandleCopiesChange();\n    sapUpdateFloating();\n  });\n\n  document.getElementById('printSpecsToggler').addEventListener('click', () => {\n    const body = document.getElementById('printSpecsBody');\n    const hdr = document.getElementById('printSpecsToggler');\n    const open = body.style.display !== 'none';\n    body.style.display = open ? 'none' : 'block';\n    hdr.classList.toggle('open', !open);\n  });\n\n  document.getElementById('calculator-form').addEventListener('change', sapUpdateFloating);\n  document.getElementById('calculator-form').addEventListener('input', sapUpdateFloating);\n\n  document.getElementById('qhDate').textContent = new Date().toLocaleDateString('en-US', {year:'numeric',month:'long',day:'numeric'});\n\n  document.getElementById('clearFormBtn').addEventListener('click', () => {\n    if (confirm('Clear all inputs? This will not save your progress.')) sapResetForm();\n  });\n\n  document.getElementById('sapBtnSubmit').addEventListener('click', async function() {\n    const ok = await sapSaveQuotation(this);\n    if (ok) { window.print(); alert('Quote saved! You can now print or save as PDF.'); }\n  });\n\n  sapUpdateFloating();\n});\n\n\/\/ \u2500\u2500 5. Copies visibility (unchanged) \u2500\u2500\nfunction sapHandleCopiesChange() {\n  const selected = document.querySelector('input[name=\"copiesOption\"]:checked');\n  const isCustom = selected && selected.value === 'custom';\n  const copies = sapGetCopies();\n  const hasPrint = copies > 0;\n  document.getElementById('customCopiesInput').classList.toggle('show', isCustom);\n  document.getElementById('pageCountSection').style.display = hasPrint ? 'block' : 'none';\n  document.getElementById('printSpecsSection').style.display = hasPrint ? 'block' : 'none';\n}\nfunction sapGetCopies() {\n  const r = document.querySelector('input[name=\"copiesOption\"]:checked');\n  if (!r) return 0;\n  if (r.value === 'custom') return Number(document.getElementById('copies-custom-input').value) || 0;\n  return Number(r.value) || 0;\n}\n\n\/\/ \u2500\u2500 6. Read every dynamic service's current form state \u2500\u2500\nfunction sapGetServiceSelections() {\n  const out = {};\n  sapServicesConfig.forEach(svc => {\n    const activeEl = document.getElementById('svc_' + svc.key + '_active');\n    const optEl = document.getElementById('svc_' + svc.key + '_option');\n    const cntEl = document.getElementById('svc_' + svc.key + '_count');\n    out[svc.key] = {\n      active: !!(activeEl && activeEl.checked),\n      option: optEl ? optEl.value : '',\n      count: cntEl ? (Number(cntEl.value) || 0) : 0,\n    };\n  });\n  return out;\n}\n\n\/\/ \u2500\u2500 6b. Read every dynamic print option-group \/ add-on's current state \u2500\u2500\nfunction sapGetPrintGroupSelections() {\n  const out = {};\n  sapPrintData.optionGroups.forEach(g => {\n    const el = document.querySelector('input[name=\"og_' + g.key + '\"]:checked');\n    if (el) { out[g.key] = el.value; return; }\n    const def = g.options.find(o => o.is_default) || g.options[0];\n    out[g.key] = def ? def.key : '';\n  });\n  return out;\n}\nfunction sapGetPrintAddonSelections() {\n  const out = {};\n  sapPrintData.addons.forEach(a => {\n    const el = document.getElementById('addon_' + a.key + '_active');\n    out[a.key] = !!(el && el.checked);\n  });\n  return out;\n}\n\n\/\/ \u2500\u2500 7. Get all selections (project fields unchanged; services AND print\n\/\/    specs are both dynamic now) \u2500\u2500\nfunction sapGetSelections() {\n  const g = (id) => { const el = document.getElementById(id); return el ? el.value : ''; };\n\n  return {\n    bookTitle: g('bookTitle') || 'My Book Project',\n    wordCount: Number(g('wordCount')) || 0,\n    copies: sapGetCopies(),\n    pageCount: Number(g('pageCount')) || 0,\n    desiredPrintSize: g('desiredPrintSize') || (sapPrintData.printSizeMultipliers['A5'] !== undefined ? 'A5' : ''),\n    printGroups: sapGetPrintGroupSelections(),\n    printAddons: sapGetPrintAddonSelections(),\n    services: sapGetServiceSelections(),\n  };\n}\n\n\/\/ \u2500\u2500 8. Per-service cost dispatcher \u2014 the ENTIRE calculation engine\n\/\/    for non-print services lives in this one switch. Adding a new\n\/\/    `type` in the future means adding one case here, once. \u2500\u2500\nfunction sapCalcOneService(svc, svcSel, wordCount) {\n  if (!svcSel || !svcSel.active) return 0;\n  switch (svc.type) {\n    case 'flat':\n      return Number(svc.price) || 0;\n\n    case 'tiered': {\n      const opt = (svc.options || []).find(o => o.key === svcSel.option) || (svc.options || [])[0];\n      return opt ? (Number(opt.price) || 0) : 0;\n    }\n\n    case 'count': {\n      const min = Number(svc.min_count) || 1;\n      if (svcSel.count < min) return 0;\n      return svcSel.count * (Number(svc.rate) || 0);\n    }\n\n    case 'wordcount_flat': {\n      if (wordCount < (Number(svc.min_word_count) || 0)) return 0;\n      return wordCount * (Number(svc.rate_per_word) || 0);\n    }\n\n    case 'wordcount_variable': {\n      if (wordCount < (Number(svc.min_word_count) || 0)) return 0;\n      const lvl = (svc.levels || []).find(l => l.label === svcSel.option) || (svc.levels || [])[0];\n      return lvl ? wordCount * (Number(lvl.rate_per_word) || 0) : 0;\n    }\n\n    case 'formatting': {\n      if (wordCount < (Number(svc.min_word_count) || 0)) return 0;\n      const base = Math.ceil(wordCount \/ svc.divider) * svc.base_rate;\n      const ft = (svc.format_types || []).find(f => f.key === svcSel.option);\n      return (ft && ft.is_combo) ? base * 2 * svc.combo_discount : base;\n    }\n\n    case 'transcription': {\n      if (wordCount < (Number(svc.min_word_count) || 0)) return 0;\n      const pages = Math.ceil(wordCount \/ svc.divider);\n      const lang = (svc.languages || []).find(l => l.label === svcSel.option) || (svc.languages || [])[0];\n      return lang ? pages * (Number(lang.rate) || 0) : 0;\n    }\n\n    case 'link_only':\n    default:\n      return 0;\n  }\n}\n\n\/\/ \u2500\u2500 9. Core calculation \u2014 dynamic services + unchanged print formula \u2500\u2500\nfunction sapCalculate(sel) {\n  let total = 0;\n  const bd = { printingCost: 0, meta_pricePerCopy: 0, meta_copiesCount: sel.copies, sampleProofingCost: 0, deductionAmount: 0, deductionReason: 'N\/A' };\n\n  sapServicesConfig.forEach(svc => {\n    const cost = sapCalcOneService(svc, sel.services[svc.key], sel.wordCount);\n    bd[svc.key] = cost;\n    total += cost;\n  });\n\n  \/\/ Print \u2014 base formula unchanged; option groups\/add-ons are now dynamic\n  const copies = sel.copies, pages = sel.pageCount;\n  if (copies > 0 && pages >= 30) {\n    const ppc = sapCalcBasePrice(sel.desiredPrintSize, pages, copies);\n    const ppcM = sapApplyPrintOptions(ppc, sel);\n    bd.printingCost = ppcM * copies;\n    bd.meta_pricePerCopy = ppcM;\n    total += bd.printingCost;\n\n    \/\/ sample_proofing is a special case: it's a ONE-OFF line item (cost of\n    \/\/ producing a single physical proof copy at the per-copy price, plus a\n    \/\/ surcharge) \u2014 NOT a per-copy addition multiplied across the whole run.\n    \/\/ That's why it's excluded from sapApplyPrintOptions() below and handled\n    \/\/ here instead. If the \"sample_proofing\" add-on is ever renamed or\n    \/\/ removed from the dashboard, this line item simply stops appearing.\n    if (sel.printAddons.sample_proofing) {\n      const spAddon = sapPrintData.addons.find(a => a.key === 'sample_proofing');\n      const spAmount = spAddon ? (Number(spAddon.amount) || 0) : 0;\n      bd.sampleProofingCost = ppcM + spAmount;\n      total += bd.sampleProofingCost;\n    }\n  }\n\n  return { total, bd };\n}\n\nfunction sapCalcBasePrice(size, pages, copies) {\n  if (pages < 30) return 0;\n\n  \/\/ Find the page-count bracket from the admin-configured range list.\n  \/\/ 'max === null' means an open-ended top bracket (e.g. \"1001+\").\n  const range = sapPrintData.pageRanges.find(r => pages >= r.min && (r.max === null || pages <= r.max))\n             || sapPrintData.pageRanges[sapPrintData.pageRanges.length - 1];\n  if (!range) return 0;\n\n  const tierPrices = sapPrintData.basePricing[range.key];\n  if (!tierPrices) return 0;\n\n  \/\/ Bucket the requested copy count into the nearest configured tier\n  \/\/ at-or-above it (same \"round up to the next tier\" behaviour as before,\n  \/\/ just driven by whatever tiers are configured instead of a fixed list).\n  const tiers = sapPrintData.copyTiers.slice().sort((a, b) => a - b);\n  const c = Math.max(copies, tiers[0]);\n  let bucket = tiers[tiers.length - 1];\n  for (const t of tiers) { if (c <= t) { bucket = t; break; } }\n\n  const base = Number(tierPrices[bucket]) || 0;\n  return base * (sapPrintData.printSizeMultipliers[size] || 1.0);\n}\n\n\/\/ Applies every selected option-group choice and every checked stackable\n\/\/ add-on (except sample_proofing, handled separately above) to the base\n\/\/ per-copy price. Fully dynamic \u2014 loops over whatever groups\/add-ons are\n\/\/ configured in the dashboard instead of checking fixed field names.\nfunction sapApplyPrintOptions(base, sel) {\n  let p = base;\n\n  sapPrintData.optionGroups.forEach(g => {\n    const selectedKey = sel.printGroups[g.key];\n    const opt = g.options.find(o => o.key === selectedKey);\n    if (opt) p += (Number(opt.amount) || 0);\n  });\n\n  sapPrintData.addons.forEach(a => {\n    if (a.key === 'sample_proofing') return; \/\/ one-off line item, not per-copy\n    if (sel.printAddons[a.key]) p += (Number(a.amount) || 0);\n  });\n\n  return p;\n}\n\n\/\/ \u2500\u2500 10. Inline validation \u2014 shows\/hides each service's min-input error \u2500\u2500\nfunction sapValidateServices(sel) {\n  sapServicesConfig.forEach(svc => {\n    const errEl = document.getElementById('svc_' + svc.key + '_error');\n    if (!errEl) return;\n    const svcSel = sel.services[svc.key] || {};\n    let invalid = false;\n    if (svcSel.active) {\n      if (['wordcount_flat', 'wordcount_variable', 'formatting', 'transcription'].includes(svc.type)) {\n        invalid = sel.wordCount < (Number(svc.min_word_count) || 0);\n      } else if (svc.type === 'count') {\n        invalid = svcSel.count < (Number(svc.min_count) || 1);\n      }\n    }\n    errEl.classList.toggle('show', invalid);\n  });\n}\n\n\/\/ \u2500\u2500 10b. Inline validation for print constraints (min pages \/ copy bounds),\n\/\/    dynamic from Toolkit Settings \u2192 Print Pricing \u2192 Constraints. \u2500\u2500\nfunction sapValidatePrintConstraints(sel) {\n  const c = sapPrintData.constraints || {};\n\n  const pageErr = document.getElementById('pageCountError');\n  if (pageErr) {\n    const invalid = sel.copies > 0 && sel.pageCount > 0 && sel.pageCount < (Number(c.min_pages) || 0);\n    pageErr.classList.toggle('show', invalid);\n  }\n\n  const copiesErr = document.getElementById('customCopiesError');\n  if (copiesErr) {\n    const isCustom = document.querySelector('input[name=\"copiesOption\"]:checked')?.value === 'custom';\n    const val = sapGetCopies();\n    const invalid = isCustom && (val < (Number(c.min_copies) || 0) || val > (Number(c.max_copies) || Infinity));\n    copiesErr.classList.toggle('show', invalid);\n  }\n}\n\n\/\/ \u2500\u2500 11. Floating total \u2500\u2500\nfunction sapUpdateFloating() {\n  const sel = sapGetSelections();\n  sapValidateServices(sel);\n  sapValidatePrintConstraints(sel);\n  const { total } = sapCalculate(sel);\n  const ft = document.getElementById('sapFloatingTotal');\n  document.getElementById('sapFloatValue').textContent = sapFmt.format(total);\n  ft.classList.toggle('show', total > 0);\n}\n\n\/\/ \u2500\u2500 12. Quotation panel \u2014 service rows now built dynamically \u2500\u2500\nfunction sapUpdateQuote() {\n  const sel = sapGetSelections();\n  const { total, bd } = sapCalculate(sel);\n  const fmt = sapFmt.format.bind(sapFmt);\n\n  document.getElementById('qhBookTitle').textContent = sel.bookTitle;\n  document.getElementById('qhWords').textContent = sel.wordCount.toLocaleString() + ' words';\n  document.getElementById('qhTotal').textContent = fmt(total);\n  document.getElementById('qGrandTotal').textContent = fmt(total);\n\n  const block = document.getElementById('qServicesBlock');\n  let rowsHtml = '';\n  sapServicesConfig.forEach(svc => {\n    if (svc.type === 'link_only') return; \/\/ advertisement-only \u2014 never priced\/listed\n    const val = bd[svc.key] || 0;\n    const svcSel = sel.services[svc.key] || {};\n    let suffix = '';\n    if (svcSel.active) {\n      if (svc.type === 'tiered') {\n        const opt = (svc.options || []).find(o => o.key === svcSel.option);\n        if (opt) suffix = ' (' + opt.label + ')';\n      } else if (svc.type === 'wordcount_variable' || svc.type === 'transcription') {\n        if (svcSel.option) suffix = ' (' + svcSel.option + ')';\n      } else if (svc.type === 'formatting') {\n        const ft = (svc.format_types || []).find(f => f.key === svcSel.option);\n        if (ft) suffix = ' (' + ft.label + ')';\n      } else if (svc.type === 'count' && svcSel.count) {\n        suffix = ' (' + svcSel.count + ' ' + (svc.unit_label || 'unit') + 's)';\n      }\n    }\n    rowsHtml += '<div class=\"sap-quote-row' + (val ? '' : ' dimmed') + '\">'\n              +   '<span class=\"qr-label\">' + (svc.icon || '') + ' ' + svc.label + suffix + '<\/span>'\n              +   '<span class=\"qr-value\">' + fmt(val) + '<\/span>'\n              + '<\/div>';\n  });\n  block.innerHTML = rowsHtml;\n\n  const hasPrint = bd.printingCost > 0;\n  document.getElementById('qPrintBlock').style.display = hasPrint ? 'block' : 'none';\n  if (hasPrint) {\n    document.getElementById('qPrintCopies').textContent = sel.copies.toLocaleString() + ' Copies';\n    document.getElementById('qPrintPricePerCopy').textContent = fmt(bd.meta_pricePerCopy);\n\n    \/\/ Dynamic spec list: trim size, then each selected option-group choice,\n    \/\/ then each checked add-on. Pulls labels live from sapPrintData so a\n    \/\/ dashboard relabel shows up here immediately.\n    const specMap = [];\n    specMap.push(['Trim Size', sel.desiredPrintSize]);\n    sapPrintData.optionGroups.forEach(g => {\n      const opt = g.options.find(o => o.key === sel.printGroups[g.key]);\n      if (opt) specMap.push([g.label, opt.label]);\n    });\n    sapPrintData.addons.forEach(a => {\n      if (sel.printAddons[a.key]) specMap.push([a.label, 'Added']);\n    });\n    document.getElementById('qPrintSpecs').textContent = specMap.map(s => s[1]).filter(Boolean).join(' \u00b7 ');\n    document.getElementById('qSpecsGrid').innerHTML = specMap.map(([k,v]) => `<div class=\"sap-spec-pill\"><strong>${k}<\/strong>: ${v}<\/div>`).join('');\n  }\n}\n\n\/\/ \u2500\u2500 13. Save quotation \u2500\u2500\nasync function sapSaveQuotation(btn) {\n  if (typeof jQuery === 'undefined' || typeof calculator_ajax_object === 'undefined') {\n    alert('WordPress dependencies missing.'); return false;\n  }\n  const emailEl = document.getElementById('clientEmail');\n  const emailOk = emailEl && \/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/.test(emailEl.value);\n  document.getElementById('emailError').classList.toggle('show', !emailOk);\n  if (!emailOk) { sapGoStep(1); return false; }\n\n  const sel = sapGetSelections();\n  const { total, bd } = sapCalculate(sel);\n  const totalStr = sapFmt.format(total);\n\n  const data = {\n    action: 'save_quote',\n    client_name: document.getElementById('clientName').value || 'Anonymous',\n    client_email: emailEl.value,\n    client_phone: document.getElementById('clientPhone').value || '',\n    total_cost: totalStr,\n    book_title: sel.bookTitle || 'Untitled Project',\n    security: calculator_ajax_object.security,\n    quote_details: JSON.stringify({ selections: sel, breakdown: bd }),\n  };\n\n  const orig = btn.textContent;\n  btn.textContent = 'Saving\u2026'; btn.disabled = true;\n\n  try {\n    const res = await jQuery.post(calculator_ajax_object.ajax_url, data);\n    btn.textContent = orig; btn.disabled = false;\n    if (res.success) return true;\n    alert('Error: ' + (res.data || 'Unknown error.')); return false;\n  } catch (e) {\n    alert('Connection error.'); btn.textContent = orig; btn.disabled = false; return false;\n  }\n}\n\n\/\/ \u2500\u2500 14. Reset form \u2014 services AND print specs reset generically from config \u2500\u2500\nfunction sapResetForm() {\n  document.getElementById('bookTitle').value = 'My Book Project';\n  document.getElementById('wordCount').value = '20000';\n  document.getElementById('clientName').value = '';\n  document.getElementById('clientEmail').value = '';\n  document.getElementById('clientPhone').value = '';\n  document.getElementById('pageCount').value = '100';\n  document.getElementById('copies-custom-input').value = String(sapPrintData.constraints.min_copies || 20);\n\n  sapServicesConfig.forEach(svc => {\n    const activeEl = document.getElementById('svc_' + svc.key + '_active');\n    if (activeEl && activeEl.checked) { activeEl.checked = false; activeEl.dispatchEvent(new Event('change')); }\n    const optEl = document.getElementById('svc_' + svc.key + '_option');\n    if (optEl) optEl.selectedIndex = 0;\n    const cntEl = document.getElementById('svc_' + svc.key + '_count');\n    if (cntEl) cntEl.value = '';\n    const errEl = document.getElementById('svc_' + svc.key + '_error');\n    if (errEl) errEl.classList.remove('show');\n  });\n\n  document.querySelectorAll('input[name=\"copiesOption\"]').forEach(r => { r.checked = r.value === '0'; });\n  document.querySelectorAll('[data-group=\"copiesOption\"]').forEach(c => c.classList.remove('selected'));\n  const noPrintCard = document.querySelector('[data-group=\"copiesOption\"][data-copies=\"0\"]');\n  if (noPrintCard) noPrintCard.classList.add('selected');\n\n  \/\/ Trim size \u2014 first option in the dropdown (matches original \"select first\" behaviour)\n  const sizeSelect = document.getElementById('desiredPrintSize');\n  if (sizeSelect) sizeSelect.selectedIndex = 0;\n\n  \/\/ Option groups \u2014 reset each to its configured default (no-extra-cost) choice\n  sapPrintData.optionGroups.forEach(g => {\n    const def = g.options.find(o => o.is_default) || g.options[0];\n    if (!def) return;\n    const radio = document.querySelector(`input[name=\"og_${g.key}\"][value=\"${def.key}\"]`);\n    if (radio) radio.checked = true;\n    document.querySelectorAll(`[data-group=\"og_${g.key}\"]`).forEach(c => c.classList.toggle('selected', c.dataset.val === def.key));\n  });\n\n  \/\/ Add-ons \u2014 reset each to its configured default-on\/off state\n  sapPrintData.addons.forEach(a => {\n    const cb = document.getElementById('addon_' + a.key + '_active');\n    if (cb) {\n      cb.checked = !!a.default_on;\n      cb.dispatchEvent(new Event('change'));\n    }\n  });\n\n  const pageErr = document.getElementById('pageCountError'); if (pageErr) pageErr.classList.remove('show');\n  const copiesErr = document.getElementById('customCopiesError'); if (copiesErr) copiesErr.classList.remove('show');\n\n  sapHandleCopiesChange();\n  sapUpdateFloating();\n  sapGoStep(1);\n}\n<\/script>\n\n\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<style>.kt-accordion-id75203_f57254-2e .kt-accordion-inner-wrap{column-gap:var(--global-kb-gap-md, 2rem);row-gap:10px;}.kt-accordion-id75203_f57254-2e .kt-accordion-panel-inner{border-top:0px solid transparent;border-right:0px solid transparent;border-bottom:0px solid transparent;border-left:0px solid transparent;background:#ffffff;padding-top:var(--global-kb-spacing-sm, 1.5rem);padding-right:var(--global-kb-spacing-sm, 1.5rem);padding-bottom:var(--global-kb-spacing-sm, 1.5rem);padding-left:var(--global-kb-spacing-sm, 1.5rem);}.kt-accordion-id75203_f57254-2e > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top:1px solid #f2f2f2;border-right:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;border-left:1px solid #f2f2f2;border-top-left-radius:6px;border-top-right-radius:6px;border-bottom-right-radius:6px;border-bottom-left-radius:6px;color:var(--global-palette3, #1A202C);padding-top:13px;padding-right:15px;padding-bottom:13px;padding-left:15px;}.kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap .kt-blocks-accordion-icon-trigger:before{background:var(--global-palette3, #1A202C);}.kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-icon-trigger{background:var(--global-palette3, #1A202C);}.kt-accordion-id75203_f57254-2e > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id75203_f57254-2e .kt-blocks-accordion-header:focus-visible{color:#444444;background:#eeeeee;border-top:1px solid #878787;border-right:1px solid #878787;border-bottom:1px solid #878787;border-left:1px solid #878787;}.kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:before, body:not(.hide-focus-outline) .kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-blocks-accordion--visible .kt-blocks-accordion-icon-trigger:after, body:not(.hide-focus-outline) .kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle ) .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:before{background:#444444;}.kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger, body:not(.hide-focus-outline) .kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger{background:#444444;}.kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:hover .kt-blocks-accordion-icon-trigger:before, body:not(.hide-focus-outline) .kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:after, body:not(.hide-focus-outline) .kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible .kt-blocks-accordion-icon-trigger:before{background:#eeeeee;}.kt-accordion-id75203_f57254-2e .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id75203_f57254-2e > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{color:#ffffff;background:#BE530B;border-top:1px solid #BE530B;border-right:1px solid #BE530B;border-bottom:1px solid #BE530B;border-left:1px solid #BE530B;}.kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basiccircle ):not( .kt-accodion-icon-style-xclosecircle ):not( .kt-accodion-icon-style-arrowcircle )  > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:before{background:#ffffff;}.kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger{background:#ffffff;}.kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:after, .kt-accordion-id75203_f57254-2e:not( .kt-accodion-icon-style-basic ):not( .kt-accodion-icon-style-xclose ):not( .kt-accodion-icon-style-arrow ) .kt-blocks-accordion-header.kt-accordion-panel-active .kt-blocks-accordion-icon-trigger:before{background:#BE530B;}@media all and (max-width: 1024px){.kt-accordion-id75203_f57254-2e .kt-accordion-panel-inner{border-top:0px solid transparent;border-right:0px solid transparent;border-bottom:0px solid transparent;border-left:0px solid transparent;}}@media all and (max-width: 1024px){.kt-accordion-id75203_f57254-2e > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top:1px solid #f2f2f2;border-right:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;border-left:1px solid #f2f2f2;}}@media all and (max-width: 1024px){.kt-accordion-id75203_f57254-2e > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id75203_f57254-2e .kt-blocks-accordion-header:focus-visible{border-top:1px solid #878787;border-right:1px solid #878787;border-bottom:1px solid #878787;border-left:1px solid #878787;}}@media all and (max-width: 1024px){.kt-accordion-id75203_f57254-2e .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id75203_f57254-2e > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{border-top:1px solid #BE530B;border-right:1px solid #BE530B;border-bottom:1px solid #BE530B;border-left:1px solid #BE530B;}}@media all and (max-width: 767px){.kt-accordion-id75203_f57254-2e .kt-accordion-inner-wrap{display:block;}.kt-accordion-id75203_f57254-2e .kt-accordion-inner-wrap .kt-accordion-pane:not(:first-child){margin-top:10px;}.kt-accordion-id75203_f57254-2e .kt-accordion-panel-inner{border-top:0px solid transparent;border-right:0px solid transparent;border-bottom:0px solid transparent;border-left:0px solid transparent;}.kt-accordion-id75203_f57254-2e > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header{border-top:1px solid #f2f2f2;border-right:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;border-left:1px solid #f2f2f2;}.kt-accordion-id75203_f57254-2e > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header:hover, \n\t\t\t\tbody:not(.hide-focus-outline) .kt-accordion-id75203_f57254-2e .kt-blocks-accordion-header:focus-visible{border-top:1px solid #878787;border-right:1px solid #878787;border-bottom:1px solid #878787;border-left:1px solid #878787;}.kt-accordion-id75203_f57254-2e .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id75203_f57254-2e > .kt-accordion-inner-wrap > .wp-block-kadence-pane > .kt-accordion-header-wrap > .kt-blocks-accordion-header.kt-accordion-panel-active{border-top:1px solid #BE530B;border-right:1px solid #BE530B;border-bottom:1px solid #BE530B;border-left:1px solid #BE530B;}}<\/style>\n<div class=\"wp-block-kadence-accordion alignnone\"><div class=\"kt-accordion-wrap kt-accordion-id75203_f57254-2e kt-accordion-has-2-panes kt-active-pane-0 kt-accordion-block kt-pane-header-alignment-left kt-accodion-icon-style-basic kt-accodion-icon-side-right\" style=\"max-width:none\"><div class=\"kt-accordion-inner-wrap\" data-allow-multiple-open=\"false\" data-start-open=\"none\">\n<div class=\"wp-block-kadence-pane kt-accordion-pane kt-accordion-pane-1 kt-pane75203_8c9ce8-a0\"><div class=\"kt-accordion-header-wrap\"><button class=\"kt-blocks-accordion-header kt-acccordion-button-label-show\" type=\"button\"><span class=\"kt-blocks-accordion-title-wrap\"><span class=\"kt-blocks-accordion-title\">How it Works<\/span><\/span><span class=\"kt-blocks-accordion-icon-trigger\"><\/span><\/button><\/div><div class=\"kt-accordion-panel kt-accordion-panel-hidden\"><div class=\"kt-accordion-panel-inner\">\n<h2 class=\"wp-block-heading\">About the Publishing Calculator<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<strong>Publishing Calculator<\/strong>&nbsp;helps authors and publishers to quickly estimate the cost of publishing a book. By selecting the services you need\u2014such as editing, typesetting, cover design, ISBN registration, copyright protection, distribution, or printing\u2014the tool automatically calculates an estimated quote for your project.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This makes it easier to understand how different publishing services affect your overall budget and helps you plan your publishing journey more confidently.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Whether you are a&nbsp;<strong>first-time author, self-publisher, or organization preparing a book<\/strong>, the calculator provides a fast and convenient way to preview potential publishing costs and generate a formal quotation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em><strong>Note<\/strong>: Estimates generated by this tool are indicative and may vary depending on manuscript specifications and project requirements.<\/em><\/p>\n<\/div><\/div><\/div>\n<\/div><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Know how much it costs to publish and print your book. Choose publishing services according to your preferences and select print specifications to get instant quotation.<\/p>\n","protected":false},"author":1,"featured_media":76781,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_kb_optimizer_status":2,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"normal","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[16],"tags":[17,13,12],"class_list":["post-75203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pricing-tools","tag-calculator","tag-fast","tag-free"],"acf":[],"_links":{"self":[{"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/posts\/75203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/comments?post=75203"}],"version-history":[{"count":27,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/posts\/75203\/revisions"}],"predecessor-version":[{"id":77199,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/posts\/75203\/revisions\/77199"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/media\/76781"}],"wp:attachment":[{"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/media?parent=75203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/categories?post=75203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/tags?post=75203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}