Greasy Fork is available in English.

AO3: [Wrangling] Rainbow Home Page and Bins

adds CSS classes to style table rows as a rainbow, and updates dynamically when filters are applied

// ==UserScript==
// @name         AO3: [Wrangling] Rainbow Home Page and Bins
// @namespace    https://greasyfork.org/en/users/906106-escctrl
// @description  adds CSS classes to style table rows as a rainbow, and updates dynamically when filters are applied
// @author       escctrl
// @version      5.1
// @match        *://*.archiveofourown.org/tag_wranglers/*
// @match        *://*.archiveofourown.org/tags/*/wrangle?*
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js
// @license      MIT
// ==/UserScript==

// CONFIGURATION
    // choose if you want to use your AO3 skin to define the colors (skin), or if you'll add the css in this script (script)
    // if you use a skin, note that the classes are added to the table rows (tr) and named .rainbow0 through .rainbow5
    const SOURCE = 'script';

    // choose if you'd like the rainbow coloring on the wrangling homepage and/or on the bins
    const ONHOMEPAGE = true;
    const ONBINS = true;

    // set the six different background colors here, for example "rgba(255, 21, 164, 0.86)" or "#ff15a4"
    // tip: rgba let's you define the color in order red-green-blue. the fourth number (alpha) is transparency between 0 (transparent) and 1 (opaque)
    const RAINBOW = ["rgba(246,  48,  63, .2)",
                     "rgba(241, 137,   4, .2)",
                     "rgba(253, 221,   0, .2)",
                     "rgba(119, 189,  30, .2)",
                     "rgba(  1, 152, 207, .2)",
                     "rgba(114,  32, 130, .2)" ];

    const TEXT = "#000000"; // color of the link text in the table
    const BORDER = "#FFFFFF"; // color of the borders in the table
    const HIGHLIGHT = "#FFFFFF"; // background color of the highlighted row (on mouseover)

(function($) {
    'use strict';

    // quit script if this page is disabled
    if (ONHOMEPAGE === false && $('#main').hasClass('tag_wranglers-show')) return;
    if (ONBINS === false && $('#main').hasClass('tags-wrangle')) return;

    if (SOURCE == 'script') {
        var fullCSS = RAINBOW.map((e, i) => ".rainbow"+i+" { background-color: "+e+"; color: inherit !important }" );

        $('head').append(`<style type="text/css">
            .assigned thead th, #wrangulator thead th { text-align: center; vertical-align: bottom; }
            .assigned thead, #wrangulator thead { border-bottom: 0px; }
            .assigned tbody th { background: transparent !important; border: 1px solid ${BORDER}; vertical-align: middle; padding: 0.2em 0.5em; }
            .assigned tbody td { vertical-align: middle; border: 1px solid ${BORDER}; padding: 0.2em 0.5em; text-align: right; }
            #wrangulator tbody th { background: transparent !important; border: 1px solid ${BORDER}; vertical-align: middle; }
            #wrangulator tbody td { vertical-align: middle; border: 1px solid ${BORDER}; }
            .assigned tbody tr:hover, #wrangulator tbody tr:hover { background-color: ${HIGHLIGHT}; }

            .assigned tbody a, #wrangulator tbody a,
            .assigned tbody a:hover, #wrangulator tbody a:hover,
            .assigned tbody a:visited, #wrangulator tbody a:visited,
            .assigned tbody a:active, #wrangulator tbody a:active {
              color: ${TEXT}; border-bottom: 0; }
            ${fullCSS.join(' ')}
        </style>`);
    }

    function resetRainbow() {
        $('.assigned tbody tr, #wrangulator tbody tr').removeClass('rainbow0 rainbow1 rainbow2 rainbow3 rainbow4 rainbow5');
        $('.assigned tbody tr:visible, #wrangulator tbody tr:visible').each( (it, row) => $(row).addClass('rainbow'+it%6) );
    }

    if (ONHOMEPAGE === true && $('#main').hasClass('tag_wranglers-show')) {
        // add events for dynamic updates of the CSS classes when filters are applied. delegated to allow any script order
        $('.assigned').on('click', 'p:contains(Show only fandoms with) a', resetRainbow); // Standard (doesn't specify a p#id so we have to go by text content)
        $('.assigned').on('click', '#filter-fandoms *', resetRainbow); // Redux
        $('.assigned').on('click', '#media-filter a, #source-filter a, #fandom-filter a, #setup-filter a, #reset-filter a', resetRainbow); // N-in-1
        $('.assigned').on('click', '#sortunwrangled, #sortname, #sortchars, #sortrels, #sortff', resetRainbow); // Sorting by Total Unwrangled
        $('.assigned').on('click', 'p:contains(Show:) a, tr a:contains([Snooze])', resetRainbow); // Snooze fandom buttons/filters

        // Search
        $('.assigned').on('keyup', '#fandom_search', resetRainbow);
    }

    if (ONBINS === true && $('#main').hasClass('tags-wrangle')) {
        // Snooze "Drafts" button is "slow" and needs a little bit of a delay
        // has to use document for delegation because the snooze script removes the button before it bubbles up to #wrangulator (!?!?)
        $(document).on('click', 'a#snooze_drafts', function(e) { setTimeout(resetRainbow, 500); });
        // other snooze buttons/filters are pretty instantaneous
        $('#wrangulator').on('click', 'td[title="snooze"] a, p:contains(Show:) a', function(e) { setTimeout(resetRainbow, 10); } );
    }

    $(document).ready(function() {
        // executes on page load for initial coloring
        resetRainbow();
    });

})(jQuery);