Skip to content

Instantly share code, notes, and snippets.

@dwesh163
Last active July 9, 2026 06:19
Show Gist options
  • Select an option

  • Save dwesh163/5cec2e2964b0651b2dc21bb925c3009b to your computer and use it in GitHub Desktop.

Select an option

Save dwesh163/5cec2e2964b0651b2dc21bb925c3009b to your computer and use it in GitHub Desktop.
(function () {
'use strict';
var STYLE_ID = 'xdew-authentik-theme';
var CSS = [
':root, body {',
' --ak-accent: #3b82f6;',
' --ak-flow-background: #0a0a0a;',
' --pf-global--primary-color--100: #3b82f6;',
' --pf-global--primary-color--200: #2563eb;',
' --pf-global--BackgroundColor--100: #0a0a0a;',
' --pf-global--BackgroundColor--dark-100: #141416;',
' --pf-global--Color--100: #f5f5f5;',
' --pf-global--Color--200: #9a9aa0;',
' --pf-global--BorderColor--100: rgba(255,255,255,.12);',
'}',
'body, .pf-c-background-image, .pf-c-login {',
' background: #0a0a0a !important;',
' font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif !important;',
'}',
'.pf-c-login__main, .pf-c-login__main-body, ak-flow-executor, .ak-brand {',
' background: transparent !important;',
' box-shadow: none !important;',
'}',
'.pf-c-login__main-body {',
' background: #141416 !important;',
' border: 1px solid rgba(255,255,255,.08) !important;',
' border-radius: 16px !important;',
' box-shadow: 0 20px 40px rgba(0,0,0,.45) !important;',
' padding: 2rem !important;',
'}',
'.pf-c-login__main-header-desc, .pf-c-title, h1, h2, h3, p, span, label {',
' color: #f5f5f5;',
'}',
'.pf-c-login__main-header-desc { color: #9a9aa0 !important; }',
'.pf-c-form__label-text { color: #f5f5f5 !important; font-weight: 600 !important; }',
'.pf-c-form-control, input:not([type="checkbox"]):not([type="radio"]) {',
' background: #1c1c1f !important;',
' border: 1px solid rgba(255,255,255,.12) !important;',
' border-radius: 10px !important;',
' color: #f5f5f5 !important;',
' transition: border-color .15s ease;',
'}',
'.pf-c-form-control:focus, input:focus {',
' border-color: #3b82f6 !important;',
' box-shadow: 0 0 0 1px #3b82f6 !important;',
'}',
'.pf-c-button.pf-m-primary {',
' background: #3b82f6 !important;',
' border-radius: 10px !important;',
' font-weight: 600 !important;',
' border: none !important;',
'}',
'.pf-c-button.pf-m-primary:hover { background: #2563eb !important; }',
'a, .pf-c-login__main-footer-links a { color: #3b82f6 !important; text-decoration: none; }',
'a:hover { text-decoration: underline; }',
'.pf-c-switch__toggle { background: rgba(255,255,255,.15) !important; }',
'.pf-c-switch__input:checked ~ .pf-c-switch__toggle { background: #3b82f6 !important; }',
'.xdew-icon-wrap { position: relative; }',
'.xdew-icon {',
' position: absolute; left: 12px; top: 50%; transform: translateY(-50%);',
' width: 16px; height: 16px; color: #8a8a90; pointer-events: none; z-index: 2;',
' display: flex; align-items: center; justify-content: center;',
'}',
'.xdew-icon-wrap input { padding-left: 38px !important; }',
'.xdew-logo {',
' display: flex; align-items: center; justify-content: center; gap: .5rem;',
' margin-bottom: 1.5rem; color: #f5f5f5; font-weight: 700; font-size: 1.1rem;',
'}',
'.xdew-logo-badge {',
' width: 32px; height: 32px; border-radius: 9px; background: #3b82f6;',
' display: flex; align-items: center; justify-content: center; color: #fff;',
'}',
].join('\n');
var ICONS = {
mail: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>',
lock: '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>',
cloud: '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"/></svg>'
};
// --- Style injection: page-level + every shadow root we can find ------
function injectStyle(root) {
if (!root || !root.appendChild) return;
try {
if (root.querySelector && root.querySelector('#' + STYLE_ID)) return;
var style = document.createElement('style');
style.id = STYLE_ID;
style.textContent = CSS;
(root.head || root).appendChild(style);
} catch (e) { /* never let a styling failure break the flow */ }
}
// --- Icons: only decorate, never touch name/id/value/listeners --------
function decorateInputs(root) {
if (!root || !root.querySelectorAll) return;
try {
root.querySelectorAll(
'input[type="email"], input[name="uid_field"], input[autocomplete="username"]'
).forEach(function (input) { addIcon(input, 'mail'); });
root.querySelectorAll('input[type="password"]').forEach(function (input) {
addIcon(input, 'lock');
});
} catch (e) {}
}
function addIcon(input, name) {
if (!input || input.dataset.xdewIconized) return;
var wrapper = input.parentElement;
if (!wrapper) return;
input.dataset.xdewIconized = '1';
wrapper.classList.add('xdew-icon-wrap');
var span = document.createElement('span');
span.className = 'xdew-icon';
span.innerHTML = ICONS[name];
wrapper.appendChild(span);
}
// --- Optional brand header, added once above the card ------------------
function addLogo(root) {
if (!root || !root.querySelector) return;
try {
var body = root.querySelector('.pf-c-login__main-body');
if (!body || body.dataset.xdewLogo) return;
body.dataset.xdewLogo = '1';
var logo = document.createElement('div');
logo.className = 'xdew-logo';
logo.innerHTML =
'<span class="xdew-logo-badge">' + ICONS.cloud + '</span><span>xdew Console</span>';
body.parentElement.insertBefore(logo, body);
} catch (e) {}
}
// --- Walk light DOM + every nested shadow root --------------------------
function walk(node) {
if (!node) return;
injectStyle(node);
decorateInputs(node);
addLogo(node);
var all = node.querySelectorAll ? node.querySelectorAll('*') : [];
for (var i = 0; i < all.length; i++) {
if (all[i].shadowRoot) walk(all[i].shadowRoot);
}
}
function tick() {
try {
walk(document);
} catch (e) {}
}
document.addEventListener('DOMContentLoaded', tick);
var mo = new MutationObserver(function () { tick(); });
mo.observe(document.documentElement, { childList: true, subtree: true });
tick();
// Safety net: Lit re-renders stages async, a MutationObserver can miss a
// beat between stage swaps - a cheap poll costs nothing and never removes
// anything, only (re)adds styling/icons that are already idempotent.
setInterval(tick, 800);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment