diff --git a/index.html b/index.html
index e5a8517..02c7546 100644
--- a/index.html
+++ b/index.html
@@ -1440,7 +1440,10 @@
+
+
+ The campaigns you're actually running, up to 3 lanes β Boost Planner mixes welcome (e.g. L4+L4+L2)
@@ -2746,30 +2749,64 @@ function updateROI() {
// Update label to reflect profit mode
document.getElementById('roiStatRemaining').querySelector('.roi-stat-label').textContent = remaining > 0 ? 'To Breakeven' : 'Pure Profit';
- // Phase progress
- const pd = PHASE_DATA[phase];
+ // Phase progress. "custom" = the Boost Planner reality: any mix of up to
+ // 3 campaign slots (e.g. L4+L4+L2). Economics derived from LEVELS; the
+ // cycles-to-next estimate is accelerate-basis (bank everything) β pocket
+ // modes stretch it, so it's labeled est.
+ const customEl = document.getElementById('roiCustomLanes');
+ const customHintEl = document.getElementById('roiCustomHint');
+ const isCustom = phase === 'custom';
+ customEl.style.display = isCustom ? '' : 'none';
+ customHintEl.style.display = isCustom ? '' : 'none';
+ let pd, phaseKeyForLadder = phase, customBadge = null, customHi = 0;
+ if (isCustom) {
+ const lanes = (customEl.value.match(/[1-7]/g) || []).slice(0, 3).map(Number);
+ if (lanes.length) {
+ const profitPer = lanes.reduce((s, l) => s + LEVELS[l - 1].netProfit, 0);
+ customHi = Math.max(...lanes);
+ const nextLvl = customHi < 7 ? LEVELS[customHi] : null; // LEVELS[hi] = the (hi+1) record
+ pd = {
+ cycles: nextLvl ? Math.max(1, Math.ceil(nextLvl.total / profitPer)) : 999,
+ profitPer,
+ nextLabel: nextLvl ? `L${customHi + 1}` : null,
+ needsCapital: nextLvl ? nextLvl.total : 0,
+ est: true,
+ };
+ const equiv = { 1: 'l1', 2: 'l2l1', 3: 'l3l1', 4: 'l4', 5: 'l5', 6: 'l6', 7: 'l7solo' };
+ phaseKeyForLadder = equiv[customHi];
+ customBadge = 'Custom: ' + lanes.map(l => 'L' + l).join('+') + ` Β· $${profitPer.toFixed(2)}/cycle`;
+ } else {
+ pd = { cycles: 0, profitPer: 0, nextLabel: null, needsCapital: 0 };
+ customBadge = 'Type your lanes above (e.g. L4+L4+L2)';
+ }
+ } else {
+ pd = PHASE_DATA[phase] || { cycles: 0, profitPer: 0, nextLabel: null, needsCapital: 0 };
+ }
let phasePct = 0;
let phaseLabel = '';
if (phase === 'l7x3') {
phasePct = 100;
phaseLabel = 'π Endgame Reached';
- } else {
+ } else if (pd.cycles > 0) {
phasePct = Math.min((cyclesDone / pd.cycles) * 100, 100);
- phaseLabel = `Cycle ${cyclesDone} of ${pd.cycles}`;
+ phaseLabel = pd.est ? `Cycle ${cyclesDone} of ~${pd.cycles} (est.)` : `Cycle ${cyclesDone} of ${pd.cycles}`;
+ } else {
+ phaseLabel = 'β';
}
document.getElementById('roiStatPhase').querySelector('.roi-stat-value').textContent = phaseLabel;
document.getElementById('roiBarPhase').style.width = phasePct + '%';
- // Ladder visualization
+ // Ladder visualization (custom lanes map to their highest level's rung)
const ladderOrder = ['l1','l2l1','l3l1','l4','l4l3','l5','l5l3','l6','l6l3','l7solo','l7x3'];
- const phaseIndex = ladderOrder.indexOf(phase);
+ const phaseIndex = ladderOrder.indexOf(phaseKeyForLadder);
// Location badge
const phaseNames = {
l1:'L1 Only', l2l1:'L2 + L1', l3l1:'L3 + L1', l4:'L4 Only',
l4l3:'L4 + L3 Hybrid', l5:'L5 Only', l5l3:'L5 + L3 Hybrid',
l6:'L6 Only', l6l3:'L6 + L3 Hybrid', l7solo:'L7 Solo', l7x3:'3Γ L7 Endgame'
};
- document.getElementById('roiHerePhase').textContent = phase && phaseNames[phase] ? phaseNames[phase] : 'β';
+ document.getElementById('roiHerePhase').textContent =
+ customBadge || (phase && phaseNames[phase] ? phaseNames[phase] : "β");
document.querySelectorAll('.roi-ladder-step').forEach(el => {
el.classList.remove('active', 'passed');
@@ -2785,11 +2822,11 @@ function updateROI() {
if (earned >= 337.50) milestones.push({ icon: 'β
', label: '75% ROI Recouped', sub: 'Three quarters there' });
if (earned >= deposits) milestones.push({ icon: 'π°', label: '100% ROI β Breakeven!', sub: 'Everything from here is pure profit' });
- if (phase === 'l5l3' || phaseIndex > ladderOrder.indexOf('l5l3'))
+ if (phase === 'l5l3' || phaseIndex > ladderOrder.indexOf('l5l3') || customHi >= 5)
milestones.push({ icon: 'π
', label: 'L5 Active', sub: 'You reached the serious scaling tier' });
- if (phase === 'l6l3' || phaseIndex > ladderOrder.indexOf('l6l3'))
+ if (phase === 'l6l3' || phaseIndex > ladderOrder.indexOf('l6l3') || customHi >= 6)
milestones.push({ icon: 'π
', label: 'L6 Active', sub: 'Double-digit clicks/day territory' });
- if (phase === 'l7solo' || phaseIndex > ladderOrder.indexOf('l7solo'))
+ if (phase === 'l7solo' || phaseIndex > ladderOrder.indexOf('l7solo') || customHi >= 7)
milestones.push({ icon: 'π', label: 'L7 β The Big One', sub: '$840/cycle profit, $270/day clicks' });
if (phase === 'l7x3')
@@ -2833,7 +2870,7 @@ function updateROI() {
`).join('');
// Save to localStorage
- saveROIData(deposits, earned, phase, cyclesDone);
+ saveROIData(deposits, earned, phase, cyclesDone, customEl.value);
}
// βββ localStorage persistence ββββββββββββββββββββββββββ
@@ -2842,9 +2879,9 @@ function getROIStorageKey() {
return 'cbp_roi_' + ref;
}
-function saveROIData(deposits, earned, phase, cyclesDone) {
+function saveROIData(deposits, earned, phase, cyclesDone, customLanes) {
const key = getROIStorageKey();
- const data = { deposits, earned, phase, cyclesDone };
+ const data = { deposits, earned, phase, cyclesDone, customLanes: customLanes || '' };
try { localStorage.setItem(key, JSON.stringify(data)); } catch(e) {}
}
@@ -2858,7 +2895,7 @@ function loadROIData() {
}
// Wire up ROI inputs
-['roiDeposits','roiTotalEarned','roiPhase','roiCyclesDone'].forEach(id => {
+['roiDeposits','roiTotalEarned','roiPhase','roiCyclesDone','roiCustomLanes'].forEach(id => {
const el = document.getElementById(id);
el.addEventListener('input', updateROI);
el.addEventListener('change', updateROI);
@@ -2871,6 +2908,7 @@ if (saved) {
document.getElementById('roiTotalEarned').value = saved.earned || '';
if (saved.phase) document.getElementById('roiPhase').value = saved.phase;
document.getElementById('roiCyclesDone').value = saved.cyclesDone !== undefined ? saved.cyclesDone : '';
+ document.getElementById('roiCustomLanes').value = saved.customLanes || '';
}
// Initial render on page load