{"id":76013,"date":"2026-03-13T00:27:23","date_gmt":"2026-03-13T00:27:23","guid":{"rendered":"https:\/\/aceworldpgs.com\/?page_id=76013"},"modified":"2026-05-12T03:15:45","modified_gmt":"2026-05-12T03:15:45","slug":"bulk-isbn-validator","status":"publish","type":"post","link":"https:\/\/aceworldpgs.com\/tools\/bulk-isbn-validator\/","title":{"rendered":"Bulk ISBN Validator"},"content":{"rendered":"\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"WebApplication\",\n  \"name\": \"ACEworld Pro Bulk ISBN Validator & Catalog Auditor\",\n  \"url\": \"https:\/\/aceworldpgs.com\/tools\/bulk-isbn-validator\/\",\n  \"description\": \"A professional bulk ISBN validation tool that allows publishers, libraries, and distributors to validate large batches of ISBN-10 and ISBN-13 numbers. Check checksums, identify publisher groups and registration regions, convert ISBN-10 to ISBN-13 in bulk, and export validation reports for catalog auditing.\",\n  \"applicationCategory\": \"BusinessApplication\",\n  \"operatingSystem\": \"All\",\n  \"browserRequirements\": \"Requires JavaScript\",\n  \"creator\": {\n    \"@type\": \"Organization\",\n    \"name\": \"ACEworld Publishing Services\",\n    \"url\": \"https:\/\/aceworldpgs.com\"\n  },\n  \"featureList\": [\n    \"Bulk ISBN checksum validation\",\n    \"Validate multiple ISBN-10 and ISBN-13 numbers simultaneously\",\n    \"Batch ISBN-10 to ISBN-13 conversion\",\n    \"Identify publisher groups and registration regions\",\n    \"Export validation reports to CSV for catalog audits\"\n  ],\n  \"keywords\": [\n    \"bulk ISBN validator\",\n    \"ISBN batch validation tool\",\n    \"publisher catalog ISBN checker\",\n    \"bulk ISBN verification\",\n    \"ISBN catalog auditing tool\"\n  ],\n  \"offers\": {\n    \"@type\": \"Offer\",\n    \"price\": \"0\",\n    \"priceCurrency\": \"USD\",\n    \"availability\": \"https:\/\/schema.org\/InStock\"\n  },\n  \"aggregateRating\": {\n    \"@type\": \"AggregateRating\",\n    \"ratingValue\": \"5.0\",\n    \"reviewCount\": \"85\"\n  }\n}\n<\/script>\n\n\n\n<p class=\"has-text-align-center\"><style>\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n   BULK ISBN VALIDATOR \u2014 ACEworld Toolkit design system.\n   Local tokens for self-containment.\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 *\/\n:root {\n  --bv-navy:       #0f1c3f;\n  --bv-blue:       #1d4ed8;\n  --bv-blue-lt:    #3b82f6;\n  --bv-blue-pale:  #eff6ff;\n  --bv-green:      #166534;\n  --bv-green-lt:   #dcfce7;\n  --bv-green-bd:   #86efac;\n  --bv-green-mid:  #16a34a;\n  --bv-red:        #dc2626;\n  --bv-red-lt:     #fef2f2;\n  --bv-red-bd:     #fca5a5;\n  --bv-amber:      #f59e0b;\n  --bv-amber-lt:   #fffbeb;\n  --bv-amber-bd:   #fde68a;\n  --bv-amber-dark: #92400e;\n  --bv-cyan:       #00BBFF;\n  --bv-white:      #ffffff;\n  --bv-gray-50:    #f8fafc;\n  --bv-gray-100:   #f1f5f9;\n  --bv-gray-200:   #e2e8f0;\n  --bv-gray-300:   #cbd5e1;\n  --bv-gray-400:   #94a3b8;\n  --bv-gray-500:   #64748b;\n  --bv-gray-600:   #475569;\n  --bv-gray-800:   #1e293b;\n  --bv-radius:     12px;\n  --bv-radius-sm:  8px;\n  --bv-radius-lg:  16px;\n  --bv-shadow:     0 4px 24px rgba(15,28,63,0.08);\n  --bv-shadow-lg:  0 12px 48px rgba(15,28,63,0.12);\n  --bv-trans:      all 0.2s cubic-bezier(0.4,0,0.2,1);\n  --bv-font:       'DM Sans', 'Segoe UI', system-ui, sans-serif;\n  --bv-mono:       'DM Mono', 'Fira Code', ui-monospace, monospace;\n}\n\n\/* \u2500\u2500 ACE HEADER local copy (self-contained) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.ace-tool { max-width: 900px; margin: 0 auto; font-family: var(--bv-font); }\n.ace-header {\n  background: linear-gradient(135deg, var(--bv-navy) 0%, #1e3a7a 100%);\n  padding: 28px 32px 24px;\n  border-radius: 20px 20px 0 0;\n  position: relative;\n  overflow: hidden;\n}\n.ace-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.ace-header::before {\n  content: '';\n  position: absolute;\n  left: -40px; bottom: -50px;\n  width: 160px; height: 160px;\n  border-radius: 50%;\n  background: rgba(245,158,11,0.06);\n  pointer-events: none;\n}\n.ace-header-inner {\n  display: flex;\n  align-items: flex-start;\n  justify-content: space-between;\n  gap: 16px;\n  flex-wrap: wrap;\n  position: relative;\n  z-index: 1;\n}\n.ace-header-identity { display: flex; flex-direction: column; gap: 6px; }\n.ace-header-badge {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  padding: 3px 10px;\n  border-radius: 20px;\n  font-size: 10px;\n  font-weight: 800;\n  text-transform: uppercase;\n  letter-spacing: 0.08em;\n  border: 1px solid rgba(255,255,255,0.25);\n  width: fit-content;\n  color: #fff;\n  background: rgba(255,255,255,0.15);\n}\n.ace-header-badge.badge-isbn {\n  background: rgba(245,158,11,0.35);\n  border-color: rgba(245,158,11,0.6);\n}\n.ace-header-title {\n  color: #fff;\n  font-size: clamp(18px,3vw,24px);\n  font-weight: 700;\n  letter-spacing: -0.02em;\n  line-height: 1.2;\n  margin: 0;\n}\n.ace-header-subtitle {\n  color: rgba(255,255,255,0.68);\n  font-size: 13px;\n  font-weight: 400;\n  line-height: 1.5;\n  margin: 0;\n  max-width: 480px;\n}\n.ace-header-cta {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  background: rgba(255,255,255,0.10);\n  color: #fff;\n  font-family: var(--bv-font);\n  font-size: 11px;\n  font-weight: 600;\n  padding: 8px 14px;\n  border-radius: 20px;\n  text-decoration: none;\n  border: 1px solid rgba(255,255,255,0.22);\n  white-space: nowrap;\n  transition: var(--bv-trans);\n  flex-shrink: 0;\n  position: relative;\n  z-index: 1;\n}\n.ace-header-cta:hover { background: rgba(255,255,255,0.20); color: #fff; text-decoration: none; }\n.ace-cta-badge {\n  background: var(--bv-amber);\n  color: #000;\n  font-size: 9px;\n  font-weight: 800;\n  padding: 2px 6px;\n  border-radius: 4px;\n}\n@media (max-width: 560px) {\n  .ace-header { padding: 20px 20px 18px; border-radius: 16px 16px 0 0; }\n  .ace-header-inner { flex-direction: column; gap: 14px; }\n  .ace-header-cta { align-self: flex-start; }\n}\n\n\/* \u2500\u2500 TOOL SHELL \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\u2500\u2500\u2500\u2500\u2500 *\/\n.bv-shell {\n  background: var(--bv-white);\n  border-radius: 0 0 20px 20px;\n  box-shadow: var(--bv-shadow-lg);\n  overflow: hidden;\n}\n\n\/* \u2500\u2500 TOP UTILITY BAR \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.bv-utility-bar {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  flex-wrap: wrap;\n  gap: 10px;\n  padding: 12px 28px;\n  background: var(--bv-gray-50);\n  border-bottom: 1px solid var(--bv-gray-200);\n}\n@media (max-width: 480px) { .bv-utility-bar { padding: 10px 18px; } }\n\n.bv-back-link {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  font-size: 12px;\n  font-weight: 600;\n  color: var(--bv-blue);\n  text-decoration: none;\n  transition: var(--bv-trans);\n}\n.bv-back-link:hover { color: var(--bv-navy); text-decoration: none; }\n\n.bv-checklist-link {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  font-size: 12px;\n  font-weight: 600;\n  color: var(--bv-blue);\n  text-decoration: none;\n}\n.bv-checklist-link:hover { color: var(--bv-navy); text-decoration: none; }\n.bv-checklist-tag {\n  background: var(--bv-amber);\n  color: #000;\n  font-size: 9px;\n  font-weight: 800;\n  padding: 2px 6px;\n  border-radius: 4px;\n  text-transform: uppercase;\n}\n\n\/* \u2500\u2500 PRO STATUS BANNER \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.bv-pro-banner {\n  margin: 18px 28px 0;\n  padding: 12px 16px;\n  border-radius: var(--bv-radius-sm);\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  gap: 12px;\n  flex-wrap: wrap;\n  background: var(--bv-amber-lt);\n  border: 1.5px solid var(--bv-amber-bd);\n  transition: var(--bv-trans);\n}\n.bv-pro-banner.active {\n  background: var(--bv-green-lt);\n  border-color: var(--bv-green-bd);\n}\n@media (max-width: 480px) { .bv-pro-banner { margin: 14px 18px 0; } }\n\n.bv-pro-banner-left {\n  display: flex;\n  align-items: center;\n  gap: 10px;\n}\n.bv-pro-icon { font-size: 18px; }\n.bv-pro-label {\n  font-size: 13px;\n  font-weight: 700;\n  color: var(--bv-amber-dark);\n}\n.bv-pro-banner.active .bv-pro-label { color: var(--bv-green); }\n.bv-pro-sub {\n  font-size: 11px;\n  color: #78350f;\n  margin-top: 1px;\n}\n.bv-pro-banner.active .bv-pro-sub { color: var(--bv-green); opacity: 0.8; }\n\n.bv-upgrade-pill {\n  display: inline-flex;\n  align-items: center;\n  gap: 5px;\n  padding: 6px 14px;\n  background: var(--bv-amber);\n  color: #000;\n  font-size: 11px;\n  font-weight: 800;\n  border-radius: 20px;\n  cursor: pointer;\n  border: none;\n  font-family: var(--bv-font);\n  transition: var(--bv-trans);\n  white-space: nowrap;\n  text-transform: uppercase;\n  letter-spacing: 0.05em;\n}\n.bv-upgrade-pill:hover { background: #e08d00; }\n.bv-pro-banner.active .bv-upgrade-pill { display: none; }\n\n\/* \u2500\u2500 INPUT SECTION \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\u2500\u2500 *\/\n.bv-input-section {\n  padding: 20px 28px;\n}\n@media (max-width: 480px) { .bv-input-section { padding: 18px 18px; } }\n\n.bv-input-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  margin-bottom: 10px;\n  flex-wrap: wrap;\n  gap: 8px;\n}\n.bv-input-label {\n  font-size: 11px;\n  font-weight: 800;\n  text-transform: uppercase;\n  letter-spacing: 0.08em;\n  color: var(--bv-gray-600);\n}\n.bv-input-hint {\n  font-size: 11px;\n  color: var(--bv-gray-400);\n  font-style: italic;\n}\n\n.bv-textarea-wrap { position: relative; }\n#bulkInput {\n  width: 100%;\n  padding: 16px;\n  border: 1.5px solid var(--bv-gray-200);\n  border-radius: var(--bv-radius-sm);\n  font-family: var(--bv-mono);\n  font-size: 13px;\n  color: var(--bv-gray-800);\n  background: var(--bv-gray-50);\n  resize: vertical;\n  outline: none;\n  transition: var(--bv-trans);\n  line-height: 1.8;\n  letter-spacing: 0.04em;\n  box-sizing: border-box;\n  min-height: 160px;\n}\n#bulkInput::placeholder {\n  font-family: var(--bv-font);\n  color: var(--bv-gray-300);\n  font-style: italic;\n  letter-spacing: 0;\n  font-size: 12px;\n}\n#bulkInput:focus {\n  border-color: var(--bv-blue-lt);\n  background: var(--bv-white);\n  box-shadow: 0 0 0 3px rgba(59,130,246,0.1);\n}\n\n.bv-input-footer {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  margin-top: 8px;\n  flex-wrap: wrap;\n  gap: 8px;\n}\n.bv-line-count {\n  font-size: 11px;\n  color: var(--bv-gray-400);\n  font-family: var(--bv-mono);\n}\n.bv-free-limit-note {\n  font-size: 11px;\n  color: var(--bv-gray-400);\n}\n.bv-free-limit-note strong { color: var(--bv-amber-dark); }\n\n\/* \u2500\u2500 ACTION BUTTONS \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\u2500 *\/\n.bv-action-row {\n  display: flex;\n  gap: 10px;\n  padding: 0 28px 20px;\n  flex-wrap: wrap;\n}\n@media (max-width: 480px) { .bv-action-row { padding: 0 18px 18px; flex-direction: column; } }\n\n.bv-validate-btn {\n  flex: 2;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 8px;\n  padding: 14px 20px;\n  background: var(--bv-navy);\n  color: #fff;\n  border: none;\n  border-radius: var(--bv-radius-sm);\n  font-size: 14px;\n  font-weight: 700;\n  font-family: var(--bv-font);\n  cursor: pointer;\n  transition: var(--bv-trans);\n}\n.bv-validate-btn:hover {\n  background: #0a1128;\n  box-shadow: 0 4px 16px rgba(15,28,63,0.25);\n}\n.bv-validate-btn:active { transform: scale(0.98); }\n.bv-validate-btn .bv-btn-icon { font-size: 16px; }\n\n.bv-download-btn {\n  flex: 1;\n  display: none;\n  align-items: center;\n  justify-content: center;\n  gap: 8px;\n  padding: 14px 16px;\n  background: var(--bv-green-mid);\n  color: #fff;\n  border: none;\n  border-radius: var(--bv-radius-sm);\n  font-size: 13px;\n  font-weight: 700;\n  font-family: var(--bv-font);\n  cursor: pointer;\n  transition: var(--bv-trans);\n  white-space: nowrap;\n}\n.bv-download-btn.show { display: flex; }\n.bv-download-btn:hover { filter: brightness(1.08); box-shadow: 0 4px 14px rgba(22,101,52,0.3); }\n.bv-download-btn.locked {\n  background: var(--bv-gray-400);\n  cursor: default;\n}\n.bv-download-btn.locked:hover { filter: none; box-shadow: none; }\n\n\/* \u2500\u2500 SUMMARY STATS BAR \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.bv-stats-bar {\n  display: none;\n  margin: 0 28px;\n  background: var(--bv-navy);\n  border-radius: var(--bv-radius-sm);\n  padding: 16px 20px;\n  gap: 0;\n  animation: bvFadeIn 0.3s ease;\n}\n.bv-stats-bar.show {\n  display: flex;\n  align-items: center;\n  flex-wrap: wrap;\n}\n@media (max-width: 480px) { .bv-stats-bar { margin: 0 18px; } }\n\n.bv-stat {\n  flex: 1;\n  min-width: 80px;\n  text-align: center;\n  padding: 8px 12px;\n  position: relative;\n}\n.bv-stat:not(:last-child)::after {\n  content: '';\n  position: absolute;\n  right: 0; top: 20%; bottom: 20%;\n  width: 1px;\n  background: rgba(255,255,255,0.12);\n}\n.bv-stat-value {\n  font-size: 22px;\n  font-weight: 800;\n  font-family: var(--bv-mono);\n  color: #fff;\n  line-height: 1;\n  margin-bottom: 4px;\n}\n.bv-stat-value.green  { color: #4ade80; }\n.bv-stat-value.red    { color: #f87171; }\n.bv-stat-value.amber  { color: var(--bv-amber); }\n.bv-stat-label {\n  font-size: 10px;\n  font-weight: 700;\n  text-transform: uppercase;\n  letter-spacing: 0.08em;\n  color: rgba(255,255,255,0.5);\n}\n\n\/* \u2500\u2500 RESULTS TABLE \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\u2500\u2500 *\/\n.bv-table-section {\n  display: none;\n  padding: 18px 28px;\n  animation: bvFadeIn 0.35s ease;\n}\n.bv-table-section.show { display: block; }\n@media (max-width: 480px) { .bv-table-section { padding: 16px 18px; } }\n\n.bv-table-header {\n  display: flex;\n  align-items: center;\n  gap: 8px;\n  margin-bottom: 12px;\n}\n.bv-table-title {\n  font-size: 10px;\n  font-weight: 800;\n  text-transform: uppercase;\n  letter-spacing: 0.1em;\n  color: var(--bv-blue);\n  white-space: nowrap;\n}\n.bv-table-line { flex: 1; height: 1px; background: var(--bv-gray-200); }\n\n.bv-table-wrap { overflow-x: auto; border-radius: var(--bv-radius-sm); border: 1.5px solid var(--bv-gray-200); }\n\ntable.bv-table { width: 100%; border-collapse: collapse; min-width: 380px; }\ntable.bv-table thead { background: var(--bv-gray-50); }\ntable.bv-table th {\n  padding: 11px 16px;\n  font-size: 10px;\n  font-weight: 800;\n  text-transform: uppercase;\n  letter-spacing: 0.08em;\n  color: var(--bv-gray-500);\n  border-bottom: 1.5px solid var(--bv-gray-200);\n  text-align: left;\n  white-space: nowrap;\n}\ntable.bv-table td {\n  padding: 11px 16px;\n  font-size: 13px;\n  border-bottom: 1px solid var(--bv-gray-100);\n  vertical-align: middle;\n}\ntable.bv-table tr:last-child td { border-bottom: none; }\ntable.bv-table tbody tr { transition: background 0.15s; }\ntable.bv-table tbody tr:hover { background: var(--bv-gray-50); }\n\n.bv-isbn-cell {\n  font-family: var(--bv-mono);\n  font-size: 13px;\n  font-weight: 500;\n  color: var(--bv-gray-800);\n  letter-spacing: 0.05em;\n}\n\n.bv-status-badge {\n  display: inline-flex;\n  align-items: center;\n  gap: 4px;\n  padding: 4px 10px;\n  border-radius: 20px;\n  font-size: 10px;\n  font-weight: 800;\n  text-transform: uppercase;\n  letter-spacing: 0.06em;\n  white-space: nowrap;\n}\n.bv-status-badge.valid {\n  background: var(--bv-green-lt);\n  color: var(--bv-green);\n  border: 1px solid var(--bv-green-bd);\n}\n.bv-status-badge.invalid {\n  background: var(--bv-red-lt);\n  color: var(--bv-red);\n  border: 1px solid var(--bv-red-bd);\n}\n\n.bv-region-cell {\n  font-size: 12px;\n  color: var(--bv-gray-500);\n  font-weight: 500;\n}\n\n.bv-row-num {\n  font-size: 11px;\n  font-family: var(--bv-mono);\n  color: var(--bv-gray-300);\n  text-align: right;\n  width: 32px;\n}\n\n\/* \u2500\u2500 FOOTER UPSELL \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\u2500\u2500 *\/\n.bv-upsell {\n  margin: 0 28px 24px;\n  padding: 12px 16px;\n  background: var(--bv-blue-pale);\n  border: 1.5px solid #bfdbfe;\n  border-radius: var(--bv-radius-sm);\n  font-size: 12px;\n  color: var(--bv-gray-600);\n  display: flex;\n  align-items: center;\n  gap: 10px;\n  line-height: 1.5;\n}\n.bv-upsell a { color: var(--bv-blue); font-weight: 700; text-decoration: none; }\n.bv-upsell a:hover { text-decoration: underline; }\n@media (max-width: 480px) { .bv-upsell { margin: 0 18px 20px; } }\n\n\/* \u2500\u2500 PAYWALL MODAL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.bv-modal-overlay {\n  display: none;\n  position: fixed;\n  inset: 0;\n  z-index: 9999;\n  background: rgba(10,15,40,0.75);\n  align-items: center;\n  justify-content: center;\n  padding: 20px;\n  backdrop-filter: blur(4px);\n}\n.bv-modal-overlay.show { display: flex; }\n\n.bv-modal {\n  background: var(--bv-white);\n  border-radius: 20px;\n  max-width: 440px;\n  width: 100%;\n  padding: 0;\n  overflow: hidden;\n  box-shadow: 0 24px 80px rgba(10,15,40,0.35);\n  animation: bvModalPop 0.3s cubic-bezier(0.34,1.56,0.64,1);\n  position: relative;\n}\n\n@keyframes bvModalPop { from { opacity:0; transform:scale(0.92) translateY(12px); } to { opacity:1; transform:scale(1) translateY(0); } }\n\n.bv-modal-head {\n  background: linear-gradient(135deg, var(--bv-navy) 0%, #1e3a7a 100%);\n  padding: 28px 28px 24px;\n  position: relative;\n  text-align: center;\n}\n.bv-modal-close {\n  position: absolute;\n  top: 14px; right: 16px;\n  background: rgba(255,255,255,0.12);\n  border: 1px solid rgba(255,255,255,0.18);\n  color: #fff;\n  font-size: 16px;\n  line-height: 1;\n  width: 28px; height: 28px;\n  border-radius: 50%;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  transition: var(--bv-trans);\n  font-family: var(--bv-font);\n}\n.bv-modal-close:hover { background: rgba(255,255,255,0.25); }\n\n.bv-modal-gem { font-size: 36px; margin-bottom: 10px; }\n.bv-modal-title {\n  color: #fff;\n  font-size: 20px;\n  font-weight: 800;\n  margin: 0 0 6px;\n  letter-spacing: -0.02em;\n}\n.bv-modal-desc {\n  color: rgba(255,255,255,0.65);\n  font-size: 13px;\n  margin: 0;\n  line-height: 1.5;\n}\n\n.bv-modal-body { padding: 24px 28px; }\n\n.bv-paystack-btn {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 8px;\n  width: 100%;\n  padding: 14px;\n  background: var(--bv-cyan);\n  color: var(--bv-navy);\n  text-decoration: none;\n  border-radius: var(--bv-radius-sm);\n  font-size: 14px;\n  font-weight: 800;\n  font-family: var(--bv-font);\n  transition: var(--bv-trans);\n  margin-bottom: 20px;\n}\n.bv-paystack-btn:hover {\n  background: #00a8e6;\n  color: var(--bv-navy);\n  text-decoration: none;\n  box-shadow: 0 4px 16px rgba(0,187,255,0.35);\n}\n\n.bv-modal-divider {\n  display: flex;\n  align-items: center;\n  gap: 10px;\n  margin-bottom: 18px;\n}\n.bv-modal-divider::before,\n.bv-modal-divider::after { content:''; flex:1; height:1px; background:var(--bv-gray-200); }\n.bv-modal-divider span {\n  font-size: 11px;\n  font-weight: 700;\n  color: var(--bv-gray-400);\n  text-transform: uppercase;\n  letter-spacing: 0.08em;\n  white-space: nowrap;\n}\n\n.bv-key-label {\n  font-size: 11px;\n  font-weight: 700;\n  text-transform: uppercase;\n  letter-spacing: 0.06em;\n  color: var(--bv-gray-600);\n  margin-bottom: 8px;\n  display: block;\n}\n\n.bv-key-row {\n  display: flex;\n  gap: 8px;\n}\n#proKeyInput {\n  flex: 2;\n  padding: 12px 14px;\n  border: 1.5px solid var(--bv-gray-200);\n  border-radius: var(--bv-radius-sm);\n  font-size: 14px;\n  font-family: var(--bv-mono);\n  outline: none;\n  transition: var(--bv-trans);\n  color: var(--bv-gray-800);\n}\n#proKeyInput:focus { border-color: var(--bv-blue-lt); box-shadow: 0 0 0 3px rgba(59,130,246,0.1); }\n#proKeyInput.error { border-color: var(--bv-red); }\n\n.bv-unlock-btn {\n  flex: 1;\n  padding: 12px 16px;\n  background: var(--bv-navy);\n  color: #fff;\n  border: none;\n  border-radius: var(--bv-radius-sm);\n  font-size: 13px;\n  font-weight: 700;\n  font-family: var(--bv-font);\n  cursor: pointer;\n  transition: var(--bv-trans);\n  white-space: nowrap;\n}\n.bv-unlock-btn:hover { background: #0a1128; }\n\n#keyError {\n  font-size: 11px;\n  color: var(--bv-red);\n  margin-top: 8px;\n  display: none;\n  font-weight: 600;\n}\n#keyError.show { display: block; }\n\n\/* \u2500\u2500 ANIMATIONS \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\u2500\u2500\u2500\u2500\u2500 *\/\n@keyframes bvFadeIn { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:translateY(0); } }\n@keyframes bvRowIn  { from { opacity:0; transform:translateX(-6px); } to { opacity:1; transform:translateX(0); } }\n.bv-row-anim { animation: bvRowIn 0.2s ease both; }\n\n\/* \u2500\u2500 SPINNER \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.bv-spinner {\n  width: 16px; height: 16px;\n  border: 2px solid rgba(255,255,255,0.3);\n  border-top-color: #fff;\n  border-radius: 50%;\n  animation: bvSpin 0.6s linear infinite;\n  display: none;\n}\n.bv-spinner.show { display: inline-block; }\n@keyframes bvSpin { to { transform: rotate(360deg); } }\n\n\/* \u2500\u2500 FOOTER SPACE \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\u2500\u2500\u2500 *\/\n.bv-foot { height: 4px; }\n<\/style>\n\n<!-- ============================================================\n     MARKUP\n============================================================ -->\n<div class=\"ace-tool\">\n\n  <!-- Shared header -->\n  \n<div class=\"ace-header\">\n  <div class=\"ace-header-inner\">\n\n    <!-- Left: identity block -->\n    <div class=\"ace-header-identity\">\n\n            <span class=\"ace-header-badge badge-default\">\n        ISBN      <\/span>\n      \n      <h2 class=\"ace-header-title\">Bulk ISBN Validator<\/h2>\n\n            <p class=\"ace-header-subtitle\">The tool helps authors, self-publishers, and booksellers who need to verify multiple ISBNs at once.<\/p>\n      \n    <\/div><!-- \/.ace-header-identity -->\n\n    <!-- Right: CTA button -->\n    <a href=\"https:\/\/aceworldpgs.com\/acepublishingchecklist\" class=\"ace-header-cta\" target=\"_blank\" rel=\"noopener\">\n      Download Publishing Checklist            <span class=\"ace-cta-badge\">\u2b07<\/span>\n          <\/a>\n\n  <\/div><!-- \/.ace-header-inner -->\n<\/div><!-- \/.ace-header -->\n\n\n        \n  <div class=\"bv-shell\">\n\n    <!-- Utility bar -->\n    <div class=\"bv-utility-bar\">\n      <a href=\"https:\/\/aceworldpgs.com\/tools\/isbn-validator\/\" class=\"bv-back-link\">\n        \u2190 Back to Single Validator\n      <\/a>\n      <a href=\"https:\/\/aceworldpgs.com\/acepublishingchecklist\" class=\"bv-checklist-link\">\n        Download Publishing Checklist <span class=\"bv-checklist-tag\">\u2b07<\/span>\n      <\/a>\n    <\/div>\n\n    <!-- Pro status banner -->\n    <div class=\"bv-pro-banner\" id=\"globalBadge\">\n      <div class=\"bv-pro-banner-left\">\n        <span class=\"bv-pro-icon\" id=\"proBannerIcon\">\u2b50<\/span>\n        <div>\n          <div class=\"bv-pro-label\" id=\"proBannerLabel\">PRO FEATURES: Bulk Validation, Catalog Export<\/div>\n          <div class=\"bv-pro-sub\" id=\"proBannerSub\">Free plan: up to 3 ISBNs per session. Upgrade for unlimited.<\/div>\n        <\/div>\n      <\/div>\n      <button class=\"bv-upgrade-pill\" id=\"upgradePill\"\n              onclick=\"trackTool('upgrade_to_pro'); bvOpenPaywall('Pro CSV Export', 'Batch processing requires a Pro Access Key.')\">\n        \ud83d\udc8e Upgrade to Pro\n      <\/button>\n    <\/div>\n\n    <!-- Input section -->\n    <div class=\"bv-input-section\">\n      <div class=\"bv-input-header\">\n        <span class=\"bv-input-label\">Enter ISBN List:<\/span>\n        <span class=\"bv-input-hint\">One ISBN per line \u2014 10 or 13 digits<\/span>\n      <\/div>\n      <div class=\"bv-textarea-wrap\">\n        <textarea id=\"bulkInput\"\n                  rows=\"8\"\n                  placeholder=\"9789785890525&#10;9780141036144&#10;9783161484100&#10;(one ISBN per line)\"\n                  oninput=\"bvUpdateLineCount()\"><\/textarea>\n      <\/div>\n      <div class=\"bv-input-footer\">\n        <span class=\"bv-line-count\" id=\"lineCount\">0 ISBNs entered<\/span>\n        <span class=\"bv-free-limit-note\" id=\"limitNote\">\n          Free plan: <strong>3 ISBNs max<\/strong>\n        <\/span>\n      <\/div>\n    <\/div>\n\n    <!-- Action buttons -->\n    <div class=\"bv-action-row\">\n      <button class=\"bv-validate-btn\" id=\"validateBtn\"\n              onclick=\"trackTool('bulk_isbn_validator'); bvProcessBulk()\">\n        <div class=\"bv-spinner\" id=\"validateSpinner\"><\/div>\n        <span class=\"bv-btn-icon\" id=\"validateIcon\">\u2713<\/span>\n        <span id=\"validateLabel\">Validate Catalog<\/span>\n      <\/button>\n      <button class=\"bv-download-btn\" id=\"downloadBtn\"\n              onclick=\"trackTool('isbn_report_export'); bvExportToCSV()\">\n        \u2b07 Download CSV Report\n      <\/button>\n    <\/div>\n\n    <!-- Summary stats bar -->\n    <div class=\"bv-stats-bar\" id=\"statsBar\">\n      <div class=\"bv-stat\">\n        <div class=\"bv-stat-value\" id=\"statTotal\">0<\/div>\n        <div class=\"bv-stat-label\">Total ISBNs<\/div>\n      <\/div>\n      <div class=\"bv-stat\">\n        <div class=\"bv-stat-value green\" id=\"statValid\">0<\/div>\n        <div class=\"bv-stat-label\">Valid<\/div>\n      <\/div>\n      <div class=\"bv-stat\">\n        <div class=\"bv-stat-value red\" id=\"statInvalid\">0<\/div>\n        <div class=\"bv-stat-label\">Invalid<\/div>\n      <\/div>\n      <div class=\"bv-stat\">\n        <div class=\"bv-stat-value amber\" id=\"statRate\">0%<\/div>\n        <div class=\"bv-stat-label\">Pass Rate<\/div>\n      <\/div>\n    <\/div>\n\n    <!-- Results table -->\n    <div class=\"bv-table-section\" id=\"tableWrapper\">\n      <div class=\"bv-table-header\">\n        <span class=\"bv-table-title\">Validation Results<\/span>\n        <span class=\"bv-table-line\"><\/span>\n      <\/div>\n      <div class=\"bv-table-wrap\">\n        <table class=\"bv-table\">\n          <thead>\n            <tr>\n              <th class=\"bv-row-num\">#<\/th>\n              <th>ISBN<\/th>\n              <th>Status<\/th>\n              <th>Region \/ Publisher<\/th>\n            <\/tr>\n          <\/thead>\n          <tbody id=\"bulkTableBody\"><\/tbody>\n        <\/table>\n      <\/div>\n    <\/div>\n\n    <!-- Footer upsell -->\n    <div class=\"bv-upsell\" style=\"margin-top: 18px;\">\n      <span style=\"font-size:18px; flex-shrink:0;\">\ud83d\udcda<\/span>\n      <span>\n        Need ISBNs for your books?\n        <a href=\"https:\/\/aceworldpgs.com\/tools\/publishing-calculator\/\" target=\"_blank\">Get an ISBN through our publishing calculator \u2192<\/a>\n      <\/span>\n    <\/div>\n\n    <div class=\"bv-foot\"><\/div>\n\n  <\/div><!-- \/.bv-shell -->\n<\/div><!-- \/.ace-tool -->\n\n<!-- \u2500\u2500 PAYWALL MODAL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n<div class=\"bv-modal-overlay\" id=\"paywallModal\">\n  <div class=\"bv-modal\">\n\n    <div class=\"bv-modal-head\">\n      <button class=\"bv-modal-close\" onclick=\"bvClosePaywall()\" aria-label=\"Close\">\u2715<\/button>\n      <div class=\"bv-modal-gem\">\ud83d\udc8e<\/div>\n      <h2 class=\"bv-modal-title\" id=\"modalTitle\">Pro CSV Export<\/h2>\n      <p class=\"bv-modal-desc\" id=\"modalDesc\">Batch processing requires a Pro Access Key.<\/p>\n    <\/div>\n\n    <div class=\"bv-modal-body\">\n      <a href=\"https:\/\/paystack.com\/pay\/aceworldp\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"bv-paystack-btn\">\n        \ud83d\udcb3 Get Access Key via Paystack\n      <\/a>\n\n      <div class=\"bv-modal-divider\">\n        <span>Already have a key?<\/span>\n      <\/div>\n\n      <label class=\"bv-key-label\" for=\"proKeyInput\">Enter Your Access Key<\/label>\n      <div class=\"bv-key-row\">\n        <input type=\"text\" id=\"proKeyInput\" placeholder=\"Enter Key Here\u2026\" autocomplete=\"off\">\n        <button class=\"bv-unlock-btn\" onclick=\"bvVerifyAndUnlock()\">Unlock<\/button>\n      <\/div>\n      <p id=\"keyError\">Invalid Access Key. Please try again.<\/p>\n    <\/div>\n\n  <\/div>\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<!-- ============================================================\n     JAVASCRIPT \u2014 All original logic preserved, UI updated\n============================================================ -->\n<script>\n(function() {\n\n\/\/ \u2500\u2500 State \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet bulkData       = [];\nconst PRO_KEY      = 'ISBNV2026';\nconst FREE_LIMIT   = 3;\n\n\/\/ \u2500\u2500 Pro check \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\u2500\u2500\u2500\u2500\u2500\u2500\nfunction isPro() {\n  return localStorage.getItem('isbn_pro_key') === PRO_KEY;\n}\n\n\/\/ \u2500\u2500 Update UI to pro state \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\nfunction updateToProUI() {\n  const banner = document.getElementById('globalBadge');\n  const label  = document.getElementById('proBannerLabel');\n  const sub    = document.getElementById('proBannerSub');\n  const icon   = document.getElementById('proBannerIcon');\n  const note   = document.getElementById('limitNote');\n\n  if (banner) banner.classList.add('active');\n  if (label)  label.textContent = 'PRO ACCESS ACTIVE';\n  if (sub)    sub.textContent   = 'Unlimited bulk validation and CSV export unlocked.';\n  if (icon)   icon.textContent  = '\u2705';\n  if (note)   note.style.display = 'none';\n}\n\n\/\/ \u2500\u2500 Line counter \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\u2500\u2500\u2500\nfunction bvUpdateLineCount() {\n  const lines = (document.getElementById('bulkInput').value || '')\n    .split(\/\\r?\\n\/).filter(l => l.trim() !== '');\n  const count = lines.length;\n  document.getElementById('lineCount').textContent =\n    count === 0 ? '0 ISBNs entered'\n    : count === 1 ? '1 ISBN entered'\n    : count + ' ISBNs entered';\n}\n\n\/\/ \u2500\u2500 ISBN validation logic (original, unchanged) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction validateSingleIsbn(isbn) {\n  let clean = isbn.replace(\/-\/g, '').trim();\n  if (clean.length === 10) {\n    let temp = '978' + clean.substring(0, 9);\n    let sum  = 0;\n    for (let i = 0; i < 12; i++) sum += (i % 2 === 0) ? parseInt(temp[i]) : parseInt(temp[i]) * 3;\n    clean = temp + (10 - (sum % 10)) % 10;\n  }\n  if (clean.length !== 13 || !\/^\\d+$\/.test(clean)) return { valid: false, clean };\n  let sum = 0;\n  for (let i = 0; i < 12; i++) sum += (i % 2 === 0) ? parseInt(clean[i]) : parseInt(clean[i]) * 3;\n  return { valid: (10 - (sum % 10)) % 10 === parseInt(clean[12]), clean };\n}\n\nfunction getRegion(isbn) {\n  if (isbn.startsWith('978978'))  return 'Nigeria';\n  const c = isbn.substring(3);\n  if (c.startsWith('0') || c.startsWith('1')) return 'English (USA \/ UK)';\n  if (c.startsWith('2')) return 'French';\n  if (c.startsWith('3')) return 'German';\n  if (c.startsWith('4')) return 'Japanese';\n  return 'International';\n}\n\n\/\/ \u2500\u2500 Main process \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\u2500\u2500\u2500\nasync function bvProcessBulk() {\n  const text  = document.getElementById('bulkInput').value || '';\n  const lines = text.split(\/\\r?\\n\/).filter(l => l.trim() !== '');\n  if (lines.length === 0) return;\n\n  \/\/ Free limit gate\n  if (lines.length > FREE_LIMIT && !isPro()) {\n    bvOpenPaywall(\n      'Bulk Limit Reached',\n      `Free users can only validate up to ${FREE_LIMIT} ISBNs. Upgrade to Pro to audit your entire catalog.`\n    );\n    return;\n  }\n\n  \/\/ Loading state\n  const btn      = document.getElementById('validateBtn');\n  const spinner  = document.getElementById('validateSpinner');\n  const icon     = document.getElementById('validateIcon');\n  const lbl      = document.getElementById('validateLabel');\n  btn.disabled   = true;\n  spinner.classList.add('show');\n  icon.style.display  = 'none';\n  lbl.textContent     = 'Validating\u2026';\n\n  \/\/ Small delay for UX\n  await new Promise(r => setTimeout(r, 180));\n\n  const tbody = document.getElementById('bulkTableBody');\n  tbody.innerHTML = '';\n  bulkData = [];\n  let validCount = 0;\n\n  lines.forEach((line, i) => {\n    const result = validateSingleIsbn(line);\n    const region = result.valid ? getRegion(result.clean) : 'Invalid Checksum';\n    const status = result.valid ? 'Valid' : 'Invalid';\n    bulkData.push({ isbn: result.clean, status, region });\n    if (result.valid) validCount++;\n\n    const delay = Math.min(i * 30, 300);\n    const tr = document.createElement('tr');\n    tr.className = 'bv-row-anim';\n    tr.style.animationDelay = delay + 'ms';\n    tr.innerHTML = `\n      <td class=\"bv-row-num\">${i + 1}<\/td>\n      <td class=\"bv-isbn-cell\">${result.clean}<\/td>\n      <td>\n        <span class=\"bv-status-badge ${result.valid ? 'valid' : 'invalid'}\">\n          ${result.valid ? '\u2713 VALID' : '\u2717 INVALID'}\n        <\/span>\n      <\/td>\n      <td class=\"bv-region-cell\">${region}<\/td>`;\n    tbody.appendChild(tr);\n  });\n\n  \/\/ Reset button\n  btn.disabled       = false;\n  spinner.classList.remove('show');\n  icon.style.display = '';\n  lbl.textContent    = 'Validate Catalog';\n\n  \/\/ Stats bar\n  const total    = lines.length;\n  const invalid  = total - validCount;\n  const rate     = Math.round((validCount \/ total) * 100);\n  document.getElementById('statTotal').textContent   = total;\n  document.getElementById('statValid').textContent   = validCount;\n  document.getElementById('statInvalid').textContent = invalid;\n  document.getElementById('statRate').textContent    = rate + '%';\n  document.getElementById('statsBar').classList.add('show');\n\n  \/\/ Table\n  document.getElementById('tableWrapper').classList.add('show');\n\n  \/\/ Download button\n  const dlBtn = document.getElementById('downloadBtn');\n  dlBtn.classList.add('show');\n  if (isPro()) {\n    dlBtn.classList.remove('locked');\n    dlBtn.innerHTML = '\u2b07 Download CSV Report';\n  } else {\n    dlBtn.classList.add('locked');\n    dlBtn.innerHTML = '\ud83d\udd12 Download CSV (Pro Only)';\n  }\n\n  \/\/ Log\n  logBulkSummaryToWordPress(validCount, total);\n\n  \/\/ Scroll stats into view\n  document.getElementById('statsBar').scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n}\n\n\/\/ \u2500\u2500 Paywall modal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction bvOpenPaywall(title, desc) {\n  document.getElementById('modalTitle').textContent = title;\n  document.getElementById('modalDesc').textContent  = desc;\n  document.getElementById('paywallModal').classList.add('show');\n  document.getElementById('proKeyInput').value      = '';\n  document.getElementById('proKeyInput').className  = '';\n  document.getElementById('keyError').className     = '';\n}\n\nfunction bvClosePaywall() {\n  document.getElementById('paywallModal').classList.remove('show');\n}\n\n\/\/ Close on overlay click\ndocument.getElementById('paywallModal').addEventListener('click', function(e) {\n  if (e.target === this) bvClosePaywall();\n});\n\n\/\/ \u2500\u2500 Key verification \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\nfunction bvVerifyAndUnlock() {\n  const key = (document.getElementById('proKeyInput').value || '').trim();\n  if (key === PRO_KEY) {\n    localStorage.setItem('isbn_pro_key', key);\n    updateToProUI();\n    bvClosePaywall();\n    bvProcessBulk();\n  } else {\n    document.getElementById('proKeyInput').classList.add('error');\n    document.getElementById('keyError').classList.add('show');\n  }\n}\n\n\/\/ \u2500\u2500 CSV export \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\u2500\u2500\u2500\u2500\u2500\nfunction bvExportToCSV() {\n  if (!isPro()) {\n    bvOpenPaywall('Pro CSV Export', 'Batch exporting requires a Pro Access Key.');\n    return;\n  }\n  let csv = 'data:text\/csv;charset=utf-8,ISBN,Status,Region\\n';\n  bulkData.forEach(r => { csv += `${r.isbn},${r.status},${r.region}\\n`; });\n  const link = document.createElement('a');\n  link.setAttribute('href', encodeURI(csv));\n  link.setAttribute('download', 'isbn_catalog_report.csv');\n  document.body.appendChild(link);\n  link.click();\n  document.body.removeChild(link);\n}\n\n\/\/ \u2500\u2500 Logging \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nasync function logBulkSummaryToWordPress(validCount, totalCount) {\n  let geo = { country: 'Unknown', city: 'Unknown' };\n  try {\n    const res  = await fetch('https:\/\/ipapi.co\/json\/');\n    const data = await res.json();\n    geo.country = data.country_name || 'Unknown';\n    geo.city    = data.city         || 'Unknown';\n  } catch (e) { \/* silent *\/ }\n  const fd = new FormData();\n  fd.append('action',       'save_isbn_usage');\n  fd.append('isbn',         `${validCount} Valid \/ ${totalCount} Total`);\n  fd.append('isbn_origin',  'Bulk Audit');\n  fd.append('country',      geo.country);\n  fd.append('city',         geo.city);\n  fetch('\/wp-admin\/admin-ajax.php', { method: 'POST', body: fd }).catch(() => {});\n}\n\n\/\/ \u2500\u2500 Expose globals \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\u2500\nwindow.processBulk      = bvProcessBulk;   \/\/ backward compat\nwindow.bvProcessBulk    = bvProcessBulk;\nwindow.exportToCSV      = bvExportToCSV;   \/\/ backward compat\nwindow.bvExportToCSV    = bvExportToCSV;\nwindow.bvOpenPaywall    = bvOpenPaywall;\nwindow.bvClosePaywall   = bvClosePaywall;\nwindow.bvVerifyAndUnlock = bvVerifyAndUnlock;\nwindow.verifyAndUnlock  = bvVerifyAndUnlock; \/\/ backward compat\nwindow.closePaywall     = bvClosePaywall;    \/\/ backward compat\nwindow.bvUpdateLineCount = bvUpdateLineCount;\n\n\/\/ \u2500\u2500 Init \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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nif (isPro()) updateToProUI();\nbvUpdateLineCount();\n\n\/\/ Enter key in key field\ndocument.getElementById('proKeyInput').addEventListener('keydown', function(e) {\n  if (e.key === 'Enter') bvVerifyAndUnlock();\n});\n\n})();\n<\/script>\n\n<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n<style>.kt-accordion-id76013_8d6fb2-30 .kt-accordion-inner-wrap{column-gap:var(--global-kb-gap-md, 2rem);row-gap:10px;}.kt-accordion-id76013_8d6fb2-30 .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-id76013_8d6fb2-30 > .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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30 > .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-id76013_8d6fb2-30 .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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id76013_8d6fb2-30 > .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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30: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-id76013_8d6fb2-30 .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-id76013_8d6fb2-30 > .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-id76013_8d6fb2-30 > .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-id76013_8d6fb2-30 .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-id76013_8d6fb2-30 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id76013_8d6fb2-30 > .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-id76013_8d6fb2-30 .kt-accordion-inner-wrap{display:block;}.kt-accordion-id76013_8d6fb2-30 .kt-accordion-inner-wrap .kt-accordion-pane:not(:first-child){margin-top:10px;}.kt-accordion-id76013_8d6fb2-30 .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-id76013_8d6fb2-30 > .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-id76013_8d6fb2-30 > .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-id76013_8d6fb2-30 .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-id76013_8d6fb2-30 .kt-accordion-header-wrap .kt-blocks-accordion-header:focus-visible,\n\t\t\t\t.kt-accordion-id76013_8d6fb2-30 > .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-id76013_8d6fb2-30 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-pane76013_734194-12\"><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 Bulk ISBN Validator<\/h2>\n\n\n\n<p>The&nbsp;<strong>Bulk ISBN Validator<\/strong>&nbsp;is designed for publishers, libraries, bookstores, and catalog managers who need to verify multiple ISBN numbers at once. Instead of checking each ISBN individually, this tool allows you to paste or upload a list of ISBNs and validate them instantly in a single process.<\/p>\n\n\n\n<p>The validator checks whether each ISBN follows the correct structure and mathematical checksum required for&nbsp;<strong>ISBN-10 or ISBN-13 numbers<\/strong>, helping you identify invalid or incorrectly formatted entries before publishing or cataloging books.<\/p>\n\n\n\n<p>After validation, the tool can generate a&nbsp;<strong>clean exportable report (CSV)<\/strong>, making it easier to organize book catalogs, manage publishing inventories, or prepare ISBN lists for distributors and databases.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Disclaimer &amp; Terms of Use<\/h3>\n\n\n\n<p>The <strong>Bulk ISBN Validator &amp; Catalog Auditor<\/strong> is provided &#8220;as is&#8221; without warranties of any kind, express or implied. This tool is designed for catalog auditing and informational purposes and should not be used as the sole determinant for legal or financial publishing decisions.<\/p>\n\n\n\n<p><strong>By utilizing the Bulk ISBN Validator &amp; Catalog Auditor, you acknowledge the following:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Professional Scope:<\/strong> This tool provides algorithmic verification and does not constitute legal or professional publishing advice.<\/li>\n\n\n\n<li><strong>Data Integrity:<\/strong> The accuracy of the audit report is dependent on the quality of the raw data provided in the batch input.<\/li>\n\n\n\n<li><strong>Non-Guarantee:<\/strong> Successful checksum validation does not guarantee that a title is currently in print or registered with a specific agency.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Limitation of Liability<\/h3>\n\n\n\n<p>In no event shall ACEworld, its developers, or affiliates be held liable for any damages\u2014including but not limited to incidental, consequential, or punitive damages\u2014resulting from the use of this tool or the reliance on its generated reports. <em>Barcode Services provided via TEC-IT Integration.<\/em><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Intellectual Property Rights<\/h3>\n\n\n\n<p>The ACEworld Bulk ISBN Validator &amp; Catalog Auditor, including its proprietary logic, interface design, and documentation, is protected by international intellectual property laws. Unauthorized reproduction, distribution, or commercial exploitation of this tool&#8217;s components is strictly prohibited and may result in civil and criminal penalties.<\/p>\n\n\n\n<script type=\"application\/ld+json\">\r\n{\r\n  \"@context\": \"https:\/\/schema.org\",\r\n  \"@type\": \"FAQPage\",\r\n  \"mainEntity\": [\r\n    {\r\n      \"@type\": \"Question\",\r\n      \"name\": \"How do I validate a large list of ISBNs at once?\",\r\n      \"acceptedAnswer\": {\r\n        \"@type\": \"Answer\",\r\n        \"text\": \"To validate a batch of ISBNs, paste your list into the ACEworld Bulk ISBN Auditor textarea (one ISBN per line). Click 'Validate Catalog' to run an algorithmic checksum check and identify the region for every number in your list.\"\r\n      }\r\n    },\r\n    {\r\n      \"@type\": \"Question\",\r\n      \"name\": \"Can I export my ISBN validation results to Excel?\",\r\n      \"acceptedAnswer\": {\r\n        \"@type\": \"Answer\",\r\n        \"text\": \"Yes. After processing your list, the ACEworld Pro tool generates a 'Download CSV' button. Clicking this allows you to save a full report including the ISBN, validity status, and region\/publisher group, which can be opened in Microsoft Excel or Google Sheets.\"\r\n      }\r\n    },\r\n    {\r\n      \"@type\": \"Question\",\r\n      \"name\": \"Does the bulk tool support both ISBN-10 and ISBN-13?\",\r\n      \"acceptedAnswer\": {\r\n        \"@type\": \"Answer\",\r\n        \"text\": \"The tool is optimized for ISBN-13 but automatically converts ISBN-10 inputs into the modern 13-digit format before performing the checksum audit, ensuring your entire catalog is up to date.\"\r\n      }\r\n    },\r\n    {\r\n      \"@type\": \"Question\",\r\n      \"name\": \"Why does an ISBN show as 'Invalid' in the bulk audit?\",\r\n      \"acceptedAnswer\": {\r\n        \"@type\": \"Answer\",\r\n        \"text\": \"An ISBN is marked as invalid if it fails the weighted modulo-10 check digit calculation. This usually indicates a typo, a missing digit, or a counterfeit number that does not follow international GS1 standards.\"\r\n      }\r\n    }\r\n  ]\r\n}\r\n<\/script>\n<\/div><\/div><\/div>\n<\/div><\/div><\/div>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Bulk ISBN Validator tool is designed for publishers, libraries, and bookstores to verify large lists of ISBNs instantly. Other tools Bulk ISBN Validator\u2026<\/p>\n","protected":false},"author":1,"featured_media":73258,"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":"","_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":[15],"tags":[18,13,12,14],"class_list":["post-76013","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-isbn-tools","tag-beta","tag-fast","tag-free","tag-isbn"],"acf":[],"_links":{"self":[{"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/posts\/76013","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=76013"}],"version-history":[{"count":9,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/posts\/76013\/revisions"}],"predecessor-version":[{"id":77201,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/posts\/76013\/revisions\/77201"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/media?parent=76013"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/categories?post=76013"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aceworldpgs.com\/tools\/wp-json\/wp\/v2\/tags?post=76013"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}