1291 lines
46 KiB
HTML
1291 lines
46 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>CBP What-If Calculator</title>
|
||
<style>
|
||
:root {
|
||
--bg: #0f1117;
|
||
--card: #1a1d2e;
|
||
--card-hover: #212539;
|
||
--border: #2a2e45;
|
||
--accent: #6c5ce7;
|
||
--accent-glow: rgba(108,92,231,0.3);
|
||
--green: #00d68f;
|
||
--green-dim: rgba(0,214,143,0.12);
|
||
--red: #ff6b6b;
|
||
--yellow: #ffd93d;
|
||
--orange: #ff9f43;
|
||
--text: #e4e6f0;
|
||
--text-dim: #8a8fa8;
|
||
--text-muted: #5a5e7a;
|
||
--font: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
||
--radius: 12px;
|
||
--radius-sm: 8px;
|
||
}
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
body {
|
||
font-family: var(--font);
|
||
background: var(--bg);
|
||
color: var(--text);
|
||
min-height: 100vh;
|
||
padding: 16px;
|
||
}
|
||
.container { max-width: 1200px; margin: 0 auto; }
|
||
|
||
/* Header */
|
||
.header {
|
||
text-align: center;
|
||
padding: 30px 16px 24px;
|
||
}
|
||
.header h1 {
|
||
font-size: 2rem;
|
||
font-weight: 700;
|
||
background: linear-gradient(135deg, var(--accent), #a78bfa);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
}
|
||
.header p {
|
||
color: var(--text-dim);
|
||
margin-top: 6px;
|
||
font-size: 0.9rem;
|
||
}
|
||
.cta-bar {
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 12px;
|
||
margin-top: 16px;
|
||
flex-wrap: wrap;
|
||
}
|
||
.cta-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 12px 28px;
|
||
border-radius: var(--radius);
|
||
font-size: 1rem;
|
||
font-weight: 600;
|
||
text-decoration: none;
|
||
transition: all .2s;
|
||
cursor: pointer;
|
||
border: none;
|
||
}
|
||
.cta-btn-primary {
|
||
background: var(--accent);
|
||
color: #fff;
|
||
box-shadow: 0 0 20px var(--accent-glow);
|
||
}
|
||
.cta-btn-primary:hover {
|
||
background: #7c6df7;
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 0 30px var(--accent-glow);
|
||
}
|
||
.cta-btn-secondary {
|
||
background: var(--card);
|
||
color: var(--text);
|
||
border: 1px solid var(--border);
|
||
}
|
||
.cta-btn-secondary:hover {
|
||
background: var(--card-hover);
|
||
border-color: var(--accent);
|
||
}
|
||
|
||
/* Controls */
|
||
.controls {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||
gap: 12px;
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
padding: 20px;
|
||
margin-bottom: 20px;
|
||
}
|
||
.control-group {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 5px;
|
||
}
|
||
.control-group label {
|
||
font-size: 0.72rem;
|
||
font-weight: 600;
|
||
color: var(--text-dim);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.5px;
|
||
}
|
||
.control-group .fixed-value {
|
||
font-size: 1.1rem;
|
||
font-weight: 600;
|
||
color: var(--green);
|
||
padding: 8px 0;
|
||
}
|
||
.control-group .fixed-value .note {
|
||
font-size: 0.7rem;
|
||
font-weight: 400;
|
||
color: var(--text-muted);
|
||
}
|
||
.control-group input, .control-group select {
|
||
background: var(--bg);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
padding: 9px 12px;
|
||
color: var(--text);
|
||
font-size: 0.9rem;
|
||
font-family: var(--font);
|
||
outline: none;
|
||
transition: border-color 0.2s;
|
||
}
|
||
.control-group input:focus, .control-group select:focus {
|
||
border-color: var(--accent);
|
||
box-shadow: 0 0 0 3px var(--accent-glow);
|
||
}
|
||
.control-group input[type="number"] { -moz-appearance: textfield; }
|
||
.control-group input::-webkit-inner-spin-button, .control-group input::-webkit-outer-spin-button { -webkit-appearance: none; }
|
||
.checkbox-group {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding-top: 20px;
|
||
}
|
||
.checkbox-group label {
|
||
font-size: 0.82rem;
|
||
font-weight: 400;
|
||
text-transform: none;
|
||
letter-spacing: 0;
|
||
color: var(--text);
|
||
}
|
||
.checkbox-group input[type="checkbox"] {
|
||
width: 16px;
|
||
height: 16px;
|
||
accent-color: var(--accent);
|
||
}
|
||
|
||
/* Tabs */
|
||
.tabs {
|
||
display: flex;
|
||
gap: 4px;
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
padding: 4px;
|
||
margin-bottom: 18px;
|
||
overflow-x: auto;
|
||
}
|
||
.tab-btn {
|
||
flex: 1;
|
||
padding: 9px 14px;
|
||
border: none;
|
||
border-radius: 8px;
|
||
background: transparent;
|
||
color: var(--text-dim);
|
||
font-size: 0.82rem;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
white-space: nowrap;
|
||
font-family: var(--font);
|
||
}
|
||
.tab-btn:hover { color: var(--text); background: var(--card-hover); }
|
||
.tab-btn.active { background: var(--accent); color: white; }
|
||
|
||
.results { display: none; }
|
||
.results.active { display: block; }
|
||
|
||
/* Summary */
|
||
.summary-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
||
gap: 10px;
|
||
margin-bottom: 20px;
|
||
}
|
||
.summary-card {
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
padding: 16px;
|
||
text-align: center;
|
||
}
|
||
.summary-card .label {
|
||
font-size: 0.68rem;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.5px;
|
||
color: var(--text-dim);
|
||
font-weight: 600;
|
||
}
|
||
.summary-card .value {
|
||
font-size: 1.5rem;
|
||
font-weight: 700;
|
||
margin-top: 5px;
|
||
}
|
||
.summary-card .value.green { color: var(--green); }
|
||
.summary-card .value.accent { color: var(--accent); }
|
||
.summary-card .value.yellow { color: var(--yellow); }
|
||
.summary-card .value.orange { color: var(--orange); }
|
||
.summary-card .sub {
|
||
font-size: 0.75rem;
|
||
color: var(--text-muted);
|
||
margin-top: 3px;
|
||
}
|
||
|
||
/* Chart area */
|
||
.chart-wrap {
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
padding: 20px;
|
||
margin-bottom: 20px;
|
||
overflow: hidden;
|
||
}
|
||
.chart-wrap h3 {
|
||
font-size: 0.85rem;
|
||
font-weight: 600;
|
||
color: var(--text-dim);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.5px;
|
||
margin-bottom: 16px;
|
||
}
|
||
#chartContainer {
|
||
width: 100%;
|
||
height: 320px;
|
||
position: relative;
|
||
}
|
||
#profitChart {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
/* Tables */
|
||
.table-wrap {
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
overflow: hidden;
|
||
margin-bottom: 18px;
|
||
}
|
||
.table-wrap .table-title {
|
||
padding: 14px 18px 0;
|
||
font-size: 0.82rem;
|
||
font-weight: 600;
|
||
color: var(--text-dim);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.5px;
|
||
}
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
font-size: 0.84rem;
|
||
}
|
||
thead th {
|
||
text-align: left;
|
||
padding: 12px 18px;
|
||
font-size: 0.7rem;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.5px;
|
||
color: var(--text-dim);
|
||
font-weight: 600;
|
||
border-bottom: 1px solid var(--border);
|
||
background: rgba(255,255,255,0.02);
|
||
}
|
||
tbody td {
|
||
padding: 10px 18px;
|
||
border-bottom: 1px solid rgba(42,46,69,0.5);
|
||
}
|
||
tbody tr:last-child td { border-bottom: none; }
|
||
tbody tr:hover { background: var(--card-hover); }
|
||
tbody tr.highlight td { background: var(--green-dim); font-weight: 600; }
|
||
tbody tr.endgame td { background: rgba(108,92,231,0.12); font-weight: 600; }
|
||
.num { text-align: right; font-variant-numeric: tabular-nums; }
|
||
.green-text { color: var(--green); }
|
||
.accent-text { color: var(--accent); }
|
||
|
||
.legend {
|
||
display: flex;
|
||
gap: 16px;
|
||
padding: 0 18px 12px;
|
||
flex-wrap: wrap;
|
||
}
|
||
.legend-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
font-size: 0.75rem;
|
||
color: var(--text-dim);
|
||
}
|
||
.legend-dot {
|
||
width: 10px;
|
||
height: 10px;
|
||
border-radius: 3px;
|
||
flex-shrink: 0;
|
||
}
|
||
.legend-dot.green { background: var(--green); }
|
||
.legend-dot.accent { background: var(--accent); }
|
||
.legend-dot.yellow { background: var(--yellow); }
|
||
.legend-dot.orange { background: var(--orange); }
|
||
|
||
/* Comparison table styling */
|
||
.scenario-row { cursor: pointer; transition: background 0.15s; }
|
||
.scenario-row:hover { background: var(--card-hover) !important; }
|
||
.scenario-row.active-row { background: rgba(108,92,231,0.15) !important; }
|
||
|
||
@media (max-width: 640px) {
|
||
body { padding: 10px; }
|
||
.header h1 { font-size: 1.4rem; }
|
||
.controls { grid-template-columns: 1fr 1fr; gap: 10px; padding: 14px; }
|
||
.summary-grid { grid-template-columns: repeat(2, 1fr); }
|
||
.summary-card .value { font-size: 1.15rem; }
|
||
.tab-btn { font-size: 0.75rem; padding: 7px 10px; }
|
||
table { font-size: 0.74rem; }
|
||
thead th, tbody td { padding: 8px 10px; }
|
||
#chartContainer { height: 240px; }
|
||
}
|
||
|
||
/* Shared link row */
|
||
.shared-link-row {
|
||
display: flex;
|
||
gap: 4px;
|
||
}
|
||
.shared-link-row input {
|
||
flex: 1;
|
||
font-size: 0.78rem;
|
||
font-family: monospace;
|
||
color: var(--accent);
|
||
background: var(--bg);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius-sm);
|
||
padding: 7px 10px;
|
||
outline: none;
|
||
}
|
||
.copy-sm-btn {
|
||
background: var(--accent);
|
||
color: #fff;
|
||
border: none;
|
||
padding: 7px 14px;
|
||
border-radius: var(--radius-sm);
|
||
cursor: pointer;
|
||
font-size: 0.78rem;
|
||
font-weight: 600;
|
||
white-space: nowrap;
|
||
transition: opacity 0.2s;
|
||
}
|
||
.copy-sm-btn:hover { opacity: 0.85; }
|
||
.copy-sm-btn.copied { background: var(--green); }
|
||
.sub-hint {
|
||
font-size: 0.68rem;
|
||
color: var(--text-muted);
|
||
margin-top: 4px;
|
||
}
|
||
|
||
/* Shareable plan section */
|
||
.plan-section {
|
||
background: var(--card);
|
||
border: 1px solid var(--border);
|
||
border-radius: var(--radius);
|
||
margin: 16px 0 20px;
|
||
overflow: hidden;
|
||
}
|
||
.plan-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 12px 16px;
|
||
background: var(--card-hover);
|
||
border-bottom: 1px solid var(--border);
|
||
font-weight: 600;
|
||
font-size: 0.85rem;
|
||
}
|
||
.copy-btn {
|
||
background: var(--accent);
|
||
color: #fff;
|
||
border: none;
|
||
padding: 5px 14px;
|
||
border-radius: var(--radius-sm);
|
||
cursor: pointer;
|
||
font-size: 0.78rem;
|
||
font-weight: 600;
|
||
transition: opacity 0.2s;
|
||
}
|
||
.copy-btn:hover { opacity: 0.85; }
|
||
.copy-btn.copied { background: var(--green); }
|
||
.plan-output {
|
||
padding: 16px;
|
||
margin: 0;
|
||
font-size: 0.82rem;
|
||
line-height: 1.6;
|
||
color: var(--text);
|
||
white-space: pre-wrap;
|
||
font-family: var(--font);
|
||
max-height: 500px;
|
||
overflow-y: auto;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
|
||
<div class="header">
|
||
<h1>CBP What-If Calculator</h1>
|
||
<p>Full ladder modeling — profit timeline, referral earnings, and scenario comparison</p>
|
||
<div class="cta-bar" id="ctaBar">
|
||
<a class="cta-btn cta-btn-primary" id="signupBtn" target="_blank" rel="noopener">
|
||
🚀 Sign Up with My Referral Link
|
||
</a>
|
||
<button class="cta-btn cta-btn-secondary" onclick="copyCalculatorLink()">
|
||
📄 Copy Calculator Link
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Controls -->
|
||
<div class="controls">
|
||
<div class="control-group">
|
||
<label>Number of people</label>
|
||
<input type="number" id="numPeople" value="1" min="1" max="100">
|
||
</div>
|
||
<div class="control-group">
|
||
<label>Your referral commission</label>
|
||
<div class="fixed-value">10% <span class="note">(fixed, not variable)</span></div>
|
||
<input type="hidden" id="commissionPct" value="10">
|
||
</div>
|
||
<div class="control-group">
|
||
<label>You gift up to level</label>
|
||
<select id="giftLevel">
|
||
<option value="0">None (no gift)</option>
|
||
<option value="1">Level 1 ($14)</option>
|
||
<option value="2">Level 2 ($98)</option>
|
||
<option value="3" selected>Level 3 ($263)</option>
|
||
<option value="4">Level 4 ($593)</option>
|
||
<option value="5">Level 5 ($1,253)</option>
|
||
</select>
|
||
</div>
|
||
<div class="control-group">
|
||
<label>They self-fund through level</label>
|
||
<select id="selfFundLevel">
|
||
<option value="0" selected>None (gift only)</option>
|
||
<option value="1">Level 1 ($14)</option>
|
||
<option value="2">Level 2 ($98)</option>
|
||
<option value="3">Level 3 ($263)</option>
|
||
<option value="4">Level 4 ($593)</option>
|
||
<option value="5">Level 5 ($1,253)</option>
|
||
</select>
|
||
</div>
|
||
<div class="checkbox-group">
|
||
<input type="checkbox" id="showReferral" checked>
|
||
<label for="showReferral">Show referral earnings (my 10%)</label>
|
||
</div>
|
||
<div class="control-group">
|
||
<label>Share this link (sends the plan as-is)</label>
|
||
<div class="shared-link-row">
|
||
<input type="text" id="sharedLink" readonly>
|
||
<button class="copy-sm-btn" id="copyLinkBtn" onclick="copySharedLink()">📄 Copy</button>
|
||
</div>
|
||
<div class="sub-hint">The referral opens the calculator with your username pre-loaded</div>
|
||
<div class="qr-row" style="margin-top: 12px; text-align: center;">
|
||
<img id="refQrCode" src="https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=https://cbp-calculator.saasy.top?ref=cryptoteambuild" alt="QR Code" style="width:160px;height:160px;border-radius:12px;border:2px solid var(--border);">
|
||
<div style="font-size:12px;color:var(--text-secondary);margin-top:6px;">📱 Scan to open calculator</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="shareablePlan" class="plan-section">
|
||
<div class="plan-header">
|
||
<span>📋 Referral Plan Preview</span>
|
||
<button class="copy-btn" id="copyPlanBtn" onclick="copyPlan()">📄 Copy Plan</button>
|
||
</div>
|
||
<pre id="planOutput" class="plan-output"></pre>
|
||
</div>
|
||
|
||
<!-- Tabs -->
|
||
<div class="tabs">
|
||
<button class="tab-btn active" data-tab="overview">📊 Overview</button>
|
||
<button class="tab-btn" data-tab="timeline">📈 Profit Timeline</button>
|
||
<button class="tab-btn" data-tab="ladder">🪜 Full Ladder</button>
|
||
<button class="tab-btn" data-tab="comparison">⚖️ Compare</button>
|
||
</div>
|
||
|
||
<!-- Tab: Overview -->
|
||
<div class="results active" id="tab-overview">
|
||
<div class="summary-grid" id="summaryCards"></div>
|
||
|
||
<div class="chart-wrap">
|
||
<h3>📈 Cumulative Profit Over Time</h3>
|
||
<div id="chartContainer">
|
||
<canvas id="profitChart"></canvas>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="table-wrap" id="overviewPhaseWrap">
|
||
<div class="table-title">📍 Phase-by-Phase Journey</div>
|
||
<div class="legend">
|
||
<div class="legend-item"><div class="legend-dot green"></div> ROI achieved</div>
|
||
<div class="legend-item"><div class="legend-dot accent"></div> Endgame (3× L7)</div>
|
||
</div>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Phase</th>
|
||
<th class="num">Cycles</th>
|
||
<th>Timeline</th>
|
||
<th class="num">Their Payout/Cycle</th>
|
||
<th class="num referral-col">Your 10% Cut/Cycle</th>
|
||
<th class="num">Cumulative to You</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="overviewBody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab: Profit Timeline -->
|
||
<div class="results" id="tab-timeline">
|
||
<div class="chart-wrap">
|
||
<h3>📈 Monthly Profit Progression</h3>
|
||
<div id="chartContainer2">
|
||
<canvas id="timelineChart"></canvas>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="table-wrap">
|
||
<div class="table-title">📅 Month-by-Month Breakdown</div>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Month</th>
|
||
<th>Active Phase</th>
|
||
<th class="num">Their Profit This Month</th>
|
||
<th class="num referral-col">Your 10% Commission/Month</th>
|
||
<th class="num">Your Cumulative</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="timelineBody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab: Full Ladder -->
|
||
<div class="results" id="tab-ladder">
|
||
<div class="table-wrap">
|
||
<div class="table-title">🪜 Complete Ladder — All Levels</div>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Level</th>
|
||
<th>Activation Fee</th>
|
||
<th class="num">Campaign Cost</th>
|
||
<th class="num">Total Prerequisite</th>
|
||
<th class="num">Payout (After 10% Fee)</th>
|
||
<th class="num">Net Profit/Cycle</th>
|
||
<th class="num">Clicks/Day</th>
|
||
<th class="num">CPC</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="ladderBody"></tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="table-wrap">
|
||
<div class="table-title">🪜 Your Ladder Progression (based on starting position)</div>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Step</th>
|
||
<th>Required Capital</th>
|
||
<th class="num">Investment</th>
|
||
<th class="num">Return</th>
|
||
<th class="num">Profit</th>
|
||
<th class="num">Cycles</th>
|
||
<th>Est. Time</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="ladderProgressionBody"></tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab: Compare -->
|
||
<div class="results" id="tab-comparison">
|
||
<div class="table-wrap">
|
||
<div class="table-title">⚖️ All Scenarios Side by Side (per person)</div>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Scenario</th>
|
||
<th class="num">Their Upfront</th>
|
||
<th class="num">Your Cost</th>
|
||
<th class="num">Time to 3× L7</th>
|
||
<th class="num">Year 1 Earnings</th>
|
||
<th class="num">Total to Endgame</th>
|
||
<th class="num">Monthly at 3× L7</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="comparisonBody"></tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="chart-wrap">
|
||
<h3>⚖️ Scenario Comparison — Year 1 Earnings by Start</h3>
|
||
<div id="chartContainer3">
|
||
<canvas id="compareChart"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="text-align:center;padding:24px 0 10px;color:var(--text-muted);font-size:0.75rem;">
|
||
Built for CBP wargaming • All figures in USDT • 10% withdrawal fee already factored into payouts • <br>
|
||
Referral link: https://clickbaitpays.me/?ref=cryptoteambuild
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script>
|
||
<script>
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
// CORE DATA
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
const LEVELS = [
|
||
{ level: 1, act: 1, camp: 13, total: 14, payout: 17.17, clicks: 3, cpc: 0.48, netProfit: 4.17 },
|
||
{ level: 2, act: 7, camp: 77, total: 84, payout: 101.74, clicks: 3, cpc: 2.83, netProfit: 24.74 },
|
||
{ level: 3, act: 15, camp: 150, total: 165, payout: 194.40, clicks: 3, cpc: 5.40, netProfit: 44.40 },
|
||
{ level: 4, act: 30, camp: 300, total: 330, payout: 388.80, clicks: 5, cpc: 6.48, netProfit: 88.80 },
|
||
{ level: 5, act: 60, camp: 600, total: 660, payout: 777.60, clicks: 6, cpc: 10.80, netProfit: 177.60 },
|
||
{ level: 6, act: 120, camp: 1200, total: 1320, payout: 1555.20,clicks: 10, cpc: 12.96, netProfit: 355.20 },
|
||
{ level: 7, act: 240, camp: 2400, total: 2640, payout: 3240.00,clicks: 20, cpc: 13.50, netProfit: 840.00 },
|
||
];
|
||
|
||
const HYBRIDS = {
|
||
'L1-only': { label: 'L1 Only', reinvest: 13, payout: 17.17, profit: 4.17, cycles: 9, months: 3.0, daysPer: 19 },
|
||
'L2+L1': { label: 'L2 + L1', reinvest: 90, payout: 118.91, profit: 28.91, cycles: 4, months: 2.5, daysPer: 19 },
|
||
'L3+L1': { label: 'L3 + L1', reinvest: 163, payout: 211.57, profit: 48.57, cycles: 4, months: 2.5, daysPer: 19 },
|
||
'L4+L3': { label: 'L4 + L3', reinvest: 450, payout: 583.20, profit: 133.20,cycles: 5, months: 3.0, daysPer: 19 },
|
||
'L5+L4': { label: 'L5 + L4', reinvest: 900, payout: 1166.40,profit: 266.40,cycles: 4, months: 2.0, daysPer: 19 },
|
||
'L6': { label: 'L6', reinvest: 1200, payout: 1555.20,profit: 355.20,cycles: 4, months: 2.0, daysPer: 19 },
|
||
'L7': { label: 'Single L7', reinvest: 2400, payout: 3240.00,profit: 840.00,cycles: 7, months: 3.0, daysPer: 19 },
|
||
'3xL7': { label: '3× L7 Endgame', reinvest: 7200, payout: 9720, profit: 2520, cycles: 1, months: 0.63, daysPer: 19 },
|
||
};
|
||
|
||
// Ladder to endgame taken from the skill
|
||
const LADDER_STEPS = [
|
||
{ step: 'L4 Funded', capital: 300, invest: 300, ret: 388.80, profit: 88.80, cycles: 5, months: 3.0 },
|
||
{ step: 'L5 Ready', capital: 660, invest: 660, ret: 777.60, profit: 177.60,cycles: 5, months: 3.0 },
|
||
{ step: 'L6 Ready', capital: 1320, invest: 1320, ret: 1555.20,profit: 355.20,cycles: 4, months: 2.0 },
|
||
{ step: 'L7 Ready', capital: 2640, invest: 2640, ret: 3240.00,profit: 840.00,cycles: 7, months: 3.0 },
|
||
{ step: '3× L7 Endgame',capital: 7200, invest: 7200, ret: 9720, profit: 2520, cycles: 0, months: 0 },
|
||
];
|
||
|
||
const THREE_L7_YOUR_CUT = 972; // 10% of 9720
|
||
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
// SCENARIO DATA — computed from functions for consistency with Overview tab
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
function buildSCENARIOS() {
|
||
const levels = [
|
||
{ giftLvl: 1, selfLvl: 0, id: 'gift1', label: 'L1 Gift ($14)', yourCost: 14 },
|
||
{ giftLvl: 0, selfLvl: 1, id: 'self1', label: 'Self L1 ($14)', yourCost: 0 },
|
||
{ giftLvl: 2, selfLvl: 0, id: 'gift2', label: 'L1-L2 Gift ($98)', yourCost: 98 },
|
||
{ giftLvl: 0, selfLvl: 2, id: 'self2', label: 'Self L2 ($98)', yourCost: 0 },
|
||
{ giftLvl: 3, selfLvl: 0, id: 'gift3', label: 'L1-L3 Gift ($263)', yourCost: 263},
|
||
{ giftLvl: 0, selfLvl: 3, id: 'self3', label: 'Self L3 ($263)', yourCost: 0 },
|
||
{ giftLvl: 4, selfLvl: 0, id: 'gift4', label: 'L1-L4 Gift ($593)', yourCost: 593},
|
||
{ giftLvl: 0, selfLvl: 4, id: 'self4', label: 'Self L4 ($593)', yourCost: 0 },
|
||
{ giftLvl: 5, selfLvl: 0, id: 'gift5', label: 'L1-L5 Gift ($1,253)', yourCost:1253},
|
||
{ giftLvl: 0, selfLvl: 5, id: 'self5', label: 'Self L5 ($1,253)', yourCost: 0 },
|
||
];
|
||
return levels.map(s => {
|
||
const eff = Math.max(s.giftLvl, s.selfLvl);
|
||
const phases = getPhaseSequence(eff);
|
||
const t = Math.round(estimateMonths(phases));
|
||
const y = estimateYear1Cum(phases, 10, s.giftLvl);
|
||
const eg = phases.filter(k => k !== '3xL7')
|
||
.reduce((sum, k) => sum + HYBRIDS[k].payout * 0.10 * HYBRIDS[k].cycles, 0);
|
||
return { ...s, time: t, yr1: Math.round(y), totalEG: Math.round(eg), monthly: 1860 };
|
||
});
|
||
}
|
||
const SCENARIOS = buildSCENARIOS();
|
||
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
// HELPERS
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
function getLevelCost(upTo) {
|
||
if (upTo <= 0) return 0;
|
||
return LEVELS.slice(0, upTo).reduce((s, l) => s + l.total, 0);
|
||
}
|
||
|
||
function getEffectiveStart(gift, selfF) {
|
||
return Math.max(gift, selfF);
|
||
}
|
||
|
||
function getPhaseSequence(effectiveStart) {
|
||
// Returns ordered list of phase keys
|
||
if (effectiveStart >= 5) return ['L5+L4','L6','L7','3xL7'];
|
||
if (effectiveStart >= 4) return ['L4+L3','L5+L4','L6','L7','3xL7'];
|
||
if (effectiveStart >= 3) return ['L3+L1','L4+L3','L5+L4','L6','L7','3xL7'];
|
||
if (effectiveStart >= 2) return ['L2+L1','L3+L1','L4+L3','L5+L4','L6','L7','3xL7'];
|
||
return ['L1-only','L2+L1','L3+L1','L4+L3','L5+L4','L6','L7','3xL7'];
|
||
}
|
||
|
||
function estimateMonths(phases) {
|
||
let total = 0;
|
||
for (const k of phases) {
|
||
if (k === '3xL7') break;
|
||
total += HYBRIDS[k].months;
|
||
}
|
||
return Math.round(total * 10) / 10;
|
||
}
|
||
|
||
function estimateYear1Cum(phases, commPct, giftLevel) {
|
||
let cum = 0;
|
||
let months = 0;
|
||
for (const k of phases) {
|
||
if (k === '3xL7') break;
|
||
const p = HYBRIDS[k];
|
||
const yourCut = p.payout * (commPct / 100);
|
||
const cycInMonth = p.months / (p.daysPer / 30.4);
|
||
const cyclesInYear1 = Math.min(p.cycles, Math.max(0, (12 - months) / (p.months / p.cycles)));
|
||
const actual = Math.floor(cyclesInYear1);
|
||
for (let i = 0; i < actual; i++) cum += yourCut;
|
||
months += p.months;
|
||
if (months >= 12) break;
|
||
}
|
||
return Math.round(cum);
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
// BUILD MONTHLY TIMELINE DATA
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
function buildMonthlyTimeline(phases, commPct) {
|
||
const months = [];
|
||
let cumProf = 0, cumComm = 0;
|
||
let m = 0;
|
||
for (const k of phases) {
|
||
if (k === '3xL7') {
|
||
// Endgame: show a few months of ongoing
|
||
for (let i = 0; i < 6; i++) {
|
||
m++;
|
||
const p = HYBRIDS[k];
|
||
const yourCut = p.payout * (commPct / 100);
|
||
cumProf += p.profit;
|
||
cumComm += yourCut;
|
||
months.push({ m, phase: p.label, prof: Math.round(p.profit), comm: Math.round(yourCut), cumComm: Math.round(cumComm) });
|
||
}
|
||
break;
|
||
}
|
||
const p = HYBRIDS[k];
|
||
const yourCut = p.payout * (commPct / 100);
|
||
const cyclesThisPhase = p.cycles;
|
||
for (let c = 0; c < cyclesThisPhase; c++) {
|
||
m++;
|
||
cumProf += p.profit;
|
||
cumComm += yourCut;
|
||
months.push({ m, phase: c === 0 ? p.label : '', prof: Math.round(p.profit), comm: Math.round(yourCut), cumComm: Math.round(cumComm) });
|
||
}
|
||
if (m >= 30) break; // safety
|
||
}
|
||
return months;
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
// UI UPDATE
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
let chart1 = null, chart2 = null, chart3 = null;
|
||
|
||
function updateAll() {
|
||
const numPeople = parseInt(document.getElementById('numPeople').value) || 1;
|
||
const commPct = parseFloat(document.getElementById('commissionPct').value) || 10;
|
||
const giftLevel = parseInt(document.getElementById('giftLevel').value);
|
||
const selfLevel = parseInt(document.getElementById('selfFundLevel').value);
|
||
const showRef = document.getElementById('showReferral').checked;
|
||
|
||
const mult = commPct / 10;
|
||
const giftCost = getLevelCost(giftLevel);
|
||
const selfCost = getLevelCost(selfLevel);
|
||
const effective = getEffectiveStart(giftLevel, selfLevel);
|
||
const phases = getPhaseSequence(effective);
|
||
const totalMonths = estimateMonths(phases);
|
||
|
||
// Referral column visibility
|
||
document.querySelectorAll('.referral-col').forEach(el => {
|
||
el.style.display = showRef ? '' : 'none';
|
||
});
|
||
|
||
// ─── Overview Summary Cards ──────────────────────────
|
||
const yr1Cum = estimateYear1Cum(phases, commPct, giftLevel) * numPeople;
|
||
const yr1PerPerson = estimateYear1Cum(phases, commPct, giftLevel);
|
||
const totalEG = Math.round(phases.filter(k => k !== '3xL7')
|
||
.reduce((s, k) => s + HYBRIDS[k].payout * (commPct / 100) * HYBRIDS[k].cycles, 0) * 10) / 10;
|
||
const monthlyPassive = Math.round(THREE_L7_YOUR_CUT * mult * numPeople);
|
||
|
||
// Est total to 3× L7 per person
|
||
let totalToEGPerPerson = 0;
|
||
for (const k of phases) {
|
||
if (k === '3xL7') break;
|
||
totalToEGPerPerson += HYBRIDS[k].payout * (commPct / 100) * HYBRIDS[k].cycles;
|
||
}
|
||
totalToEGPerPerson = Math.round(totalToEGPerPerson * 100) / 100;
|
||
|
||
// ROI
|
||
let roiText = 'N/A', roiSub = '';
|
||
if (giftCost > 0) {
|
||
let cumCheck = 0;
|
||
for (const k of phases) {
|
||
if (k === '3xL7') break;
|
||
const p = HYBRIDS[k];
|
||
const yourCut = p.payout * (commPct / 100);
|
||
for (let i = 0; i < p.cycles; i++) {
|
||
cumCheck += yourCut;
|
||
if (cumCheck >= giftCost) {
|
||
const monthsTo = (phases.indexOf(k) * (p.daysPer / 30.4)) + (i + 1) * (p.daysPer / 30.4);
|
||
roiText = `~${Math.round(monthsTo * 10) / 10} months`;
|
||
roiSub = `during ${p.label}`;
|
||
break;
|
||
}
|
||
}
|
||
if (roiSub) break;
|
||
}
|
||
if (!roiSub) roiText = '~5.5 months';
|
||
}
|
||
|
||
const summaryHtml = `
|
||
<div class="summary-card">
|
||
<div class="label">Your Cost</div>
|
||
<div class="value accent">$${giftCost.toLocaleString()}</div>
|
||
<div class="sub">${numPeople > 1 ? `× ${numPeople} = $${(giftCost * numPeople).toLocaleString()}` : ''}</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="label">Their Cost</div>
|
||
<div class="value yellow">$${selfCost.toLocaleString()}</div>
|
||
<div class="sub">per person</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="label">Time to 3× L7</div>
|
||
<div class="value orange" style="font-size:1.3rem">~${totalMonths} months</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="label">Year 1 Referral Earnings</div>
|
||
<div class="value green">$${yr1Cum.toLocaleString()}</div>
|
||
<div class="sub">${numPeople > 1 ? `$${yr1PerPerson.toLocaleString()} / person` : ''}</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="label">ROI on Gift</div>
|
||
<div class="value green">${roiText}</div>
|
||
<div class="sub">${roiSub || (giftCost > 0 ? '' : 'no gift cost')}</div>
|
||
</div>
|
||
<div class="summary-card">
|
||
<div class="label">Monthly Passive (3× L7)</div>
|
||
<div class="value green">$${monthlyPassive.toLocaleString()}</div>
|
||
<div class="sub">${numPeople > 1 ? `$${Math.round(monthlyPassive / numPeople).toLocaleString()} / person` : 'per month'}</div>
|
||
</div>
|
||
`;
|
||
document.getElementById('summaryCards').innerHTML = summaryHtml;
|
||
|
||
// ─── Overview Phase Table ────────────────────────────
|
||
let cumRunning = 0;
|
||
let roiHit = false;
|
||
let rows = '';
|
||
for (const k of phases) {
|
||
const p = HYBRIDS[k];
|
||
const yourCut = p.payout * (commPct / 100);
|
||
const cyclesNum = p.cycles;
|
||
|
||
if (!roiHit && giftCost > 0) {
|
||
for (let i = 0; i < cyclesNum; i++) cumRunning += yourCut;
|
||
if (cumRunning >= giftCost) roiHit = true;
|
||
}
|
||
|
||
const isRoi = giftCost > 0 && !roiHit ? true : false;
|
||
const cls = k === '3xL7' ? 'endgame' : (isRoi && roiHit ? 'highlight' : '');
|
||
|
||
rows += `<tr class="${cls}">
|
||
<td>${p.label}</td>
|
||
<td class="num">${k === '3xL7' ? 'every 19d' : `${cyclesNum}×`}</td>
|
||
<td>${k === '3xL7' ? 'ongoing' : `~${p.months} months`}</td>
|
||
<td class="num">$${p.payout.toFixed(2)}</td>
|
||
<td class="num green-text">$${yourCut.toFixed(2)}</td>
|
||
<td class="num">$${cumRunning.toFixed(2)}</td>
|
||
</tr>`;
|
||
}
|
||
document.getElementById('overviewBody').innerHTML = rows;
|
||
|
||
// ─── Profit Chart ─────────────────────────────────────
|
||
const chartData = [];
|
||
let chartCum = 0;
|
||
let chartMonth = 0;
|
||
for (const k of phases) {
|
||
const p = HYBRIDS[k];
|
||
const yourCut = p.payout * (commPct / 100);
|
||
const cycles = k === '3xL7' ? 6 : p.cycles;
|
||
for (let i = 0; i < cycles; i++) {
|
||
chartMonth++;
|
||
chartCum += yourCut;
|
||
chartData.push({ m: chartMonth, cum: Math.round(chartCum * 100) / 100 });
|
||
}
|
||
if (k === '3xL7') break;
|
||
}
|
||
|
||
const chartLabels = chartData.map(d => `M${d.m}`);
|
||
const chartValues = chartData.map(d => d.cum);
|
||
|
||
// Destroy old charts
|
||
if (chart1) { chart1.destroy(); chart1 = null; }
|
||
if (chart2) { chart2.destroy(); chart2 = null; }
|
||
if (chart3) { chart3.destroy(); chart3 = null; }
|
||
|
||
const ctx1 = document.getElementById('profitChart').getContext('2d');
|
||
chart1 = new Chart(ctx1, {
|
||
type: 'line',
|
||
data: {
|
||
labels: chartLabels,
|
||
datasets: [{
|
||
label: `${numPeople > 1 ? `Total (${numPeople} people)` : 'Your'} Cumulative Referral Earnings`,
|
||
data: numPeople > 1 ? chartValues.map(v => v * numPeople) : chartValues,
|
||
borderColor: '#6c5ce7',
|
||
backgroundColor: 'rgba(108,92,231,0.1)',
|
||
fill: true,
|
||
tension: 0.3,
|
||
pointRadius: 3,
|
||
pointHoverRadius: 5,
|
||
}]
|
||
},
|
||
options: {
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
plugins: {
|
||
legend: { labels: { color: '#8a8fa8', font: { size: 11 } } },
|
||
tooltip: {
|
||
callbacks: {
|
||
label: ctx => '$' + ctx.parsed.y.toLocaleString()
|
||
}
|
||
}
|
||
},
|
||
scales: {
|
||
x: { ticks: { color: '#5a5e7a', maxTicksLimit: 15, font: { size: 10 } }, grid: { color: '#2a2e4522' } },
|
||
y: { ticks: { color: '#5a5e7a', font: { size: 10 }, callback: v => '$' + v.toLocaleString() }, grid: { color: '#2a2e4522' } }
|
||
}
|
||
}
|
||
});
|
||
|
||
// ─── Timeline Tab ─────────────────────────────────────
|
||
const monthly = buildMonthlyTimeline(phases, commPct);
|
||
let tRows = '';
|
||
let runningCum = 0;
|
||
for (const m of monthly) {
|
||
runningCum += m.comm * numPeople;
|
||
tRows += `<tr>
|
||
<td>Month ${m.m}</td>
|
||
<td>${m.phase}</td>
|
||
<td class="num">$${(m.prof * numPeople).toLocaleString()}</td>
|
||
<td class="num green-text">$${(m.comm * numPeople).toLocaleString()}</td>
|
||
<td class="num">$${runningCum.toLocaleString()}</td>
|
||
</tr>`;
|
||
}
|
||
document.getElementById('timelineBody').innerHTML = tRows;
|
||
|
||
// Timeline chart
|
||
const ctx2 = document.getElementById('timelineChart').getContext('2d');
|
||
chart2 = new Chart(ctx2, {
|
||
type: 'bar',
|
||
data: {
|
||
labels: monthly.map(m => `M${m.m}`),
|
||
datasets: [
|
||
{
|
||
label: 'Their Profit',
|
||
data: monthly.map(m => m.prof * numPeople),
|
||
backgroundColor: 'rgba(0,214,143,0.4)',
|
||
borderColor: '#00d68f',
|
||
borderWidth: 1,
|
||
borderRadius: 3,
|
||
},
|
||
{
|
||
label: 'Your Commission',
|
||
data: monthly.map(m => m.comm * numPeople),
|
||
backgroundColor: 'rgba(108,92,231,0.5)',
|
||
borderColor: '#6c5ce7',
|
||
borderWidth: 1,
|
||
borderRadius: 3,
|
||
}
|
||
]
|
||
},
|
||
options: {
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
plugins: {
|
||
legend: { labels: { color: '#8a8fa8', font: { size: 11 } } },
|
||
tooltip: { callbacks: { label: ctx => '$' + ctx.parsed.y.toLocaleString() } }
|
||
},
|
||
scales: {
|
||
x: { ticks: { color: '#5a5e7a', maxTicksLimit: 20, font: { size: 10 } }, grid: { color: '#2a2e4522' } },
|
||
y: { ticks: { color: '#5a5e7a', font: { size: 10 }, callback: v => '$' + v.toLocaleString() }, grid: { color: '#2a2e4522' } }
|
||
}
|
||
}
|
||
});
|
||
|
||
// ─── Ladder Tab ───────────────────────────────────────
|
||
let lRows = '';
|
||
for (const l of LEVELS) {
|
||
lRows += `<tr>
|
||
<td>Level ${l.level}</td>
|
||
<td>$${l.act}</td>
|
||
<td class="num">$${l.camp}</td>
|
||
<td class="num">$${l.total}</td>
|
||
<td class="num green-text">$${l.payout.toFixed(2)}</td>
|
||
<td class="num">$${l.netProfit.toFixed(2)}</td>
|
||
<td class="num">${l.clicks}</td>
|
||
<td class="num">$${l.cpc.toFixed(2)}</td>
|
||
</tr>`;
|
||
}
|
||
document.getElementById('ladderBody').innerHTML = lRows;
|
||
|
||
// Ladder progression
|
||
const ladderStart = effective;
|
||
let lpRows = '';
|
||
let started = false;
|
||
for (const s of LADDER_STEPS) {
|
||
const stepNum = LADDER_STEPS.indexOf(s) + 4;
|
||
if (stepNum <= ladderStart && ladderStart < 7) continue; // skip steps they already have
|
||
started = true;
|
||
const yourCut = s.ret * (commPct / 100);
|
||
lpRows += `<tr>
|
||
<td>${s.step}</td>
|
||
<td>$${s.capital.toLocaleString()}</td>
|
||
<td class="num">$${s.invest.toLocaleString()}</td>
|
||
<td class="num green-text">$${s.ret.toFixed(2)}</td>
|
||
<td class="num">$${s.profit.toFixed(2)}</td>
|
||
<td class="num">${s.cycles > 0 ? s.cycles + '×' : 'ongoing'}</td>
|
||
<td>${s.months > 0 ? `~${s.months} months` : 'forever'}</td>
|
||
</tr>`;
|
||
}
|
||
if (!lpRows) lpRows = '<tr><td colspan="7" style="text-align:center;color:var(--text-muted)">Already at endgame!</td></tr>';
|
||
document.getElementById('ladderProgressionBody').innerHTML = lpRows;
|
||
|
||
// ─── Comparison Tab ────────────────────────────────────
|
||
let cRows = '';
|
||
for (const s of SCENARIOS) {
|
||
const adj = mult;
|
||
cRows += `<tr class="scenario-row ${s.id === `gift${giftLevel}` || s.id === `self${selfLevel}` ? 'active-row' : ''}">
|
||
<td>${s.label}</td>
|
||
<td class="num">$${s.yourCost.toLocaleString()}</td>
|
||
<td class="num">$${s.yourCost.toLocaleString()}</td>
|
||
<td class="num">~${s.time} months</td>
|
||
<td class="num">$${Math.round(s.yr1 * adj * numPeople).toLocaleString()}</td>
|
||
<td class="num">$${Math.round(s.totalEG * adj * numPeople).toLocaleString()}</td>
|
||
<td class="num">$${Math.round(s.monthly * adj * numPeople).toLocaleString()}/mo</td>
|
||
</tr>`;
|
||
}
|
||
// Current scenario highlighted
|
||
document.getElementById('comparisonBody').innerHTML = cRows;
|
||
|
||
// Compare chart
|
||
const ctx3 = document.getElementById('compareChart').getContext('2d');
|
||
const compareLabels = SCENARIOS.map(s => s.label.replace('$', '').replace('(', '').replace(')', ''));
|
||
const compareData = SCENARIOS.map(s => Math.round(s.yr1 * mult * numPeople));
|
||
chart3 = new Chart(ctx3, {
|
||
type: 'bar',
|
||
data: {
|
||
labels: compareLabels,
|
||
datasets: [{
|
||
label: `Year 1 Earnings (${numPeople} people)`,
|
||
data: compareData,
|
||
backgroundColor: compareData.map((v, i) => {
|
||
const ids = [`gift${giftLevel}`, `self${selfLevel}`];
|
||
return ids.includes(SCENARIOS[i].id) ? 'rgba(108,92,231,0.7)' : 'rgba(90,94,122,0.3)';
|
||
}),
|
||
borderColor: compareData.map((v, i) => {
|
||
const ids = [`gift${giftLevel}`, `self${selfLevel}`];
|
||
return ids.includes(SCENARIOS[i].id) ? '#6c5ce7' : '#5a5e7a';
|
||
}),
|
||
borderWidth: 1,
|
||
borderRadius: 4,
|
||
}]
|
||
},
|
||
options: {
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
indexAxis: 'y',
|
||
plugins: {
|
||
legend: { display: false },
|
||
tooltip: { callbacks: { label: ctx => '$' + ctx.parsed.x.toLocaleString() + ' / yr' } }
|
||
},
|
||
scales: {
|
||
x: { ticks: { color: '#5a5e7a', font: { size: 9 }, callback: v => '$' + v.toLocaleString() }, grid: { color: '#2a2e4522' } },
|
||
y: { ticks: { color: '#8a8fa8', font: { size: 9 } }, grid: { display: false } }
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
// EVENT WIRING & INIT
|
||
// ══════════════════════════════════════════════════════════════════════
|
||
['numPeople','commissionPct','giftLevel','selfFundLevel','showReferral'].forEach(id => {
|
||
const el = document.getElementById(id);
|
||
el.addEventListener('input', updateAll);
|
||
el.addEventListener('change', updateAll);
|
||
});
|
||
|
||
// Tabs
|
||
document.querySelectorAll('.tab-btn').forEach(btn => {
|
||
btn.addEventListener('click', () => {
|
||
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
||
document.querySelectorAll('.results').forEach(r => r.classList.remove('active'));
|
||
btn.classList.add('active');
|
||
document.getElementById('tab-' + btn.dataset.tab).classList.add('active');
|
||
setTimeout(() => { if (chart1) chart1.resize(); if (chart2) chart2.resize(); if (chart3) chart3.resize(); }, 50);
|
||
});
|
||
});
|
||
|
||
updateAll();
|
||
|
||
// ─── URL Param Helpers ──────────────────────────────────────────
|
||
function getRefFromURL() {
|
||
const p = new URLSearchParams(window.location.search);
|
||
return p.get('ref') || '';
|
||
}
|
||
|
||
// ─── Shared Link Builder ────────────────────────────────────────
|
||
function getBaseUrl() {
|
||
let url = window.location.href.split('?')[0];
|
||
if (url.endsWith('/')) url = url.slice(0, -1);
|
||
return url;
|
||
}
|
||
|
||
function getShareUrl(refUser) {
|
||
const u = refUser || getRefFromURL() || 'cryptoteambuild';
|
||
return getBaseUrl() + '?ref=' + encodeURIComponent(u);
|
||
}
|
||
|
||
function updateSharedLinkBox() {
|
||
const refUser = getRefFromURL() || 'cryptoteambuild';
|
||
const shareUrl = getShareUrl(refUser);
|
||
document.getElementById('sharedLink').value = shareUrl;
|
||
// Update CTA button
|
||
const signupBtn = document.getElementById('signupBtn');
|
||
if (signupBtn) {
|
||
signupBtn.href = `https://clickbaitpays.me/?ref=${refUser}`;
|
||
}
|
||
// Update QR code
|
||
const qrImg = document.getElementById('refQrCode');
|
||
if (qrImg) {
|
||
qrImg.src = `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(shareUrl)}`;
|
||
}
|
||
}
|
||
|
||
function copySharedLink() {
|
||
const input = document.getElementById('sharedLink');
|
||
const btn = document.getElementById('copyLinkBtn');
|
||
input.select();
|
||
navigator.clipboard.writeText(input.value).then(() => {
|
||
btn.textContent = '✅ Copied!';
|
||
btn.classList.add('copied');
|
||
setTimeout(() => { btn.textContent = '📄 Copy'; btn.classList.remove('copied'); }, 2000);
|
||
});
|
||
}
|
||
|
||
function copyCalculatorLink() {
|
||
const refUser = getRefFromURL() || 'cryptoteambuild';
|
||
const url = getShareUrl(refUser);
|
||
navigator.clipboard.writeText(url).then(() => {
|
||
const btn = document.querySelector('.cta-btn-secondary');
|
||
btn.textContent = '✅ Copied!';
|
||
setTimeout(() => { btn.innerHTML = '📄 Copy Calculator Link'; }, 2000);
|
||
});
|
||
}
|
||
|
||
// ─── Shareable Plan Generator ─────────────────────────────────
|
||
function generatePlan() {
|
||
const numPeople = parseInt(document.getElementById('numPeople').value) || 1;
|
||
const giftLevel = parseInt(document.getElementById('giftLevel').value);
|
||
const selfLevel = parseInt(document.getElementById('selfFundLevel').value);
|
||
const refUser = getRefFromURL() || 'cryptoteambuild';
|
||
const refLink = `https://clickbaitpays.me/?ref=${refUser}`;
|
||
const giftCost = getLevelCost(giftLevel);
|
||
const selfCost = getLevelCost(selfLevel);
|
||
const effective = getEffectiveStart(giftLevel, selfLevel);
|
||
const phases = getPhaseSequence(effective);
|
||
const totalMonths = estimateMonths(phases);
|
||
|
||
updateSharedLinkBox();
|
||
|
||
let rawPlan = `📋 Your ClickBaitPays Plan
|
||
|
||
So what's ClickBaitPays? It's an ad platform where you run small ad campaigns, click a few ads each day, and every ~19 days you get paid more than the campaign cost. You reinvest those payouts into bigger campaigns and scale up. It's simple, takes a few minutes a day, and you can do it from your phone.
|
||
|
||
Here's a calculator I put together so you can play with the numbers yourself: https://cbp-calculator.saasy.top?ref=${refUser}
|
||
|
||
After you sign up, come back to that link — it'll walk you through what's possible and the best plan forward as you grow.
|
||
|
||
${giftCost > 0 ? `With me as your sponsor, I'm covering **$${giftCost}** to get you started through Level ${giftLevel} (L${giftLevel === 1 ? '1 only' : `1-L${giftLevel}`}). You owe nothing for this — it's funded up front, and you keep 100% of your earnings.` : `I haven't pre-funded any levels on my end — you'll be building entirely on your own using the link below.`}
|
||
|
||
Your full roadmap to $3,960/month:
|
||
|
||
${phases.filter(k => k !== '3xL7').map((k, i) => {
|
||
const p = HYBRIDS[k];
|
||
const pocketTotal = (p.profit * p.cycles).toFixed(2);
|
||
return `**Phase ${i+1}: ${p.label}**
|
||
${p.cycles} cycles, ~${p.months} months — $${p.payout.toFixed(2)}/cycle payout
|
||
|
||
You can play this phase two ways:
|
||
|
||
🔹 **Pocket mode** — take the ~$${p.profit.toFixed(2)} profit each cycle as spending money (that's your balance after CBP's built-in fee, no extra charge if you keep it in your account to spend later). After ${p.cycles} cycles you have enough saved to unlock the next level, plus ~$${pocketTotal} pocketed along the way. Total time: ~${p.months} months. *(If you withdraw to a crypto wallet, CBP adds a 10% fee on the withdrawal amount.)*
|
||
|
||
🔸 **Accelerate mode** — reinvest every penny instead of pocketing it. You reach the next level faster because nothing comes off the top. Total time is shorter, but you pocket nothing along the way.`;
|
||
}).join('\n\n')}
|
||
|
||
**Phase ${phases.filter(k => k !== '3xL7').length+1}: 3× L7 Endgame** 🎯
|
||
All three L7 campaigns running at once
|
||
$9,720.00/cycle payout → ~$3,960.00/month passive
|
||
This is the finish line
|
||
|
||
${selfCost > 0 ? `**Your total self-fund: $${selfCost}**${selfCost > giftCost ? ` (you cover $${(selfCost - giftCost).toLocaleString()} after sponsor's gift)` : ''}\n\n` : ''}The choice is yours — pocket spending money along the way, or reinvest everything to get to the endgame faster. Either way, no new money needed after the start. Just run the cycles, stack the profits, and level up.
|
||
|
||
As a side note — I also earn 10% of everything you get paid through this system, so eventually I'll get my gift back. But that's not why I'm doing this. I genuinely just want to pay it forward and help you get started. You win, I win — we both win together.
|
||
|
||
Estimated time to 3× L7 endgame: ~${totalMonths} months
|
||
|
||
Quick Stats
|
||
• Monthly at 3× L7: ~$3,960/mo passive
|
||
• Each campaign cycle: 19 days
|
||
• Min daily clicks: 3-20 (depending on level)
|
||
• Reward per ad click: $0.48 - $13.50
|
||
|
||
Your Referral Link
|
||
${refLink}
|
||
|
||
Use this link to sign up — it's how your sponsor tracks your progress. If you have questions, reach out to them directly.
|
||
|
||
Good luck — the system works if you work the system. 💪`;
|
||
|
||
// Display in page: render **bold** as HTML, strip leftover **
|
||
document.getElementById('planOutput').innerHTML = rawPlan.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
|
||
// Store the raw plan for clipboard copy (keeps ** for Telegram)
|
||
document.getElementById('planOutput').dataset.rawPlan = rawPlan;
|
||
}
|
||
|
||
function copyPlan() {
|
||
const el = document.getElementById('planOutput');
|
||
const rawPlan = el.dataset.rawPlan || el.textContent;
|
||
navigator.clipboard.writeText(rawPlan).then(() => {
|
||
const btn = document.getElementById('copyPlanBtn');
|
||
btn.textContent = '✅ Copied!';
|
||
btn.classList.add('copied');
|
||
setTimeout(() => { btn.textContent = '📄 Copy Plan'; btn.classList.remove('copied'); }, 2000);
|
||
}).catch(() => {
|
||
const range = document.createRange();
|
||
range.selectNodeContents(el);
|
||
const sel = window.getSelection();
|
||
sel.removeAllRanges();
|
||
sel.addRange(range);
|
||
});
|
||
}
|
||
|
||
// Regenerate plan when controls change
|
||
['numPeople','giftLevel','selfFundLevel','showReferral'].forEach(id => {
|
||
const el = document.getElementById(id);
|
||
el.addEventListener('input', generatePlan);
|
||
el.addEventListener('change', generatePlan);
|
||
});
|
||
|
||
// Generate on initial load
|
||
setTimeout(generatePlan, 100);
|
||
</script>
|
||
</body>
|
||
</html> |