diff --git a/ads.js b/ads.js
index 33d6cd0..f552251 100644
Binary files a/ads.js and b/ads.js differ
diff --git a/db.js b/db.js
index 4bd412a..96af0c5 100644
--- a/db.js
+++ b/db.js
@@ -72,6 +72,8 @@ async function bootstrap() {
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4`);
const alterSafe0 = async sql => { try { await q(sql); } catch (e) { if (!['ER_DUP_FIELDNAME', 'ER_DUP_KEYNAME'].includes(e.code)) throw e; } };
await alterSafe0('ALTER TABLE earned_credits ADD COLUMN milestones VARCHAR(255) NULL'); // comma-joined granted milestone keys
+ await alterSafe0('ALTER TABLE earned_credits ADD COLUMN login_day CHAR(10) NULL'); // last daily-login-bonus day
+ await alterSafe0('ALTER TABLE earned_credits ADD COLUMN login_streak INT NOT NULL DEFAULT 0'); // consecutive-day streak
// additive columns (MySQL 8 has no IF NOT EXISTS for columns)
const alterSafe = async sql => {
try { await q(sql); }
diff --git a/public/assets/my.js b/public/assets/my.js
index 704f441..6ab9aac 100644
--- a/public/assets/my.js
+++ b/public/assets/my.js
@@ -285,6 +285,15 @@
chatSync(d);
MYID = d.memberId || MYID;
startLiveFeed();
+ if (!window.__lbChecked) { // daily login bonus, once per session (server guards once/day)
+ window.__lbChecked = true;
+ api('/api/my/login-bonus').then(r => {
+ if (r && r.granted > 0) {
+ IAP.status('🎁 Daily login bonus: +' + r.granted + ' credits' + (r.streak > 1 ? ' · ' + r.streak + '-day streak' : '') + '!', 'ok');
+ playSound('chaching'); setTimeout(loadDashboard, 900);
+ }
+ }).catch(() => {});
+ }
const wc = d.welcomeCredits || 0;
$('dbCredits').textContent = ((d.credits || 0) + wc).toLocaleString();
$('dbCreditsSub').textContent = wc ? (d.credits || 0).toLocaleString() + ' purchased · ' + wc + ' welcome' : '';
@@ -592,6 +601,8 @@
// fixed-cost types derive their spend (featured = day slots, visits = flat pack),
// so hide the free-form Budget field for them to avoid confusion
$('cBudgetRow').hidden = (t === 'featured' || t === 'visits');
+ // solo ads have a real floor (5cr x 10 deliveries): default to 50 so 10 isn't rejected
+ if (t === 'solo' && (!$('cBudget').value || Number($('cBudget').value) < 50)) $('cBudget').value = (lastRates && lastRates.soloCostPerRecipient ? lastRates.soloCostPerRecipient : 5) * 10;
if (t === 'visits') visitHint();
$('cTitle').placeholder = t === 'solo' ? 'Subject line (max 80)' : 'Headline (max 60)';
soloHint();
diff --git a/public/my.html b/public/my.html
index 1c3ae30..77cde4f 100644
--- a/public/my.html
+++ b/public/my.html
@@ -644,7 +644,7 @@
-
+