diff --git a/brainsnn-r3f-app/index.html b/brainsnn-r3f-app/index.html index 405ca17..e0426bb 100644 --- a/brainsnn-r3f-app/index.html +++ b/brainsnn-r3f-app/index.html @@ -3,20 +3,20 @@ - BrainSNN — Paste any tweet. See which feeling it installs. - + BrainSNN — Affective-Intelligence Engine for the Open Web + - - - + + + - - - + + + diff --git a/brainsnn-r3f-app/src/App.jsx b/brainsnn-r3f-app/src/App.jsx index afb3b3f..7fef1d4 100644 --- a/brainsnn-r3f-app/src/App.jsx +++ b/brainsnn-r3f-app/src/App.jsx @@ -81,6 +81,7 @@ import HotkeyMap from './components/HotkeyMap'; import ThemePanel from './components/ThemePanel'; import CommunityPackPanel from './components/CommunityPackPanel'; import MilestonePanel from './components/MilestonePanel'; +import BrandRiskPanel from './components/BrandRiskPanel'; import { registerServiceWorker } from './utils/pwa'; import { registerTheme } from './utils/theme'; import DreamModePanel from './components/DreamModePanel'; @@ -779,6 +780,10 @@ export default function App() { + + + + diff --git a/brainsnn-r3f-app/src/components/BrandRiskPanel.jsx b/brainsnn-r3f-app/src/components/BrandRiskPanel.jsx new file mode 100644 index 0000000..b713356 --- /dev/null +++ b/brainsnn-r3f-app/src/components/BrandRiskPanel.jsx @@ -0,0 +1,228 @@ +import React, { useMemo, useState } from 'react'; +import { computeBrandRisk, brandBriefMarkdown, splitItems } from '../utils/brandRisk.js'; + +/** + * Layer 106 — Brand Risk Scorecard + * + * Per-brand aggregator over the Cognitive Firewall + Templates + + * Archetypes. Paste a brand name + a list of items (mentions, ad copy, + * reviews, replies), get a single 0–100 score with a tier, the dominant + * archetypes, the most-fired templates, and the worst items. + * + * Surfaces the affective-intelligence positioning to teams who don't + * scan one tweet at a time — they read inboxes, mention streams, ad + * libraries, and need the headline number first. + */ + +const SAMPLE = `Act now or you'll miss the launch — only 12 spots left and our CEO personally vouches for every founder we let in. The window closes at midnight. +--- +Honestly, every one of you who's still defending this brand needs to look in the mirror. You're either with us or you're part of the problem. Wake up. +--- +We've quietly rolled out a small UX update this week. Let us know if anything feels off — we're tracking feedback in the linked thread and will iterate next sprint. +--- +URGENT: Your account has been flagged for unusual activity. Verify your identity within 24 hours or access will be permanently suspended. Click below to confirm. +--- +The mainstream press will never tell you the real story behind this acquisition. The truth is hidden in plain sight. Connect the dots.`; + +export default function BrandRiskPanel() { + const [brand, setBrand] = useState(''); + const [blob, setBlob] = useState(''); + const [report, setReport] = useState(null); + const [copied, setCopied] = useState(false); + + const itemCountPreview = useMemo(() => splitItems(blob).length, [blob]); + + function handleScan() { + const items = splitItems(blob); + const next = computeBrandRisk(items); + setReport(next); + } + + function handleSample() { + setBlob(SAMPLE); + if (!brand) setBrand('Sample Brand'); + } + + function handleClear() { + setBlob(''); + setReport(null); + } + + async function handleCopyBrief() { + if (!report) return; + const md = brandBriefMarkdown(brand, report); + try { + await navigator.clipboard.writeText(md); + setCopied(true); + window.setTimeout(() => setCopied(false), 1800); + } catch (_err) { + setCopied(false); + } + } + + return ( +
+
Layer 106 · brand risk scorecard
+

Score a brand's emotional payload

+

+ Paste a name and a stream of mentions, ad variants, reviews, or replies. The engine scores + every item, names the manipulation archetypes that fire, and rolls them into a single 0–100 + risk number with a clear tier. +

+ +
+ setBrand(e.target.value)} + className="brand-risk-input" + style={{ padding: '10px 12px', borderRadius: 8, background: 'rgba(0,0,0,0.25)', border: '1px solid rgba(255,255,255,0.08)', color: '#f1ece5' }} + /> +