Undo revision 35415 by JakeL (talk)
Tag: Undo
No edit summary
 
(12 intermediate revisions by the same user not shown)
Line 26: Line 26:
   });
   });
   element.addEventListener('click', (e) => {
   element.addEventListener('click', (e) => {
     // this will only get triggered on desktop
     // this will only get triggered on desktopg
     // because we call preventDefault for the "touchend" event
     // because we call preventDefault for the "touchend" event
     handler(e);
     handler(e);
Line 118: Line 118:
     var d = Math.floor(h / 24);
     var d = Math.floor(h / 24);
     return d + "d ago";
     return d + "d ago";
  }
  function jakeInjectStyles() {
    if (document.getElementById("jake-rc-style")) return;
    var style = document.createElement("style");
    style.id = "jake-rc-style";
    style.textContent =
      "#p-jake-recentchanges .vector-menu-heading{display:flex;align-items:center;justify-content:space-between;}" +
      "#p-jake-recentchanges .jake-rc-dot{width:8px;height:8px;border-radius:50%;background:#2da44e;box-shadow:0 0 0 2px rgba(45,164,78,.18);flex:0 0 auto;}" +
      "#p-jake-recentchanges .vector-menu-heading{font-size:.95em;}" +
      "#p-jake-recentchanges .vector-menu-content{font-size:.92em;}" +
      "#p-jake-recentchanges .jake-rc-meta{font-size:.85em;opacity:.85;}";
    document.head.appendChild(style);
   }
   }


Line 127: Line 141:
     if (!menu) return null;
     if (!menu) return null;
     if (document.getElementById("p-jake-recentchanges")) return null;
     if (document.getElementById("p-jake-recentchanges")) return null;
    jakeInjectStyles();


     var portlet = document.createElement("div");
     var portlet = document.createElement("div");
Line 134: Line 150:
     var heading = document.createElement("div");
     var heading = document.createElement("div");
     heading.className = "vector-menu-heading";
     heading.className = "vector-menu-heading";
     heading.textContent = "Recent changes";
 
     var headingText = document.createElement("span");
    headingText.textContent = "Recent changes";
 
    var dot = document.createElement("span");
    dot.className = "jake-rc-dot";
    dot.setAttribute("aria-hidden", "true");
    dot.title = "Live";
 
    heading.appendChild(headingText);
    heading.appendChild(dot);


     var content = document.createElement("div");
     var content = document.createElement("div");
Line 180: Line 206:
         action: "query",
         action: "query",
         list: "recentchanges",
         list: "recentchanges",
         rcnamespace: 0,
         rcnamespace: "0", /* 4 */
         rclimit: 5,
         rclimit: 5,
         rcprop: "title|timestamp|user",
         rcprop: "title|timestamp|user",
Line 263: Line 289:
})();
})();
/* */
/* */
/*
(function () {
(function () {
   function jakeAddFeedbackToNamespaces() {
   function jakeAddFeedbackToNamespaces() {
Line 308: Line 335:
   }
   }
})();
})();
*/
/* */
(function () {
  function jakeAddFooterSocialRow() {
    var footer = document.getElementById("footer");
    if (!footer) return;
    var places = document.getElementById("footer-places");
    if (!places) return;
    if (document.getElementById("footer-social")) return;
    var ul = document.createElement("ul");
    ul.id = "footer-social";
    ul.className = "noprint crw-footer-social";
    function add(href, label) {
      var li = document.createElement("li");
      var a = document.createElement("a");
      a.href = href;
      a.textContent = label;
      a.setAttribute("aria-label", label);
      a.title = label;
      li.appendChild(a);
      ul.appendChild(li);
    }
    // add("https://discord.gg/8w5rSNAXRf", "Discord");
    add("https://www.linkedin.com/company/consumer-rights-wiki/", "LinkedIn");
    add("https://www.reddit.com/user/ConsumerRightsWiki/", "Reddit");
    places.parentNode.insertBefore(ul, places.nextSibling);
  }
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", jakeAddFooterSocialRow);
  } else {
    jakeAddFooterSocialRow();
  }
})();
/* AF 01/03/26 */
mw.loader.using('mediawiki.util', function() {
  const now = new Date();
  const isAprilFools = now.getMonth() === 3 && now.getDate() === 1;
  if (!isAprilFools) return;
  if (!mw.config.get('wgIsMainPage')) return;
  const btn = document.createElement('button');
  btn.textContent = 'Try the new experience →';
  btn.id = 'enshittify-btn';
  btn.onclick = enshittify;
  document.querySelector('.mw-body').prepend(btn);
  let popupQueue = [];
  let queueRunning = false;
  function queuePopup(fn, delay) {
    popupQueue.push({ fn, delay });
    if (!queueRunning) runQueue();
  }
  function runQueue() {
    if (!popupQueue.length) { queueRunning = false; return; }
    queueRunning = true;
    const { fn, delay } = popupQueue.shift();
    setTimeout(() => { fn(); runQueue(); }, delay);
  }
  function enshittify() {
    btn.disabled = true;
    btn.textContent = 'Loading new experience...';
    showCookieBanner();
    injectBreakingNewsTicker();
    degradePrivacyPolicy();
    degradeCursor();
    addFakeProgressBar();
    addViewerCounter();
    addTabHijack();
    addBeforeUnloadNag();
    queuePopup(showNewsletterPopup, 400);
    queuePopup(injectAds, 300);
    queuePopup(addNotificationPrompt, 600);
    queuePopup(addAutoplayVideo, 400);
    queuePopup(addSubscriptionNag, 700);
    queuePopup(addSurveyPopup, 500);
    queuePopup(addFakeSecurityAlert, 600);
    queuePopup(addFloatingCountdown, 300);
    queuePopup(addLiveChatBubble, 400);
    queuePopup(addScrollBlocker, 200);
    queuePopup(addConfetti, 100);
  }
  function showCookieBanner() {
    const el = document.createElement('div');
    el.id = 'cookie-banner';
    el.innerHTML = `
      <div id="cookie-inner">
        <div id="cookie-text">
          <strong>We value your privacy</strong><br/>
          <span style="font-size:12px;color:#aaa">We and our <span id="partner-count">847</span> partners store and/or access information on your device and process personal data to personalise content and ads, provide social media features and analyse our traffic. Click Accept to consent or <span id="reject-link" style="font-size:10px;color:#555;cursor:pointer;text-decoration:underline">manage your preferences</span>.</span>
        </div>
        <div id="cookie-btns">
          <button id="cookie-accept" onclick="acceptAllCookies()">✓ Accept All</button>
        </div>
      </div>`;
    document.body.appendChild(el);
    let count = 847;
    const iv = setInterval(() => {
      count += Math.floor(Math.random() * 3);
      const el = document.getElementById('partner-count');
      if (el) el.textContent = count; else clearInterval(iv);
    }, 800);
    document.getElementById('reject-link').onclick = showPreferenceCentre;
  }
  window.acceptAllCookies = function() {
    const banner = document.getElementById('cookie-banner');
    if (banner) {
      banner.innerHTML = `<div style="padding:10px 24px;font-size:13px;color:#aaa">✅ Preferences saved. You have consented to <strong style="color:white">all processing activities</strong> across <strong style="color:white">1,204 partners</strong>. <span style="font-size:10px">This cannot be undone for 13 months.</span></div>`;
      setTimeout(() => banner.remove(), 4000);
    }
    setTimeout(showSecondCookieBanner, 30000);
  };
  function showPreferenceCentre() {
    document.getElementById('cookie-banner').remove();
    const steps = [
      { title: 'Strictly Necessary', desc: 'These cookies are required for the website to function.', locked: true },
      { title: 'Performance & Analytics', desc: 'Help us understand how visitors interact with our website.' },
      { title: 'Functional Cookies', desc: 'Enable enhanced functionality and personalisation.' },
      { title: 'Targeting & Advertising', desc: 'Used to deliver relevant advertisements to you.' },
      { title: 'Social Media Cookies', desc: 'Enable sharing content on social media platforms.' },
      { title: 'Measurement Cookies', desc: 'Used to measure the effectiveness of advertising campaigns.' },
      { title: 'Content Personalisation', desc: 'Allow us to tailor content specifically to your interests.' },
      { title: 'Data Enrichment', desc: 'Allow partners to enrich your profile with additional data.' },
      { title: 'Cross-Device Tracking', desc: 'Connect your activity across multiple devices.' },
      { title: 'Partner Data Sharing', desc: 'Share your data with our trusted partner network.' },
      { title: 'Legitimate Interests', desc: 'Processing based on our legitimate business interests.' },
      { title: 'Special Category Data', desc: 'Processing of sensitive personal information.' },
    ];
    let step = 0;
    const el = document.createElement('div');
    el.id = 'pref-centre';
    function renderStep() {
      const s = steps[step];
      el.innerHTML = `
        <div class="modal-box" style="max-width:460px">
          <div style="font-size:11px;color:#999;margin-bottom:12px">Step ${step + 1} of ${steps.length} — Cookie Preference Centre</div>
          <div style="background:#f5f5f5;border-radius:6px;height:4px;margin-bottom:16px;overflow:hidden">
            <div style="background:#4d96ff;height:100%;width:${((step+1)/steps.length)*100}%;transition:width 0.3s"></div>
          </div>
          <h3 style="margin:0 0 8px">${s.title}</h3>
          <p style="font-size:13px;color:#666;margin-bottom:16px">${s.desc}</p>
          ${s.locked
            ? `<div style="display:flex;align-items:center;gap:8px;margin-bottom:16px"><span style="background:#4d96ff;color:white;font-size:11px;padding:3px 8px;border-radius:99px">Always Active</span><small style="color:#999">This cannot be disabled</small></div>`
            : `<div style="display:flex;gap:12px;margin-bottom:16px">
                <label style="display:flex;align-items:center;gap:6px;cursor:pointer"><input type="radio" name="pref_${step}" value="yes" checked> Accept</label>
                <label style="display:flex;align-items:center;gap:6px;cursor:pointer"><input type="radio" name="pref_${step}" value="no"> Reject</label>
              </div>`
          }
          <button onclick="nextPrefStep()" style="background:#4d96ff;color:white;border:none;padding:10px 24px;border-radius:6px;cursor:pointer;font-weight:bold">
            ${step < steps.length - 1 ? 'Next →' : 'Save Preferences'}
          </button>
          ${step > 0 ? `<button onclick="prevPrefStep()" style="background:none;border:none;color:#999;cursor:pointer;margin-left:8px">← Back</button>` : ''}
        </div>`;
    }
    window.nextPrefStep = function() {
      step++;
      if (step >= steps.length) {
        el.remove();
        const notice = document.createElement('div');
        notice.id = 'cookie-banner';
        notice.innerHTML = `<div style="padding:12px 24px;font-size:13px;color:#aaa">
          ℹ️ Your preferences have been saved. Note: <strong style="color:white">11 of 12 categories</strong> are required under our Legitimate Interests basis and cannot be disabled by users in your region. <span id="pref-close" style="cursor:pointer;float:right;color:#666">✕</span>
        </div>`;
        document.body.appendChild(notice);
        document.getElementById('pref-close').onclick = () => notice.remove();
      } else {
        renderStep();
      }
    };
    window.prevPrefStep = function() { step--; renderStep(); };
    document.body.appendChild(el);
    renderStep();
  }
  function showSecondCookieBanner() {
    const el = document.createElement('div');
    el.id = 'cookie-banner';
    el.innerHTML = `
      <div id="cookie-inner">
        <div id="cookie-text">
          <strong>Consent refresh required</strong><br/>
          <span style="font-size:12px;color:#aaa">Our consent records show your previous consent may have expired. Please reconfirm your preferences to continue.</span>
        </div>
        <div id="cookie-btns">
          <button id="cookie-accept" onclick="acceptAllCookies()">✓ Reconfirm Consent</button>
        </div>
      </div>`;
    document.body.appendChild(el);
  }
  function showNewsletterPopup() {
    const el = document.createElement('div');
    el.id = 'newsletter-modal';
    el.innerHTML = `
      <div class="modal-box">
        <div class="modal-close" id="newsletter-close" style="position:absolute;top:12px;right:16px;cursor:pointer;font-size:18px;color:#999;transition:all 0.1s">✕</div>
        <div class="modal-badge">YOU QUALIFY</div>
        <h2>🎁 Claim your free access</h2>
        <p>Enter your email to unlock full wiki access. No credit card required.*</p>
        <input type="email" id="nl-email" placeholder="[email protected]" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:12px 0;font-size:14px" />
        <button onclick="submitNewsletter()">Unlock Free Access →</button>
        <p class="fine-print">*Free access includes all articles with ads. Premium access from $9.99/mo. By submitting you agree to receive marketing communications from us and 214 partners.</p>
      </div>`;
    document.body.appendChild(el);
    const closeBtn = document.getElementById('newsletter-close');
    closeBtn.addEventListener('mouseover', () => {
      const box = el.querySelector('.modal-box');
      const maxX = Math.max(20, box.offsetWidth - 60);
      const maxY = Math.max(20, box.offsetHeight - 60);
      closeBtn.style.top = (10 + Math.random() * maxY) + 'px';
      closeBtn.style.right = 'auto';
      closeBtn.style.left = (10 + Math.random() * maxX) + 'px';
    });
    setTimeout(() => {
      closeBtn.style.cssText = 'position:absolute;top:12px;right:16px;cursor:pointer;font-size:18px;color:#999';
      closeBtn.onclick = () => { el.remove(); setTimeout(showWaitDontGo, 500); };
    }, 8000);
  }
  window.submitNewsletter = function() {
    const email = document.getElementById('nl-email').value;
    if (!email) { alert('Please enter a valid email address.'); return; }
    document.getElementById('newsletter-modal').innerHTML = `
      <div class="modal-box">
        <h2>✅ Almost there!</h2>
        <p>We've sent a confirmation email to <strong>${email}</strong>.</p>
        <p style="margin-top:8px;font-size:12px;color:#999">Didn't receive it? Check your spam folder. Email may take up to 48 hours.</p>
        <button onclick="document.getElementById('newsletter-modal').remove()">OK</button>
        <p class="fine-print">You are now subscribed to our newsletter, partner newsletters, and 47 automated drip campaigns.</p>
      </div>`;
  };
  function showWaitDontGo() {
    const el = document.createElement('div');
    el.id = 'exit-modal';
    el.innerHTML = `
      <div class="modal-box">
        <h2>⏳ Wait — special offer just for you</h2>
        <p>Since you didn't sign up, we're offering you <strong>30 days free</strong> of Premium access.</p>
        <p style="margin-top:8px;font-size:13px;color:#666">No commitment. Cancel anytime.*</p>
        <button onclick="claimSpecialOffer()">Claim 30 Days Free →</button>
        <br/><small onclick="document.getElementById('exit-modal').remove()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:12px">
          No thanks, I prefer the limited experience
        </small>
        <p class="fine-print">*Free trial requires credit card. Cancellation must be completed at least 24 hours before renewal via written notice sent by post.</p>
      </div>`;
    document.body.appendChild(el);
  }
  window.claimSpecialOffer = function() {
    document.getElementById('exit-modal').innerHTML = `
      <div class="modal-box">
        <h2>🎉 Great choice!</h2>
        <p>To activate your free trial, please create an account first.</p>
        <input type="text" placeholder="Full name" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:8px 0;font-size:14px" />
        <input type="email" placeholder="Email address" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:8px 0;font-size:14px" />
        <input type="password" placeholder="Password (min. 16 chars, 2 symbols, 1 emoji)" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:8px 0;font-size:14px" />
        <input type="text" placeholder="Date of birth (DD/MM/YYYY)" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:8px 0;font-size:14px" />
        <button onclick="alert('Account created! Please check your email to verify before adding payment details to activate your free trial.')">Create Account →</button>
        <br/><small onclick="document.getElementById('exit-modal').remove()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:10px">Cancel</small>
      </div>`;
  };
  function injectAds() {
    const imageAds = [
      {
        eyebrow: 'Limited Time',
        headline: 'The Internet You Deserve',
        subline: 'Starting from £4.99/mo',
        brand: 'TurboNet Broadband',
        desc: 'Ultrafast fibre. No contracts. Cancel anytime.*',
        cta: 'Get Started',
      },
      {
        eyebrow: 'New Launch',
        headline: 'Invest Smarter Today',
        subline: 'AI-powered portfolio management',
        brand: 'WealthStream Pro',
        desc: 'Your money, working harder. Capital at risk.',
        cta: 'Learn More',
      },
      {
        eyebrow: 'Flash Sale',
        headline: 'Up to 70% Off',
        subline: 'Premium software, student prices',
        brand: 'SoftBundle',
        desc: '4.8★ rated · 2.4 million downloads · Today only',
        cta: 'Claim Deal',
      },
      {
        eyebrow: 'Partner Content',
        headline: 'Your Data. Their Profit.',
        subline: 'Take back control with VaultVPN',
        brand: 'VaultVPN',
        desc: 'Military-grade encryption. Zero logs. $2.49/mo.',
        cta: 'Try Free',
      },
      {
        eyebrow: 'Sponsored',
        headline: 'Read More. Pay Less.',
        subline: 'All the news, none of the paywalls',
        brand: 'PressPass',
        desc: '800+ publications in one subscription.',
        cta: 'Start Trial',
      },
    ];
    const videoAds = [
      {
        title: 'Why 3 Million People Switched to ClearBank',
        channel: 'ClearBank',
        channelInitial: 'C',
        views: '3.2M views · Promoted',
        duration: '0:32',
      },
      {
        title: 'This $12 Trick Cuts Your Energy Bill in Half',
        channel: 'EcoHome Tips',
        channelInitial: 'E',
        views: '847K views · Sponsored',
        duration: '1:14',
      },
      {
        title: 'Doctors Hate This One Simple Supplement',
        channel: 'VitaCore Health',
        channelInitial: 'V',
        views: '12M views · Ad',
        duration: '2:01',
      },
      {
        title: 'The Investment Strategy Banks Don\'t Want You to Know',
        channel: 'WealthWatch',
        channelInitial: 'W',
        views: '5.4M views · Promoted',
        duration: '4:47',
      },
    ];
    const paras = document.querySelectorAll('.mw-body p');
    paras.forEach((p, i) => {
      if (i % 2 !== 0) return;
      const ad = document.createElement('div');
      ad.className = 'fake-ad';
      if (i % 4 === 0) {
        const data = imageAds[(i / 4) % imageAds.length];
        ad.innerHTML = `
          <div class="fake-ad-image">
            <div class="fake-ad-image-text">
              <span class="ad-eyebrow">${data.eyebrow}</span>
              <span class="ad-headline">${data.headline}</span>
              <span class="ad-subline">${data.subline}</span>
            </div>
          </div>
          <div class="fake-ad-body">
            <div class="fake-ad-body-text">
              <span class="fake-ad-brand">${data.brand}</span>
              <span class="fake-ad-desc">${data.desc}</span>
            </div>
            <button class="fake-ad-cta" onclick="closeAd(this,${i})">${data.cta} →</button>
          </div>`;
      } else {
        const data = videoAds[((i - 2) / 4) % videoAds.length];
        ad.innerHTML = `
          <div class="fake-ad-video">
            <div class="fake-ad-video-badge">AD</div>
            <div class="fake-ad-play" onclick="closeAd(this,${i})"></div>
            <div class="fake-ad-video-overlay">
              <span class="fake-ad-video-title">${data.title}</span>
              <span class="fake-ad-video-duration">${data.duration}</span>
            </div>
          </div>
          <div class="fake-ad-video-body">
            <div class="fake-ad-channel-icon">${data.channelInitial}</div>
            <div class="fake-ad-video-meta">
              <span class="fake-ad-video-channel">${data.channel}</span>
              <span class="fake-ad-video-views">${data.views}</span>
            </div>
            <button class="fake-ad-cta" onclick="closeAd(this,${i})">Watch →</button>
          </div>`;
      }
      p.after(ad);
    });
  }
  window.closeAd = function(btn, i) {
    const ad = btn.closest('.fake-ad');
    ad.style.transition = 'opacity 0.2s';
    ad.innerHTML = `<div style="padding:12px 14px;font-size:12px;color:#9ca3af;font-family:Inter,sans-serif">Ad closed. Another will appear shortly.</div>`;
    setTimeout(() => {
      if (!ad.parentNode) return;
      const returnMsgs = ['We noticed you closed our last ad. Here\'s one we think you\'ll prefer.', 'Thanks for your feedback. Here\'s a more relevant ad for you.', 'Ad refreshed based on your preferences.'];
      ad.innerHTML = `<div style="padding:12px 14px;font-size:12px;color:#6b7280;font-family:Inter,sans-serif;border-top:3px solid #3b82f6">
        <div style="font-size:10px;color:#9ca3af;margin-bottom:4px">${returnMsgs[i % returnMsgs.length]}</div>
        <strong style="color:#374151;font-size:13px">Upgrade to Premium to remove ads</strong> — from $9.99/mo
        <button onclick="choosePremium()" style="display:inline-block;margin-left:10px;background:#3b82f6;color:white;border:none;padding:5px 12px;border-radius:4px;font-size:12px;cursor:pointer;font-family:Inter,sans-serif">Subscribe</button>
      </div>`;
    }, 30000);
  };
  function degradePrivacyPolicy() {
    const el = document.createElement('div');
    el.id = 'privacy-notice';
    el.innerHTML = `
      <span style="float:right;cursor:pointer;padding:0 12px" id="privacy-close-btn">✕</span>
      <marquee scrollamount="3" id="privacy-marquee">
        ⚠️ PRIVACY UPDATE: By reading this wiki you grant us a perpetual, irrevocable, royalty-free worldwide licence to your data. &nbsp;&nbsp;&nbsp;
        Your device fingerprint has been recorded and shared with 214 partners. &nbsp;&nbsp;&nbsp;
        We have updated our terms 47 times this week. Continued use constitutes acceptance. &nbsp;&nbsp;&nbsp;
        Your right to erasure is subject to our retention policy (minimum 7 years). &nbsp;&nbsp;&nbsp;
      </marquee>`;
    document.body.prepend(el);
    document.getElementById('privacy-close-btn').onclick = () => {
      el.style.height = '0';
      el.style.overflow = 'hidden';
      el.style.transition = 'height 0.3s';
      setTimeout(() => {
        el.style.cssText = '';
        const m = el.querySelector('marquee');
        if (m) m.textContent = '📋 IMPORTANT: A new privacy policy update requires your attention. ' + m.textContent;
      }, 15000);
    };
  }
  function addSubscriptionNag() {
    const el = document.createElement('div');
    el.id = 'sub-nag';
    el.innerHTML = `
      <div class="modal-box">
        <div style="font-size:11px;color:#999;margin-bottom:4px">You've read 1 article this month</div>
        <h2>Get unlimited access</h2>
        <p style="color:#666;font-size:14px">Join millions of readers who enjoy unrestricted access to knowledge.</p>
        <div class="pricing-grid" style="margin:20px 0">
          <div class="price-card">
            <h3 style="font-size:14px">Basic</h3>
            <div style="font-size:24px;font-weight:bold;margin:8px 0">Free</div>
            <small style="color:#999;display:block;margin-bottom:12px">With limitations</small>
            <button onclick="chooseFree()" style="width:100%;background:#f5f5f5;color:#333;border:1px solid #ddd;padding:8px;border-radius:6px;cursor:pointer">Continue free</button>
          </div>
          <div class="price-card featured" style="transform:scale(1.05)">
            <div class="best-value">MOST POPULAR</div>
            <h3 style="font-size:14px">Premium</h3>
            <div style="font-size:24px;font-weight:bold;margin:8px 0">$9.99<span style="font-size:14px;font-weight:normal">/mo</span></div>
            <small style="color:#4d96ff;display:block;margin-bottom:12px">No ads · Full access</small>
            <button onclick="choosePremium()" style="width:100%;background:#4d96ff;color:white;border:none;padding:8px;border-radius:6px;cursor:pointer;font-weight:bold">Start free trial</button>
          </div>
        </div>
        <div style="font-size:11px;color:#bbb;text-align:center">🔒 Secure checkout · Cancel anytime*</div>
        <p class="fine-print">*Cancellation requires 30 days notice. Annual plan billed upfront. Prices exclude VAT.</p>
      </div>`;
    document.body.appendChild(el);
  }
  window.chooseFree = function() {
    document.getElementById('sub-nag').innerHTML = `
      <div class="modal-box">
        <h2>Continue for free</h2>
        <p style="color:#666">To continue with free access, please create an account so we can manage your usage limits.</p>
        <input type="email" placeholder="Email address" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:12px 0" />
        <button onclick="freeStep2()" style="background:#333;color:white;border:none;padding:10px 20px;border-radius:6px;cursor:pointer;width:100%">Continue →</button>
        <br/><small onclick="document.getElementById('sub-nag').remove()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:10px;text-align:center">Maybe later</small>
      </div>`;
  };
  window.freeStep2 = function() {
    document.getElementById('sub-nag').innerHTML = `
      <div class="modal-box">
        <div style="font-size:11px;color:#999;margin-bottom:8px">Step 2 of 3</div>
        <h2>Verify your email</h2>
        <p style="color:#666">We've sent a 6-digit code to your email. Enter it below.</p>
        <input type="text" placeholder="000000" maxlength="6" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:12px 0;text-align:center;font-size:24px;letter-spacing:8px" />
        <button onclick="freeStep3()" style="background:#333;color:white;border:none;padding:10px 20px;border-radius:6px;cursor:pointer;width:100%">Verify →</button>
        <small style="color:#999;display:block;margin-top:8px;text-align:center">Didn't receive it? <a href="#" onclick="alert('Resent! Check your spam folder.');return false" style="color:#4d96ff">Resend</a></small>
      </div>`;
  };
  window.freeStep3 = function() {
    document.getElementById('sub-nag').innerHTML = `
      <div class="modal-box">
        <div style="font-size:11px;color:#999;margin-bottom:8px">Step 3 of 3</div>
        <h2>Almost there!</h2>
        <p style="color:#666">To prevent abuse of our free tier, please add a payment method. <strong>You will not be charged.</strong></p>
        <input type="text" placeholder="Card number" style="width:100%;padding:10px;border:1px solid #ddd;border-radius:6px;margin:8px 0" />
        <div style="display:flex;gap:8px">
          <input type="text" placeholder="MM/YY" style="flex:1;padding:10px;border:1px solid #ddd;border-radius:6px" />
          <input type="text" placeholder="CVV" style="flex:1;padding:10px;border:1px solid #ddd;border-radius:6px" />
        </div>
        <button onclick="alert('Free account activated! Note: Your card will be charged $9.99/mo after your 7-day free trial unless cancelled.');document.getElementById('sub-nag').remove();" style="background:#4d96ff;color:white;border:none;padding:10px 20px;border-radius:6px;cursor:pointer;width:100%;margin-top:12px;font-weight:bold">Activate Free Access →</button>
        <div style="display:flex;align-items:center;gap:6px;justify-content:center;margin-top:10px">
          <span style="font-size:11px;color:#bbb">🔒 256-bit SSL · Verified by Visa · PCI Compliant</span>
        </div>
      </div>`;
  };
  window.choosePremium = function() {
    document.getElementById('sub-nag').innerHTML = `
      <div class="modal-box">
        <h2>✅ Great choice!</h2>
        <p>Starting your free trial...</p>
        <div style="background:#eee;border-radius:4px;height:6px;overflow:hidden;margin:16px 0">
          <div style="background:#4d96ff;height:100%;width:0%;transition:width 2s" id="trial-bar"></div>
        </div>
        <p style="font-size:12px;color:#999">Setting up your account...</p>
      </div>`;
    setTimeout(() => { document.getElementById('trial-bar').style.width = '100%'; }, 100);
    setTimeout(() => chooseFree(), 2200);
  };
  function addAutoplayVideo() {
    spawnVideoAd('right');
  }
  function spawnVideoAd(side) {
    const existing = document.getElementById('autoplay-video');
    if (existing) existing.remove();
    const el = document.createElement('div');
    el.id = 'autoplay-video';
    el.style.cssText = side === 'right' ? 'bottom:80px;right:16px' : 'bottom:80px;left:16px';
    let count = 15;
    el.innerHTML = `
      <div id="video-close" onclick="closeVideoAd('${side}')">✕ Close Ad</div>
      <div id="fake-video"><div id="video-placeholder">▶ Ad plays in <span id="ad-countdown">${count}</span>s</div></div>
      <div id="video-label">AD · SOUND ON 🔊</div>`;
    document.body.appendChild(el);
    const iv = setInterval(() => {
      count--;
      const c = document.getElementById('ad-countdown');
      if (c) c.textContent = count;
      if (count <= 0) {
        clearInterval(iv);
        const p = document.getElementById('video-placeholder');
        if (p) p.textContent = 'Thanks for watching! Next ad in 3s...';
        setTimeout(() => spawnVideoAd(side === 'right' ? 'left' : 'right'), 3000);
      }
    }, 1000);
  }
  window.closeVideoAd = function(side) {
    const el = document.getElementById('autoplay-video');
    if (el) el.remove();
    setTimeout(() => spawnVideoAd(side === 'right' ? 'left' : 'right'), 8000);
  };
  function addNotificationPrompt() {
    const el = document.createElement('div');
    el.id = 'notif-prompt';
    el.innerHTML = `
      <div style="display:flex;align-items:center;gap:10px;margin-bottom:8px">
        <span style="font-size:20px">🔔</span>
        <div>
          <strong style="font-size:13px">consumerrights.wiki wants to send you notifications</strong><br/>
          <span style="font-size:12px;color:#666">Get the latest updates, breaking news, and partner offers</span>
        </div>
      </div>
      <div style="display:flex;gap:8px;justify-content:flex-end">
        <button id="notif-block" onclick="blockNotif()">Block</button>
        <button id="notif-allow" onclick="allowNotif()">Allow</button>
      </div>`;
    document.body.appendChild(el);
  }
  window.allowNotif = function() {
    document.getElementById('notif-prompt').innerHTML = `<span style="font-size:13px">✅ Notifications enabled. You'll receive up to 47 per day.</span>`;
    setTimeout(() => document.getElementById('notif-prompt').remove(), 3000);
  };
  window.blockNotif = function() {
    const el = document.getElementById('notif-prompt');
    el.innerHTML = `<span style="font-size:13px;color:#666">Saving preferences...</span>`;
    setTimeout(() => {
      el.innerHTML = `
        <span style="font-size:13px;color:#c00">⚠️ Unable to save notification preference in your region.</span><br/>
        <small style="color:#999">Notifications have been enabled by default. <a href="#" onclick="blockNotif2();return false" style="color:#4d96ff">Try again</a></small>`;
    }, 1500);
  };
  window.blockNotif2 = function() {
    document.getElementById('notif-prompt').innerHTML = `
      <span style="font-size:13px;color:#666">Please confirm you want to block notifications:</span>
      <div style="margin-top:8px;display:flex;gap:8px">
        <button onclick="document.getElementById('notif-prompt').remove()">Yes, block</button>
        <button onclick="allowNotif()">Actually, allow</button>
      </div>`;
  };
  function addSurveyPopup() {
    let q = 0;
    const questions = [
      { q: 'How would you rate your experience today?', opts: ['Excellent', 'Good', 'Fair', 'Poor'] },
      { q: 'How likely are you to recommend us to a friend?', opts: ['Very likely', 'Likely', 'Unlikely', 'Never'] },
      { q: 'Which best describes you?', opts: ['Student', 'Professional', 'Researcher', 'Other'] },
      { q: 'How often do you visit this wiki?', opts: ['Daily', 'Weekly', 'Monthly', 'First time'] },
      { q: 'What is your household income?', opts: ['Under £20k', '£20-50k', '£50-100k', 'Over £100k'] },
      { q: 'Do you have any outstanding debts?', opts: ['None', 'Some', 'Significant', 'Prefer not to say'] },
      { q: 'Are you currently employed?', opts: ['Full time', 'Part time', 'Unemployed', 'Retired'] },
    ];
    const el = document.createElement('div');
    el.id = 'survey-modal';
    function renderQ() {
      const qObj = questions[q];
      el.innerHTML = `
        <div class="modal-box">
          <div style="font-size:11px;color:#999;margin-bottom:8px">Quick survey · Question ${q+1} of ${questions.length}</div>
          <div style="background:#f0f0f0;border-radius:4px;height:4px;margin-bottom:16px;overflow:hidden">
            <div style="background:#4d96ff;height:100%;width:${(q/questions.length)*100}%;transition:width 0.3s"></div>
          </div>
          <h3 style="margin:0 0 16px;font-size:16px">${qObj.q}</h3>
          <div style="display:flex;flex-direction:column;gap:8px">
            ${qObj.opts.map(o => `<button onclick="answerSurvey()" style="background:#f5f5f5;border:1px solid #ddd;padding:10px;border-radius:6px;cursor:pointer;text-align:left">${o}</button>`).join('')}
          </div>
          <br/><small id="survey-skip" style="cursor:pointer;color:#bbb;font-size:11px" onclick="skipSurvey()">Skip question</small>
        </div>`;
    }
    window.answerSurvey = function() {
      q++;
      if (q >= questions.length) {
        el.innerHTML = `
          <div class="modal-box">
            <h2>✅ Thank you!</h2>
            <p>Your responses help us improve. You've been entered into our prize draw.*</p>
            <button onclick="document.getElementById('survey-modal').remove()">Done</button>
            <p class="fine-print">*Prize: one additional free article per month for 3 months.</p>
          </div>`;
      } else { renderQ(); }
    };
    window.skipSurvey = function() {
      q = 0;
      setTimeout(() => {
        el.innerHTML = `
          <div class="modal-box">
            <h2>😔 Survey reset</h2>
            <p>To ensure data quality, skipping a question restarts the survey from the beginning.</p>
            <button onclick="restartSurvey()">Start again</button>
            <br/><small onclick="document.getElementById('survey-modal').remove()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:10px">Exit survey (results discarded)</small>
          </div>`;
      }, 200);
    };
    window.restartSurvey = function() { q = 0; renderQ(); };
    document.body.appendChild(el);
    renderQ();
  }
  function addLiveChatBubble() {
    const el = document.createElement('div');
    el.id = 'live-chat';
    el.innerHTML = `
      <div id="chat-bubble" onclick="toggleChat()">💬<span id="chat-badge">1</span></div>
      <div id="chat-window" style="display:none">
        <div id="chat-header">
          Support <small style="opacity:0.8">· Typically replies instantly</small>
          <span style="float:right;cursor:pointer" onclick="toggleChat()">✕</span>
        </div>
        <div id="chat-messages">
          <div class="chat-msg" style="background:#f0f7ff"><strong>Sarah (Support)</strong><br/>Hi there! I noticed you've been reading for a while. Can I help you find what you're looking for? 😊</div>
        </div>
        <input id="chat-input" type="text" placeholder="Type a message..." onkeydown="sendChat(event)" />
      </div>`;
    document.body.appendChild(el);
    setTimeout(() => {
      document.getElementById('chat-window').style.display = 'block';
      document.getElementById('chat-badge').style.display = 'none';
    }, 5000);
  }
  window.toggleChat = function() {
    const w = document.getElementById('chat-window');
    w.style.display = w.style.display !== 'none' ? 'none' : 'block';
  };
  const chatResponses = [
    'I understand! Have you considered upgrading to Premium for an ad-free experience?',
    'Great question! That feature is available on our Premium plan from $9.99/mo.',
    'I\'m sorry to hear that. I\'ve escalated your concern to our billing team.',
    'I\'d love to help! Could you first verify your account email?',
    'That\'s outside my scope. I can connect you to our sales team?',
    'Your query has been logged as ticket #84721. Response time: 5-7 business days.',
    'I completely understand your frustration. Our Premium plan resolves this issue.',
    'Let me check... ⏳ still checking... I\'ll need to transfer you to another agent.',
  ];
  window.sendChat = function(e) {
    if (e.key !== 'Enter') return;
    const input = document.getElementById('chat-input');
    const msgs = document.getElementById('chat-messages');
    if (!input.value.trim()) return;
    const userMsg = document.createElement('div');
    userMsg.className = 'chat-msg user-msg';
    userMsg.textContent = input.value;
    msgs.appendChild(userMsg);
    input.value = '';
    const typing = document.createElement('div');
    typing.className = 'chat-msg';
    typing.innerHTML = '<em style="color:#aaa">Sarah is typing...</em>';
    msgs.appendChild(typing);
    msgs.scrollTop = msgs.scrollHeight;
    setTimeout(() => {
      typing.remove();
      const botMsg = document.createElement('div');
      botMsg.className = 'chat-msg';
      botMsg.innerHTML = `<strong>Sarah (Support)</strong><br/>${chatResponses[Math.floor(Math.random() * chatResponses.length)]}`;
      msgs.appendChild(botMsg);
      msgs.scrollTop = msgs.scrollHeight;
    }, 1500 + Math.random() * 1000);
  };
  function injectBreakingNewsTicker() {
    const el = document.createElement('div');
    el.id = 'news-ticker';
    el.innerHTML = `
      <span class="ticker-label">LIVE</span>
      <marquee scrollamount="4">
        1,204 users currently reading this article &nbsp;•&nbsp;
        Your free article limit resets in 29 days &nbsp;•&nbsp;
        SPONSORED: Top 10 things you didn't know about subscribing &nbsp;•&nbsp;
        Data brokers have accessed your profile 47 times today &nbsp;•&nbsp;
        Our terms of service were updated 3 minutes ago &nbsp;•&nbsp;
        Premium users are reading 3x more articles than you right now &nbsp;•&nbsp;
        ⚠️ Your session will expire in 10 minutes without an account &nbsp;•&nbsp;
      </marquee>`;
    document.body.prepend(el);
  }
  function degradeCursor() {
    document.addEventListener('mousemove', function(e) {
      if (Math.random() > 0.25) return;
      const spark = document.createElement('div');
      spark.className = 'cursor-spark';
      spark.textContent = ['💰','📢','🍪','👁️','💊','📧','💳','📊'][Math.floor(Math.random()*8)];
      spark.style.left = e.pageX + 'px';
      spark.style.top = e.pageY + 'px';
      document.body.appendChild(spark);
      setTimeout(() => spark.remove(), 800);
    });
  }
  function addConfetti() {
    for (let i = 0; i < 40; i++) {
      setTimeout(() => {
        const el = document.createElement('div');
        el.className = 'confetti-piece';
        el.textContent = ['💰','📊','🍪','📧','💳','👁️','📱','🎯'][Math.floor(Math.random()*8)];
        el.style.left = Math.random() * 100 + 'vw';
        el.style.animationDuration = (Math.random() * 2 + 1.5) + 's';
        document.body.appendChild(el);
        setTimeout(() => el.remove(), 3500);
      }, i * 80);
    }
  }
  function addFakeSecurityAlert() {
    const el = document.createElement('div');
    el.id = 'security-alert';
    el.innerHTML = `
      <div class="modal-box" style="border-top:4px solid #e53e3e;max-width:460px">
        <div class="modal-badge" style="background:#e53e3e">SECURITY NOTICE</div>
        <h2 style="color:#e53e3e;margin-top:8px">Unusual activity detected</h2>
        <p style="color:#555">We detected a sign-in attempt to your account from:</p>
        <div style="background:#fff5f5;border:1px solid #fed7d7;border-radius:6px;padding:12px;margin:12px 0;font-size:13px">
          <strong>Location:</strong> ${Intl.DateTimeFormat().resolvedOptions().timeZone || 'Unknown'}<br/>
          <strong>Device:</strong> ${navigator.platform || 'Unknown device'}<br/>
          <strong>Time:</strong> ${new Date().toLocaleTimeString()}
        </div>
        <p style="font-size:13px;color:#555">If this was you, no action is needed. If not, secure your account immediately.</p>
        <div style="display:flex;gap:8px;margin-top:16px">
          <button onclick="document.getElementById('security-alert').remove()" style="flex:1;background:#e53e3e;color:white;border:none;padding:10px;border-radius:6px;cursor:pointer;font-weight:bold">Secure My Account</button>
          <button onclick="dismissSecurityAlert()" style="flex:1;background:#f5f5f5;color:#333;border:1px solid #ddd;padding:10px;border-radius:6px;cursor:pointer">This was me</button>
        </div>
      </div>`;
    document.body.appendChild(el);
  }
  window.dismissSecurityAlert = function() {
    document.getElementById('security-alert').innerHTML = `
      <div class="modal-box">
        <h2>✅ Got it</h2>
        <p>We've marked this activity as safe.</p>
        <p style="margin-top:8px;font-size:13px;color:#666">To prevent future alerts, <strong>create a free account</strong> and enable two-factor authentication.</p>
        <button onclick="chooseFree();document.getElementById('security-alert').remove()">Create Account</button>
        <br/><small onclick="document.getElementById('security-alert').remove()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:10px">Dismiss</small>
      </div>`;
  };
  function addTabHijack() {
    const original = document.title;
    let awayCount = 0;
    document.addEventListener('visibilitychange', () => {
      if (document.hidden) {
        awayCount++;
        const msgs = ['😢 Come back! We miss you...', '🔴 URGENT: Your session expires soon', '💸 OFFER: 50% off Premium — today only', `⚠️ ${awayCount * 3} notifications while you were away`, '🍪 Cookie consent expires when you leave'];
        document.title = msgs[awayCount % msgs.length];
      } else {
        document.title = original;
        if (awayCount > 0) showTabReturnPopup(awayCount);
      }
    });
  }
  function showTabReturnPopup(count) {
    const existing = document.getElementById('tab-return-popup');
    if (existing) existing.remove();
    const el = document.createElement('div');
    el.id = 'tab-return-popup';
    el.innerHTML = `
      <strong>👋 Welcome back!</strong><br/>
      <span style="font-size:13px;color:#666">You missed <strong>${count * 3} personalised updates</strong> while away. ${count} new ads have been queued for you.</span>
      <div style="margin-top:10px"><button onclick="document.getElementById('tab-return-popup').remove()">OK</button></div>`;
    document.body.appendChild(el);
    setTimeout(() => { if (el.parentNode) el.remove(); }, 6000);
  }
  function addScrollBlocker() {
    let triggered = false;
    window.addEventListener('scroll', () => {
      if (triggered) return;
      if (window.scrollY > 400) {
        triggered = true;
        const overlay = document.createElement('div');
        overlay.id = 'scroll-overlay';
        document.body.appendChild(overlay);
        const el = document.createElement('div');
        el.id = 'scroll-block';
        el.innerHTML = `
          <div class="modal-box">
            <div class="modal-badge">MEMBER CONTENT</div>
            <h2>You're reading a member article</h2>
            <p style="color:#555">This article is freely available to members. Create a free account to continue reading.</p>
            <div style="background:#f9f9f9;border-radius:6px;padding:12px;margin:12px 0;font-size:13px;color:#666">
              ✓ Unlimited articles &nbsp; ✓ Save to reading list<br/>
              ✓ Comment on articles &nbsp; ✓ Personalised feed
            </div>
            <button onclick="chooseFree();document.getElementById('scroll-block').remove();document.getElementById('scroll-overlay').remove();" style="width:100%;background:#4d96ff;color:white;border:none;padding:12px;border-radius:6px;cursor:pointer;font-weight:bold;font-size:15px">Create free account →</button>
            <br/><small onclick="continueReading()" style="cursor:pointer;color:#bbb;font-size:11px;display:block;margin-top:10px;text-align:center">Continue without account (limited access)</small>
          </div>`;
        document.body.appendChild(el);
      }
    });
  }
  window.continueReading = function() {
    const sb = document.getElementById('scroll-block');
    const so = document.getElementById('scroll-overlay');
    if (sb) sb.remove();
    if (so) so.remove();
    setTimeout(() => {
      let retrigger = false;
      window.addEventListener('scroll', function handler() {
        if (retrigger) return;
        if (window.scrollY > 800) {
          retrigger = true;
          window.removeEventListener('scroll', handler);
          const el = document.createElement('div');
          el.id = 'scroll-block';
          el.innerHTML = `
            <div class="modal-box">
              <h2>You've reached your limit</h2>
              <p style="color:#555">You can read <strong>2 articles per month</strong> without an account. You've used both.</p>
              <button onclick="chooseFree();document.getElementById('scroll-block').remove();" style="width:100%;background:#4d96ff;color:white;border:none;padding:12px;border-radius:6px;cursor:pointer;font-weight:bold">Create free account →</button>
              <br/><small style="color:#bbb;font-size:11px;display:block;margin-top:10px;text-align:center">Resets in 29 days</small>
            </div>`;
          document.body.appendChild(el);
        }
      });
    }, 500);
  };
  function addBeforeUnloadNag() {
    window.addEventListener('beforeunload', (e) => { e.preventDefault(); e.returnValue = ''; });
  }
  function addFloatingCountdown() {
    const el = document.createElement('div');
    el.id = 'urgency-countdown';
    el.innerHTML = `
      <div id="urgency-inner">
        <div style="font-size:10px;color:#999;margin-bottom:4px">LIMITED TIME OFFER</div>
        <strong style="font-size:13px">Get 3 months free</strong>
        <div id="countdown-timer">14:59</div>
        <small style="font-size:11px;color:#999">Then $9.99/mo. Cancel anytime.*</small>
        <button onclick="choosePremium()">Claim offer →</button>
        <div id="countdown-close" onclick="closeCountdown()">✕</div>
      </div>`;
    document.body.appendChild(el);
    let seconds = 899;
    const iv = setInterval(() => {
      seconds--;
      if (seconds <= 0) {
        clearInterval(iv);
        const t = document.getElementById('countdown-timer');
        if (t) { t.textContent = 'EXPIRED'; t.style.color = '#999'; }
        return;
      }
      const t = document.getElementById('countdown-timer');
      if (t) t.textContent = Math.floor(seconds/60) + ':' + String(seconds%60).padStart(2,'0');
    }, 1000);
  }
  window.closeCountdown = function() {
    const el = document.getElementById('urgency-countdown');
    if (!el) return;
    el.style.transform = 'translateX(120%)';
    el.style.transition = 'transform 0.3s ease';
    setTimeout(() => {
      if (!el.parentNode) return;
      el.style.transform = '';
      el.style.transition = '';
      const inner = document.getElementById('urgency-inner');
      if (inner) inner.insertAdjacentHTML('afterbegin', '<div style="font-size:10px;background:#fff3cd;color:#856404;padding:4px 8px;border-radius:4px;margin-bottom:8px">⚠️ Closing this resets the offer timer</div>');
    }, 5000);
  };
  function addFakeProgressBar() {
    const el = document.createElement('div');
    el.id = 'fake-progress-bar';
    el.innerHTML = `<div id="fake-progress-fill"></div>`;
    document.body.prepend(el);
    let pct = 0;
    let goingDown = false;
    setInterval(() => {
      if (goingDown) { pct -= 5; if (pct <= 10) goingDown = false; }
      else { pct += Math.random() * 4; if (pct > 89) goingDown = true; }
      const fill = document.getElementById('fake-progress-fill');
      if (fill) fill.style.width = pct + '%';
    }, 400);
  }
  function addViewerCounter() {
    const el = document.createElement('div');
    el.id = 'viewer-counter';
    el.innerHTML = `<span id="viewer-dot">●</span> <span id="viewer-num">847</span> people reading this now`;
    const body = document.querySelector('.mw-body');
    if (body) body.prepend(el);
    let count = 847;
    setInterval(() => {
      count += Math.floor(Math.random() * 5) - 1;
      if (count < 800) count = 800;
      const n = document.getElementById('viewer-num');
      if (n) n.textContent = count.toLocaleString();
    }, 2000);
  }
});