{"id":195,"date":"2026-05-25T06:43:14","date_gmt":"2026-05-25T06:43:14","guid":{"rendered":"https:\/\/marketplace.dbaasltd.com\/?page_id=195"},"modified":"2026-05-30T07:31:48","modified_gmt":"2026-05-30T07:31:48","slug":"product-2","status":"publish","type":"page","link":"https:\/\/brithaventech.co.uk\/index.php\/product-2\/","title":{"rendered":"Product"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"195\" class=\"elementor elementor-195\" data-elementor-post-type=\"page\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-66846ea elementor-section-full_width elementor-section-stretched elementor-section-height-default elementor-section-height-default\" data-id=\"66846ea\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;stretch_section&quot;:&quot;section-stretched&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-812da57\" data-id=\"812da57\" data-element_type=\"column\" data-e-type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-f346861 elementor-widget elementor-widget-shortcode\" data-id=\"f346861\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Product Catalogue \u2014 BritHaven Tech<\/title>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Syne:wght@400;500;600;700;800&family=DM+Sans:ital,wght@0,300;0,400;0,500;0,600;1,400&family=Montserrat:wght@400;500;600;700;800;900&family=Poppins:wght@300;400;500;600;700&display=swap\" rel=\"stylesheet\">\n<style>\n*{box-sizing:border-box;margin:0;padding:0}\n:root{\n  --ink:#0A0F1E;--navy:#0C1A4B;--navy2:#112266;--blue:#1547E8;--blue2:#0F39C8;\n  --blue-lt:#EBF0FF;--sky:#E8F0FE;--white:#FFFFFF;--g50:#F7F8FC;--g100:#EDEEF4;\n  --g200:#D8DAE8;--g400:#9BA3BF;--g600:#5C6480;--g700:#3A405A;\n  --green:#0B7A45;--green-lt:#E6F5EE;--red:#C0272D;--red-lt:#FEF0F0;\n  --amber:#B45309;--amber-lt:#FFF8ED;--purple:#5B21B6;--purple-lt:#F3F0FF;\n  --teal:#0F766E;--teal-lt:#EDFAF8;\n  --shadow-xs:0 1px 2px rgba(10,15,30,.06);--shadow-sm:0 2px 8px rgba(10,15,30,.08);\n  --shadow-md:0 6px 20px rgba(10,15,30,.1);--shadow-lg:0 16px 48px rgba(10,15,30,.14);\n  --r4:4px;--r6:6px;--r8:8px;--r10:10px;--r12:12px;--r16:16px;\n}\nbody{font-family:'Poppins',sans-serif;background:var(--white);color:var(--ink);line-height:1.5;font-size:14px}\n\n\n\/* REQUESTED GLOBAL FONT UPDATE *\/\nh1,h2,h3,h4,h5,h6,\n.ph-title,\n.cs-name,\n.modal-title,\n.dr-title,\n.pc-name,\n.sb-title,\n.cat-strip-label,\n.ct-name{\n  font-family:'Montserrat',sans-serif!important;\n}\n\np,\n.ph-sub,\n.pc-desc,\n.pc-vendor,\n.pc-sub,\n.ct-count,\n.sb-item,\n.ct-result,\n.form-label,\n.form-input,\n.form-textarea,\nbutton,\nselect,\ninput,\ntextarea{\n  font-family:'Poppins',sans-serif!important;\n}\n\n\/* REQUESTED BANNER CENTER ALIGNMENT *\/\n.page-hero{\n  text-align:center;\n}\n\n.ph-inner{\n  display:flex;\n  flex-direction:column;\n  align-items:center;\n  justify-content:center;\n}\n\n.ph-sub{\n  margin-left:auto;\n  margin-right:auto;\n}\n\n.ph-stats{\n  justify-content:center;\n}\n\n\/* \u2500\u2500 TOPBAR \u2500\u2500 *\/\n.topbar{background:var(--navy);padding:7px 24px;display:flex;justify-content:space-between;align-items:center;font-size:11.5px;color:rgba(255,255,255,.65)}\n.tb-r{display:flex;gap:18px;align-items:center}\n.tb-badge{background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.15);border-radius:20px;padding:2px 10px;font-size:10.5px;font-weight:600;letter-spacing:.03em;color:rgba(255,255,255,.9)}\n\n\/* \u2500\u2500 HEADER \u2500\u2500 *\/\n.header{background:#fff;border-bottom:1px solid var(--g100);position:sticky;top:0;z-index:500;box-shadow:var(--shadow-xs)}\n.header-inner{max-width:1440px;margin:0 auto;padding:0 24px;height:64px;display:grid;grid-template-columns:auto 1fr auto;gap:24px;align-items:center}\n.logo{display:flex;align-items:center;gap:10px;text-decoration:none;cursor:pointer}\n.logo-mark{width:36px;height:36px;background:var(--navy);border-radius:var(--r8);display:flex;align-items:center;justify-content:center;font-family:'Syne',sans-serif;font-weight:800;font-size:12px;color:#fff;letter-spacing:-.02em}\n.logo-text{font-family:'Syne',sans-serif;font-weight:700;font-size:17px;color:var(--navy);letter-spacing:-.03em}\n.logo-text em{color:var(--blue);font-style:normal}\n.search-wrap{display:flex;background:var(--g50);border:1.5px solid var(--g200);border-radius:var(--r8);overflow:hidden;transition:border-color .2s,box-shadow .2s}\n.search-wrap:focus-within{border-color:var(--blue);box-shadow:0 0 0 3px rgba(21,71,232,.08);background:#fff}\n.search-input{flex:1;padding:10px 16px;border:none;background:transparent;font-family:'DM Sans',sans-serif;font-size:13px;color:var(--ink);outline:none}\n.search-input::placeholder{color:var(--g400)}\n.search-btn{padding:10px 20px;background:var(--blue);color:#fff;font-size:13px;font-weight:600;font-family:'DM Sans',sans-serif;border:none;cursor:pointer;transition:background .2s}\n.search-btn:hover{background:var(--blue2)}\n.header-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}\n.h-btn{display:flex;align-items:center;gap:6px;padding:8px 12px;border-radius:var(--r8);font-size:12.5px;font-weight:500;color:var(--g700);cursor:pointer;transition:all .15s;border:none;background:none;font-family:'DM Sans',sans-serif;white-space:nowrap}\n.h-btn:hover{background:var(--g50);color:var(--ink)}\n.cart-chip{display:flex;align-items:center;gap:7px;padding:8px 14px;background:var(--blue);color:#fff;border-radius:var(--r8);font-size:12.5px;font-weight:600;cursor:pointer;transition:all .2s;font-family:'DM Sans',sans-serif;border:none}\n.cart-chip:hover{background:var(--blue2);transform:translateY(-1px)}\n.cart-count{background:rgba(255,255,255,.25);border-radius:12px;padding:1px 7px;font-size:10px;font-weight:700}\n.h-contact{padding:8px 16px;background:var(--navy);color:#fff;border-radius:var(--r8);font-size:12.5px;font-weight:600;cursor:pointer;transition:background .2s;border:none;font-family:'DM Sans',sans-serif;white-space:nowrap}\n.h-contact:hover{background:var(--navy2)}\n\n\/* \u2500\u2500 NAV \u2500\u2500 *\/\n.nav{background:#fff;border-bottom:2px solid var(--navy);position:sticky;top:64px;z-index:400}\n.nav-inner{max-width:1440px;margin:0 auto;padding:0 24px;display:flex;align-items:center}\n.nav-lnk{padding:14px 16px;font-size:13px;font-weight:500;color:var(--g700);cursor:pointer;display:flex;align-items:center;gap:5px;border-bottom:3px solid transparent;margin-bottom:-2px;transition:all .15s;white-space:nowrap;font-family:'DM Sans',sans-serif}\n.nav-lnk:hover,.nav-lnk.active{color:var(--blue);border-bottom-color:var(--blue)}\n.nav-deals{color:#B45309!important;font-weight:700!important}\n\n\/* \u2500\u2500 PAGE HERO \u2500\u2500 *\/\n.page-hero{background:var(--navy);padding:44px 24px;position:relative;overflow:hidden}\n.page-hero::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse 70% 120% at 80% 50%,rgba(21,71,232,.35) 0%,transparent 70%);pointer-events:none}\n.ph-inner{max-width:1440px;margin:0 auto;position:relative;z-index:1}\n.ph-flag{display:inline-flex;align-items:center;gap:8px;padding:4px 14px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.15);border-radius:20px;font-size:11px;font-weight:600;color:rgba(255,255,255,.8);letter-spacing:.04em;text-transform:uppercase;margin-bottom:16px}\n.ph-title{font-family:'Syne',sans-serif;font-size:32px;font-weight:800;color:#fff;line-height:1.15;letter-spacing:-.03em;margin-bottom:10px}\n.ph-title em{color:#7CB9FF;font-style:normal}\n.ph-sub{font-size:14px;color:rgba(255,255,255,.65);max-width:580px;line-height:1.7;margin-bottom:24px}\n.ph-stats{display:flex;gap:32px;flex-wrap:wrap}\n.ph-stat-num{font-family:'Syne',sans-serif;font-size:24px;font-weight:800;color:#7CB9FF;letter-spacing:-.04em}\n.ph-stat-lbl{font-size:10px;color:rgba(255,255,255,.45);margin-top:2px}\n\n\/* \u2500\u2500 CATEGORY TILES \u2500\u2500 *\/\n.cat-strip{background:var(--g50);border-bottom:1px solid var(--g100);padding:20px 24px}\n.cat-strip-inner{max-width:1440px;margin:0 auto}\n.cat-strip-label{font-size:10.5px;font-weight:700;color:var(--blue);text-transform:uppercase;letter-spacing:.09em;margin-bottom:14px}\n.cat-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:8px}\n.cat-tile{background:#fff;border:1.5px solid var(--g100);border-radius:var(--r10);padding:14px 12px;text-align:center;cursor:pointer;transition:all .2s}\n.cat-tile:hover{border-color:var(--blue);box-shadow:var(--shadow-sm);transform:translateY(-2px)}\n.cat-tile.active{border-color:var(--blue);background:var(--blue-lt)}\n.cat-tile.active .ct-name{color:var(--blue)}\n.ct-icon{font-size:22px;margin-bottom:6px;line-height:1}\n.ct-name{font-size:11.5px;font-weight:600;color:var(--ink);margin-bottom:2px;line-height:1.3}\n.ct-count{font-size:10px;color:var(--g400)}\n\n\/* \u2500\u2500 MAIN LAYOUT \u2500\u2500 *\/\n.main{max-width:1440px;margin:0 auto;padding:28px 24px;display:grid;grid-template-columns:220px 1fr;gap:24px;align-items:start}\n\n\/* \u2500\u2500 SIDEBAR FILTERS \u2500\u2500 *\/\n.sidebar{position:sticky;top:140px}\n.sb-section{margin-bottom:20px}\n.sb-title{font-size:10.5px;font-weight:700;color:var(--navy);text-transform:uppercase;letter-spacing:.09em;margin-bottom:10px;padding-bottom:7px;border-bottom:2px solid var(--blue)}\n.sb-item{display:flex;align-items:center;justify-content:space-between;padding:5px 0;cursor:pointer;font-size:12.5px;color:var(--g700);transition:color .15s;user-select:none}\n.sb-item:hover{color:var(--blue)}\n.sb-item.active{color:var(--blue);font-weight:600}\n.sb-count{background:var(--g100);border-radius:10px;padding:1px 7px;font-size:10px;color:var(--g400);font-weight:600}\n.sb-item.active .sb-count{background:var(--blue-lt);color:var(--blue)}\n.sb-search{width:100%;padding:8px 10px;border:1.5px solid var(--g200);border-radius:var(--r6);font-size:12px;font-family:'DM Sans',sans-serif;color:var(--ink);outline:none;transition:border-color .2s;margin-bottom:10px}\n.sb-search:focus{border-color:var(--blue)}\n.clear-btn{width:100%;padding:8px;border:1.5px solid var(--g200);border-radius:var(--r6);background:#fff;font-size:12px;font-weight:600;color:var(--g600);cursor:pointer;font-family:'DM Sans',sans-serif;transition:all .15s}\n.clear-btn:hover{border-color:var(--blue);color:var(--blue)}\n\n\/* \u2500\u2500 CATALOGUE CONTENT \u2500\u2500 *\/\n.catalogue{min-width:0}\n.cat-toolbar{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;gap:12px;flex-wrap:wrap}\n.ct-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap}\n.ct-result{font-size:13px;color:var(--g600)}\n.ct-result strong{color:var(--ink);font-weight:700}\n.active-filters{display:flex;gap:6px;flex-wrap:wrap}\n.af-chip{display:flex;align-items:center;gap:5px;padding:4px 10px;background:var(--blue-lt);border:1px solid rgba(21,71,232,.2);border-radius:20px;font-size:11.5px;font-weight:600;color:var(--blue);cursor:pointer}\n.af-chip:hover{background:rgba(21,71,232,.15)}\n.af-x{font-size:13px;line-height:1;opacity:.7}\n.ct-right{display:flex;align-items:center;gap:8px}\n.view-btn{width:32px;height:32px;border:1.5px solid var(--g200);border-radius:var(--r6);background:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;transition:all .15s}\n.view-btn:hover,.view-btn.active{border-color:var(--blue);background:var(--blue-lt)}\n.sort-sel{padding:7px 10px;border:1.5px solid var(--g200);border-radius:var(--r6);font-size:12.5px;color:var(--ink);font-family:'DM Sans',sans-serif;outline:none;background:#fff;cursor:pointer}\n\n\/* \u2500\u2500 CATEGORY SECTION HEADER \u2500\u2500 *\/\n.cat-section{margin-bottom:32px}\n.cs-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;padding-bottom:10px;border-bottom:2px solid var(--g100)}\n.cs-left{display:flex;align-items:center;gap:10px}\n.cs-icon{font-size:20px}\n.cs-name{font-family:'Syne',sans-serif;font-size:17px;font-weight:700;color:var(--navy);letter-spacing:-.02em}\n.cs-count{font-size:11px;color:var(--g400);background:var(--g100);border-radius:10px;padding:2px 9px;font-weight:600}\n.cs-sub-tabs{display:flex;gap:5px;flex-wrap:wrap}\n.sub-tab{padding:4px 12px;border-radius:14px;font-size:11.5px;font-weight:500;color:var(--g600);background:var(--g50);border:1px solid var(--g100);cursor:pointer;transition:all .15s;font-family:'DM Sans',sans-serif}\n.sub-tab:hover{background:var(--g100);color:var(--ink)}\n.sub-tab.active{background:var(--navy);color:#fff;border-color:var(--navy)}\n\n\/* \u2500\u2500 PRODUCT GRID \u2500\u2500 *\/\n.prod-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}\n.prod-grid.list-view{grid-template-columns:1fr;gap:8px}\n\n\/* \u2500\u2500 PRODUCT CARD \u2500\u2500 *\/\n.pcard{background:#fff;border:1.5px solid var(--g100);border-radius:var(--r12);overflow:hidden;transition:all .22s;display:flex;flex-direction:column;cursor:pointer}\n.pcard:hover{box-shadow:var(--shadow-md);border-color:var(--g200);transform:translateY(-2px)}\n.pc-img{height:96px;background:var(--g50);display:flex;align-items:center;justify-content:center;font-size:32px;border-bottom:1px solid var(--g100);position:relative;overflow:hidden;flex-shrink:0}\n.pc-img::after{content:'';position:absolute;inset:0;background:linear-gradient(135deg,transparent 60%,rgba(21,71,232,.04))}\n.pc-badge{position:absolute;top:7px;left:7px;padding:2px 8px;border-radius:4px;font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:.05em}\n.pc-src{position:absolute;top:7px;right:7px;padding:2px 7px;border-radius:4px;font-size:8.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;background:rgba(10,15,30,.06);color:var(--g600)}\n.pc-body{padding:12px;flex:1;display:flex;flex-direction:column}\n.pc-vendor{font-size:9.5px;font-weight:700;color:var(--g400);text-transform:uppercase;letter-spacing:.06em;margin-bottom:3px}\n.pc-name{font-size:12.5px;font-weight:600;color:var(--ink);line-height:1.35;margin-bottom:5px}\n.pc-sub{font-size:10px;font-weight:600;color:var(--blue);background:var(--blue-lt);display:inline-block;padding:1px 7px;border-radius:4px;margin-bottom:6px}\n.pc-desc{font-size:11px;color:var(--g600);line-height:1.5;margin-bottom:10px;flex:1}\n.pc-btns{display:flex;gap:5px}\n.pc-add{flex:1;padding:8px;background:var(--blue);color:#fff;border:none;border-radius:var(--r6);font-size:11px;font-weight:600;cursor:pointer;transition:all .2s;font-family:'DM Sans',sans-serif}\n.pc-add:hover{background:var(--blue2)}\n.pc-add.added{background:var(--green)}\n.pc-quote{padding:8px 10px;background:#fff;color:var(--ink);border:1.5px solid var(--g200);border-radius:var(--r6);font-size:11px;font-weight:600;cursor:pointer;transition:all .2s;white-space:nowrap;font-family:'DM Sans',sans-serif}\n.pc-quote:hover{border-color:var(--blue);color:var(--blue)}\n\n\n\/* PRODUCT IMAGE SUPPORT - add image:'your-image-url.jpg' inside any product object *\/\n.pc-product-img{\n  width:72px;\n  height:72px;\n  object-fit:contain;\n  display:block;\n  position:relative;\n  z-index:1;\n}\n\n\/* LIST VIEW card *\/\n.list-view .pcard{flex-direction:row;height:auto}\n.list-view .pc-img{width:80px;height:auto;min-height:80px;flex-shrink:0;border-bottom:none;border-right:1px solid var(--g100);font-size:26px}\n.list-view .pc-body{flex-direction:row;align-items:center;gap:12px;padding:12px 14px}\n.list-view .pc-main{flex:1;min-width:0}\n.list-view .pc-desc{display:none}\n.list-view .pc-btns{flex-shrink:0;gap:5px}\n.list-view .pc-sub{margin-bottom:0}\n\n\/* \u2500\u2500 BADGE COLOURS \u2500\u2500 *\/\n.b-sec{background:var(--red-lt);color:var(--red)}\n.b-prod{background:var(--blue-lt);color:var(--blue)}\n.b-itops{background:var(--amber-lt);color:var(--amber)}\n.b-cont{background:var(--purple-lt);color:var(--purple)}\n.b-comm{background:var(--teal-lt);color:var(--teal)}\n.b-infra{background:var(--green-lt);color:var(--green)}\n.b-ai{background:#F3F0FF;color:#5B21B6}\n.b-hr{background:#FFF8ED;color:#92400E}\n.b-net{background:#EDFAF8;color:#0F766E}\n\n\/* \u2500\u2500 EMPTY STATE \u2500\u2500 *\/\n.empty{text-align:center;padding:60px 20px;color:var(--g400)}\n.empty-icon{font-size:40px;margin-bottom:12px}\n.empty-title{font-size:15px;font-weight:600;color:var(--g600);margin-bottom:6px}\n.empty-sub{font-size:13px}\n\n\/* \u2500\u2500 QUOTE MODAL \u2500\u2500 *\/\n.modal-overlay{position:fixed;inset:0;background:rgba(10,15,30,.55);z-index:900;display:none;align-items:center;justify-content:center;padding:20px}\n.modal-overlay.open{display:flex}\n.modal{background:#fff;border-radius:var(--r16);width:100%;max-width:580px;max-height:90vh;overflow-y:auto;box-shadow:var(--shadow-lg)}\n.modal-head{padding:18px 22px;border-bottom:1px solid var(--g100);display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;background:#fff;z-index:10}\n.modal-title{font-family:'Syne',sans-serif;font-size:16px;font-weight:700;color:var(--navy)}\n.modal-close{width:30px;height:30px;border:none;background:var(--g100);border-radius:50%;cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center;transition:all .15s;font-family:'DM Sans',sans-serif}\n.modal-close:hover{background:var(--g200)}\n.modal-body{padding:18px 22px}\n.modal-body p{font-size:13px;color:var(--g600);margin-bottom:16px;line-height:1.6}\n.form-row{margin-bottom:13px}\n.form-row-2{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:13px}\n.form-label{display:block;font-size:11.5px;font-weight:600;color:var(--g700);margin-bottom:4px}\n.form-input,.form-textarea{width:100%;padding:9px 11px;border:1.5px solid var(--g200);border-radius:var(--r6);font-size:12.5px;color:var(--ink);font-family:'DM Sans',sans-serif;outline:none;transition:border-color .2s}\n.form-input:focus,.form-textarea:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(21,71,232,.08)}\n.form-textarea{resize:vertical;min-height:80px}\n.modal-foot{padding:12px 22px;border-top:1px solid var(--g100);display:flex;justify-content:flex-end;gap:8px;position:sticky;bottom:0;background:#fff}\n.modal-cancel{padding:9px 16px;border:1.5px solid var(--g200);background:#fff;color:var(--g700);border-radius:var(--r6);font-size:12.5px;font-weight:600;cursor:pointer;font-family:'DM Sans',sans-serif}\n.modal-submit{padding:9px 20px;background:var(--blue);color:#fff;border:none;border-radius:var(--r6);font-size:12.5px;font-weight:600;cursor:pointer;font-family:'DM Sans',sans-serif;transition:background .2s}\n.modal-submit:hover{background:var(--blue2)}\n\n\/* \u2500\u2500 CART DRAWER \u2500\u2500 *\/\n.overlay{position:fixed;inset:0;background:rgba(10,15,30,.4);z-index:700;display:none}\n.overlay.open{display:block}\n.drawer{position:fixed;top:0;right:-440px;width:420px;height:100vh;background:#fff;z-index:800;box-shadow:var(--shadow-lg);transition:right .3s;display:flex;flex-direction:column}\n.drawer.open{right:0}\n.dr-head{padding:16px 20px;border-bottom:1px solid var(--g100);display:flex;align-items:center;justify-content:space-between}\n.dr-title{font-family:'Syne',sans-serif;font-size:16px;font-weight:700;color:var(--navy)}\n.dr-close{width:30px;height:30px;border:none;background:var(--g100);border-radius:50%;cursor:pointer;font-size:13px;display:flex;align-items:center;justify-content:center}\n.dr-body{flex:1;overflow-y:auto;padding:14px 20px}\n.dr-empty{text-align:center;padding:36px 16px;color:var(--g400)}\n.dr-empty-icon{font-size:32px;margin-bottom:8px}\n.dr-empty-txt{font-size:12.5px;line-height:1.65}\n.dr-item{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--g100)}\n.dr-item-icon{font-size:20px;width:36px;height:36px;background:var(--g50);border-radius:var(--r6);display:flex;align-items:center;justify-content:center;flex-shrink:0}\n.dr-item-info{flex:1;min-width:0}\n.dr-item-name{font-size:12px;font-weight:600;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.dr-item-vendor{font-size:10.5px;color:var(--g400)}\n.dr-item-remove{font-size:11px;color:var(--red);cursor:pointer;flex-shrink:0;font-weight:600}\n.dr-foot{padding:14px 20px;border-top:1px solid var(--g100);display:flex;flex-direction:column;gap:7px}\n.dr-summary{font-size:12px;color:var(--g700);text-align:center;padding:6px 0}\n.dr-checkout{padding:12px;background:var(--blue);color:#fff;border:none;border-radius:var(--r8);font-size:13px;font-weight:600;cursor:pointer;font-family:'DM Sans',sans-serif}\n.dr-checkout:hover{background:var(--blue2)}\n.dr-req-quote{padding:11px;background:#fff;color:var(--ink);border:1.5px solid var(--g200);border-radius:var(--r8);font-size:13px;font-weight:600;cursor:pointer;font-family:'DM Sans',sans-serif;transition:all .2s}\n.dr-req-quote:hover{border-color:var(--blue);color:var(--blue)}\n\n\/* \u2500\u2500 TOAST \u2500\u2500 *\/\n.toast{position:fixed;bottom:24px;right:24px;padding:11px 16px;background:var(--ink);color:#fff;border-radius:var(--r10);font-size:12.5px;font-weight:500;z-index:999;box-shadow:var(--shadow-lg);transform:translateY(16px);opacity:0;transition:all .3s;pointer-events:none;max-width:300px}\n.toast.show{transform:translateY(0);opacity:1}\n.toast.success{background:var(--green)}\n\n\/* \u2500\u2500 FOOTER \u2500\u2500 *\/\n.footer{background:var(--navy);padding:44px 24px 0;margin-top:48px}\n.footer-inner{max-width:1440px;margin:0 auto}\n.footer-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr 1fr;gap:28px;margin-bottom:32px}\n.fg-brand{font-size:12px;color:rgba(255,255,255,.5);line-height:1.7;margin-bottom:12px}\n.fg-contact{font-size:11.5px;color:rgba(255,255,255,.4);line-height:1.9}\n.fc-ttl{font-size:10.5px;font-weight:700;color:rgba(255,255,255,.45);text-transform:uppercase;letter-spacing:.09em;margin-bottom:12px}\n.fc-lnk{display:block;font-size:12.5px;color:rgba(255,255,255,.6);cursor:pointer;margin-bottom:6px;transition:color .15s}\n.fc-lnk:hover{color:#fff}\n.footer-bottom{border-top:1px solid rgba(255,255,255,.08);padding:18px 0;display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}\n.fb-left{font-size:11.5px;color:rgba(255,255,255,.35)}\n.fb-certs{display:flex;gap:6px;flex-wrap:wrap}\n.fb-cert{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);border-radius:4px;padding:2px 8px;font-size:10px;font-weight:600;color:rgba(255,255,255,.5)}\n.fb-links{display:flex;gap:14px}\n.fb-links a{font-size:11.5px;color:rgba(255,255,255,.35);cursor:pointer;text-decoration:none}\n.fb-links a:hover{color:rgba(255,255,255,.7)}\n<\/style>\n<\/head>\n<body>\n\n\n\n\n\n\n\n<!-- PAGE HERO -->\n<section class=\"page-hero\">\n  <div class=\"ph-inner\">\n    <div class=\"ph-flag\">\ud83d\udce6 Full Product Catalogue<\/div>\n    <h1 class=\"ph-title\">Browse <em>218 Products<\/em> Across 9 Categories<\/h1>\n    <p class=\"ph-sub\">Software licences, cloud subscriptions, cybersecurity, backup, communications and infrastructure solutions \u2014 all from an authorised UK reseller.<\/p>\n    <div class=\"ph-stats\">\n      <div><div class=\"ph-stat-num\">218<\/div><div class=\"ph-stat-lbl\">Products Listed<\/div><\/div>\n      <div><div class=\"ph-stat-num\">67<\/div><div class=\"ph-stat-lbl\">Vendor Partners<\/div><\/div>\n      <div><div class=\"ph-stat-num\">9<\/div><div class=\"ph-stat-lbl\">Categories<\/div><\/div>\n      <div><div class=\"ph-stat-num\">4hr<\/div><div class=\"ph-stat-lbl\">Quote Response<\/div><\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<!-- CATEGORY TILES -->\n<div class=\"cat-strip\">\n  <div class=\"cat-strip-inner\">\n    <div class=\"cat-strip-label\">Browse by Category<\/div>\n    <div class=\"cat-tiles\" id=\"catTiles\">\n      <div class=\"cat-tile active\" data-cat=\"all\" onclick=\"selectCat('all',this)\">\n        <div class=\"ct-icon\">\u26a1<\/div>\n        <div class=\"ct-name\">All Products<\/div>\n        <div class=\"ct-count\" id=\"cnt-all\">218 products<\/div>\n      <\/div>\n      <div class=\"cat-tile\" data-cat=\"Security\" onclick=\"selectCat('Security',this)\">\n        <div class=\"ct-icon\">\ud83d\udee1\ufe0f<\/div>\n        <div class=\"ct-name\">Security<\/div>\n        <div class=\"ct-count\" id=\"cnt-Security\">97 products<\/div>\n      <\/div>\n      <div class=\"cat-tile\" data-cat=\"Continuity\" onclick=\"selectCat('Continuity',this)\">\n        <div class=\"ct-icon\">\ud83d\udcbe<\/div>\n        <div class=\"ct-name\">Backup &amp; Continuity<\/div>\n        <div class=\"ct-count\" id=\"cnt-Continuity\">36 products<\/div>\n      <\/div>\n      <div class=\"cat-tile\" data-cat=\"Productivity\" onclick=\"selectCat('Productivity',this)\">\n        <div class=\"ct-icon\">\ud83c\udfa8<\/div>\n        <div class=\"ct-name\">Productivity<\/div>\n        <div class=\"ct-count\" id=\"cnt-Productivity\">29 products<\/div>\n      <\/div>\n      <div class=\"cat-tile\" data-cat=\"IT Operations\" onclick=\"selectCat('IT Operations',this)\">\n        <div class=\"ct-icon\">\ud83d\udd27<\/div>\n        <div class=\"ct-name\">IT Operations<\/div>\n        <div class=\"ct-count\" id=\"cnt-IT Operations\">25 products<\/div>\n      <\/div>\n      <div class=\"cat-tile\" data-cat=\"Communications\" onclick=\"selectCat('Communications',this)\">\n        <div class=\"ct-icon\">\ud83d\udcde<\/div>\n        <div class=\"ct-name\">Communications<\/div>\n        <div class=\"ct-count\" id=\"cnt-Communications\">12 products<\/div>\n      <\/div>\n      <div class=\"cat-tile\" data-cat=\"Infrastructure\" onclick=\"selectCat('Infrastructure',this)\">\n        <div class=\"ct-icon\">\ud83d\udda5\ufe0f<\/div>\n        <div class=\"ct-name\">Infrastructure<\/div>\n        <div class=\"ct-count\" id=\"cnt-Infrastructure\">12 products<\/div>\n      <\/div>\n      <div class=\"cat-tile\" data-cat=\"AI & Analytics\" onclick=\"selectCat('AI & Analytics',this)\">\n        <div class=\"ct-icon\">\ud83e\udd16<\/div>\n        <div class=\"ct-name\">AI &amp; Analytics<\/div>\n        <div class=\"ct-count\" id=\"cnt-AI & Analytics\">3 products<\/div>\n      <\/div>\n      <div class=\"cat-tile\" data-cat=\"Human Resources\" onclick=\"selectCat('Human Resources',this)\">\n        <div class=\"ct-icon\">\ud83d\udc65<\/div>\n        <div class=\"ct-name\">Human Resources<\/div>\n        <div class=\"ct-count\" id=\"cnt-Human Resources\">2 products<\/div>\n      <\/div>\n      <div class=\"cat-tile\" data-cat=\"Network\" onclick=\"selectCat('Network',this)\">\n        <div class=\"ct-icon\">\ud83c\udf10<\/div>\n        <div class=\"ct-name\">Network<\/div>\n        <div class=\"ct-count\" id=\"cnt-Network\">1 product<\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- MAIN: SIDEBAR + CATALOGUE -->\n<div class=\"main\">\n  <!-- SIDEBAR -->\n  <aside class=\"sidebar\">\n    <div class=\"sb-section\">\n      <div class=\"sb-title\">Vendor<\/div>\n      <input class=\"sb-search\" id=\"vendorSearch\" placeholder=\"Search vendors\u2026\" oninput=\"renderVendorList(this.value)\">\n      <div id=\"vendorList\"><\/div>\n    <\/div>\n    <div class=\"sb-section\">\n      <div class=\"sb-title\">Sub-Category<\/div>\n      <div id=\"subList\"><\/div>\n    <\/div>\n    <div class=\"sb-section\">\n      <div class=\"sb-title\">Source<\/div>\n      <div id=\"sourceList\"><\/div>\n    <\/div>\n    <button class=\"clear-btn\" onclick=\"clearAllFilters()\">\u2715 Clear All Filters<\/button>\n  <\/aside>\n\n  <!-- CATALOGUE -->\n  <div class=\"catalogue\">\n    <div class=\"cat-toolbar\">\n      <div class=\"ct-left\">\n        <span class=\"ct-result\" id=\"resultCount\"><strong>218<\/strong> products<\/span>\n        <div class=\"active-filters\" id=\"activeFilters\"><\/div>\n      <\/div>\n      <div class=\"ct-right\">\n        <button class=\"view-btn active\" id=\"gridBtn\" onclick=\"setView('grid')\" title=\"Grid view\">\u229e<\/button>\n        <button class=\"view-btn\" id=\"listBtn\" onclick=\"setView('list')\" title=\"List view\">\u2630<\/button>\n        <select class=\"sort-sel\" id=\"sortSel\" onchange=\"render()\">\n          <option value=\"az\">A\u2013Z by Product<\/option>\n          <option value=\"za\">Z\u2013A by Product<\/option>\n          <option value=\"vendor\">By Vendor<\/option>\n          <option value=\"cat\">By Category<\/option>\n        <\/select>\n      <\/div>\n    <\/div>\n    <div id=\"catalogueBody\"><\/div>\n  <\/div>\n<\/div>\n\n\n\n<!-- DRAWER -->\n<div class=\"overlay\" id=\"overlay\" onclick=\"toggleDrawer()\"><\/div>\n<div class=\"drawer\" id=\"drawer\">\n  <div class=\"dr-head\">\n    <div class=\"dr-title\">\ud83d\uded2 Basket<\/div>\n    <button class=\"dr-close\" onclick=\"toggleDrawer()\">\u2715<\/button>\n  <\/div>\n  <div class=\"dr-body\" id=\"drawerBody\">\n    <div class=\"dr-empty\"><div class=\"dr-empty-icon\">\ud83d\uded2<\/div><div class=\"dr-empty-txt\">Your basket is empty.<br>Add products to get started.<\/div><\/div>\n  <\/div>\n  <div class=\"dr-foot\" id=\"drawerFoot\" style=\"display:none\">\n    <div class=\"dr-summary\" id=\"drawerSummary\"><\/div>\n    <button class=\"dr-checkout\">Proceed to Checkout<\/button>\n    <button class=\"dr-req-quote\" onclick=\"openQuote(null)\">\ud83d\udccb Request a Quote for All Items<\/button>\n  <\/div>\n<\/div>\n\n<!-- QUOTE MODAL -->\n<div class=\"modal-overlay\" id=\"quoteModal\">\n  <div class=\"modal\">\n    <div class=\"modal-head\">\n      <div class=\"modal-title\">\ud83d\udccb Request a Quote<\/div>\n      <button class=\"modal-close\" onclick=\"closeQuote()\">\u2715<\/button>\n    <\/div>\n    <div class=\"modal-body\">\n      <p>Our UK sales team will respond within 4 business hours with competitive pricing.<\/p>\n      <div class=\"form-row-2\">\n        <div><label class=\"form-label\">First Name *<\/label><input class=\"form-input\" placeholder=\"Jane\"><\/div>\n        <div><label class=\"form-label\">Last Name *<\/label><input class=\"form-input\" placeholder=\"Smith\"><\/div>\n      <\/div>\n      <div class=\"form-row-2\">\n        <div><label class=\"form-label\">Work Email *<\/label><input class=\"form-input\" type=\"email\" placeholder=\"jane@company.co.uk\"><\/div>\n        <div><label class=\"form-label\">Phone<\/label><input class=\"form-input\" placeholder=\"0800 000 0000\"><\/div>\n      <\/div>\n      <div class=\"form-row\"><label class=\"form-label\">Company *<\/label><input class=\"form-input\" placeholder=\"Company Ltd\"><\/div>\n      <div class=\"form-row\"><label class=\"form-label\">Product(s) of Interest<\/label><textarea class=\"form-textarea\" id=\"quoteProduct\" style=\"min-height:90px\"><\/textarea><\/div>\n      <div class=\"form-row\"><label class=\"form-label\">Number of Users<\/label><input class=\"form-input\" placeholder=\"e.g. 50 users\"><\/div>\n      <div class=\"form-row\" style=\"margin-bottom:0\"><label class=\"form-label\">Additional Requirements<\/label><textarea class=\"form-textarea\" placeholder=\"Any specific requirements or questions\u2026\"><\/textarea><\/div>\n    <\/div>\n    <div class=\"modal-foot\">\n      <button class=\"modal-cancel\" onclick=\"closeQuote()\">Cancel<\/button>\n      <button class=\"modal-submit\" onclick=\"submitQuote()\">Submit Quote Request \u2192<\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<script>\n\/\/ \u2500\u2500 DATA \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst PRODUCTS = [{\"sheet\":\"SaaS\",\"vendor\":\"TalentLMS\",\"product\":\"TalentLMS\",\"category\":\"Human Resources\",\"sub\":\"LMS\",\"desc\":\"Cloud LMS for employee training and onboarding\"},{\"sheet\":\"SaaS\",\"vendor\":\"Zensai\",\"product\":\"Zensai Human Success Platform\",\"category\":\"Human Resources\",\"sub\":\"LMS\",\"desc\":\"LMS, performance management and employee engagement in Microsoft 365\"},{\"sheet\":\"SaaS\",\"vendor\":\"ConnectWise\",\"product\":\"ConnectWise CPQ (Sell)\",\"category\":\"IT Operations\",\"sub\":\"Agreements\",\"desc\":\"Quoting, proposal and agreement automation\"},{\"sheet\":\"SaaS\",\"vendor\":\"Hudu\",\"product\":\"Hudu Documentation\",\"category\":\"IT Operations\",\"sub\":\"Documentation\",\"desc\":\"IT documentation and password management for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"IT Glue\",\"product\":\"IT Glue Documentation Platform\",\"category\":\"IT Operations\",\"sub\":\"Documentation\",\"desc\":\"IT documentation, password management and SOPs for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"IT Glue\",\"product\":\"IT Glue + MyGlue\",\"category\":\"IT Operations\",\"sub\":\"Documentation\",\"desc\":\"Client-facing documentation portal\"},{\"sheet\":\"SaaS\",\"vendor\":\"Kaseya\",\"product\":\"Kaseya IT Glue\",\"category\":\"IT Operations\",\"sub\":\"Documentation\",\"desc\":\"IT documentation, password management and runbooks\"},{\"sheet\":\"SaaS\",\"vendor\":\"NinjaRMM\",\"product\":\"NinjaOne Documentation\",\"category\":\"IT Operations\",\"sub\":\"Documentation\",\"desc\":\"IT documentation and runbook management\"},{\"sheet\":\"SaaS\",\"vendor\":\"Scribe\",\"product\":\"Scribe Process Documentation\",\"category\":\"IT Operations\",\"sub\":\"Documentation\",\"desc\":\"Auto-generates step-by-step guides from screen recordings\"},{\"sheet\":\"SaaS\",\"vendor\":\"ConnectWise\",\"product\":\"ConnectWise Manage (PSA)\",\"category\":\"IT Operations\",\"sub\":\"Help Desk\",\"desc\":\"PSA ticketing, billing, time tracking and project management\"},{\"sheet\":\"SaaS\",\"vendor\":\"Datto\",\"product\":\"Datto Autotask PSA\",\"category\":\"IT Operations\",\"sub\":\"Help Desk\",\"desc\":\"Professional services automation and ticketing for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Kaseya\",\"product\":\"Kaseya BMS (PSA)\",\"category\":\"IT Operations\",\"sub\":\"Help Desk\",\"desc\":\"PSA for ticketing, time and billing\"},{\"sheet\":\"SaaS\",\"vendor\":\"Pulseway\",\"product\":\"Pulseway PSA\",\"category\":\"IT Operations\",\"sub\":\"Help Desk\",\"desc\":\"Ticketing, time tracking and billing for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"SuperOps\",\"product\":\"SuperOps PSA\",\"category\":\"IT Operations\",\"sub\":\"Help Desk\",\"desc\":\"Ticketing, client management and billing\"},{\"sheet\":\"SaaS\",\"vendor\":\"NinjaRMM\",\"product\":\"NinjaOne MDM\",\"category\":\"IT Operations\",\"sub\":\"MDM\",\"desc\":\"Mobile device management for iOS and Android\"},{\"sheet\":\"SaaS\",\"vendor\":\"Atera\",\"product\":\"Atera All-in-One MSP Platform\",\"category\":\"IT Operations\",\"sub\":\"RMM\",\"desc\":\"Unified RMM, PSA, remote access and helpdesk \u2014 per technician pricing\"},{\"sheet\":\"SaaS\",\"vendor\":\"ConnectWise\",\"product\":\"ConnectWise Automate (RMM)\",\"category\":\"IT Operations\",\"sub\":\"RMM\",\"desc\":\"Remote monitoring, patch management and automation\"},{\"sheet\":\"SaaS\",\"vendor\":\"Datto\",\"product\":\"Datto RMM\",\"category\":\"IT Operations\",\"sub\":\"RMM\",\"desc\":\"Remote monitoring and management for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Kaseya\",\"product\":\"Kaseya VSA (RMM)\",\"category\":\"IT Operations\",\"sub\":\"RMM\",\"desc\":\"Endpoint and network management with automation\"},{\"sheet\":\"SaaS\",\"vendor\":\"N-able\",\"product\":\"N-able N-sight RMM\",\"category\":\"IT Operations\",\"sub\":\"RMM\",\"desc\":\"Cloud RMM with patch management and remote access\"},{\"sheet\":\"SaaS\",\"vendor\":\"NinjaRMM\",\"product\":\"NinjaOne RMM\",\"category\":\"IT Operations\",\"sub\":\"RMM\",\"desc\":\"Unified RMM with monitoring, patching and remote access\"},{\"sheet\":\"SaaS\",\"vendor\":\"Pulseway\",\"product\":\"Pulseway RMM\",\"category\":\"IT Operations\",\"sub\":\"RMM\",\"desc\":\"Mobile-first RMM with real-time alerts and remote control\"},{\"sheet\":\"SaaS\",\"vendor\":\"SuperOps\",\"product\":\"SuperOps RMM\",\"category\":\"IT Operations\",\"sub\":\"RMM\",\"desc\":\"AI-native unified RMM and PSA platform for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Syncro\",\"product\":\"Syncro RMM + PSA\",\"category\":\"IT Operations\",\"sub\":\"RMM\",\"desc\":\"Combined RMM and PSA with flat per-tech pricing\"},{\"sheet\":\"SaaS\",\"vendor\":\"Augmentt\",\"product\":\"Augmentt Engage\",\"category\":\"IT Operations\",\"sub\":\"SaaS Management\",\"desc\":\"SaaS discovery, usage analytics and optimisation\"},{\"sheet\":\"SaaS\",\"vendor\":\"Gradient MSP\",\"product\":\"Gradient Synthesize\",\"category\":\"IT Operations\",\"sub\":\"SaaS Management\",\"desc\":\"Vendor bill reconciliation and margin management for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Rewst\",\"product\":\"Rewst Automation Platform\",\"category\":\"IT Operations\",\"sub\":\"Workflow Automation\",\"desc\":\"Low-code workflow automation and orchestration for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Adobe\",\"product\":\"Adobe Acrobat Standard \/ Pro\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"PDF creation, editing, e-signing and form creation\"},{\"sheet\":\"SaaS\",\"vendor\":\"Adobe\",\"product\":\"Adobe Creative Cloud All Apps\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Full creative suite: Photoshop, Illustrator, Premiere Pro, InDesign\"},{\"sheet\":\"SaaS\",\"vendor\":\"Adobe\",\"product\":\"Adobe Creative Cloud Single App\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Individual apps: Photoshop, Illustrator, Premiere Pro, InDesign etc\"},{\"sheet\":\"SaaS\",\"vendor\":\"Adobe\",\"product\":\"Adobe Express\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Simple design and content creation for non-designers\"},{\"sheet\":\"SaaS\",\"vendor\":\"Adobe\",\"product\":\"Adobe Captivate\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"eLearning and instructional design authoring tool\"},{\"sheet\":\"SaaS\",\"vendor\":\"Adobe\",\"product\":\"Adobe Substance 3D\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"3D design, texturing and rendering tools\"},{\"sheet\":\"SaaS\",\"vendor\":\"Gaviti\",\"product\":\"Gaviti AR Automation\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Accounts receivable automation and collections management\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft 365 Business Basic \/ Standard \/ Premium\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Core Microsoft 365 suite with Exchange, Teams, SharePoint, OneDrive\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft 365 Apps for Business \/ Enterprise\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Desktop Office apps: Word, Excel, PowerPoint, Outlook, Access\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft 365 E3 \/ E5\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Enterprise M365 with advanced compliance, security and analytics\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft 365 Copilot\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"AI productivity add-on: AI in Word, Excel, Teams, Outlook, PowerPoint\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft 365 F1 \/ F3 (Frontline)\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Firstline worker licences for shift-based teams\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Teams Essentials\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Standalone Teams for meetings and chat\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Teams Rooms Pro \/ Basic\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Meeting room device licences\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Teams Phone\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Cloud PBX and calling plans for Teams\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Visio Plan 1 \/ Plan 2\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Diagramming and flowchart tool, web and desktop\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Project Plan 1 \/ 3 \/ 5\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Project management, Gantt, resource and portfolio management\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Power BI Pro \/ Premium\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Business intelligence, dashboards and reporting\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Power Apps Premium\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Low-code custom business app builder\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Power Automate Premium\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Workflow automation with RPA capability\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Dynamics 365 Customer Service\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"CRM and customer support case management platform\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Dynamics 365 Business Central\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"ERP for SMBs: finance, supply chain, operations\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Dynamics 365 Sales\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"CRM sales automation and pipeline management\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Windows 365 Cloud PC\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"Personalised cloud-based Windows PC streamed to any device\"},{\"sheet\":\"SaaS\",\"vendor\":\"Nitro\",\"product\":\"Nitro Productivity Suite\",\"category\":\"Productivity\",\"sub\":\"Business Applications\",\"desc\":\"PDF editing, e-signing and document workflows\"},{\"sheet\":\"SaaS\",\"vendor\":\"Adobe\",\"product\":\"Adobe Sign (Acrobat Sign)\",\"category\":\"Productivity\",\"sub\":\"eSignature\",\"desc\":\"Electronic signature and document workflow automation\"},{\"sheet\":\"SaaS\",\"vendor\":\"DocuSign\",\"product\":\"DocuSign eSignature Business Pro \/ Enterprise\",\"category\":\"Productivity\",\"sub\":\"eSignature\",\"desc\":\"Electronic signature and agreement lifecycle management\"},{\"sheet\":\"SaaS\",\"vendor\":\"DocuSign\",\"product\":\"DocuSign CLM\",\"category\":\"Productivity\",\"sub\":\"eSignature\",\"desc\":\"Contract lifecycle management with workflow automation\"},{\"sheet\":\"SaaS\",\"vendor\":\"Nitro\",\"product\":\"Nitro Sign\",\"category\":\"Productivity\",\"sub\":\"eSignature\",\"desc\":\"Electronic signature with document management\"},{\"sheet\":\"SaaS\",\"vendor\":\"Barracuda\",\"product\":\"Barracuda WAF-as-a-Service\",\"category\":\"Security\",\"sub\":\"Application Security\",\"desc\":\"Web application firewall for cloud-hosted apps\"},{\"sheet\":\"SaaS\",\"vendor\":\"Egnyte\",\"product\":\"Egnyte Content Intelligence\",\"category\":\"Security\",\"sub\":\"DLP\",\"desc\":\"Data classification and governance for sensitive files\"},{\"sheet\":\"SaaS\",\"vendor\":\"Webroot\",\"product\":\"Webroot DNS Protection\",\"category\":\"Security\",\"sub\":\"DNS \/ Web Security\",\"desc\":\"DNS-layer filtering to block malicious domains\"},{\"sheet\":\"SaaS\",\"vendor\":\"Guardz\",\"product\":\"Guardz Dark Web Monitoring\",\"category\":\"Security\",\"sub\":\"Dark Web Monitoring\",\"desc\":\"Continuous dark web scanning for exposed credentials\"},{\"sheet\":\"SaaS\",\"vendor\":\"Kaseya\",\"product\":\"Kaseya ID Agent (Dark Web ID)\",\"category\":\"Security\",\"sub\":\"Dark Web Monitoring\",\"desc\":\"Dark web credential monitoring and alerting\"},{\"sheet\":\"SaaS\",\"vendor\":\"Acronis\",\"product\":\"Acronis Cyber EDR\",\"category\":\"Security\",\"sub\":\"EDR\",\"desc\":\"Endpoint detection and response with AI-based threat analysis\"},{\"sheet\":\"SaaS\",\"vendor\":\"Bitdefender\",\"product\":\"Bitdefender GravityZone Elite \/ Ultra\",\"category\":\"Security\",\"sub\":\"EDR\",\"desc\":\"EDR and full XDR with human risk analytics\"},{\"sheet\":\"SaaS\",\"vendor\":\"ESET\",\"product\":\"ESET PROTECT Elite (XDR)\",\"category\":\"Security\",\"sub\":\"EDR\",\"desc\":\"Full XDR with cloud sandbox and advanced threat intelligence\"},{\"sheet\":\"SaaS\",\"vendor\":\"Malwarebytes\",\"product\":\"Malwarebytes ThreatDown Elite\",\"category\":\"Security\",\"sub\":\"EDR\",\"desc\":\"Advanced with EDR and incident response\"},{\"sheet\":\"SaaS\",\"vendor\":\"Malwarebytes\",\"product\":\"Malwarebytes ThreatDown Ultimate\",\"category\":\"Security\",\"sub\":\"EDR\",\"desc\":\"Full-featured with MDR service\"},{\"sheet\":\"SaaS\",\"vendor\":\"N-able\",\"product\":\"N-able EDR\",\"category\":\"Security\",\"sub\":\"EDR\",\"desc\":\"Endpoint detection and response powered by SentinelOne\"},{\"sheet\":\"SaaS\",\"vendor\":\"CrowdStrike\",\"product\":\"CrowdStrike Falcon Go\",\"category\":\"Security\",\"sub\":\"EDR \/ XDR\",\"desc\":\"Entry-level next-gen AV and device control\"},{\"sheet\":\"SaaS\",\"vendor\":\"CrowdStrike\",\"product\":\"CrowdStrike Falcon Pro\",\"category\":\"Security\",\"sub\":\"EDR \/ XDR\",\"desc\":\"Next-gen AV with threat intelligence\"},{\"sheet\":\"SaaS\",\"vendor\":\"CrowdStrike\",\"product\":\"CrowdStrike Falcon Enterprise\",\"category\":\"Security\",\"sub\":\"EDR \/ XDR\",\"desc\":\"Full EDR, threat hunting and custom IOA rules\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Defender for Business \/ Endpoint\",\"category\":\"Security\",\"sub\":\"EDR \/ XDR\",\"desc\":\"SMB and enterprise endpoint protection and EDR\"},{\"sheet\":\"SaaS\",\"vendor\":\"SentinelOne\",\"product\":\"SentinelOne Singularity Core\",\"category\":\"Security\",\"sub\":\"EDR \/ XDR\",\"desc\":\"AI-powered EDR with automated threat detection and response\"},{\"sheet\":\"SaaS\",\"vendor\":\"SentinelOne\",\"product\":\"SentinelOne Singularity Control\",\"category\":\"Security\",\"sub\":\"EDR \/ XDR\",\"desc\":\"EDR plus device and firewall control\"},{\"sheet\":\"SaaS\",\"vendor\":\"SentinelOne\",\"product\":\"SentinelOne Singularity Complete\",\"category\":\"Security\",\"sub\":\"EDR \/ XDR\",\"desc\":\"Full XDR with deep visibility, threat hunting and identity\"},{\"sheet\":\"SaaS\",\"vendor\":\"Sophos\",\"product\":\"Sophos Intercept X with XDR\",\"category\":\"Security\",\"sub\":\"EDR \/ XDR\",\"desc\":\"Extended detection and response across endpoints and servers\"},{\"sheet\":\"SaaS\",\"vendor\":\"Barracuda\",\"product\":\"Barracuda Email Security Gateway\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Inbound\/outbound email filtering, anti-spam and malware\"},{\"sheet\":\"SaaS\",\"vendor\":\"Barracuda\",\"product\":\"Barracuda Email Protection (M365)\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Cloud email security, impersonation protection and archiving\"},{\"sheet\":\"SaaS\",\"vendor\":\"Cisco\",\"product\":\"Cisco Secure Email\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Email gateway with advanced threat protection\"},{\"sheet\":\"SaaS\",\"vendor\":\"Egress\",\"product\":\"Egress Protect\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Encrypted email and secure file sharing\"},{\"sheet\":\"SaaS\",\"vendor\":\"Egress\",\"product\":\"Egress Prevent (DLP)\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Outbound email DLP \u2014 prevent accidental data leakage\"},{\"sheet\":\"SaaS\",\"vendor\":\"Egress\",\"product\":\"Egress Defend\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"AI anti-phishing for Microsoft 365 inboxes\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Defender for Office 365 P1 \/ P2\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Email anti-phishing, safe links, safe attachments\"},{\"sheet\":\"SaaS\",\"vendor\":\"Mimecast\",\"product\":\"Mimecast Email Security Cloud\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"AI-powered email filtering with threat intelligence\"},{\"sheet\":\"SaaS\",\"vendor\":\"Mimecast\",\"product\":\"Mimecast Targeted Threat Protection\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Anti-impersonation, URL protection and attachment sandboxing\"},{\"sheet\":\"SaaS\",\"vendor\":\"N-able\",\"product\":\"N-able Mail Assure\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Email filtering, archiving and continuity\"},{\"sheet\":\"SaaS\",\"vendor\":\"Proofpoint\",\"product\":\"Proofpoint Essentials\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Email security for SMBs \u2014 anti-spam, malware, phishing\"},{\"sheet\":\"SaaS\",\"vendor\":\"Proofpoint\",\"product\":\"Proofpoint Email Protection\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Enterprise-grade inbound\/outbound email filtering\"},{\"sheet\":\"SaaS\",\"vendor\":\"Sophos\",\"product\":\"Sophos Email Advanced\",\"category\":\"Security\",\"sub\":\"Email Security\",\"desc\":\"Email gateway with AI anti-phishing and data loss prevention\"},{\"sheet\":\"SaaS\",\"vendor\":\"Acronis\",\"product\":\"Acronis Advanced Security\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Next-gen AV, behavioural analysis and exploit prevention\"},{\"sheet\":\"SaaS\",\"vendor\":\"Bitdefender\",\"product\":\"Bitdefender GravityZone Business Security\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Layered endpoint protection for SMBs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Bitdefender\",\"product\":\"Bitdefender GravityZone Business Security Premium\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Machine learning, anti-exploit and risk analytics\"},{\"sheet\":\"SaaS\",\"vendor\":\"ESET\",\"product\":\"ESET Endpoint Antivirus \/ Security\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Core AV and firewall for endpoints\"},{\"sheet\":\"SaaS\",\"vendor\":\"ESET\",\"product\":\"ESET PROTECT Entry \/ Advanced \/ Complete\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Tiered endpoint protection bundles with cloud management\"},{\"sheet\":\"SaaS\",\"vendor\":\"ESET\",\"product\":\"ESET Server Security\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"File server and network drive protection\"},{\"sheet\":\"SaaS\",\"vendor\":\"Fortinet\",\"product\":\"FortiClient EMS\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Endpoint security, VPN and zero-trust agent\"},{\"sheet\":\"SaaS\",\"vendor\":\"Malwarebytes\",\"product\":\"Malwarebytes ThreatDown Core\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Malware removal, real-time protection for endpoints\"},{\"sheet\":\"SaaS\",\"vendor\":\"Malwarebytes\",\"product\":\"Malwarebytes ThreatDown Advanced\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Core plus DNS filtering, patch management and VPN\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Intune\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Mobile device and endpoint management (MDM\/MAM)\"},{\"sheet\":\"SaaS\",\"vendor\":\"Sophos\",\"product\":\"Sophos Intercept X Advanced\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"AI-based next-gen endpoint protection with exploit prevention\"},{\"sheet\":\"SaaS\",\"vendor\":\"Sophos\",\"product\":\"Sophos Central Endpoint \/ Server\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Cloud management console for all Sophos products\"},{\"sheet\":\"SaaS\",\"vendor\":\"Webroot\",\"product\":\"Webroot Business Endpoint Protection\",\"category\":\"Security\",\"sub\":\"Endpoint Security\",\"desc\":\"Cloud-based anti-malware and endpoint security\"},{\"sheet\":\"SaaS\",\"vendor\":\"AvePoint\",\"product\":\"AvePoint Confide\",\"category\":\"Security\",\"sub\":\"GRC\",\"desc\":\"Data governance, compliance and sensitivity labelling\"},{\"sheet\":\"SaaS\",\"vendor\":\"CyberCert\",\"product\":\"CyberCert SMB1001 Framework\",\"category\":\"Security\",\"sub\":\"GRC \/ Security Assessment\",\"desc\":\"Cybersecurity certification framework with 5 tiers for SMBs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Entra ID P1 \/ P2\",\"category\":\"Security\",\"sub\":\"IAM\",\"desc\":\"Identity, MFA, Conditional Access, Privileged Identity Management\"},{\"sheet\":\"SaaS\",\"vendor\":\"Bitdefender\",\"product\":\"Bitdefender MDR\",\"category\":\"Security\",\"sub\":\"MDR\",\"desc\":\"Managed detection and response with dedicated SOC\"},{\"sheet\":\"SaaS\",\"vendor\":\"CrowdStrike\",\"product\":\"CrowdStrike Falcon Complete MDR\",\"category\":\"Security\",\"sub\":\"MDR\",\"desc\":\"Fully managed detection and response service\"},{\"sheet\":\"SaaS\",\"vendor\":\"Guardz\",\"product\":\"Guardz Unified Cybersecurity Platform\",\"category\":\"Security\",\"sub\":\"MDR\",\"desc\":\"AI-powered cybersecurity detection and response for SMBs via MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Huntress\",\"product\":\"Huntress Managed EDR\",\"category\":\"Security\",\"sub\":\"MDR\",\"desc\":\"Managed endpoint detection and response with 24\/7 SOC\"},{\"sheet\":\"SaaS\",\"vendor\":\"Huntress\",\"product\":\"Huntress Managed Microsoft 365 ITDR\",\"category\":\"Security\",\"sub\":\"MDR\",\"desc\":\"Identity threat detection for Microsoft 365 environments\"},{\"sheet\":\"SaaS\",\"vendor\":\"Huntress\",\"product\":\"Huntress Managed SIEM\",\"category\":\"Security\",\"sub\":\"MDR\",\"desc\":\"Managed SIEM with SOC analyst support for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"SentinelOne\",\"product\":\"SentinelOne Vigilance MDR\",\"category\":\"Security\",\"sub\":\"MDR\",\"desc\":\"Managed detection and response service on Singularity platform\"},{\"sheet\":\"SaaS\",\"vendor\":\"Sophos\",\"product\":\"Sophos MDR\",\"category\":\"Security\",\"sub\":\"MDR\",\"desc\":\"Managed detection and response with 24\/7 threat neutralisation\"},{\"sheet\":\"SaaS\",\"vendor\":\"ESET\",\"product\":\"ESET Secure Authentication\",\"category\":\"Security\",\"sub\":\"MFA\",\"desc\":\"Two-factor authentication for VPN, RDP and web portals\"},{\"sheet\":\"SaaS\",\"vendor\":\"Cisco\",\"product\":\"Cisco Duo (MFA)\",\"category\":\"Security\",\"sub\":\"MFA \/ IAM\",\"desc\":\"Multi-factor authentication and zero-trust access\"},{\"sheet\":\"SaaS\",\"vendor\":\"Duo Security\",\"product\":\"Duo Free \/ Essentials\",\"category\":\"Security\",\"sub\":\"MFA \/ IAM\",\"desc\":\"Two-factor authentication for apps and VPNs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Duo Security\",\"product\":\"Duo Advantage\",\"category\":\"Security\",\"sub\":\"MFA \/ IAM\",\"desc\":\"MFA plus adaptive access policies and device trust\"},{\"sheet\":\"SaaS\",\"vendor\":\"Duo Security\",\"product\":\"Duo Premier\",\"category\":\"Security\",\"sub\":\"MFA \/ IAM\",\"desc\":\"Full zero-trust access with SSO and device health checks\"},{\"sheet\":\"SaaS\",\"vendor\":\"ConnectWise\",\"product\":\"ConnectWise SIEM\",\"category\":\"Security\",\"sub\":\"Managed Security\",\"desc\":\"Managed SIEM and 24\/7 threat monitoring for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Cork\",\"product\":\"Cork Cyber Insurance & Risk\",\"category\":\"Security\",\"sub\":\"Managed Security\",\"desc\":\"Cyber risk intelligence and financial protection for SMBs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Keeper Security\",\"product\":\"Keeper Secrets Manager\",\"category\":\"Security\",\"sub\":\"PAM\",\"desc\":\"Secrets management for DevOps and CI\/CD pipelines\"},{\"sheet\":\"SaaS\",\"vendor\":\"Keeper Security\",\"product\":\"Keeper PAM\",\"category\":\"Security\",\"sub\":\"PAM\",\"desc\":\"Privileged access management with session recording\"},{\"sheet\":\"SaaS\",\"vendor\":\"1Password\",\"product\":\"1Password Teams Starter Pack\",\"category\":\"Security\",\"sub\":\"Password Management\",\"desc\":\"Password manager for small teams up to 10 users\"},{\"sheet\":\"SaaS\",\"vendor\":\"1Password\",\"product\":\"1Password Business\",\"category\":\"Security\",\"sub\":\"Password Management\",\"desc\":\"Enterprise password manager with admin controls and audit logs\"},{\"sheet\":\"SaaS\",\"vendor\":\"1Password\",\"product\":\"1Password Extended Access Management\",\"category\":\"Security\",\"sub\":\"Password Management\",\"desc\":\"Zero-trust device trust and access management\"},{\"sheet\":\"SaaS\",\"vendor\":\"Keeper Security\",\"product\":\"Keeper Business\",\"category\":\"Security\",\"sub\":\"Password Management\",\"desc\":\"Enterprise password manager with role-based access\"},{\"sheet\":\"SaaS\",\"vendor\":\"LastPass\",\"product\":\"LastPass Teams\",\"category\":\"Security\",\"sub\":\"Password Management\",\"desc\":\"Password management for small teams\"},{\"sheet\":\"SaaS\",\"vendor\":\"LastPass\",\"product\":\"LastPass Business\",\"category\":\"Security\",\"sub\":\"Password Management\",\"desc\":\"Enterprise password vault with SSO and MFA\"},{\"sheet\":\"SaaS\",\"vendor\":\"N-able\",\"product\":\"N-able Passportal\",\"category\":\"Security\",\"sub\":\"Password Management\",\"desc\":\"Password and documentation management for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Cato Networks\",\"product\":\"Cato SASE Cloud\",\"category\":\"Security\",\"sub\":\"SASE\",\"desc\":\"Cloud-native SASE with SD-WAN, SWG, CASB and ZTNA\"},{\"sheet\":\"SaaS\",\"vendor\":\"Cisco\",\"product\":\"Cisco Meraki (Cloud Networking)\",\"category\":\"Security\",\"sub\":\"SASE\",\"desc\":\"Cloud-managed networking: switches, APs, firewalls\"},{\"sheet\":\"SaaS\",\"vendor\":\"Fortinet\",\"product\":\"FortiSASE\",\"category\":\"Security\",\"sub\":\"SASE\",\"desc\":\"Cloud-delivered SASE with secure web gateway and ZTNA\"},{\"sheet\":\"SaaS\",\"vendor\":\"Todyl\",\"product\":\"Todyl SASE + SIEM + MDR\",\"category\":\"Security\",\"sub\":\"SASE\",\"desc\":\"Unified SASE, SIEM and MDR platform for MSPs\"},{\"sheet\":\"SaaS\",\"vendor\":\"Zscaler\",\"product\":\"Zscaler Internet Access (ZIA)\",\"category\":\"Security\",\"sub\":\"SASE \/ Zero Trust\",\"desc\":\"Cloud-native secure web gateway and CASB\"},{\"sheet\":\"SaaS\",\"vendor\":\"Zscaler\",\"product\":\"Zscaler Private Access (ZPA)\",\"category\":\"Security\",\"sub\":\"SASE \/ Zero Trust\",\"desc\":\"Zero-trust network access \u2014 replace VPN\"},{\"sheet\":\"SaaS\",\"vendor\":\"Zscaler\",\"product\":\"Zscaler Digital Experience (ZDX)\",\"category\":\"Security\",\"sub\":\"SASE \/ Zero Trust\",\"desc\":\"Digital experience monitoring for remote workers\"},{\"sheet\":\"SaaS\",\"vendor\":\"Fortinet\",\"product\":\"FortiSIEM\",\"category\":\"Security\",\"sub\":\"SIEM\",\"desc\":\"SIEM with asset discovery and compliance reporting\"},{\"sheet\":\"SaaS\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Sentinel\",\"category\":\"Security\",\"sub\":\"SIEM\",\"desc\":\"Cloud-native SIEM and SOAR platform\"},{\"sheet\":\"SaaS\",\"vendor\":\"Blumira\",\"product\":\"Blumira SIEM + XDR\",\"category\":\"Security\",\"sub\":\"SIEM \/ XDR\",\"desc\":\"Cloud-native SIEM and XDR for MSPs \u2014 pre-tuned detections\"},{\"sheet\":\"SaaS\",\"vendor\":\"Augmentt\",\"product\":\"Augmentt Secure\",\"category\":\"Security\",\"sub\":\"SaaS Security\",\"desc\":\"Microsoft 365 security baselines and policy enforcement\"},{\"sheet\":\"SaaS\",\"vendor\":\"Huntress\",\"product\":\"Huntress Security Awareness Training\",\"category\":\"Security\",\"sub\":\"Security Awareness\",\"desc\":\"Phishing simulation and employee security training\"},{\"sheet\":\"SaaS\",\"vendor\":\"Kaseya\",\"product\":\"Kaseya BullPhish ID\",\"category\":\"Security\",\"sub\":\"Security Awareness\",\"desc\":\"Phishing simulation and security awareness training\"},{\"sheet\":\"SaaS\",\"vendor\":\"Mimecast\",\"product\":\"Mimecast Awareness Training\",\"category\":\"Security\",\"sub\":\"Security Awareness\",\"desc\":\"Phishing simulation and employee training\"},{\"sheet\":\"SaaS\",\"vendor\":\"Proofpoint\",\"product\":\"Proofpoint Security Awareness Training\",\"category\":\"Security\",\"sub\":\"Security Awareness\",\"desc\":\"Phishing simulation and security culture training\"},{\"sheet\":\"SaaS\",\"vendor\":\"Webroot\",\"product\":\"Webroot Security Awareness Training\",\"category\":\"Security\",\"sub\":\"Security Awareness\",\"desc\":\"Phishing simulation and security training platform\"},{\"sheet\":\"SaaS\",\"vendor\":\"CrowdStrike\",\"product\":\"CrowdStrike Falcon Intelligence\",\"category\":\"Security\",\"sub\":\"Threat Intelligence\",\"desc\":\"Threat intelligence feeds and adversary tracking\"},{\"sheet\":\"SaaS\",\"vendor\":\"Vicarius\",\"product\":\"Vicarius vRx\",\"category\":\"Security\",\"sub\":\"Vulnerability Management\",\"desc\":\"Autonomous vulnerability detection, prioritisation and remediation\"},{\"sheet\":\"SaaS\",\"vendor\":\"Barracuda\",\"product\":\"Barracuda Web Security Gateway\",\"category\":\"Security\",\"sub\":\"Web Security\",\"desc\":\"Web filtering, SSL inspection and application control\"},{\"sheet\":\"SaaS\",\"vendor\":\"SentinelOne\",\"product\":\"SentinelOne Singularity XDR\",\"category\":\"Security\",\"sub\":\"XDR\",\"desc\":\"Extended detection across endpoint, cloud, identity and network\"},{\"sheet\":\"Infra\",\"vendor\":\"ConnectWise\",\"product\":\"ConnectWise ScreenConnect\",\"category\":\"IT Operations\",\"sub\":\"Remote Access\",\"desc\":\"Remote desktop access and support tool\"},{\"sheet\":\"Infra\",\"vendor\":\"Citrix\",\"product\":\"Citrix DaaS (Cloud Desktop)\",\"category\":\"Infrastructure\",\"sub\":\"DaaS\",\"desc\":\"Virtual apps and desktops delivered from cloud or on-prem\"},{\"sheet\":\"Infra\",\"vendor\":\"Citrix\",\"product\":\"Citrix Virtual Apps and Desktops\",\"category\":\"Infrastructure\",\"sub\":\"DaaS\",\"desc\":\"Application and desktop virtualisation platform\"},{\"sheet\":\"Infra\",\"vendor\":\"Nerdio\",\"product\":\"Nerdio Manager for MSP\",\"category\":\"Infrastructure\",\"sub\":\"DaaS \/ IaaS Management\",\"desc\":\"Manage and optimise Azure Virtual Desktop and Windows 365 for MSPs\"},{\"sheet\":\"Infra\",\"vendor\":\"Nerdio\",\"product\":\"Nerdio Manager for Enterprise\",\"category\":\"Infrastructure\",\"sub\":\"DaaS \/ IaaS Management\",\"desc\":\"Enterprise AVD management with cost optimisation\"},{\"sheet\":\"Infra\",\"vendor\":\"Microsoft\",\"product\":\"Microsoft Azure (Prepayment \/ Pay-as-you-go)\",\"category\":\"Infrastructure\",\"sub\":\"IaaS\",\"desc\":\"Full Azure cloud platform: compute, storage, networking, AI, databases\"},{\"sheet\":\"Infra\",\"vendor\":\"Microsoft\",\"product\":\"Azure Virtual Desktop\",\"category\":\"Infrastructure\",\"sub\":\"IaaS\",\"desc\":\"Cloud-hosted Windows desktop and app virtualisation\"},{\"sheet\":\"Infra\",\"vendor\":\"Microsoft\",\"product\":\"SQL Server (Standard \/ Enterprise \u2014 CSP)\",\"category\":\"Infrastructure\",\"sub\":\"IaaS\",\"desc\":\"Relational database server, cloud subscription licensing\"},{\"sheet\":\"Infra\",\"vendor\":\"Microsoft\",\"product\":\"Windows Server Datacenter \/ Standard\",\"category\":\"Infrastructure\",\"sub\":\"IaaS\",\"desc\":\"Server OS licensing for physical and virtual environments\"},{\"sheet\":\"Infra\",\"vendor\":\"Pax8 Private Cloud\",\"product\":\"Pax8 Private Cloud (IaaS)\",\"category\":\"Infrastructure\",\"sub\":\"IaaS\",\"desc\":\"Dedicated UK-based cloud compute, storage and networking\"},{\"sheet\":\"Infra\",\"vendor\":\"Pax8 Private Cloud\",\"product\":\"Pax8 Virtual Server\",\"category\":\"Infrastructure\",\"sub\":\"IaaS\",\"desc\":\"Cloud-hosted VMs with UK data residency\"},{\"sheet\":\"Infra\",\"vendor\":\"Egnyte\",\"product\":\"Egnyte Business \/ Enterprise\",\"category\":\"Infrastructure\",\"sub\":\"Storage\",\"desc\":\"Hybrid cloud file storage with governance and compliance\"},{\"sheet\":\"Infra\",\"vendor\":\"Wasabi\",\"product\":\"Wasabi Hot Cloud Storage\",\"category\":\"Infrastructure\",\"sub\":\"Storage\",\"desc\":\"S3-compatible object storage \u2014 no egress or API fees\"},{\"sheet\":\"Infra\",\"vendor\":\"Cisco\",\"product\":\"Cisco Umbrella (DNS Security)\",\"category\":\"Network\",\"sub\":\"Network Security\",\"desc\":\"DNS-layer security and cloud-delivered firewall\"},{\"sheet\":\"Infra\",\"vendor\":\"Fortinet\",\"product\":\"FortiGate NGFW\",\"category\":\"Security\",\"sub\":\"Firewall\",\"desc\":\"Next-generation firewall with IPS, SSL inspection, SD-WAN\"},{\"sheet\":\"Infra\",\"vendor\":\"Sophos\",\"product\":\"Sophos Firewall (XGS)\",\"category\":\"Security\",\"sub\":\"Firewall\",\"desc\":\"Next-gen firewall with deep packet inspection and SD-WAN\"},{\"sheet\":\"Infra\",\"vendor\":\"Barracuda\",\"product\":\"Barracuda CloudGen Firewall\",\"category\":\"Security\",\"sub\":\"Network Security\",\"desc\":\"Next-gen firewall with SD-WAN and advanced threat protection\"},{\"sheet\":\"Infra\",\"vendor\":\"Datto\",\"product\":\"Datto Networking\",\"category\":\"Security\",\"sub\":\"Network Security\",\"desc\":\"Managed networking: switches, APs and SD-WAN\"},{\"sheet\":\"Infra\",\"vendor\":\"Citrix\",\"product\":\"Citrix Secure Private Access\",\"category\":\"Security\",\"sub\":\"VPN \/ Network\",\"desc\":\"Zero-trust application access without VPN\"},{\"sheet\":\"Cloud\",\"vendor\":\"Adobe\",\"product\":\"Adobe Firefly\",\"category\":\"AI & Analytics\",\"sub\":\"AI Productivity\",\"desc\":\"AI-powered generative image and creative content tool\"},{\"sheet\":\"Cloud\",\"vendor\":\"Amazon Bedrock Claude\",\"product\":\"Claude for SMBs (via Amazon Bedrock)\",\"category\":\"AI & Analytics\",\"sub\":\"AI Productivity\",\"desc\":\"Anthropic Claude AI assistant available for SMBs through Pax8 Marketplace\"},{\"sheet\":\"Cloud\",\"vendor\":\"Pax8 AI Agents\",\"product\":\"Pax8 Agent Store (AI Agents)\",\"category\":\"AI & Analytics\",\"sub\":\"AI Productivity\",\"desc\":\"Agentic AI workflows for MSPs \u2014 automate client management tasks\"},{\"sheet\":\"Cloud\",\"vendor\":\"8x8\",\"product\":\"8x8 Contact Centre\",\"category\":\"Communications\",\"sub\":\"CCaaS\",\"desc\":\"Omnichannel cloud contact centre with analytics\"},{\"sheet\":\"Cloud\",\"vendor\":\"RingCentral\",\"product\":\"RingCentral Contact Centre\",\"category\":\"Communications\",\"sub\":\"CCaaS\",\"desc\":\"Cloud contact centre with omnichannel support\"},{\"sheet\":\"Cloud\",\"vendor\":\"Vonage\",\"product\":\"Vonage Contact Centre\",\"category\":\"Communications\",\"sub\":\"CCaaS\",\"desc\":\"Cloud contact centre with CRM integration\"},{\"sheet\":\"Cloud\",\"vendor\":\"Zoom\",\"product\":\"Zoom Contact Centre\",\"category\":\"Communications\",\"sub\":\"CCaaS\",\"desc\":\"Cloud contact centre on Zoom platform\"},{\"sheet\":\"Cloud\",\"vendor\":\"8x8\",\"product\":\"8x8 X Series (X2\/X4\/X6\/X8)\",\"category\":\"Communications\",\"sub\":\"UCaaS\",\"desc\":\"Cloud PBX, call centre and collaboration platform\"},{\"sheet\":\"Cloud\",\"vendor\":\"8x8\",\"product\":\"8x8 Work\",\"category\":\"Communications\",\"sub\":\"UCaaS\",\"desc\":\"Business phone, video and messaging app\"},{\"sheet\":\"Cloud\",\"vendor\":\"Cisco\",\"product\":\"Cisco Webex Calling\",\"category\":\"Communications\",\"sub\":\"UCaaS\",\"desc\":\"Cloud calling and UCaaS platform\"},{\"sheet\":\"Cloud\",\"vendor\":\"RingCentral\",\"product\":\"RingCentral MVP (Message, Video, Phone)\",\"category\":\"Communications\",\"sub\":\"UCaaS\",\"desc\":\"All-in-one cloud communications: calls, SMS, meetings, team chat\"},{\"sheet\":\"Cloud\",\"vendor\":\"RingCentral\",\"product\":\"RingCentral Video Pro\",\"category\":\"Communications\",\"sub\":\"UCaaS\",\"desc\":\"Video meetings and team collaboration\"},{\"sheet\":\"Cloud\",\"vendor\":\"Vonage\",\"product\":\"Vonage Business Communications (VBC)\",\"category\":\"Communications\",\"sub\":\"UCaaS\",\"desc\":\"Cloud phone system with meetings and messaging\"},{\"sheet\":\"Cloud\",\"vendor\":\"Zoom\",\"product\":\"Zoom One Pro \/ Business \/ Enterprise\",\"category\":\"Communications\",\"sub\":\"UCaaS\",\"desc\":\"Video meetings, team chat and phone\"},{\"sheet\":\"Cloud\",\"vendor\":\"Zoom\",\"product\":\"Zoom Phone\",\"category\":\"Communications\",\"sub\":\"UCaaS\",\"desc\":\"Cloud PBX and calling plans\"},{\"sheet\":\"Cloud\",\"vendor\":\"Acronis\",\"product\":\"Acronis Cyber Protect Cloud\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Unified backup, anti-malware, EDR and endpoint management\"},{\"sheet\":\"Cloud\",\"vendor\":\"Acronis\",\"product\":\"Acronis Cyber Backup Cloud\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Cloud and on-premise backup for endpoints, servers, VMs\"},{\"sheet\":\"Cloud\",\"vendor\":\"Arcserve\",\"product\":\"Arcserve Unified Data Protection (UDP)\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Backup, replication and DR for physical and virtual\"},{\"sheet\":\"Cloud\",\"vendor\":\"Axcient\",\"product\":\"Axcient x360Recover\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"BCDR with direct-to-cloud and local appliance options\"},{\"sheet\":\"Cloud\",\"vendor\":\"Axcient\",\"product\":\"Axcient x360Sync\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"File sync and share with cloud backup\"},{\"sheet\":\"Cloud\",\"vendor\":\"Barracuda\",\"product\":\"Barracuda Backup\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"On-premise backup appliance with cloud replication\"},{\"sheet\":\"Cloud\",\"vendor\":\"Cove Data Protection\",\"product\":\"Cove Data Protection (Backup)\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Cloud-first backup for servers, workstations and M365\"},{\"sheet\":\"Cloud\",\"vendor\":\"Datto\",\"product\":\"Datto SIRIS (BCDR)\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Business continuity and disaster recovery for servers and VMs\"},{\"sheet\":\"Cloud\",\"vendor\":\"Datto\",\"product\":\"Datto ALTO (BCDR)\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Compact BCDR device for small offices\"},{\"sheet\":\"Cloud\",\"vendor\":\"Datto\",\"product\":\"Datto Backupify\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"SaaS backup for Salesforce, Google Workspace and M365\"},{\"sheet\":\"Cloud\",\"vendor\":\"N-able\",\"product\":\"N-able Backup\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Cloud backup for endpoints, servers and Microsoft 365\"},{\"sheet\":\"Cloud\",\"vendor\":\"NinjaRMM\",\"product\":\"NinjaOne Backup\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Cloud backup for endpoints and servers\"},{\"sheet\":\"Cloud\",\"vendor\":\"Redstor\",\"product\":\"Redstor Backup for Microsoft 365\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Backup for Exchange, SharePoint, OneDrive and Teams\"},{\"sheet\":\"Cloud\",\"vendor\":\"Redstor\",\"product\":\"Redstor Backup for Endpoints\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Cloud backup for Windows and Mac endpoints\"},{\"sheet\":\"Cloud\",\"vendor\":\"Redstor\",\"product\":\"Redstor Backup for Servers\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Cloud backup for Windows and Linux servers\"},{\"sheet\":\"Cloud\",\"vendor\":\"Veeam\",\"product\":\"Veeam Backup & Replication\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Backup, replication and recovery for VMs, physical and cloud\"},{\"sheet\":\"Cloud\",\"vendor\":\"Veeam\",\"product\":\"Veeam Data Platform Essentials\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Bundled backup for SMBs \u2014 VMs and physical servers\"},{\"sheet\":\"Cloud\",\"vendor\":\"Veeam\",\"product\":\"Veeam Data Platform Foundation \/ Advanced\",\"category\":\"Continuity\",\"sub\":\"Backup\",\"desc\":\"Enterprise backup with analytics and ransomware detection\"},{\"sheet\":\"Cloud\",\"vendor\":\"Acronis\",\"product\":\"Acronis Disaster Recovery Cloud\",\"category\":\"Continuity\",\"sub\":\"Disaster Recovery\",\"desc\":\"Cloud-based disaster recovery and failover for critical systems\"},{\"sheet\":\"Cloud\",\"vendor\":\"Arcserve\",\"product\":\"Arcserve Cloud Direct\",\"category\":\"Continuity\",\"sub\":\"Disaster Recovery\",\"desc\":\"Cloud-based DRaaS with automated failover\"},{\"sheet\":\"Cloud\",\"vendor\":\"Cove Data Protection\",\"product\":\"Cove Disaster Recovery\",\"category\":\"Continuity\",\"sub\":\"Disaster Recovery\",\"desc\":\"Cloud DR with standby VMs and automated testing\"},{\"sheet\":\"Cloud\",\"vendor\":\"Veeam\",\"product\":\"Veeam Disaster Recovery Orchestrator\",\"category\":\"Continuity\",\"sub\":\"Disaster Recovery\",\"desc\":\"Automated DR orchestration and testing\"},{\"sheet\":\"Cloud\",\"vendor\":\"Barracuda\",\"product\":\"Barracuda Message Archiver\",\"category\":\"Continuity\",\"sub\":\"Email Archiving\",\"desc\":\"Email archiving for compliance and eDiscovery\"},{\"sheet\":\"Cloud\",\"vendor\":\"Dropsuite\",\"product\":\"Dropsuite Email Archiving\",\"category\":\"Continuity\",\"sub\":\"Email Archiving\",\"desc\":\"Compliance-grade email archive with eDiscovery search\"},{\"sheet\":\"Cloud\",\"vendor\":\"Mimecast\",\"product\":\"Mimecast Cloud Archive\",\"category\":\"Continuity\",\"sub\":\"Email Archiving\",\"desc\":\"Email archiving, compliance and eDiscovery\"},{\"sheet\":\"Cloud\",\"vendor\":\"Proofpoint\",\"product\":\"Proofpoint Essentials Archiving\",\"category\":\"Continuity\",\"sub\":\"Email Archiving\",\"desc\":\"Email retention and eDiscovery for compliance\"},{\"sheet\":\"Cloud\",\"vendor\":\"Mimecast\",\"product\":\"Mimecast Email Continuity\",\"category\":\"Continuity\",\"sub\":\"Email Continuity\",\"desc\":\"Keep email flowing during outages\"},{\"sheet\":\"Cloud\",\"vendor\":\"Acronis\",\"product\":\"Acronis Cloud Backup for Microsoft 365\",\"category\":\"Continuity\",\"sub\":\"SaaS Backup\",\"desc\":\"Backup for Exchange, SharePoint, OneDrive and Teams\"},{\"sheet\":\"Cloud\",\"vendor\":\"Arcserve\",\"product\":\"Arcserve SaaS Backup\",\"category\":\"Continuity\",\"sub\":\"SaaS Backup\",\"desc\":\"Microsoft 365 and Google Workspace backup\"},{\"sheet\":\"Cloud\",\"vendor\":\"AvePoint\",\"product\":\"AvePoint Cloud Backup\",\"category\":\"Continuity\",\"sub\":\"SaaS Backup\",\"desc\":\"Backup for Microsoft 365, Google Workspace, Salesforce and D365\"},{\"sheet\":\"Cloud\",\"vendor\":\"AvePoint\",\"product\":\"AvePoint MyHub\",\"category\":\"Continuity\",\"sub\":\"SaaS Backup\",\"desc\":\"Microsoft Teams governance and provisioning\"},{\"sheet\":\"Cloud\",\"vendor\":\"Axcient\",\"product\":\"Axcient x360Cloud (M365 & Google)\",\"category\":\"Continuity\",\"sub\":\"SaaS Backup\",\"desc\":\"SaaS backup for Microsoft 365 and Google Workspace\"},{\"sheet\":\"Cloud\",\"vendor\":\"Datto\",\"product\":\"Datto SaaS Protection (M365 & Google)\",\"category\":\"Continuity\",\"sub\":\"SaaS Backup\",\"desc\":\"Backup for Microsoft 365 and Google Workspace\"},{\"sheet\":\"Cloud\",\"vendor\":\"Dropsuite\",\"product\":\"Dropsuite Email Backup & Archiving\",\"category\":\"Continuity\",\"sub\":\"SaaS Backup\",\"desc\":\"Backup and archiving for Microsoft 365 and Google Workspace\"},{\"sheet\":\"Cloud\",\"vendor\":\"Kaseya\",\"product\":\"Kaseya SaaS Backup (Spanning)\",\"category\":\"Continuity\",\"sub\":\"SaaS Backup\",\"desc\":\"Backup for Microsoft 365 and Google Workspace\"},{\"sheet\":\"Cloud\",\"vendor\":\"Veeam\",\"product\":\"Veeam Backup for Microsoft 365\",\"category\":\"Continuity\",\"sub\":\"SaaS Backup\",\"desc\":\"Backup for Exchange Online, SharePoint, OneDrive and Teams\"},\n{\"sheet\":\"Manual\",\"vendor\":\"BritHaven Tech\",\"product\":\"Managed IT Support\",\"category\":\"IT Operations\",\"sub\":\"Managed Services\",\"desc\":\"Fully managed IT support, monitoring, patching and helpdesk services\",\"image\":\"\"},\n{\"sheet\":\"Manual\",\"vendor\":\"BritHaven Tech\",\"product\":\"Managed Security & SOC\",\"category\":\"Security\",\"sub\":\"Managed Security\",\"desc\":\"Managed detection, response, SIEM monitoring and security operations support\",\"image\":\"\"}];\n\n\/\/ \u2500\u2500 CATEGORY METADATA \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst CAT_META = {\n  'Security':        {icon:'\ud83d\udee1\ufe0f', cls:'b-sec'},\n  'Continuity':      {icon:'\ud83d\udcbe', cls:'b-cont'},\n  'Productivity':    {icon:'\ud83c\udfa8', cls:'b-prod'},\n  'IT Operations':   {icon:'\ud83d\udd27', cls:'b-itops'},\n  'Communications':  {icon:'\ud83d\udcde', cls:'b-comm'},\n  'Infrastructure':  {icon:'\ud83d\udda5\ufe0f', cls:'b-infra'},\n  'AI & Analytics':  {icon:'\ud83e\udd16', cls:'b-ai'},\n  'Human Resources': {icon:'\ud83d\udc65', cls:'b-hr'},\n  'Network':         {icon:'\ud83c\udf10', cls:'b-net'},\n};\n\nconst VENDOR_ICONS = {\n  'Microsoft':'\ud83e\ude9f','Adobe':'\ud83c\udfa8','CrowdStrike':'\ud83e\udd85','SentinelOne':'\ud83d\udee1\ufe0f','Huntress':'\ud83d\udd0d',\n  'Sophos':'\ud83d\udd12','Mimecast':'\ud83d\udce7','Veeam':'\ud83d\udcbe','Datto':'\ud83d\udcbf','Acronis':'\ud83d\udd10','Cisco':'\ud83c\udf10',\n  'Zscaler':'\ud83d\udd35','N-able':'\u2699\ufe0f','Kaseya':'\ud83d\udd11','NinjaRMM':'\ud83e\udd77','ConnectWise':'\ud83d\udd17',\n  'Barracuda':'\ud83d\udc1f','Fortinet':'\ud83c\udff0','ESET':'\ud83e\udd89','Bitdefender':'\ud83d\udc09','Proofpoint':'\ud83d\udcec',\n  'Egress':'\ud83d\udce4','1Password':'\ud83d\udd11','Duo Security':'\ud83d\udd10','Keeper Security':'\ud83d\udddd\ufe0f',\n  'Zoom':'\ud83d\udcf9','RingCentral':'\ud83d\udcde','8x8':'\ud83d\udcf1','Vonage':'\ud83d\udcf2','Citrix':'\ud83d\udcbb',\n  'Malwarebytes':'\ud83e\uddb7','Webroot':'\ud83c\udf10','LastPass':'\ud83d\udd12','DocuSign':'\u270d\ufe0f',\n  'AvePoint':'\u2601\ufe0f','Axcient':'\ud83d\udd04','Redstor':'\ud83d\udce6','Arcserve':'\ud83d\uddc4\ufe0f',\n  'Nerdio':'\ud83d\udda5\ufe0f','Pax8 Private Cloud':'\u2601\ufe0f','Amazon Bedrock Claude':'\ud83e\udd16',\n  'Pax8 AI Agents':'\ud83e\udd16','Augmentt':'\ud83d\udcca','Blumira':'\ud83d\udd35','Cato Networks':'\ud83c\udf10',\n  'Todyl':'\ud83d\udd10','Guardz':'\ud83d\udee1\ufe0f','CyberCert':'\ud83c\udfc6','AvePoint':'\u2601\ufe0f','Egnyte':'\ud83d\udcc1',\n  'Wasabi':'\ud83d\udca7','Zensai':'\ud83d\udca1','TalentLMS':'\ud83d\udcda','Atera':'\u26a1','Pulseway':'\ud83d\udcf1',\n  'SuperOps':'\ud83d\ude80','Syncro':'\ud83d\udd04','IT Glue':'\ud83d\udcd7','Hudu':'\ud83d\udcd8','Scribe':'\ud83d\udcdd',\n  'Rewst':'\u2699\ufe0f','Gradient MSP':'\ud83d\udcca','Cork':'\ud83c\udff7\ufe0f','Vicarius':'\ud83d\udd0d','Dropsuite':'\ud83d\udcec',\n  'Cove Data Protection':'\ud83d\udd12','Nitro':'\u26a1','Gaviti':'\ud83d\udcb0','N-able':'\u2699\ufe0f',\n};\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet state = {\n  cat: 'all',\n  vendors: new Set(),\n  subs: new Set(),\n  sources: new Set(),\n  search: '',\n  view: 'grid',\n};\nlet cart = [];\n\n\/\/ \u2500\u2500 HELPERS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 getIcon(p) {\n  return VENDOR_ICONS[p.vendor] || CAT_META[p.category]?.icon || '\ud83d\udce6';\n}\nfunction getBadgeCls(cat) {\n  return CAT_META[cat]?.cls || 'b-prod';\n}\nfunction getSubLabel(sub) {\n  return sub.length > 22 ? sub.substring(0,20)+'\u2026' : sub;\n}\nfunction sheetLabel(s) {\n  return s === 'SaaS' ? 'SaaS' : s === 'Infra' ? 'Infra' : 'Cloud';\n}\n\n\/\/ \u2500\u2500 FILTER LOGIC \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 filtered() {\n  let list = PRODUCTS.slice();\n  if (state.cat !== 'all') list = list.filter(p => p.category === state.cat);\n  if (state.vendors.size) list = list.filter(p => state.vendors.has(p.vendor));\n  if (state.subs.size) list = list.filter(p => state.subs.has(p.sub));\n  if (state.sources.size) list = list.filter(p => state.sources.has(p.sheet));\n  if (state.search) {\n    const q = state.search.toLowerCase();\n    list = list.filter(p =>\n      p.product.toLowerCase().includes(q) ||\n      p.vendor.toLowerCase().includes(q) ||\n      p.desc.toLowerCase().includes(q) ||\n      p.sub.toLowerCase().includes(q) ||\n      p.category.toLowerCase().includes(q)\n    );\n  }\n  const sort = document.getElementById('sortSel')?.value || 'az';\n  if (sort === 'az') list.sort((a,b) => a.product.localeCompare(b.product));\n  else if (sort === 'za') list.sort((a,b) => b.product.localeCompare(a.product));\n  else if (sort === 'vendor') list.sort((a,b) => a.vendor.localeCompare(b.vendor));\n  else list.sort((a,b) => a.category.localeCompare(b.category) || a.product.localeCompare(b.product));\n  return list;\n}\n\n\/\/ \u2500\u2500 RENDER \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 render() {\n  const list = filtered();\n  const body = document.getElementById('catalogueBody');\n  document.getElementById('resultCount').innerHTML = `<strong>${list.length}<\/strong> product${list.length!==1?'s':''}`;\n  renderActiveFilters();\n\n  if (!list.length) {\n    body.innerHTML = `<div class=\"empty\"><div class=\"empty-icon\">\ud83d\udd0d<\/div><div class=\"empty-title\">No products match your filters<\/div><div class=\"empty-sub\">Try adjusting your search or clearing filters<\/div><\/div>`;\n    return;\n  }\n\n  const sort = document.getElementById('sortSel')?.value || 'az';\n  const isByCategory = sort === 'cat' && state.cat === 'all';\n\n  if (isByCategory) {\n    \/\/ Group by category\n    const grouped = {};\n    list.forEach(p => { if(!grouped[p.category]) grouped[p.category]=[]; grouped[p.category].push(p); });\n    body.innerHTML = Object.keys(CAT_META)\n      .filter(c => grouped[c])\n      .map(cat => renderCatSection(cat, grouped[cat]))\n      .join('');\n  } else if (state.cat === 'all' && !state.search && !state.vendors.size && !state.subs.size && !state.sources.size) {\n    \/\/ Group by category for \"all\" unfiltered view\n    const grouped = {};\n    list.forEach(p => { if(!grouped[p.category]) grouped[p.category]=[]; grouped[p.category].push(p); });\n    body.innerHTML = Object.keys(CAT_META)\n      .filter(c => grouped[c])\n      .map(cat => renderCatSection(cat, grouped[cat]))\n      .join('');\n  } else {\n    const gridCls = state.view === 'list' ? 'prod-grid list-view' : 'prod-grid';\n    body.innerHTML = `<div class=\"${gridCls}\">${list.map(p => cardHTML(p)).join('')}<\/div>`;\n  }\n}\n\nfunction renderCatSection(cat, products) {\n  const meta = CAT_META[cat];\n  const subs = [...new Set(products.map(p=>p.sub))].sort();\n  const gridCls = state.view === 'list' ? 'prod-grid list-view' : 'prod-grid';\n  return `\n  <div class=\"cat-section\">\n    <div class=\"cs-header\">\n      <div class=\"cs-left\">\n        <span class=\"cs-icon\">${meta.icon}<\/span>\n        <span class=\"cs-name\">${cat}<\/span>\n        <span class=\"cs-count\">${products.length}<\/span>\n      <\/div>\n      <div class=\"cs-sub-tabs\">\n        ${subs.map(s=>`<span class=\"sub-tab\" onclick=\"toggleSub('${s}',this)\">${getSubLabel(s)}<\/span>`).join('')}\n      <\/div>\n    <\/div>\n    <div class=\"${gridCls}\">${products.map(p=>cardHTML(p)).join('')}<\/div>\n  <\/div>`;\n}\n\nfunction cardHTML(p) {\n  const icon = getIcon(p);\n  const cls = getBadgeCls(p.category);\n  const inCart = cart.some(c => c.id === p.product);\n  if (state.view === 'list') {\n    return `<div class=\"pcard\">\n      <div class=\"pc-img\">${icon}<span class=\"pc-src\">${sheetLabel(p.sheet)}<\/span><\/div>\n      <div class=\"pc-body\">\n        <div class=\"pc-main\">\n          <div class=\"pc-vendor\">${p.vendor}<\/div>\n          <div class=\"pc-name\">${p.product}<\/div>\n          <span class=\"pc-sub\">${getSubLabel(p.sub)}<\/span>\n        <\/div>\n        <div class=\"pc-btns\">\n          <button class=\"pc-add ${inCart?'added':''}\" onclick=\"addToCart(event,'${esc(p.product)}','${esc(p.vendor)}','${icon}')\">${inCart?'\u2713 Added':'+ Add'}<\/button>\n          <button class=\"pc-quote\" onclick=\"openQuote('${esc(p.product)}')\">Quote<\/button>\n        <\/div>\n      <\/div>\n    <\/div>`;\n  }\n  return `<div class=\"pcard\">\n    <div class=\"pc-img\">${icon}<span class=\"pc-badge ${cls}\">${getSubLabel(p.sub)}<\/span><span class=\"pc-src\">${sheetLabel(p.sheet)}<\/span><\/div>\n    <div class=\"pc-body\">\n      <div class=\"pc-vendor\">${p.vendor}<\/div>\n      <div class=\"pc-name\">${p.product}<\/div>\n      <div class=\"pc-desc\">${p.desc}<\/div>\n      <div class=\"pc-btns\">\n        <button class=\"pc-add ${inCart?'added':''}\" onclick=\"addToCart(event,'${esc(p.product)}','${esc(p.vendor)}','${icon}')\">${inCart?'\u2713 Added':'Add to Basket'}<\/button>\n        <button class=\"pc-quote\" onclick=\"openQuote('${esc(p.product)}')\">Quote<\/button>\n      <\/div>\n    <\/div>\n  <\/div>`;\n}\n\nfunction esc(s) { return s.replace(\/'\/g,\"\\\\'\"); }\n\n\/\/ \u2500\u2500 SIDEBAR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 renderVendorList(search='') {\n  const relevant = filtered();\n  const vendorCounts = {};\n  PRODUCTS.forEach(p => {\n    if (!search || p.vendor.toLowerCase().includes(search.toLowerCase())) {\n      const inRelevant = relevant.some(r => r.vendor === p.vendor);\n      if (!vendorCounts[p.vendor]) vendorCounts[p.vendor] = {total:0, inCurrent:0};\n      vendorCounts[p.vendor].total++;\n      if (inRelevant) vendorCounts[p.vendor].inCurrent++;\n    }\n  });\n  const vendors = Object.entries(vendorCounts).sort((a,b)=>a[0].localeCompare(b[0]));\n  document.getElementById('vendorList').innerHTML = vendors.map(([v,c])=>`\n    <div class=\"sb-item ${state.vendors.has(v)?'active':''}\" onclick=\"toggleVendor('${v}')\">\n      <span>${v}<\/span><span class=\"sb-count\">${c.total}<\/span>\n    <\/div>`).join('');\n}\n\nfunction renderSubList() {\n  const subCounts = {};\n  PRODUCTS.forEach(p => {\n    if (state.cat === 'all' || p.category === state.cat) {\n      subCounts[p.sub] = (subCounts[p.sub]||0) + 1;\n    }\n  });\n  const subs = Object.entries(subCounts).sort((a,b)=>a[0].localeCompare(b[0]));\n  document.getElementById('subList').innerHTML = subs.map(([s,c])=>`\n    <div class=\"sb-item ${state.subs.has(s)?'active':''}\" onclick=\"toggleSubFilter('${esc(s)}')\">\n      <span>${s}<\/span><span class=\"sb-count\">${c}<\/span>\n    <\/div>`).join('');\n}\n\nfunction renderSourceList() {\n  const srcCounts = {SaaS:0, Infra:0, Cloud:0};\n  PRODUCTS.forEach(p => { if(srcCounts[p.sheet]!==undefined) srcCounts[p.sheet]++; });\n  const labels = {SaaS:'SaaS', Infra:'Infrastructure', Cloud:'Cloud'};\n  document.getElementById('sourceList').innerHTML = Object.entries(srcCounts).map(([s,c])=>`\n    <div class=\"sb-item ${state.sources.has(s)?'active':''}\" onclick=\"toggleSource('${s}')\">\n      <span>${labels[s]||s}<\/span><span class=\"sb-count\">${c}<\/span>\n    <\/div>`).join('');\n}\n\n\/\/ \u2500\u2500 INTERACTIONS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 selectCat(cat, el) {\n  state.cat = cat;\n  state.vendors.clear();\n  state.subs.clear();\n  document.querySelectorAll('.cat-tile').forEach(t => t.classList.remove('active'));\n  el.classList.add('active');\n  renderSubList();\n  renderVendorList();\n  render();\n}\n\nfunction toggleVendor(v) {\n  if (state.vendors.has(v)) state.vendors.delete(v); else state.vendors.add(v);\n  renderVendorList();\n  render();\n}\n\nfunction toggleSubFilter(s) {\n  if (state.subs.has(s)) state.subs.delete(s); else state.subs.add(s);\n  renderSubList();\n  render();\n}\n\nfunction toggleSub(s, el) {\n  if (state.subs.has(s)) { state.subs.delete(s); el.classList.remove('active'); }\n  else { state.subs.add(s); el.classList.add('active'); }\n  render();\n}\n\nfunction toggleSource(s) {\n  if (state.sources.has(s)) state.sources.delete(s); else state.sources.add(s);\n  renderSourceList();\n  render();\n}\n\nfunction clearAllFilters() {\n  state = { cat:'all', vendors:new Set(), subs:new Set(), sources:new Set(), search:'', view:state.view };\n  document.getElementById('globalSearch').value = '';\n  document.querySelectorAll('.cat-tile').forEach(t => t.classList.remove('active'));\n  document.querySelector('.cat-tile[data-cat=\"all\"]').classList.add('active');\n  renderVendorList();\n  renderSubList();\n  renderSourceList();\n  render();\n}\n\nfunction renderActiveFilters() {\n  const af = document.getElementById('activeFilters');\n  let chips = '';\n  if (state.cat !== 'all') chips += `<span class=\"af-chip\" onclick=\"clearAllFilters()\">${CAT_META[state.cat]?.icon||''} ${state.cat} <span class=\"af-x\">\u2715<\/span><\/span>`;\n  state.vendors.forEach(v => chips += `<span class=\"af-chip\" onclick=\"toggleVendor('${v}')\">\ud83c\udfe2 ${v} <span class=\"af-x\">\u2715<\/span><\/span>`);\n  state.subs.forEach(s => chips += `<span class=\"af-chip\" onclick=\"toggleSubFilter('${esc(s)}')\">${s} <span class=\"af-x\">\u2715<\/span><\/span>`);\n  state.sources.forEach(s => chips += `<span class=\"af-chip\" onclick=\"toggleSource('${s}')\">${s} <span class=\"af-x\">\u2715<\/span><\/span>`);\n  if (state.search) chips += `<span class=\"af-chip\" onclick=\"clearSearch()\">\ud83d\udd0d \"${state.search}\" <span class=\"af-x\">\u2715<\/span><\/span>`;\n  af.innerHTML = chips;\n}\n\nfunction doSearch(val) {\n  state.search = val;\n  render();\n}\n\nfunction clearSearch() {\n  state.search = '';\n  document.getElementById('globalSearch').value = '';\n  render();\n}\n\nfunction setView(v) {\n  state.view = v;\n  document.getElementById('gridBtn').classList.toggle('active', v==='grid');\n  document.getElementById('listBtn').classList.toggle('active', v==='list');\n  render();\n}\n\n\/\/ \u2500\u2500 BASKET \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 addToCart(e, name, vendor, icon) {\n  e.stopPropagation();\n  if (!cart.find(c => c.id === name)) {\n    cart.push({ id:name, name, vendor, icon });\n    updateCartUI();\n    showToast(`\u2713 ${name} added to basket`, 'success');\n  } else {\n    showToast(`${name} already in basket`);\n  }\n  render();\n}\n\nfunction removeFromCart(name) {\n  cart = cart.filter(c => c.id !== name);\n  updateCartUI();\n  render();\n}\n\nfunction updateCartUI() {\n  document.getElementById('cartCount').textContent = cart.length;\n  const body = document.getElementById('drawerBody');\n  const foot = document.getElementById('drawerFoot');\n  if (!cart.length) {\n    body.innerHTML = '<div class=\"dr-empty\"><div class=\"dr-empty-icon\">\ud83d\uded2<\/div><div class=\"dr-empty-txt\">Your basket is empty.<br>Add products to get started.<\/div><\/div>';\n    foot.style.display = 'none';\n    return;\n  }\n  body.innerHTML = cart.map(c=>`\n    <div class=\"dr-item\">\n      <div class=\"dr-item-icon\">${c.icon}<\/div>\n      <div class=\"dr-item-info\">\n        <div class=\"dr-item-name\">${c.name}<\/div>\n        <div class=\"dr-item-vendor\">${c.vendor}<\/div>\n      <\/div>\n      <span class=\"dr-item-remove\" onclick=\"removeFromCart('${esc(c.id)}')\">Remove<\/span>\n    <\/div>`).join('');\n  document.getElementById('drawerSummary').textContent = `${cart.length} product${cart.length!==1?'s':''} in basket`;\n  foot.style.display = 'flex';\n}\n\nfunction toggleDrawer() {\n  document.getElementById('drawer').classList.toggle('open');\n  document.getElementById('overlay').classList.toggle('open');\n}\n\n\/\/ \u2500\u2500 QUOTE \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 openQuote(name) {\n  const ta = document.getElementById('quoteProduct');\n  if (name) ta.value = name;\n  else if (cart.length) ta.value = cart.map(c=>c.name).join('\\n');\n  else ta.value = '';\n  document.getElementById('quoteModal').classList.add('open');\n  document.getElementById('drawer').classList.remove('open');\n  document.getElementById('overlay').classList.remove('open');\n}\nfunction closeQuote() { document.getElementById('quoteModal').classList.remove('open'); }\nfunction submitQuote() { showToast(\"\u2713 Quote submitted! We'll respond within 4 hours.\",'success'); closeQuote(); }\ndocument.getElementById('quoteModal').addEventListener('click',function(e){if(e.target===this)closeQuote();});\n\n\/\/ \u2500\u2500 TOAST \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 showToast(msg,type=''){\n  const t = document.getElementById('toast');\n  t.textContent = msg;\n  t.className = 'toast'+(type?' '+type:'');\n  t.classList.add('show');\n  setTimeout(()=>t.classList.remove('show'),3000);\n}\n\n\/\/ \u2500\u2500 KEYBOARD \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ndocument.addEventListener('keydown',e=>{\n  if(e.key==='Escape'){closeQuote();document.getElementById('drawer').classList.remove('open');document.getElementById('overlay').classList.remove('open');}\n});\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nrenderVendorList();\nrenderSubList();\nrenderSourceList();\nrender();\n\n\/* REQUESTED ADD TO BASKET FUNCTIONALITY *\/\nconst BRITHAVEN_CART_KEY = \"brithaven_cart\";\n\nfunction getCartItems(){\n  try{\n    return JSON.parse(localStorage.getItem(BRITHAVEN_CART_KEY)) || [];\n  }catch(e){\n    return [];\n  }\n}\n\nfunction saveCartItems(items){\n  localStorage.setItem(BRITHAVEN_CART_KEY, JSON.stringify(items));\n  updateBasketCount();\n}\n\nfunction getProductFromButton(btn){\n  const card = btn.closest(\".pcard\");\n  if(!card){\n    return null;\n  }\n\n  const name = card.querySelector(\".pc-name\")?.textContent?.trim() || \"Product\";\n  const vendor = card.querySelector(\".pc-vendor\")?.textContent?.trim() || \"\";\n  const sub = card.querySelector(\".pc-sub\")?.textContent?.trim() || \"\";\n  const desc = card.querySelector(\".pc-desc\")?.textContent?.trim() || \"\";\n  const icon = card.querySelector(\".pc-img\")?.textContent?.trim() || \"\ud83d\udce6\";\n\n  return {\n    id: (vendor + \"-\" + name).toLowerCase().replace(\/[^a-z0-9]+\/g,\"-\").replace(\/^-|-$\/g,\"\"),\n    name: name,\n    product: name,\n    vendor: vendor,\n    sub: sub,\n    desc: desc,\n    icon: icon,\n    qty: 1\n  };\n}\n\nfunction addToBasket(btn){\n  const product = getProductFromButton(btn);\n  if(!product) return;\n\n  const cart = getCartItems();\n  const existing = cart.find(item => item.id === product.id);\n\n  if(existing){\n    existing.qty = (parseInt(existing.qty) || 1) + 1;\n  }else{\n    cart.push(product);\n  }\n\n  saveCartItems(cart);\n\n  btn.classList.add(\"added\");\n  btn.textContent = \"Added\";\n  showToast(\"Added to basket\", \"success\");\n\n  setTimeout(function(){\n    btn.classList.remove(\"added\");\n    btn.textContent = \"Add to Basket\";\n  }, 1200);\n}\n\nfunction updateBasketCount(){\n  const cart = getCartItems();\n  const count = cart.reduce((total,item)=> total + (parseInt(item.qty) || 1), 0);\n\n  document.querySelectorAll(\".cart-count,#cartCount,#headerCartCount,[data-cart-count],[data-basket-count]\").forEach(function(el){\n    el.textContent = count;\n  });\n}\n\ndocument.addEventListener(\"DOMContentLoaded\",function(){\n  updateBasketCount();\n});\n\n<\/script>\n<\/body>\n<\/html><\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Product Catalogue \u2014 BritHaven Tech \ud83d\udce6 Full Product Catalogue Browse 218 Products Across 9 Categories Software licences, cloud subscriptions, cybersecurity, backup, communications and infrastructure solutions \u2014 all from an authorised UK reseller. 218Products Listed 67Vendor Partners 9Categories 4hrQuote Response Browse by Category \u26a1 All Products 218 products \ud83d\udee1\ufe0f Security 97 products \ud83d\udcbe Backup &amp; Continuity [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-195","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Product - Brithaventech<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/brithaventech.co.uk\/index.php\/product-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Product - Brithaventech\" \/>\n<meta property=\"og:description\" content=\"Product Catalogue \u2014 BritHaven Tech \ud83d\udce6 Full Product Catalogue Browse 218 Products Across 9 Categories Software licences, cloud subscriptions, cybersecurity, backup, communications and infrastructure solutions \u2014 all from an authorised UK reseller. 218Products Listed 67Vendor Partners 9Categories 4hrQuote Response Browse by Category \u26a1 All Products 218 products \ud83d\udee1\ufe0f Security 97 products \ud83d\udcbe Backup &amp; Continuity [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/brithaventech.co.uk\/index.php\/product-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Brithaventech\" \/>\n<meta property=\"article:modified_time\" content=\"2026-05-30T07:31:48+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/brithaventech.co.uk\\\/index.php\\\/product-2\\\/\",\"url\":\"https:\\\/\\\/brithaventech.co.uk\\\/index.php\\\/product-2\\\/\",\"name\":\"Product - Brithaventech\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/brithaventech.co.uk\\\/#website\"},\"datePublished\":\"2026-05-25T06:43:14+00:00\",\"dateModified\":\"2026-05-30T07:31:48+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/brithaventech.co.uk\\\/index.php\\\/product-2\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/brithaventech.co.uk\\\/index.php\\\/product-2\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/brithaventech.co.uk\\\/index.php\\\/product-2\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/brithaventech.co.uk\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Product\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/brithaventech.co.uk\\\/#website\",\"url\":\"https:\\\/\\\/brithaventech.co.uk\\\/\",\"name\":\"Brithaventech\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/brithaventech.co.uk\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Product - Brithaventech","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/brithaventech.co.uk\/index.php\/product-2\/","og_locale":"en_US","og_type":"article","og_title":"Product - Brithaventech","og_description":"Product Catalogue \u2014 BritHaven Tech \ud83d\udce6 Full Product Catalogue Browse 218 Products Across 9 Categories Software licences, cloud subscriptions, cybersecurity, backup, communications and infrastructure solutions \u2014 all from an authorised UK reseller. 218Products Listed 67Vendor Partners 9Categories 4hrQuote Response Browse by Category \u26a1 All Products 218 products \ud83d\udee1\ufe0f Security 97 products \ud83d\udcbe Backup &amp; Continuity [&hellip;]","og_url":"https:\/\/brithaventech.co.uk\/index.php\/product-2\/","og_site_name":"Brithaventech","article_modified_time":"2026-05-30T07:31:48+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/brithaventech.co.uk\/index.php\/product-2\/","url":"https:\/\/brithaventech.co.uk\/index.php\/product-2\/","name":"Product - Brithaventech","isPartOf":{"@id":"https:\/\/brithaventech.co.uk\/#website"},"datePublished":"2026-05-25T06:43:14+00:00","dateModified":"2026-05-30T07:31:48+00:00","breadcrumb":{"@id":"https:\/\/brithaventech.co.uk\/index.php\/product-2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/brithaventech.co.uk\/index.php\/product-2\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/brithaventech.co.uk\/index.php\/product-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/brithaventech.co.uk\/"},{"@type":"ListItem","position":2,"name":"Product"}]},{"@type":"WebSite","@id":"https:\/\/brithaventech.co.uk\/#website","url":"https:\/\/brithaventech.co.uk\/","name":"Brithaventech","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/brithaventech.co.uk\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/brithaventech.co.uk\/index.php\/wp-json\/wp\/v2\/pages\/195","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/brithaventech.co.uk\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/brithaventech.co.uk\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/brithaventech.co.uk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/brithaventech.co.uk\/index.php\/wp-json\/wp\/v2\/comments?post=195"}],"version-history":[{"count":16,"href":"https:\/\/brithaventech.co.uk\/index.php\/wp-json\/wp\/v2\/pages\/195\/revisions"}],"predecessor-version":[{"id":539,"href":"https:\/\/brithaventech.co.uk\/index.php\/wp-json\/wp\/v2\/pages\/195\/revisions\/539"}],"wp:attachment":[{"href":"https:\/\/brithaventech.co.uk\/index.php\/wp-json\/wp\/v2\/media?parent=195"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}