[object Object]

← back to Norma Sdcc Pitch

add: 'Why custom CRM?' section — head-to-head vs Salesforce/EveryAction/HubSpot across 8 axes + hybrid play + honest risks + 'the real question'

16362c021395b8043ed3785ac9901723a4be42e0 · 2026-05-20 08:33:54 -0700 · SteveStudio2

Files touched

Diff

commit 16362c021395b8043ed3785ac9901723a4be42e0
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date:   Wed May 20 08:33:54 2026 -0700

    add: 'Why custom CRM?' section — head-to-head vs Salesforce/EveryAction/HubSpot across 8 axes + hybrid play + honest risks + 'the real question'
---
 data/features.json | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 public/app.js      | 31 +++++++++++++++++++++
 public/index.html  | 26 ++++++++++++++++++
 public/styles.css  | 28 +++++++++++++++++++
 4 files changed, 166 insertions(+)

diff --git a/data/features.json b/data/features.json
index d285b2a..851e6b7 100644
--- a/data/features.json
+++ b/data/features.json
@@ -123,6 +123,87 @@
     ]
   },
 
+  "why_custom_crm": {
+    "headline": "Why build a custom CRM instead of using Salesforce / EveryAction / HubSpot?",
+    "intro": "The most common objection. Real answer: off-the-shelf CRMs were built for sales teams, not borrower advocacy. SDCC's work doesn't fit their schema, and the AI era makes that mismatch worse.",
+    "the_short_answer": "Off-the-shelf CRMs model 'leads → opportunities → closed deals.' SDCC models 'borrower in crisis → story tagged → policy lever → press hit → coalition activation.' Same word ('CRM'), totally different shape. Forcing SDCC into a sales schema costs more, slows the team, and locks the data away.",
+    "comparison": [
+      {
+        "axis": "Cost (5 staff, year 1)",
+        "salesforce": "$2,400-$9,000 + Einstein add-on ($1,000+/mo) + implementation consultant ($30k)",
+        "everyaction": "$5k-$25k base + per-user + onboarding",
+        "hubspot": "$1,200-$14,400 + AI add-ons",
+        "norma": "$2,400-$9,600/year all-in (incl. AI inference + hosting)",
+        "winner": "norma"
+      },
+      {
+        "axis": "AI native",
+        "salesforce": "Einstein is bolted on. Doesn't know SDCC's voice. Extra cost.",
+        "everyaction": "Limited AI; mostly templated automations.",
+        "hubspot": "Breeze AI exists but is generic marketing-flavored.",
+        "norma": "AI is the substrate. Claude is the model. SDCC's voice library + KB are first-class.",
+        "winner": "norma"
+      },
+      {
+        "axis": "Data ownership",
+        "salesforce": "Your data lives in their schema. Export costs extra. Lock-in is the business model.",
+        "everyaction": "Better than Salesforce on export, still proprietary.",
+        "hubspot": "Lock-in by integration sprawl.",
+        "norma": "Postgres on SDCC's tenancy. Daily SQL dump exportable. Standard formats (CSV/JSON) on day 1.",
+        "winner": "norma"
+      },
+      {
+        "axis": "Borrower-story modeling",
+        "salesforce": "Force-fit into 'Contact' or 'Lead' object. No native debt-type/urgency/anonymizability fields.",
+        "everyaction": "Closer fit (designed for advocacy) but still record-based, not story-based.",
+        "hubspot": "Generic contact records. Definitely not modeled for this.",
+        "norma": "BorrowerStory is a first-class object. Structured by debt type, urgency, program, anonymizability, consent status.",
+        "winner": "norma"
+      },
+      {
+        "axis": "Speed of change",
+        "salesforce": "Workflow change = consultant + months + committee.",
+        "everyaction": "Faster than Salesforce, still gated by their roadmap.",
+        "hubspot": "Marketing automation strong; nonprofit-specific changes slow.",
+        "norma": "Workflow change = code commit. Hours, not months.",
+        "winner": "norma"
+      },
+      {
+        "axis": "Community + ecosystem",
+        "salesforce": "Huge consultant + admin community. Lots of tutorials. Industry standard.",
+        "everyaction": "Strong nonprofit community.",
+        "hubspot": "Massive community.",
+        "norma": "Tiny community (it's bespoke). Documentation lives in this app + Steve's brain.",
+        "winner": "off-the-shelf"
+      },
+      {
+        "axis": "Donations + bulk email",
+        "salesforce": "Strong with Pardot/Marketing Cloud, expensive.",
+        "everyaction": "BEST in class for nonprofit donations + bulk email.",
+        "hubspot": "Marketing-first, donation tooling weaker.",
+        "norma": "Not focus. Should integrate with EveryAction or ActBlue, not replace.",
+        "winner": "everyaction"
+      },
+      {
+        "axis": "Compliance + audit",
+        "salesforce": "Strong audit trail, expensive to access.",
+        "everyaction": "Adequate for nonprofit compliance.",
+        "hubspot": "Marketing-grade audit.",
+        "norma": "Append-only audit log. Every AI decision logged with model + prompt + actor + timestamp. Regulator-ready.",
+        "winner": "norma"
+      }
+    ],
+    "the_hybrid_play": "Don't replace EveryAction. SDCC keeps EveryAction for donations + bulk email (where it's actually best in class). Norma owns the advocacy-specific work no off-the-shelf tool handles — borrower stories, press response, coalition map, AI drafting, inbox triage. Two tools, clear boundaries, no overlap.",
+    "honest_risks": [
+      "Maintenance burden — SDCC needs a technical owner (Steve, initially). Off-the-shelf is more turnkey.",
+      "If the technical owner leaves, continuity risk. Mitigation: full Postgres + code + voice library export at any time, plus 30-day handoff clause.",
+      "No huge user community asking 'how do I do X'. Mitigation: Norma's interface mirrors Gmail patterns, so staff onboarding is faster than enterprise CRMs anyway.",
+      "Standard integrations (Mailchimp, ActBlue, Slack) need to be built per request — not pre-configured.",
+      "Bus factor — Norma's success depends on a small team's ongoing maintenance. The off-the-shelf path has 'somebody else's problem' built in."
+    ],
+    "the_real_question": "The real question isn't 'Salesforce vs Norma.' It's 'do we want our CRM to fit our work, or do we want to bend our work to fit a CRM?' Salesforce works for sales teams because its schema matches their work. SDCC's schema doesn't match any off-the-shelf product. Either bend the work or build the tool."
+  },
+
   "wix_integration": {
     "headline": "Wix ↔ Norma — concrete integration guide",
     "intro": "Wix is fine. It's where SDCC's site lives. Here's exactly how to make it work with Norma's data + workflows.",
diff --git a/public/app.js b/public/app.js
index ecdca5f..6c71aba 100644
--- a/public/app.js
+++ b/public/app.js
@@ -52,6 +52,7 @@
     renderPriorities();
     renderObjections();
     renderShiftTable();
+    renderCrmCompare();
     renderWixOptions();
     renderWixPrinciples();
     renderAgents();
@@ -604,6 +605,36 @@ ${items.map((a) => `
     `).join('');
   }
 
+  /* ─────────────── CRM compare table ─────────────── */
+  function renderCrmCompare() {
+    const w = state.data.why_custom_crm;
+    if (!w) return;
+    const t = document.getElementById('crm-compare');
+    if (!t) return;
+    t.innerHTML = `
+      <thead>
+        <tr>
+          <th>Axis</th>
+          <th>Salesforce</th>
+          <th>EveryAction</th>
+          <th>HubSpot</th>
+          <th class="norma-col">Norma</th>
+        </tr>
+      </thead>
+      <tbody>
+        ${w.comparison.map((row) => `
+          <tr>
+            <td class="axis">${escapeHtml(row.axis)}</td>
+            <td class="${row.winner === 'salesforce' ? 'win' : ''}">${escapeHtml(row.salesforce)}</td>
+            <td class="${row.winner === 'everyaction' ? 'win' : ''}">${escapeHtml(row.everyaction)}</td>
+            <td class="${row.winner === 'hubspot' ? 'win' : ''}">${escapeHtml(row.hubspot)}</td>
+            <td class="norma-col ${row.winner === 'norma' ? 'win' : ''}">${escapeHtml(row.norma)}</td>
+          </tr>
+        `).join('')}
+      </tbody>
+    `;
+  }
+
   /* ─────────────── wix options + principles ─────────────── */
   function renderWixOptions() {
     const w = state.data.wix_integration;
diff --git a/public/index.html b/public/index.html
index 608c28b..c51f770 100644
--- a/public/index.html
+++ b/public/index.html
@@ -20,6 +20,7 @@
       <a href="#reluctant">Skeptic?</a>
       <a href="#db-shift">DB Era</a>
       <a href="#wix">Wix</a>
+      <a href="#why-custom">Why custom CRM</a>
       <a href="#why">Why AI</a>
       <a href="#loops">Loops</a>
       <a href="#cron">Cron</a>
@@ -113,6 +114,31 @@
   </div>
 </section>
 
+<!-- ─────────── why custom CRM (vs Salesforce/EveryAction/HubSpot) ─────────── -->
+<section id="why-custom" class="lecture">
+  <div class="lecture-inner">
+    <span class="section-num" style="background:#047857;">$</span>
+    <h2 data-bind="why_custom_crm.headline"></h2>
+    <p class="sub" data-bind="why_custom_crm.intro"></p>
+    <div class="callout callout-strategy">
+      <h3>The short answer</h3>
+      <p data-bind="why_custom_crm.the_short_answer"></p>
+    </div>
+    <h3 class="subsection">Head-to-head — 8 axes</h3>
+    <div class="crm-compare-wrap"><table class="crm-compare" id="crm-compare"></table></div>
+    <div class="callout callout-info">
+      <h3>The hybrid play</h3>
+      <p data-bind="why_custom_crm.the_hybrid_play"></p>
+    </div>
+    <h3 class="subsection">Honest risks (don't hide these from SDCC)</h3>
+    <ul class="lecture-bullets compact" data-bind-list="why_custom_crm.honest_risks"></ul>
+    <div class="callout callout-honest">
+      <h3>The real question to ask SDCC</h3>
+      <p data-bind="why_custom_crm.the_real_question"></p>
+    </div>
+  </div>
+</section>
+
 <!-- ─────────── wix integration ─────────── -->
 <section id="wix" class="lecture alt">
   <div class="lecture-inner">
diff --git a/public/styles.css b/public/styles.css
index 8f372d9..a0caffd 100644
--- a/public/styles.css
+++ b/public/styles.css
@@ -637,6 +637,34 @@ code { font-family: 'SF Mono', Menlo, Consolas, monospace; font-size: .85em; bac
 }
 .shift-table td.after-col { background: var(--good-soft); color: #064e3b; }
 
+/* ────── CRM compare table ────── */
+.crm-compare-wrap { overflow-x: auto; margin: 0 0 24px; }
+.crm-compare {
+  width: 100%; border-collapse: separate; border-spacing: 0;
+  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
+  overflow: hidden; min-width: 720px;
+}
+.crm-compare th {
+  background: linear-gradient(180deg, #f8fafc, #fff); padding: 14px 16px;
+  text-align: left; font-size: 13px; color: var(--muted);
+  text-transform: uppercase; letter-spacing: 1px;
+  border-bottom: 2px solid var(--border);
+}
+.crm-compare th.norma-col { color: var(--sdcc-blue-deep); background: var(--info-soft); }
+.crm-compare td {
+  padding: 14px 16px; font-size: 13.5px; color: var(--ink-2); line-height: 1.55;
+  border-bottom: 1px solid var(--border-soft); vertical-align: top;
+}
+.crm-compare td.axis { font-weight: 700; color: var(--ink); background: var(--bg); }
+.crm-compare td.norma-col { background: var(--info-soft); }
+.crm-compare td.win { position: relative; background: var(--good-soft); color: #064e3b; font-weight: 500; }
+.crm-compare td.win::before {
+  content: "★"; position: absolute; top: 6px; right: 8px;
+  color: var(--good); font-size: 12px;
+}
+.crm-compare td.norma-col.win { background: linear-gradient(180deg, var(--good-soft), var(--info-soft)); }
+.crm-compare tr:last-child td { border-bottom: none; }
+
 /* ────── wix options ────── */
 .wix-options { display: grid; gap: 14px; margin-bottom: 28px; }
 .wix-option-card {

← 2907114 add: top-5 priorities, reluctant-adopter, companies-are-data  ·  back to Norma Sdcc Pitch  ·  hero: lead with 'A CRM that fits SDCC's work. Not the other 502c282 →