Force dark mode on base44.com
// ==UserScript==
// @name Base44 Dark Mode
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Force dark mode on base44.com
// @author xSp1d3r99x
// @match https://*.base44.com/*
// @icon https://i.postimg.cc/bJw7hcQN/Base44-Logo.png
// @grant GM_addStyle
// @run-at document-start
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const darkCSS = `
html {
filter: invert(1) hue-rotate(180deg);
background: #fff;
}
img, video, picture, canvas, svg, iframe,
[style*="background-image"] {
filter: invert(1) hue-rotate(180deg);
}
/* Hide the Upgrade button and its wrapper */
button[aria-label="Upgrade plan"] {
display: none !important;
}
div.flex.items-center.align-middle:has(button[aria-label="Upgrade plan"]) {
display: none !important;
}
/* Hide the GitHub button and its wrapper */
button:has(svg.lucide-github) {
display: none !important;
}
div.flex.items-center.align-middle:has(button svg.lucide-github) {
display: none !important;
}
`;
if (typeof GM_addStyle !== 'undefined') {
GM_addStyle(darkCSS);
} else {
const style = document.createElement('style');
style.textContent = darkCSS;
document.documentElement.appendChild(style);
}
// Replace the logo image with a custom one
const OLD_LOGO_SRC = '/static/logo_v3-BqJrIa65.png';
const NEW_LOGO_SRC = 'https://i.postimg.cc/bJw7hcQN/Base44-Logo.png';
function swapLogo(img) {
if (img.src.includes(OLD_LOGO_SRC)) {
img.src = NEW_LOGO_SRC;
}
}
// Replace "Base44" text with "Base44 - AI" in matching spans
function swapText(el) {
if (
el.tagName === 'SPAN' &&
el.classList.contains('text-xs') &&
el.classList.contains('text-gray-500') &&
el.textContent.includes('Base44')
) {
el.textContent = el.textContent.replace(/Base44/g, 'Base44 - AI');
}
}
// Colour the credits-used bar based on percentage consumed
const CREDITS_BAR_SELECTOR = 'div.w-full.h-2.bg-slate-100.rounded-full.flex.overflow-hidden > div:first-child';
const CREDITS_THRESHOLDS = { orange: 60, red: 85 }; // % usage breakpoints, adjust as you like
const CREDITS_COLORS = { green: '#22c55e', orange: '#f97316', red: '#ef4444' };
function updateCreditsBarColor(bar) {
const pct = parseFloat(bar.style.width);
if (isNaN(pct)) return;
let color;
if (pct < CREDITS_THRESHOLDS.orange) {
color = CREDITS_COLORS.green;
} else if (pct < CREDITS_THRESHOLDS.red) {
color = CREDITS_COLORS.orange;
} else {
color = CREDITS_COLORS.red;
}
bar.style.setProperty('background-color', color, 'important');
}
function scanForCreditsBar() {
document.querySelectorAll(CREDITS_BAR_SELECTOR).forEach(updateCreditsBarColor);
}
function scanForLogos() {
document.querySelectorAll('img').forEach(swapLogo);
}
function scanForText() {
document.querySelectorAll('span.text-xs.text-gray-500').forEach(swapText);
}
// Run on initial load
document.addEventListener('DOMContentLoaded', () => {
scanForLogos();
scanForText();
scanForCreditsBar();
});
// Watch for dynamically added/changed elements (SPA-friendly)
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
mutation.addedNodes.forEach((node) => {
if (node.nodeType !== 1) return;
if (node.tagName === 'IMG') {
swapLogo(node);
} else if (node.tagName === 'SPAN') {
swapText(node);
}
if (node.matches && node.matches(CREDITS_BAR_SELECTOR)) {
updateCreditsBarColor(node);
}
if (node.querySelectorAll) {
node.querySelectorAll('img').forEach(swapLogo);
node.querySelectorAll('span.text-xs.text-gray-500').forEach(swapText);
node.querySelectorAll(CREDITS_BAR_SELECTOR).forEach(updateCreditsBarColor);
}
});
if (mutation.type === 'attributes' && mutation.target.tagName === 'IMG') {
swapLogo(mutation.target);
}
if (
mutation.type === 'attributes' &&
mutation.attributeName === 'style' &&
mutation.target.matches &&
mutation.target.matches(CREDITS_BAR_SELECTOR)
) {
updateCreditsBarColor(mutation.target);
}
if (mutation.type === 'characterData' && mutation.target.parentElement) {
swapText(mutation.target.parentElement);
}
}
});
observer.observe(document.documentElement, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['src', 'style'],
characterData: true
});
})();