Skip to content

Instantly share code, notes, and snippets.

@alipha
Created August 17, 2025 22:32
Show Gist options
  • Select an option

  • Save alipha/5d78cb67c08eceda2f9cd8edb2a506ed to your computer and use it in GitHub Desktop.

Select an option

Save alipha/5d78cb67c08eceda2f9cd8edb2a506ed to your computer and use it in GitHub Desktop.
Allow player to mark cards as possibly innocent or criminal
// ==UserScript==
// @name CluesBySam Markers
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Allow player to mark cards as possibly innocent or criminal
// @match https://cluesbysam.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
window.addEventListener('load', () => {
// Inject custom CSS overrides
const style = document.createElement('style');
style.textContent = `
.maybe-group .btn-innocent,
.maybe-group .btn-criminal {
min-width: 0px !important;
}
.card-front.maybe-innocent {
border: 20px solid var(--border-innocent) !important;
}
.card-front.maybe-criminal {
border: 20px solid var(--border-criminal) !important;
}
`;
document.head.appendChild(style);
// Select only elements with class "card-front" and no others
const cards = Array.from(document.querySelectorAll('.card-front'))
.filter(el => el.classList.length === 1);
cards.forEach(card => {
card.addEventListener('click', () => {
// Wait a little to let modal render
setTimeout(() => {
const modal = document.querySelector('.modal');
if (!modal) return;
// Prevent adding multiple button groups
if (modal.querySelector('.maybe-group')) return;
// Create container
const group = document.createElement('div');
group.className = 'button-group maybe-group';
// Innocent button
const btnInnocent = document.createElement('button');
btnInnocent.className = 'btn btn-innocent';
btnInnocent.textContent = 'Mark';
// Unmark button
const btnUnmark = document.createElement('button');
btnUnmark.className = 'btn btn-close';
btnUnmark.style.marginTop = '15px';
btnUnmark.textContent = 'Unmark';
// Criminal button
const btnCriminal = document.createElement('button');
btnCriminal.className = 'btn btn-criminal';
btnCriminal.textContent = 'Mark';
// Shared handler
function handleClick(action) {
const nameEl = modal.querySelector('.name');
if (!nameEl) return;
const targetName = nameEl.textContent.trim();
// Close modal (real close button inside modal, not ours)
const realClose = modal.querySelector(':scope > .btn-close');
if (realClose) realClose.click();
// Find matching card-front by name
const match = Array.from(document.querySelectorAll('.card-front')).find(cf => {
const cfName = cf.querySelector('.name');
return cfName && cfName.textContent.trim() === targetName;
});
if (!match) return;
// Apply classes based on action
if (action === 'innocent') {
match.classList.remove('maybe-criminal');
match.classList.add('maybe-innocent');
} else if (action === 'criminal') {
match.classList.remove('maybe-innocent');
match.classList.add('maybe-criminal');
} else if (action === 'unmark') {
match.classList.remove('maybe-innocent', 'maybe-criminal');
}
}
// Attach handlers
btnInnocent.addEventListener('click', () => handleClick('innocent'));
btnCriminal.addEventListener('click', () => handleClick('criminal'));
btnUnmark.addEventListener('click', () => handleClick('unmark'));
// Append in order
group.appendChild(btnInnocent);
group.appendChild(btnUnmark);
group.appendChild(btnCriminal);
// Insert as the first element of modal
modal.insertBefore(group, modal.firstChild);
}, 10); // 10ms delay
});
});
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment