Home Wiki

MediaWiki:Common.js

Last updated View on consumerrights.wiki ↗

/* Any JavaScript here will be loaded for all users on every page load. */
// stolen from Lajos Mészáros on this post https://stackoverflow.com/questions/13358292/capture-tap-event-with-pure-javascript
const onClickOrTap = (element, handler) => {
  let touchMoveHappened = false;
  element.addEventListener('touchstart', () => {
    // on mobile this is the 1st event that happens
    touchMoveHappened = false;
  });
  element.addEventListener('touchmove', () => {
    // on mobile this might get triggered in which case the
    // click or tap will get cancelled
    // we'll keep a track of it
    touchMoveHappened = true;
  });
  element.addEventListener('touchend', (e) => {
    // happens after touchstart, but before click
    // if touch happened then we'll exit
    if (touchMoveHappened) {
      return;
    }
    // calling preventDefault() will make sure the
    // subsequent click will not get triggered
    e.preventDefault();
    // at this point we are ready to call our original handler
    handler(e);
  });
  element.addEventListener('click', (e) => {
    // this will only get triggered on desktopg
    // because we call preventDefault for the "touchend" event
    handler(e);
  });
}

/* Create Page */
const createPageTargetIdDataSetString = "[data-create-page-target-id]";

if (document.querySelector(createPageTargetIdDataSetString)) {
  /**
   * @type {HTMLElement[]}
   */
  let itemsCreateInputPageGrid = [];
  let itemsCreatePageGrid = [];
  const createPageTargetId = "createPageTargetId";
  const createPageInputHiddenClass = "hidden";
  const createPageInputActiveClass = "pageInputActive";

  /**
   * @param {HTMLElement} element
   */
  function getGridTarget(element) {
    const targetId = element.dataset[createPageTargetId];

    return document.getElementById(targetId);
  }

  /**
   * @this {HTMLDivElement}
   */
  function toggleGridTarget(element, targetElement) {
    for (let index = 0; index < itemsCreateInputPageGrid.length; index += 1) {
      const target = itemsCreateInputPageGrid[index];

      target.classList.add(createPageInputHiddenClass);

      if (target === targetElement) {
        target.classList.remove(createPageInputHiddenClass);
      }

      const clickedElement = itemsCreatePageGrid[index];
      
      clickedElement.classList.remove(createPageInputActiveClass);

      if (clickedElement === element) {
        clickedElement.classList.add(createPageInputActiveClass);
      }
    }
  }

  /**
   * @param {HTMLElement} element
   * @param {HTMLElement} targetElement
   */
  function addToggleGridTargetEvent(element, targetElement) {
    itemsCreatePageGrid.push(element);
    itemsCreateInputPageGrid.push(targetElement);
    
    onClickOrTap(element, (e) => {
     toggleGridTarget(element, targetElement)
    });
    //element.addEventListener("click", () =>
    //    toggleGridTarget(element, targetElement)
    //);
  }

  const createPageTargetElements = document.querySelectorAll(
    createPageTargetIdDataSetString
  );

  for (let index = 0; index < createPageTargetElements.length; index += 1) {
    const element = createPageTargetElements[index];

    const targetElement = getGridTarget(element);

    if (targetElement) {
      addToggleGridTargetEvent(element, targetElement);
    }
  }
}
/* Jakes Recent Changes Portlet */
(function () {
  function jakeTimeAgo(date) {
    var s = Math.floor((Date.now() - date.getTime()) / 1000);
    if (s < 60) return s + "s ago";
    var m = Math.floor(s / 60);
    if (m < 60) return m + "m ago";
    var h = Math.floor(m / 60);
    if (h < 24) return h + "h ago";
    var d = Math.floor(h / 24);
    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);
  }

  function jakeBuildPortlet() {
    var menu =
      document.getElementById("vector-main-menu") ||
      document.getElementById("mw-panel");

    if (!menu) return null;
    if (document.getElementById("p-jake-recentchanges")) return null;

    jakeInjectStyles();

    var portlet = document.createElement("div");
    portlet.id = "p-jake-recentchanges";
    portlet.className = "vector-menu mw-portlet";

    var heading = document.createElement("div");
    heading.className = "vector-menu-heading";

    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");
    content.className = "vector-menu-content";

    var ul = document.createElement("ul");
    ul.className = "vector-menu-content-list";
    ul.id = "jake-rc-list";

    var moreWrap = document.createElement("div");
    moreWrap.className = "jake-rc-more";

    var moreLink = document.createElement("a");
    moreLink.href = mw.util.getUrl("Special:RecentChanges");
    moreLink.textContent = "Show more…";
    moreWrap.appendChild(moreLink);

    content.appendChild(ul);
    content.appendChild(moreWrap);

    portlet.appendChild(heading);
    portlet.appendChild(content);

    var discordPortlet = menu.querySelector("#p-Community");
    if (discordPortlet && discordPortlet.parentNode) {
      discordPortlet.parentNode.insertBefore(portlet, discordPortlet.nextSibling);
    } else {
      var navPortlet = menu.querySelector("#p-navigation");
      if (navPortlet && navPortlet.parentNode) {
        navPortlet.parentNode.insertBefore(portlet, navPortlet.nextSibling);
      } else {
        menu.appendChild(portlet);
      }
    }

    return ul;
  }

  function jakeLoadRecentChanges(ul) {
    if (!ul) return;

    var api = new mw.Api();
    api
      .get({
        action: "query",
        list: "recentchanges",
        rcnamespace: "0", /* 4 */
        rclimit: 5,
        rcprop: "title|timestamp|user",
        rcshow: "!bot",
        formatversion: 2
      })
      .then(function (data) {
        var items =
          data && data.query && data.query.recentchanges
            ? data.query.recentchanges
            : [];

        ul.textContent = "";

        for (var i = 0; i < items.length; i++) {
          var rc = items[i];

          var li = document.createElement("li");
          li.className = "mw-list-item jake-rc-item";

          var a = document.createElement("a");
          a.href = mw.util.getUrl(rc.title);
          a.textContent = rc.title;

          var meta = document.createElement("div");
          meta.className = "jake-rc-meta";
          meta.textContent = jakeTimeAgo(new Date(rc.timestamp)) + " · " + (rc.user || "");

          li.appendChild(a);
          li.appendChild(meta);
          ul.appendChild(li);
        }
      })
      .catch(function () {
        ul.textContent = "";

        var li = document.createElement("li");
        li.className = "mw-list-item jake-rc-item";

        var a = document.createElement("a");
        a.href = mw.util.getUrl("Special:RecentChanges");
        a.textContent = "View recent changes";

        li.appendChild(a);
        ul.appendChild(li);
      });
  }

  function jakeInitRecentChanges() {
    if (!window.mw || !mw.util || !mw.Api) return;

    var ul = jakeBuildPortlet();
    if (!ul) ul = document.getElementById("jake-rc-list");
    if (!ul) return;

    jakeLoadRecentChanges(ul);
    setInterval(function () {
      jakeLoadRecentChanges(ul);
    }, 60000);
  }

  function jakeWaitForMenu() {
    var tries = 0;

    var timer = setInterval(function () {
      var menu =
        document.getElementById("vector-main-menu") ||
        document.getElementById("mw-panel");

      if (menu) {
        clearInterval(timer);
        jakeInitRecentChanges();
        return;
      }

      tries++;
      if (tries > 50) clearInterval(timer);
    }, 200);
  }

  jakeWaitForMenu();
})();
/* */
/*
(function () {
  function jakeAddFeedbackToNamespaces() {
    var list = document.querySelector("#p-associated-pages .vector-menu-content-list");
    if (!list) return;

    var existing = document.getElementById("jake-feedback-btn");
    if (existing && !existing.closest("#p-associated-pages")) {
      var oldLi = existing.closest("li");
      if (oldLi) oldLi.remove();
      else existing.remove();
    }

    if (document.getElementById("ca-jake-feedback")) return;

    var li = document.createElement("li");
    li.id = "ca-jake-feedback";
    li.className = "vector-tab-noicon mw-list-item";

    var a = document.createElement("a");
    a.id = "jake-feedback-btn";
    a.className = "jake-feedback-btn";
    a.href = mw.util.getUrl("Consumer_Rights_Wiki:Feedback", {
      from: mw.config.get("wgPageName")
    });
    a.title = "Give feedback";

    var span = document.createElement("span");
    span.textContent = "Give feedback";

    a.appendChild(span);
    li.appendChild(a);
    list.appendChild(li);
  }

  function jakeInit() {
    if (!window.mw || !mw.util || !mw.config) return;
    jakeAddFeedbackToNamespaces();
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", jakeInit);
  } else {
    jakeInit();
  }
})();
*/
/* */
(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="your@email.com" 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);
  }

});