6a7c5161ff
Marty's read was right — the upper tiers felt flat, and the reason is that they scaled QUANTITY, not KIND. L1->L2 was a category change (you couldn't write, now you can). Everything above L4 was a multiplier on a capability already owned at L2: sound more like you, measure it, more pages, five at once. Meanwhile the price doubles each rung — Corona costs ~17x Culmen. No batch button is worth 17x a voice profile. The fix is a change of axis. Every tool from L1 to L8 was a "me" tool, but past the first levels this business isn't about you: get two, help your two, teach them to teach. So the top now operates on the ORGANISATION. L7 Team Grants — hand Suite capacity down to anyone in your own org. Deliberately from a separate pool that the level grants, NOT out of the leader's own allowance: making someone choose between equipping their team and using their own tools means nobody ever grants anything. Recipients are verified in-org against the contract. Grants can lift a tool the recipient's level hasn't unlocked — that's the point, not a loophole. Being helped is made visible to the recipient, since half the value is knowing an upline backed you. L8 Network Intelligence — every team ad pooled and anonymised: which angles, headlines, creative and formats actually earn their impressions. No member alone has enough traffic to learn anything from display; together they do. It can't be bought, and it compounds monthly with no further work. Holds two lines: nothing identifies anyone, and nothing under 2,000 impressions gets a reported rate — under-evidenced rows are counted and disclosed rather than silently dropped. The written readout is hand-authored, not generated: these are conclusions about money, and a model paraphrasing a table is exactly where an invented number slips in. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
90 lines
4.2 KiB
JavaScript
90 lines
4.2 KiB
JavaScript
// Network Intelligence client — renders the pooled, anonymised ad results.
|
||
(function () {
|
||
'use strict';
|
||
var $ = function (id) { return document.getElementById(id); };
|
||
function esc(s) {
|
||
return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) {
|
||
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c];
|
||
});
|
||
}
|
||
function n(v) { return Number(v || 0).toLocaleString(); }
|
||
function pct(r) { return (Number(r || 0) * 100).toFixed(3) + '%'; }
|
||
|
||
function gate(msg) {
|
||
$('iLoading').style.display = 'none';
|
||
$('iGate').style.display = 'block';
|
||
$('iGate').innerHTML = msg;
|
||
}
|
||
|
||
function tile(v, label, cls) {
|
||
return '<div class="i-tile ' + (cls || '') + '"><div class="big">' + v + '</div><div class="lab">' + label + '</div></div>';
|
||
}
|
||
|
||
function section(title, why, group, unitLabel) {
|
||
if (!group || !group.rows.length) return '';
|
||
var top = group.rows[0].rate || 1;
|
||
var rows = group.rows.map(function (r) {
|
||
var w = Math.max(2, Math.round((r.rate / top) * 100));
|
||
return '<tr><td><b>' + esc(r.label) + '</b></td>' +
|
||
'<td>' + n(r.served) + '</td>' +
|
||
'<td>' + n(r.clicks) + '</td>' +
|
||
'<td><b>' + pct(r.rate) + '</b></td>' +
|
||
'<td style="width:110px"><div class="i-bar" style="width:' + w + '%"></div></td></tr>';
|
||
}).join('');
|
||
var thin = group.thin
|
||
? '<div class="i-thin">' + group.thin + ' more not shown — under the evidence threshold (' +
|
||
n(group.thinServed) + ' impressions between them).</div>'
|
||
: '';
|
||
return '<div class="i-sec"><h2>' + esc(title) + '</h2><div class="why">' + esc(why) + '</div>' +
|
||
'<div class="table-wrap"><table class="i-tbl"><thead><tr><th>' + esc(unitLabel) +
|
||
'</th><th>Served</th><th>Clicks</th><th>Rate</th><th></th></tr></thead><tbody>' +
|
||
rows + '</tbody></table></div>' + thin + '</div>';
|
||
}
|
||
|
||
function render(d) {
|
||
var rep = d.report;
|
||
$('iLoading').style.display = 'none';
|
||
if (!rep || !rep.ready) {
|
||
gate('<b>Not enough data yet.</b> ' + esc((rep && rep.reason) || 'This fills in as the team advertises.'));
|
||
return;
|
||
}
|
||
$('iBody').style.display = 'block';
|
||
|
||
$('iTiles').innerHTML =
|
||
tile(n(rep.totals.ads), 'team ads measured', 'cool') +
|
||
tile(n(rep.totals.served), 'impressions served') +
|
||
tile(n(rep.totals.clicks), 'clicks', 'cool') +
|
||
tile(pct(rep.totals.rate), 'network click rate');
|
||
|
||
$('iReadout').innerHTML = (d.readout || []).map(function (line) {
|
||
return '<div>' + esc(line) + '</div>';
|
||
}).join('') || '<div>Not enough evidence yet to draw conclusions.</div>';
|
||
|
||
var html = '';
|
||
html += section('Format', 'Text placements against banner placements, across everything the team has run.', rep.format, 'Format');
|
||
html += section('Angle', 'Which hook the destination link carried. This is the one worth acting on — it tells you what to lead with everywhere, not just in ads.', rep.angle, 'Angle');
|
||
html += section('Banner creative', 'Which designs from the team kit are actually earning their impressions.', rep.creative, 'Design');
|
||
html += section('Banner size', 'Placement size, pooled across every design.', rep.size, 'Size');
|
||
html += section('Text ad headlines', 'Individual headlines that have run enough to be judged.', rep.headline, 'Headline');
|
||
$('iSections').innerHTML = html || '<div class="i-sec"><div class="why">Nothing has crossed the evidence threshold yet. Keep the ads running.</div></div>';
|
||
}
|
||
|
||
async function boot() {
|
||
try {
|
||
var r = await fetch('/api/public/suite-intel');
|
||
if (r.status === 401) { gate('You’re not signed in yet. <a href="/suite" style="color:var(--gold);font-weight:700">Open the Suite</a> and connect the wallet that holds your position, then come back.'); return; }
|
||
if (r.status === 403) {
|
||
var g = await r.json();
|
||
gate((g.error || 'Not open for this position yet.') + ' <a href="/suite" style="color:var(--gold);font-weight:700">See your Suite</a>.');
|
||
return;
|
||
}
|
||
if (!r.ok) { gate('Could not read the network just now — try again shortly.'); return; }
|
||
render(await r.json());
|
||
} catch (e) {
|
||
gate('Connection hiccup — reload to try again.');
|
||
}
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', boot);
|
||
})();
|