// ==UserScript==
// @name ModernMonkeyConfig Edition
// @namespace http://odyniec.net/
// @description Easy configuration dialog builder for user scripts - Modern Edition
// @version 0.1.4
// @include *
// ==/UserScript==
/*
* ModernMonkeyConfig Edition
* version 0.1.4
*
* Based on MonkeyConfig by Michal Wojciechowski (odyniec.net)
* Modernized with responsive design, modern icons, fixed header/footer
*/
function ModernMonkeyConfig() {
var cfg = this,
/* Data object passed to the constructor */
data,
/* Configuration parameters (data.parameters or data.params) */
params,
/* Current values of configuration parameters */
values = {},
/* Identifier used to store/retrieve configuration */
storageKey,
/* Is the configuration dialog displayed? */
displayed,
/* Currently displayed window/layer */
openWin, openLayer,
/* DOM element wrapping the configuration form */
container,
/* Darkened overlay used in the layer display mode */
overlay;
/**
* Initialize configuration
*
* @param newData New data object
*/
function init(newData) {
data = newData;
if (data) {
params = data.parameters || data.params;
if (data.buttons === undefined)
/* Set default buttons */
data.buttons = [ 'save', 'defaults', 'cancel' ];
if (data.title === undefined)
/*
* If GM_getMetadata is available, get the name of the script
* and use it in the dialog title
*/
if (typeof GM_getMetadata == 'function') {
var scriptName = GM_getMetadata('name');
data.title = scriptName + ' Configuration';
}
else
data.title = 'Configuration';
}
/* Make a safe version of title to be used as stored value identifier */
var safeTitle = data && data.title ?
data.title.replace(/[^a-zA-Z0-9]/g, '_') : '';
storageKey = '_ModernMonkeyConfig_' + safeTitle + '_cfg';
var storedValues;
/* Load stored values (if present) */
if (GM_getValue(storageKey))
storedValues = JSON.parse(GM_getValue(storageKey));
for (var name in params) {
/* If there's a value defined in the passed data object, use it */
if (params[name]['value'] !== undefined)
set(name, params[name].value);
/* Check if there's a stored value for this parameter */
else if (storedValues && storedValues[name] !== undefined)
set(name, storedValues[name]);
/* Otherwise, set the default value (if defined) */
else if (params[name]['default'] !== undefined)
set(name, params[name]['default']);
else
set(name, '');
}
if (data.menuCommand) {
/* Add an item to the User Script Commands menu */
var caption = data.menuCommand !== true ? data.menuCommand :
data.title;
GM_registerMenuCommand(caption, function () { cfg.open(); });
}
/* Expose public methods */
cfg.open = open;
cfg.close = close;
cfg.get = get;
cfg.set = function (name, value) {
set(name, value);
update();
};
}
/**
* Get the value of a configuration parameter
*
* @param name Name of the configuration parameter
* @returns Value of the configuration parameter
*/
function get(name) {
return values[name];
}
/**
* Set the value of a configuration parameter
*
* @param name Name of the configuration parameter
* @param value New value of the configuration parameter
*/
function set(name, value) {
values[name] = value;
}
/**
* Reset configuration parameters to default values
*/
function setDefaults() {
for (var name in params) {
if (typeof params[name]['default'] !== 'undefined') {
set(name, params[name]['default']);
}
}
}
/**
* Render the configuration dialog
*/
function render() {
var html = '<div class="__ModernMonkeyConfig_layer">' +
'<div class="__ModernMonkeyConfig_header">' +
'<h5>' + data.title + '</h5>' +
'<button type="button" class="__ModernMonkeyConfig_close_btn" id="__ModernMonkeyConfig_button_close">' +
ModernMonkeyConfig.res.icons.x +
'</button>' +
'</div>' +
'<div class="__ModernMonkeyConfig_container">' +
'<div class="__ModernMonkeyConfig_content">' +
'<div class="__ModernMonkeyConfig_form">';
for (var name in params) {
html += ModernMonkeyConfig.formatters['field'](name, params[name]);
}
html += '</div>' +
'</div>' +
'</div>' +
'<div class="__ModernMonkeyConfig_footer">' +
'<div class="__ModernMonkeyConfig_buttons">';
/* Render buttons */
for (var button in data.buttons) {
switch (data.buttons[button]) {
case 'cancel':
html += '<button type="button" class="__ModernMonkeyConfig_btn __ModernMonkeyConfig_btn_secondary" ' +
'id="__ModernMonkeyConfig_button_cancel">' +
ModernMonkeyConfig.res.icons.x + ' Cancel</button>';
break;
case 'defaults':
html += '<button type="button" class="__ModernMonkeyConfig_btn __ModernMonkeyConfig_btn_secondary" ' +
'id="__ModernMonkeyConfig_button_defaults">' +
ModernMonkeyConfig.res.icons.rotateCounterClockwise + ' Reset</button>';
break;
case 'save':
html += '<button type="button" class="__ModernMonkeyConfig_btn __ModernMonkeyConfig_btn_primary" ' +
'id="__ModernMonkeyConfig_button_save">' +
ModernMonkeyConfig.res.icons.check + ' Save</button>';
break;
}
}
html += '</div></div></div>';
return html;
}
/**
* Update the fields in the dialog to reflect current values
*/
function update() {
/* Do nothing if the dialog is not currently displayed */
if (!displayed)
return;
for (var name in params) {
var value = values[name];
switch (params[name].type) {
case 'checkbox':
var elem = container.querySelector('[name="' + name + '"]');
elem.checked = !!value;
break;
case 'custom':
params[name].set(value, container
.querySelector('#__ModernMonkeyConfig_parent_' + name));
break;
case 'number':
case 'text':
case 'color':
var elem = container.querySelector('[name="' + name + '"]');
elem.value = value;
break;
case 'select':
var elem = container.querySelector('[name="' + name + '"]');
if (elem.tagName.toLowerCase() == 'input') {
if (elem.type && elem.type == 'radio') {
/* Single selection with radio buttons */
elem = container.querySelector(
'[name="' + name + '"][value="' + value + '"]');
elem.checked = true;
}
else if (elem.type && elem.type == 'checkbox') {
/* Multiple selection with checkboxes */
var checkboxes = container.querySelectorAll(
'input[name="' + name + '"]');
for (var i = 0; i < checkboxes.length; i++)
checkboxes[i].checked =
(value.indexOf(checkboxes[i].value) > -1);
}
}
else if (elem.tagName.toLowerCase() == 'select')
if (elem.multiple) {
/* Multiple selection element */
var options = container.querySelectorAll(
'select[name="' + name + '"] option');
for (var i = 0; i < options.length; i++)
options[i].selected =
(value.indexOf(options[i].value) > -1);
}
else
/* Single selection element */
elem.value = value;
break;
}
}
}
/**
* Save button click event handler
*/
function saveClick() {
for (var name in params) {
switch (params[name].type) {
case 'checkbox':
var elem = container.querySelector('[name="' + name + '"]');
values[name] = elem.checked;
break;
case 'custom':
values[name] = params[name].get(container
.querySelector('#__ModernMonkeyConfig_parent_' + name));
break;
case 'number':
case 'text':
case 'color':
var elem = container.querySelector('[name="' + name + '"]');
values[name] = elem.value;
break;
case 'select':
var elem = container.querySelector('[name="' + name + '"]');
if (elem.tagName.toLowerCase() == 'input') {
if (elem.type && elem.type == 'radio')
/* Single selection with radio buttons */
values[name] = container.querySelector(
'[name="' + name + '"]:checked').value;
else if (elem.type && elem.type == 'checkbox') {
/* Multiple selection with checkboxes */
values[name] = [];
var inputs = container.querySelectorAll(
'input[name="' + name + '"]');
for (var i = 0; i < inputs.length; i++)
if (inputs[i].checked)
values[name].push(inputs[i].value);
}
}
else if (elem.tagName.toLowerCase() == 'select' && elem.multiple) {
/* Multiple selection element */
values[name] = [];
var options = container.querySelectorAll(
'select[name="' + name + '"] option');
for (var i = 0; i < options.length; i++)
if (options[i].selected)
values[name].push(options[i].value);
}
else
values[name] = elem.value;
break;
}
}
GM_setValue(storageKey, JSON.stringify(values));
close();
if (data.onSave)
data.onSave(values);
}
/**
* Cancel button click event handler
*/
function cancelClick() {
close();
}
/**
* Set Defaults button click event handler
*/
function defaultsClick() {
setDefaults();
update();
}
/**
* Close button click event handler
*/
function closeClick() {
close();
}
/**
* Open configuration dialog
*
* @param mode
* Display mode ("iframe", "layer", or "window", defaults to
* "layer")
* @param options
* Display mode options
*/
function open(mode, options) {
mode = mode || 'layer';
function openDone() {
/* Attach button event handlers */
var button;
if (button = openLayer.querySelector('#__ModernMonkeyConfig_button_save'))
button.addEventListener('click', saveClick, true);
if (button = openLayer.querySelector('#__ModernMonkeyConfig_button_cancel'))
button.addEventListener('click', cancelClick, true);
if (button = openLayer.querySelector('#__ModernMonkeyConfig_button_defaults'))
button.addEventListener('click', defaultsClick, true);
if (button = openLayer.querySelector('#__ModernMonkeyConfig_button_close'))
button.addEventListener('click', closeClick, true);
displayed = true;
update();
}
switch (mode) {
case 'window':
var windowFeatures = {
location: 'no',
status: 'no',
left: window.screenX,
top: window.screenY,
width: 100,
height: 100
};
/* Additional features may be specified as an option */
if (options && options.windowFeatures)
for (var name in options.windowFeatures)
windowFeatures[name] = options.windowFeatures[name];
var featuresArray = [];
for (var name in windowFeatures)
featuresArray.push(name + '=' + windowFeatures[name]);
var win = window.open('', data.title, featuresArray.join(','));
/* Find head and body */
var head = win.document.getElementsByTagName('head')[0],
body = win.document.getElementsByTagName('body')[0];
head.innerHTML = '<title>' + data.title + '</title>' +
'<style type="text/css">' +
ModernMonkeyConfig.res.stylesheets.main + '</style>';
body.className = '__ModernMonkeyConfig_window';
/* Place the rendered configuration dialog inside the window body */
body.innerHTML = render();
/* Find the container */
container = win.document.querySelector('.__ModernMonkeyConfig_container');
/* Resize window to the dimensions of the container div */
win.innerWidth = container.clientWidth;
win.resizeBy(0, -win.innerHeight + container.clientHeight);
/* Place the window centered relative to the parent */
win.moveBy(Math.round((window.outerWidth - win.outerWidth) / 2),
Math.round((window.outerHeight - win.outerHeight) / 2));
openWin = win;
openDone();
break;
case 'layer':
default:
if (!ModernMonkeyConfig.styleAdded) {
GM_addStyle(ModernMonkeyConfig.res.stylesheets.main);
ModernMonkeyConfig.styleAdded = true;
}
var body = document.querySelector('body');
/* Create the overlay */
overlay = document.createElement('div');
overlay.className = '__ModernMonkeyConfig_overlay';
overlay.addEventListener('click', function(e) {
if (e.target === overlay) {
close();
}
}, true);
body.appendChild(overlay);
/*
* Place the rendered configuration dialog inside the overlay
*/
overlay.innerHTML = render();
/* Find the layer element */
openLayer = overlay.querySelector('.__ModernMonkeyConfig_layer');
container = overlay.querySelector('.__ModernMonkeyConfig_container');
openDone();
break;
}
}
/**
* Close configuration dialog
*/
function close() {
if (openWin) {
openWin.close();
openWin = undefined;
}
else if (overlay) {
overlay.parentNode.removeChild(overlay);
overlay = undefined;
openLayer = undefined;
}
displayed = false;
}
init(arguments[0]);
}
/**
* Replace double quotes with entities so that the string can be safely used
* in a HTML attribute
*
* @param string A string
* @returns String with double quotes replaced with entities
*/
ModernMonkeyConfig.esc = function (string) {
return string.replace(/"/g, '"');
};
ModernMonkeyConfig.HTML = {
'_field': function (name, options, data) {
var html;
if (options.type && ModernMonkeyConfig.HTML[options.type])
html = ModernMonkeyConfig.HTML[options.type](name, options, data);
else
return;
if (/\[FIELD\]/.test(options.html)) {
html = options.html.replace(/\[FIELD\]/, html);
}
return html;
},
'_label': function (name, options, data) {
var label = options['label'] ||
name.substring(0, 1).toUpperCase() + name.substring(1)
.replace(/_/g, ' ');
return '<label for="__ModernMonkeyConfig_field_' + name + '">' + label + '</label>';
},
'checkbox': function (name, options, data) {
return '<div class="__ModernMonkeyConfig_checkbox_wrapper">' +
'<input id="__ModernMonkeyConfig_field_' + name +
'" type="checkbox" name="' + name + '" class="__ModernMonkeyConfig_checkbox" />' +
'<span class="__ModernMonkeyConfig_checkmark"></span>' +
'</div>';
},
'custom': function (name, options, data) {
return options.html;
},
'number': function (name, options, data) {
return '<input id="__ModernMonkeyConfig_field_' + name + '" ' +
'type="number" class="__ModernMonkeyConfig_input" ' +
'name="' + name + '" />';
},
'select': function (name, options, data) {
var choices = {}, html = '';
if (options.choices.constructor == Array) {
/* options.choices is an array -- build key/value pairs */
for (var i = 0; i < options.choices.length; i++)
choices[options.choices[i]] = options.choices[i];
}
else
/* options.choices is an object -- use it as it is */
choices = options.choices;
if (!options.multiple) {
/* Single selection */
if (!/^radio/.test(options.variant)) {
/* Select element */
html += '<select id="__ModernMonkeyConfig_field_' + name + '" ' +
'class="__ModernMonkeyConfig_select" ' +
'name="' + name + '">';
for (var value in choices)
html += '<option value="' + ModernMonkeyConfig.esc(value) + '">' +
choices[value] + '</option>';
html += '</select>';
}
else {
/* Radio buttons */
html += '<div class="__ModernMonkeyConfig_radio_group">';
for (var value in choices) {
html += '<label class="__ModernMonkeyConfig_radio_label">' +
'<input type="radio" name="' + name + '" ' +
'value="' + ModernMonkeyConfig.esc(value) + '" class="__ModernMonkeyConfig_radio" />' +
'<span class="__ModernMonkeyConfig_radio_mark"></span>' +
choices[value] + '</label>';
}
html += '</div>';
}
}
else {
/* Multiple selection */
if (!/^checkbox/.test(options.variant)) {
/* Select element */
html += '<select id="__ModernMonkeyConfig_field_' + name + '" ' +
'class="__ModernMonkeyConfig_select" ' +
'multiple="multiple" ' +
'name="' + name + '">';
for (var value in choices)
html += '<option value="' + ModernMonkeyConfig.esc(value) + '">' +
choices[value] + '</option>';
html += '</select>';
}
else {
/* Checkboxes */
html += '<div class="__ModernMonkeyConfig_checkbox_group">';
for (var value in choices) {
html += '<label class="__ModernMonkeyConfig_checkbox_label">' +
'<input type="checkbox" ' +
'name="' + name + '" ' +
'value="' + ModernMonkeyConfig.esc(value) + '" class="__ModernMonkeyConfig_checkbox" />' +
'<span class="__ModernMonkeyConfig_checkmark"></span>' +
choices[value] + '</label>';
}
html += '</div>';
}
}
return html;
},
'text': function (name, options, data) {
if (options.long)
return '<textarea id="__ModernMonkeyConfig_field_' + name + '" ' +
'class="__ModernMonkeyConfig_textarea" ' +
(!isNaN(options.long) ? 'rows="' + options.long + '" ' : '') +
'name="' + name + '"></textarea>';
else
return '<input id="__ModernMonkeyConfig_field_' + name + '" ' +
'type="text" class="__ModernMonkeyConfig_input" ' +
'name="' + name + '" />';
},
'color': function(name, options, data) {
return '<input id="__ModernMonkeyConfig_field_' + name + '" ' +
'type="color" class="__ModernMonkeyConfig_color" ' +
'name="' + name + '" />';
}
};
ModernMonkeyConfig.formatters = {
'field': function (name, options, data) {
var html = '<div class="__ModernMonkeyConfig_field_group">';
switch (options.type) {
case 'checkbox':
/* Checkboxes get special treatment */
html += '<div id="__ModernMonkeyConfig_parent_' + name + '" class="__ModernMonkeyConfig_checkbox_field">';
html += ModernMonkeyConfig.HTML['_field'](name, options, data);
html += ModernMonkeyConfig.HTML['_label'](name, options, data);
html += '</div>';
break;
default:
html += '<div class="__ModernMonkeyConfig_label_wrapper">';
html += ModernMonkeyConfig.HTML['_label'](name, options, data);
html += '</div>';
html += '<div id="__ModernMonkeyConfig_parent_' + name + '" class="__ModernMonkeyConfig_input_wrapper">';
html += ModernMonkeyConfig.HTML['_field'](name, options, data);
html += '</div>';
break;
}
html += '</div>';
return html;
}
};
/* Has the stylesheet been added? */
ModernMonkeyConfig.styleAdded = false;
/* Resources */
ModernMonkeyConfig.res = {};
/* Modern SVG Icons (Lucide style) */
ModernMonkeyConfig.res.icons = {
'check': '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20,6 9,17 4,12"></polyline></svg>',
'x': '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>',
'rotateCounterClockwise': '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 4v6h6"></path><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg>'
};
/* Modern Responsive Stylesheets with Fixed Header/Footer */
ModernMonkeyConfig.res.stylesheets = {
'main': `
/* Reset and base styles */
.__ModernMonkeyConfig_overlay * {
box-sizing: border-box;
}
/* Overlay */
.__ModernMonkeyConfig_overlay {
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 100vw !important;
height: 100vh !important;
background: rgba(0, 0, 0, 0.5) !important;
backdrop-filter: blur(4px) !important;
z-index: 999999 !important;
animation: __ModernMonkeyConfig_fadeIn 0.2s ease-out !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
/* Layer container - Fixed size */
.__ModernMonkeyConfig_layer {
width: 280px !important;
max-width: 90vw !important;
max-height: 90vh !important;
background: #ffffff !important;
border-radius: 12px !important;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04) !important;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif !important;
font-size: 12px !important;
line-height: 1.5 !important;
color: #1f2937 !important;
border: 1px solid #e5e7eb !important;
display: flex !important;
flex-direction: column !important;
animation: __ModernMonkeyConfig_slideIn 0.3s ease-out !important;
overflow: hidden !important;
user-select: none !important;
}
/* Fixed Header */
.__ModernMonkeyConfig_header {
position: relative !important;
padding: 10px 14px !important;
border-bottom: 1px solid #f3f4f6 !important;
background: #ffffff !important;
border-radius: 12px 12px 0 0 !important;
flex-shrink: 0 !important;
display: flex !important;
align-items: center !important;
justify-content: space-between !important;
}
.__ModernMonkeyConfig_header h5 {
margin: 0 !important;
padding: 0 !important;
font-size: 14px !important;
font-weight: 600 !important;
color: #111827 !important;
line-height: 1.25 !important;
flex: 1 !important;
}
/* Close button */
.__ModernMonkeyConfig_close_btn {
display: flex !important;
align-items: center !important;
justify-content: center !important;
width: 18px !important;
height: 18px !important;
border: none !important;
background: transparent !important;
border-radius: 6px !important;
cursor: pointer !important;
transition: all 0.2s ease !important;
color: #6b7280 !important;
padding: 0 !important;
margin: 0 !important;
}
.__ModernMonkeyConfig_close_btn:hover {
background: #f3f4f6 !important;
color: #374151 !important;
}
.__ModernMonkeyConfig_close_btn svg {
width: 18px !important;
height: 18px !important;
}
/* Scrollable Container */
.__ModernMonkeyConfig_container {
flex: 1 !important;
overflow-y: auto !important;
overflow-x: hidden !important;
padding: 0 !important;
margin: 0 !important;
}
/* Content area */
.__ModernMonkeyConfig_content {
padding: 14px !important;
}
/* Form */
.__ModernMonkeyConfig_form {
display: flex !important;
flex-direction: column !important;
gap: 20px !important;
}
/* Field groups */
.__ModernMonkeyConfig_field_group {
display: flex !important;
flex-direction: column !important;
gap: 8px !important;
}
.__ModernMonkeyConfig_label_wrapper {
display: flex !important;
align-items: center !important;
}
.__ModernMonkeyConfig_label_wrapper label {
font-weight: 500 !important;
color: #374151 !important;
font-size: 12px !important;
margin: 0 !important;
padding: 0 !important;
line-height: 1.5 !important;
}
.__ModernMonkeyConfig_input_wrapper {
display: flex !important;
flex-direction: column !important;
}
/* Input styles */
.__ModernMonkeyConfig_input,
.__ModernMonkeyConfig_select,
.__ModernMonkeyConfig_textarea {
width: 100% !important;
padding: 4px 6px !important;
border: 1px solid #d1d5db !important;
border-radius: 6px !important;
font-size: 12px !important;
font-family: inherit !important;
color: #1f2937 !important;
background: #ffffff !important;
transition: all 0.2s ease !important;
margin: 0 !important;
outline: none !important;
}
.__ModernMonkeyConfig_input:focus,
.__ModernMonkeyConfig_select:focus,
.__ModernMonkeyConfig_textarea:focus {
border-color: #3b82f6 !important;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important;
}
.__ModernMonkeyConfig_textarea {
resize: vertical !important;
min-height: 80px !important;
}
.__ModernMonkeyConfig_color {
width: 60px !important;
height: 40px !important;
padding: 4px !important;
border: 1px solid #d1d5db !important;
border-radius: 6px !important;
background: #ffffff !important;
cursor: pointer !important;
}
/* Checkbox styles */
.__ModernMonkeyConfig_checkbox_field {
display: flex !important;
align-items: center !important;
gap: 12px !important;
flex-direction: row-reverse !important;
justify-content: flex-end !important;
}
.__ModernMonkeyConfig_checkbox_wrapper {
position: relative !important;
display: inline-block !important;
}
.__ModernMonkeyConfig_checkbox {
opacity: 0 !important;
position: absolute !important;
width: 0 !important;
height: 0 !important;
}
.__ModernMonkeyConfig_checkmark {
display: inline-block !important;
width: 20px !important;
height: 20px !important;
border: 2px solid #d1d5db !important;
border-radius: 4px !important;
background: #ffffff !important;
cursor: pointer !important;
transition: all 0.2s ease !important;
position: relative !important;
}
.__ModernMonkeyConfig_checkbox:checked + .__ModernMonkeyConfig_checkmark {
background: #3b82f6 !important;
border-color: #3b82f6 !important;
}
.__ModernMonkeyConfig_checkbox:checked + .__ModernMonkeyConfig_checkmark::after {
content: '' !important;
position: absolute !important;
left: 6px !important;
top: 1px !important;
width: 5px !important;
height: 10px !important;
border: solid #ffffff !important;
border-width: 0 2px 2px 0 !important;
transform: rotate(45deg) !important;
}
/* Radio button styles */
.__ModernMonkeyConfig_radio_group {
display: flex !important;
flex-direction: column !important;
gap: 8px !important;
}
.__ModernMonkeyConfig_radio_label {
display: flex !important;
align-items: center !important;
gap: 8px !important;
cursor: pointer !important;
font-size: 12px !important;
color: #374151 !important;
}
.__ModernMonkeyConfig_radio {
opacity: 0 !important;
position: absolute !important;
width: 0 !important;
height: 0 !important;
}
.__ModernMonkeyConfig_radio_mark {
display: inline-block !important;
width: 18px !important;
height: 18px !important;
border: 2px solid #d1d5db !important;
border-radius: 50% !important;
background: #ffffff !important;
transition: all 0.2s ease !important;
position: relative !important;
}
.__ModernMonkeyConfig_radio:checked + .__ModernMonkeyConfig_radio_mark {
border-color: #3b82f6 !important;
}
.__ModernMonkeyConfig_radio:checked + .__ModernMonkeyConfig_radio_mark::after {
content: '' !important;
position: absolute !important;
top: 50% !important;
left: 50% !important;
width: 8px !important;
height: 8px !important;
border-radius: 50% !important;
background: #3b82f6 !important;
transform: translate(-50%, -50%) !important;
}
/* Checkbox group styles */
.__ModernMonkeyConfig_checkbox_group {
display: flex !important;
flex-direction: column !important;
gap: 8px !important;
}
.__ModernMonkeyConfig_checkbox_label {
display: flex !important;
align-items: center !important;
gap: 8px !important;
cursor: pointer !important;
font-size: 12px !important;
color: #374151 !important;
}
/* Fixed Footer */
.__ModernMonkeyConfig_footer {
position: relative !important;
padding: 10px 14px !important;
border-top: 1px solid #f3f4f6 !important;
background: #ffffff !important;
border-radius: 0 0 12px 12px !important;
flex-shrink: 0 !important;
}
/* Button styles */
.__ModernMonkeyConfig_buttons {
display: flex !important;
gap: 12px !important;
justify-content: center !important;
}
.__ModernMonkeyConfig_btn {
display: inline-flex !important;
align-items: center !important;
gap: 8px !important;
padding: 5px 8px !important;
border-radius: 6px !important;
font-size: 12px !important;
font-weight: 500 !important;
font-family: inherit !important;
cursor: pointer !important;
transition: all 0.2s ease !important;
border: 1px solid transparent !important;
text-decoration: none !important;
outline: none !important;
margin: 0 !important;
}
.__ModernMonkeyConfig_btn_primary {
background: #3b82f6 !important;
color: #ffffff !important;
border-color: #3b82f6 !important;
}
.__ModernMonkeyConfig_btn_primary:hover {
background: #2563eb !important;
border-color: #2563eb !important;
box-shadow: 0 4px 8px rgba(59, 130, 246, 0.3) !important;
}
.__ModernMonkeyConfig_btn_secondary {
background: #ffffff !important;
color: #374151 !important;
border-color: #d1d5db !important;
}
.__ModernMonkeyConfig_btn_secondary:hover {
background: #f9fafb !important;
border-color: #9ca3af !important;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
}
.__ModernMonkeyConfig_btn svg {
flex-shrink: 0 !important;
}
/* Custom scrollbar */
.__ModernMonkeyConfig_container::-webkit-scrollbar {
width: 6px !important;
}
.__ModernMonkeyConfig_container::-webkit-scrollbar-track {
background: #f1f5f9 !important;
}
.__ModernMonkeyConfig_container::-webkit-scrollbar-thumb {
background: #cbd5e1 !important;
border-radius: 3px !important;
}
.__ModernMonkeyConfig_container::-webkit-scrollbar-thumb:hover {
background: #94a3b8 !important;
}
/* Window mode styles */
body.__ModernMonkeyConfig_window {
margin: 0 !important;
padding: 0 !important;
background: #f9fafb !important;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif !important;
}
body.__ModernMonkeyConfig_window .__ModernMonkeyConfig_layer {
width: 100% !important;
height: 100vh !important;
max-width: none !important;
max-height: none !important;
border-radius: 0 !important;
box-shadow: none !important;
border: none !important;
}
/* Animations */
@keyframes __ModernMonkeyConfig_fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes __ModernMonkeyConfig_slideIn {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
/* Responsive design */
@media (max-width: 640px) {
.__ModernMonkeyConfig_layer {
width: 90vw !important;
max-height: 60vh !important;
border-radius: 8px !important;
}
.__ModernMonkeyConfig_header,
.__ModernMonkeyConfig_content,
.__ModernMonkeyConfig_footer {
padding-left: 16px !important;
padding-right: 16px !important;
}
.__ModernMonkeyConfig_buttons {
flex-direction: column-reverse !important;
gap: 8px !important;
}
.__ModernMonkeyConfig_btn {
width: 100% !important;
justify-content: center !important;
}
}
/* High contrast mode */
@media (prefers-contrast: high) {
.__ModernMonkeyConfig_layer {
border-width: 2px !important;
}
.__ModernMonkeyConfig_input,
.__ModernMonkeyConfig_select,
.__ModernMonkeyConfig_textarea {
border-width: 2px !important;
}
.__ModernMonkeyConfig_btn {
border-width: 2px !important;
}
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
.__ModernMonkeyConfig_overlay,
.__ModernMonkeyConfig_layer,
.__ModernMonkeyConfig_input,
.__ModernMonkeyConfig_select,
.__ModernMonkeyConfig_textarea,
.__ModernMonkeyConfig_btn,
.__ModernMonkeyConfig_checkmark,
.__ModernMonkeyConfig_radio_mark,
.__ModernMonkeyConfig_close_btn {
animation: none !important;
transition: none !important;
}
}
`
};