step 1: calling local:qwen3.6:35b-a3b
plan: I'll start by exploring the repository structure and running the test suite to understand what's failing.
tool list <- {"path":"."}
tool list ok: .git/
.gitattributes
.github/
.gitignore
.npmignore
CHANGELOG.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
LICENSE
README.md
SECURITY.md
docs/
eslint-plugin-local.js
eslint.config.js
index.d.ts
integrity/
node_modules/
package-lock.json
package.json
src/
tasks/
tests/
[evidence record sha256:82e259fae91c0b34c95431c93ce39bc45ed0b64701802d550c1df32605950b17 kind tool-call:list]
tool shell <- {"command":"cat package.json"}
tool shell ok: exit code: 0
stdout:
{
  "name": "darkreader",
  "version": "4.9.130",
  "description": "Dark mode for every website",
  "scripts": {
    "api": "node --max-old-space-size=3072 tasks/cli.js build --api",
    "build": "node --max-old-space-size=3072 tasks/cli.js build --release",
    "build:all": "node --max-old-space-size=3072 tasks/cli.js build --debug --release --api",
    "build:firefox": "node --max-old-space-size=3072 tasks/cli.js build --release --firefox",
    "build:plus": "node --max-old-space-size=3072 tasks/cli.js build --plus --release",
    "code-style": "npm run lint",
    "config-cleanup": "node --max-http-header-size=131072 tasks/ping.js dark-sites detector-hints dynamic-theme-fixes inversion-fixes",
    "debug": "node --max-old-space-size=3072 tasks/cli.js build --debug",
    "debug:watch": "node --max-old-space-size=3072 tasks/cli.js build --debug --watch --chrome --firefox",
    "debug:watch:mv3": "node --max-old-space-size=3072 tasks/cli.js build --debug --watch --chrome-mv3",
    "debug:watch:plus": "node --max-old-space-size=3072 tasks/cli.js build --debug --watch --plus --chrome",
    "dependencies:upgrade": "node tasks/dependencies.js",
    "lint": "eslint -- 'src/**/*.ts' 'src/**/*.tsx' 'tasks/**/*.js' 'tests/[!coverage]**/*.js' 'tests/**/*.ts' eslint.config.js index.d.ts",
    "lint:bundle": "(node ./tasks/check-exists.js ./build/debug/chrome || node tasks/build.js --debug --api --chrome) && eslint -- 'build/debug/chrome/**/*.js' 'darkreader.js' 'darkreader.mjs'",
    "plus-link": "cd src && ln -s ../../darkreader-plus plus",
    "prepublishOnly": "npm test && npm run api",
    "release": "npm test && npm run lint && node tasks/cli.js build --release",
    "test": "npm run test:unit",
    "test:all": "npm run test:unit; npm run test:browser; npm run test:inject",
    "test:browser": "npm run test:chrome && npm run test:chrome-mv3 && npm run test:firefox",
    "test:chrome": "node tasks/cli.js build --debug --test --chrome-mv2 && jest --config=tests/browser/jest.config.mjs --runInBand",
    "test:chrome-mv3": "node tasks/cli.js build --debug --test --chrome-mv3 && jest --config=tests/browser/jest.config.chrome-mv3.mjs --runInBand",
    "test:ci": "npm run test:unit",
    "test:coverage": "jest --config=tests/unit/jest.config.mjs --coverage",
    "test:edge": "node tasks/cli.js build --debug --test --plus && jest --config=tests/browser/jest.config.mjs --runInBand",
    "test:firefox": "node tasks/cli.js build --debug --test --firefox-mv2 && jest --config=tests/browser/jest.config.firefox.mjs --runInBand",
    "test:inject": "node --max-old-space-size=3072 node_modules/.bin/karma start ./tests/inject/karma.conf.cjs",
    "test:inject:debug": "node --max-old-space-size=3072 node_modules/.bin/karma start ./tests/inject/karma.conf.cjs --debug",
    "test:unit": "jest --config=tests/unit/jest.config.mjs",
    "test:unit:debug": "node --inspect-brk ./node_modules/jest/bin/jest --config=tests/unit/jest.config.mjs --runInBand --no-cache --watch",
    "translate-en-message": "node ./tasks/translate.js --message",
    "translate-new-en-messages": "node ./tasks/translate.js --new-messages",
    "deno:bootstrap": "deno run --allow-read=./ --allow-sys=uid --allow-write=deno.json tasks/deno.js"
  },
  "main": "darkreader.js",
  "module": "darkreader.mjs",
  "type": "module",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/darkreader/darkreader.git"
  },
  "author": "Alexander Shutau <darkreaderapp@gmail.com> (https://darkreader.org/)",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/darkreader/darkreader/issues"
  },
  "keywords": [
    "dark-theme",
    "dark-mode",
    "night-mode",
    "darkmode",
    "nightmode",
    "accessibility",
    "eye-care"
  ],
  "homepage": "https://darkreader.org/",
  "funding": {
    "type": "opencollective",
    "url": "https://opencollective.com/darkreader/donate"
  },
  "dependencies": {
    "malevic": "0.20.3"
  },
  "devDependencies": {
    "@eslint/compat": "2.1.0",
    "@eslint/eslintrc": "3.3.7",
    "@eslint/js": "10.0.0",
    "@rollup/plugin-node-resolve": "16.0.3",
    "@rollup/plugin-replace": "6.0.3",
    "@rollup/plugin-typescript": "12.3.0",
    "@stylistic/eslint-plugin": "5.10.0",
    "@types/chrome": "0.2.8",
    "@types/eslint": "9.6.1",
    "@types/jasmine": "6.0.0",
    "@types/jest": "30.0.0",
    "@types/karma": "6.3.9",
    "@types/karma-coverage": "2.0.3",
    "@types/node": "26.4.1",
    "@types/ws": "8.18.1",
    "chokidar": "5.0.0",
    "eslint-plugin-compat": "7.0.2",
    "eslint-plugin-import": "2.32.0",
    "globals": "17.12.0",
    "globby": "16.2.4",
    "jasmine-core": "7.0.2",
    "jest": "30.5.1",
    "jest-extended": "7.0.0",
    "karma": "6.4.4",
    "karma-chrome-launcher": "3.2.0",
    "karma-coverage": "2.2.1",
    "karma-firefox-launcher": "2.1.3",
    "karma-jasmine": "5.1.0",
    "karma-rollup-preprocessor": "7.0.8",
    "karma-safari-launcher": "1.0.0",
    "karma-spec-reporter": "0.0.36",
    "less": "4.9.0",
    "prettier": "3.9.6",
    "puppeteer-core": "25.9.0",
    "rollup": "4.63.1",
    "rollup-plugin-istanbul": "5.0.0",
    "ts-jest": "29.4.12",
    "tslib": "2.8.1",
    "typescript": "6.0.3",
    "typescript-eslint": "8.69.0",
    "ws": "8.21.3",
    "yazl": "3.3.1"
  },
  "optionalDependencies": {
    "@rollup/rollup-linux-x64-gnu": "4.63.1",
    "@rollup/rollup-win32-x64-msvc": "4.63.1"
  }
}
[evidence record sha256:c5a6e0441cba7320e2c6ff0c590ed158b36934fc66e6dd505f8d90b3c5601df2 kind tool-call:shell]
step 2: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"npm run --silent test 2>&1 | head -200","timeoutMs":120000}
tool shell ok: exit code: 0
stdout:
PASS tests/unit/generators/utils/parse.tests.ts
PASS tests/unit/utils/state-manager.tests.ts
PASS tests/unit/utils/url.tests.ts
FAIL tests/unit/config/config.tests.ts
  ● Dynamic Theme Fixes config

    TypeError: (invert || []).concat(...).concat(...).every is not a function

      167 |     // selectors should have no comma
      168 |     const commaSelector = /\,(?![^\(|\"]*(\)|\"))/;
    > 169 |     expect(fixes.every(({invert, ignoreInlineStyle, ignoreImageAnalysis}) => (invert || []).concat(ignoreInlineStyle || []).concat(ignoreImageAnalysis || []).every((s) => !commaSelector.test(s)))).toBe(true);
          |                                                                                                                                                               ^
      170 |
      171 |     // fixes are properly formatted
      172 |     expect(throwIfDifferent(file, formatDynamicThemeFixes(fixes), 'Dynamic fixes format error')).not.toThrow();

      at tests/unit/config/config.tests.ts:169:159
          at Array.every (<anonymous>)
      at Object.<anonymous> (tests/unit/config/config.tests.ts:169:18)

PASS tests/unit/utils/time.tests.ts
PASS tests/unit/inject/fixes.tests.ts
PASS tests/unit/utils/color.tests.ts
PASS tests/unit/utils/parsing.tests.ts
PASS tests/unit/utils/validation.tests.ts
PASS tests/unit/utils/promise-barrier.tests.ts
PASS tests/unit/utils/text.tests.ts
PASS tests/unit/inject/selectors.tests.ts
PASS tests/unit/config/locales.tests.ts
PASS tests/unit/utils/uid.tests.ts
PASS tests/unit/utils/math.tests.ts
PASS tests/unit/csp/csp.tests.ts

Test Suites: 1 failed, 15 passed, 16 total
Tests:       1 failed, 74 passed, 75 total
Snapshots:   0 total
Time:        2.37 s
Ran all test suites.
[evidence record sha256:928e8a1190a1463d06cd4a310a928c0c495d4cfdbdccb9091639aa18a9f50861 kind tool-call:shell]
step 3: calling local:qwen3.6:35b-a3b
tool read <- {"path":"tests/unit/config/config.tests.ts"}
tool read ok: import {readFile} from 'node:fs';

import type {StaticTheme} from '../../../src/definitions';
import {parseInversionFixes, formatInversionFixes} from '../../../src/generators/css-filter';
import {parseDetectorHints, formatDetectorHints} from '../../../src/generators/detector-hints';
import {parseDynamicThemeFixes, formatDynamicThemeFixes} from '../../../src/generators/dynamic-theme';
import {parseStaticThemes, formatStaticThemes} from '../../../src/generators/static-theme';
import {parseColorSchemeConfig} from '../../../src/utils/colorscheme-parser';
import type {ParsedColorSchemeConfig} from '../../../src/utils/colorscheme-parser';
import {parseArray, formatArray, getTextDiffIndex, getTextPositionMessage} from '../../../src/utils/text';
import {compareURLPatterns} from '../../../src/utils/url';
import {rootPath} from '../../support/test-utils';

function readConfig(fileName: string) {
    return new Promise<string>((resolve, reject) => {
        readFile(rootPath('src/config', fileName), {encoding: 'utf-8'}, (err, data) => {
            if (err) {
                reject(err);
                return;
            }
            resolve(data);
        });
    });
}

function isURLPatternValid(url: string) {
    return url.length > 0 && url.indexOf('://') < 0;
}

function throwIfDifferent(input: string, expected: string, message: string) {
    return () => {
        const diffIndex = getTextDiffIndex(input, expected);
        if (diffIndex >= 0) {
            throw new Error(`${message}\n${getTextPositionMessage(input, diffIndex)}`);
        }
    };
}

function formatColorSchemeConfig(scheme: ParsedColorSchemeConfig): string {
    const names = Object.keys(scheme.dark);
    const lines = [];
    for (const name of names) {
        lines.push(name);
        lines.push('');
        for (const color of ['dark', 'light']) {
            const style = scheme[color as keyof ParsedColorSchemeConfig][name];
            if (style) {
                const {backgroundColor, textColor} = style;
                lines.push(color.toUpperCase());
                if (backgroundColor) {
                    lines.push(`background: ${backgroundColor.toLowerCase()}`);
                }
                if (textColor) {
                    lines.push(`text: ${textColor.toLowerCase()}`);
                }
                lines.push('');
            }
        }
        lines.push('='.repeat(32));
        lines.push('');
    }
    lines.pop();
    lines.pop();
    return lines.join('\n');
}

test('Dark Sites list', async () => {
    const file = await readConfig('dark-sites.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const sites = parseArray(file);

    // is not empty
    expect(sites.length).toBeGreaterThan(0);

    // url patterns should have no protocol
    expect(sites.every(isURLPatternValid)).toBe(true);

    // sites are sorted alphabetically
    expect(sites.slice().sort(compareURLPatterns)).toEqual(sites);

    // sites are properly formatted
    expect(throwIfDifferent(file, formatArray(sites), 'Dark Sites list format error')).not.toThrow();
});

test('Detector Hints config', async () => {
    const file = await readConfig('detector-hints.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const hints = parseDetectorHints(file);

    // each hint has valid URL
    expect(hints.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // hints are sorted alphabetically
    expect(hints.map(({url}) => url[0])).toEqual(hints.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    const commaSelector = /\,(?![^\(|\"]*(\)|\"))/;
    expect(hints.every(({target, match}) => ![target].concat(match).some((s) => commaSelector.test(s)))).toBe(true);

    // only a single selector is allowed for target
    expect(hints.every(({target, noDarkTheme, systemTheme}) => noDarkTheme || systemTheme || typeof target === 'string' && !target.includes('\n'))).toBe(true);

    // hints are properly formatted
    expect(throwIfDifferent(file, formatDetectorHints(hints), 'Detector Hints format error')).not.toThrow();

    // should parse empty config
    expect(parseDetectorHints('')).toEqual([]);

    // should skip unsupported commands
    expect(parseDetectorHints([
        'inbox.google.com',
        'mail.google.com',
        'TARGET', 'a',
        'MATCH', '.b', '#c',
        'UNSUPPORTED', 'c',
        '========',
        'proton.me',
        'SYSTEM THEME',
        '========',
        'twitter.com',
        'UNSUPPORTED', 'a', 'b',
        'TARGET', 'c',
        'MATCH', '[d="e"]',
        '========',
        'wikipedia.org',
        'NO DARK THEME',
    ].join('\n'))).toEqual([
        {url: ['inbox.google.com', 'mail.google.com'], target: 'a', match: ['.b', '#c']},
        {url: ['proton.me'], systemTheme: true},
        {url: ['twitter.com'], target: 'c', match: ['[d="e"]']},
        {url: ['wikipedia.org'], noDarkTheme: true},
    ] as any);
});

test('Dynamic Theme Fixes config', async () => {
    const file = await readConfig('dynamic-theme-fixes.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const fixes = parseDynamicThemeFixes(file);

    // there is a common fix
    expect(fixes[0].url[0]).toEqual('*');

    // each fix has valid URL
    expect(fixes.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // fixes are sorted alphabetically
    expect(fixes.map(({url}) => url[0])).toEqual(fixes.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    const commaSelector = /\,(?![^\(|\"]*(\)|\"))/;
    expect(fixes.every(({invert, ignoreInlineStyle, ignoreImageAnalysis}) => (invert || []).concat(ignoreInlineStyle || []).concat(ignoreImageAnalysis || []).every((s) => !commaSelector.test(s)))).toBe(true);

    // fixes are properly formatted
    expect(throwIfDifferent(file, formatDynamicThemeFixes(fixes), 'Dynamic fixes format error')).not.toThrow();

    // should parse empty config
    expect(parseDynamicThemeFixes('')).toEqual([]);

    // should skip unsupported commands
    expect(parseDynamicThemeFixes([
        'inbox.google.com',
        'mail.google.com',
        'INVERT', 'a', 'b',
        'CSS', '.x { color: white !important; }',
        'UNSUPPORTED', 'c', 'd',
        '========',
        'twitter.com',
        'UNSUPPORTED', 'a', 'b',
        'INVERT', 'c', 'd',
        '========',
        'wikipedia.org',
        'IGNORE INLINE STYLE', 'a', 'b',
        '========',
        'duckduckgo.com',
        'IGNORE IMAGE ANALYSIS', 'img[alt="Logo"]', 'canvas',
    ].join('\n'))).toEqual([
        {url: ['inbox.google.com', 'mail.google.com'], invert: ['a', 'b'], css: '.x { color: white !important; }'},
        {url: ['twitter.com'], invert: ['c', 'd']},
        {url: ['wikipedia.org'], ignoreInlineStyle: ['a', 'b']},
        {url: ['duckduckgo.com'], ignoreImageAnalysis: ['img[alt="Logo"]', 'canvas']},
    ] as any);
});

test('Inversion Fixes config', async () => {
    const file = await readConfig('inversion-fixes.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const fixes = parseInversionFixes(file);

    // there is a common fix
    expect(fixes[0].url[0]).toEqual('*');

    // each fix has valid URL
    expect(fixes.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // fixes are sorted alphabetically
    expect(fixes.map(({url}) => url[0])).toEqual(fixes.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    expect(fixes.every(({invert, noinvert, removebg}) => (invert || []).concat(noinvert || []).concat(removebg || []).every((s) => s.indexOf(',') < 0))).toBe(true);

    // fixes are properly formatted
    expect(throwIfDifferent(file, formatInversionFixes(fixes), 'Inversion fixes format error')).not.toThrow();
});

test('Static Themes config', async () => {
    const file = await readConfig('static-themes.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const themes = parseStaticThemes(file);

    // there is a common theme
    expect(themes[0].url[0]).toEqual('*');

    // each theme has valid URL
    expect(themes.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // themes are sorted alphabetically
    expect(themes.map(({url}) => url[0])).toEqual(themes.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    expect(themes.every((t) => (Object.keys(t) as Array<keyof StaticTheme>)
        .filter((prop) => ['url', 'noCommon'].indexOf(prop) < 0)
        .every((prop) => (t[prop] as string[])
            .every((s) => s.indexOf(',') < 0)))).toBe(true);

    // fixes are properly formatted
    expect(throwIfDifferent(file, formatStaticThemes(themes), 'Static theme format error')).not.toThrow();
});

test('Colorscheme config', async () => {
    const file = await readConfig('color-schemes.drconf');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const {result: schemes, error} = parseColorSchemeConfig(file);

    // Their is no error
    expect(error).toBeNull();

    // There is a default Dark color scheme
    expect(schemes.dark['Default']).toBeDefined();

    // There is a default Light color scheme
    expect(schemes.light['Default']).toBeDefined();

    // Check formatting
    expect(formatColorSchemeConfig(schemes)).toEqual(file);
});

[evidence record sha256:5d171b533e87c9279f40460390dfbb6daad01330b4466ed4cb3b3ff0a311dc37 kind tool-call:read]
step 4: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/generators/dynamic-theme.ts"}
tool read ok: import type {DynamicThemeFix} from '../definitions';
import {formatCSS} from '../utils/css-text/format-css';
import {parseArray, formatArray} from '../utils/text';
import {compareURLPatterns} from '../utils/url';

import {formatSitesFixesConfig} from './utils/format';
import {parseSitesFixesConfig, getSitesFixesFor, getDomain} from './utils/parse';
import type {SiteFixesIndex} from './utils/parse';

declare const __CHROMIUM_MV2__: boolean;
declare const __CHROMIUM_MV3__: boolean;

const dynamicThemeFixesCommands: { [key: string]: keyof DynamicThemeFix } = {
    'INVERT': 'invert',
    'CSS': 'css',
    'IGNORE INLINE STYLE': 'ignoreInlineStyle',
    'IGNORE IMAGE ANALYSIS': 'ignoreImageAnalysis',
    'IGNORE CSS URL': 'ignoreCSSUrl',
};

export function parseDynamicThemeFixes(text: string): DynamicThemeFix[] {
    return parseSitesFixesConfig<DynamicThemeFix>(text, {
        commands: Object.keys(dynamicThemeFixesCommands),
        getCommandPropName: (command) => dynamicThemeFixesCommands[command],
        parseCommandValue: (command, value) => {
            if (command !== 'CSS') {
                return value.trim();
            }
            return parseArray(value);
        },
    });
}

export function formatDynamicThemeFixes(dynamicThemeFixes: DynamicThemeFix[]): string {
    const fixes = dynamicThemeFixes.slice().sort((a, b) => compareURLPatterns(a.url[0], b.url[0]));

    return formatSitesFixesConfig(fixes, {
        props: Object.values(dynamicThemeFixesCommands),
        getPropCommandName: (prop) => Object.entries(dynamicThemeFixesCommands).find(([, p]) => p === prop)![0],
        formatPropValue: (prop, value) => {
            if (prop === 'css') {
                return formatCSS(value as string);
            }
            return formatArray(value as string[]).trim();
        },
        shouldIgnoreProp: (prop, value) => {
            if (prop === 'css') {
                return !value;
            }
            return !(Array.isArray(value) && value.length > 0);
        },
    });
}

export function getDynamicThemeFixesFor(url: string, text: string, index: SiteFixesIndex, enabledForPDF: boolean): DynamicThemeFix[] | null {
    const fixes = getSitesFixesFor(url, text, index, parseDynamicThemeFixes);

    if (fixes.length === 0 || fixes[0].url[0] !== '*') {
        return null;
    }

    if (enabledForPDF) {
        // Copy part of fixes which will be mutated
        const invert = fixes[0].invert?.slice();
        const commonFix = {...fixes[0], invert};
        const pdfFixes: DynamicThemeFix[] = [
            commonFix,
            ...fixes.slice(1),
        ];

        const inversionFix = __CHROMIUM_MV2__ || __CHROMIUM_MV3__ ?
            '\nembed[type="application/pdf"][src="about:blank"] { filter: invert(100%) contrast(90%); }' :
            '\nembed[type="application/pdf"] { filter: invert(100%) contrast(90%); }';
        if (!commonFix.css.endsWith(inversionFix)) {
            commonFix.css += inversionFix;
        }

        if (['drive.google.com', 'mail.google.com'].includes(getDomain(url))) {
            const nestedInversionFix = 'div[role="dialog"] div[role="document"]';
            if (commonFix.invert.at(-1) !== nestedInversionFix) {
                commonFix.invert.push(nestedInversionFix);
            }
        }

        return pdfFixes;
    }

    return fixes;
}

[evidence record sha256:c624d263beceb4cbb33161996f84d7d39caedd18d9b4f728b3fc5fe2c8e14da3 kind tool-call:read]
step 5: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/generators/utils/parse.ts"}
tool read ok: import {parseArray} from '../../utils/text';
import {indexURLTemplateList, getURLMatchesFromIndexedList} from '../../utils/url';
import type {URLTrie} from '../../utils/url';

interface SiteProps {
    url: string[];
}

export interface SiteListIndex {
    urls: readonly string[];
    domains: Readonly<{[domain: string]: number[]}>;
    domainLabels: Readonly<{[domainLabel: string]: readonly number[]}>;
    nonstandard: readonly number[];
}

export interface SitesFixesParserOptions<T> {
    commands: readonly string[];
    getCommandPropName: (command: string) => keyof T;
    parseCommandValue: (command: string, value: string) => any;
}

export type SiteFixesIndex = URLTrie<[number, number]>;

export function parseSitesFixesConfig<T extends SiteProps>(text: string, options: SitesFixesParserOptions<T>): T[] {
    const sites: T[] = [];

    const blocks = text.replace(/\r/g, '').split(/^\s*={2,}\s*$/gm);
    blocks.forEach((block) => {
        const lines = block.split('\n');
        const commandIndices: number[] = [];
        lines.forEach((ln, i) => {
            if (ln.match(/^[A-Z]+(\s[A-Z]+){0,2}$/)) {
                commandIndices.push(i);
            }
        });

        if (commandIndices.length === 0) {
            return;
        }

        const siteFix = {
            url: parseArray(lines.slice(0, commandIndices[0]).join('\n')) as readonly string[],
        } as T;

        commandIndices.forEach((commandIndex, i) => {
            const command = lines[commandIndex].trim();
            const valueText = lines.slice(commandIndex + 1, i === commandIndices.length - 1 ? lines.length : commandIndices[i + 1]).join('\n');
            const prop = options.getCommandPropName(command);
            if (!prop) {
                return;
            }
            const value = options.parseCommandValue(command, valueText);
            siteFix[prop] = value;
        });

        sites.push(siteFix);
    });

    return sites;
}

// URL patterns are guaranteed to not have protocol and leading '/'
export function getDomain(url: string): string {
    try {
        return (new URL(url)).hostname.toLowerCase();
    } catch (error) {
        return url.split('/')[0].toLowerCase();
    }
}

function processSiteFixesConfigBlock(text: string, offsets: Array<[number, number]>, recordStart: number, recordEnd: number, urls: Array<readonly string[]>) {
    // TODO: more formal definition of URLs and delimiters
    const block = text.substring(recordStart, recordEnd);
    const lines = block.split('\n');
    const commandIndices: number[] = [];
    lines.forEach((ln, i) => {
        if (ln.match(/^[A-Z]+(\s[A-Z]+){0,2}$/)) {
            commandIndices.push(i);
        }
    });

    if (commandIndices.length === 0) {
        return;
    }

    offsets.push([recordStart, recordEnd - recordStart]);

    const urls_ = parseArray(lines.slice(0, commandIndices[0]).join('\n'));
    urls.push(urls_);
}

function extractURLsFromSiteFixesConfig(text: string): {urls: string[][]; offsets: Array<[number, number]>} {
    const urls: string[][] = [];
    // Array of tuples, where first number is an offset of record start and second number is record length.
    const offsets: Array<[number, number]> = [];

    let recordStart = 0;
    // Delimiter between two blocks
    const delimiterRegex = /^\s*={2,}\s*$/gm;
    let delimiter: RegExpMatchArray | null;
    while ((delimiter = delimiterRegex.exec(text))) {
        const nextDelimiterStart = delimiter.index!;
        const nextDelimiterEnd = delimiter.index! + delimiter[0].length;
        processSiteFixesConfigBlock(text, offsets, recordStart, nextDelimiterStart, urls);
        recordStart = nextDelimiterEnd;
    }
    processSiteFixesConfigBlock(text, offsets, recordStart, text.length, urls);

    return {urls, offsets};
}

export function indexSitesFixesConfig(text: string): SiteFixesIndex {
    const {urls, offsets: offsetsGrouped} = extractURLsFromSiteFixesConfig(text);
    const offsetMap = new Map<string, [number, number]>();
    const templates: string[] = [];
    const offsets: Array<[number, number]> = [];
    urls.forEach((block, i) => {
        block.forEach((u) => {
            templates.push(u);
            offsets.push(offsetsGrouped[i]);
            offsetMap.set(u, offsetsGrouped[i]);
        });
    });
    const indexedList = indexURLTemplateList(templates, (_, i) => {
        return offsets[i];
    });
    return indexedList;
}

const siteFixesCache = new WeakMap<[number, number], any>();

export function getSitesFixesFor<T extends SiteProps>(url: string, text: string, index: SiteFixesIndex, parse: (text: string) => T[]): Array<Readonly<T>> {
    const matches = getURLMatchesFromIndexedList(url, index);

    const fixes = matches.map((offset) => {
        const cache = siteFixesCache.get(offset);
        if (cache) {
            return cache;
        }
        const [start, length] = offset;
        const block = text.slice(start, start + length);
        const fix = parse(block)[0];
        siteFixesCache.set(offset, fix);
        return fix;
    });

    if (fixes.length > 0) {
        const commonFixIndex = fixes.findIndex((f) => f.url?.[0] === '*');
        if (commonFixIndex > 0) {
            const commonFix = fixes[commonFixIndex];
            fixes.splice(commonFixIndex, 1);
            fixes.unshift(commonFix);
        }
    }

    return fixes;
}

[evidence record sha256:b376d60f853813db27a02be78c1eab7b3aa0dac57dc8e39d2d80d5716bbc9d80 kind tool-call:read]
step 6: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/generators/css-filter.ts"}
tool read ok: import type {Theme, InversionFix} from '../definitions';
import {compareChromeVersions, chromiumVersion, isFirefox, firefoxVersion} from '../utils/platform';
import {parseArray, formatArray} from '../utils/text';
import {compareURLPatterns, isURLInList} from '../utils/url';

import {createTextStyle} from './text-style';
import {formatSitesFixesConfig} from './utils/format';
import {applyColorMatrix, createFilterMatrix} from './utils/matrix';
import {parseSitesFixesConfig, getSitesFixesFor} from './utils/parse';
import type {SiteFixesIndex} from './utils/parse';

declare const __CHROMIUM_MV2__: boolean;
declare const __CHROMIUM_MV3__: boolean;

export enum FilterMode {
    light = 0,
    dark = 1
}

/**
 * This checks if the current chromium version has the patch in it.
 * As of Chromium v81.0.4035.0 this has been the situation
 *
 * Bug report: https://bugs.chromium.org/p/chromium/issues/detail?id=501582
 * Patch: https://chromium-review.googlesource.com/c/chromium/src/+/1979258
 */
export function hasPatchForChromiumIssue501582(): boolean {
    return __CHROMIUM_MV3__ || Boolean(
        __CHROMIUM_MV2__ &&
        compareChromeVersions(chromiumVersion, '81.0.4035.0') >= 0
    );
}

/**
 * Since Firefox v102.0, they have changed to the new root behavior.
 * This was already the case for Chromium v81.0.4035.0 and Firefox now
 * switched over as well.
 */
export function hasFirefoxNewRootBehavior(): boolean {
    return Boolean(
        isFirefox &&
        compareChromeVersions(firefoxVersion, '102.0') >= 0
    );
}

export default function createCSSFilterStyleSheet(config: Theme, url: string, isTopFrame: boolean, fixes: string, index: SiteFixesIndex): string {
    const filterValue = getCSSFilterValue(config)!;
    const reverseFilterValue = 'invert(100%) hue-rotate(180deg)';
    return cssFilterStyleSheetTemplate('html', filterValue, reverseFilterValue, config, url, isTopFrame, fixes, index);
}

export function cssFilterStyleSheetTemplate(filterRoot: string, filterValue: string, reverseFilterValue: string, config: Theme, url: string, isTopFrame: boolean, fixes: string, index: SiteFixesIndex): string {
    const fix = getInversionFixesFor(url, fixes, index);

    const lines: string[] = [];

    lines.push('@media screen {');

    // Add leading rule
    if (filterValue && isTopFrame) {
        lines.push('');
        lines.push('/* Leading rule */');
        lines.push(createLeadingRule(filterRoot, filterValue));
    }

    if (config.mode === FilterMode.dark) {
        // Add reverse rule
        lines.push('');
        lines.push('/* Reverse rule */');
        lines.push(createReverseRule(reverseFilterValue, fix));
    }

    if (config.useFont || config.textStroke > 0) {
        // Add text rule
        lines.push('');
        lines.push('/* Font */');
        lines.push(createTextStyle(config));
    }

    // Full screen fix
    lines.push('');
    lines.push('/* Full screen */');
    [':-webkit-full-screen', ':-moz-full-screen', ':fullscreen'].forEach((fullScreen) => {
        lines.push(`${fullScreen}, ${fullScreen} * {`);
        lines.push('  -webkit-filter: none !important;');
        lines.push('  filter: none !important;');
        lines.push('}');
    });

    if (isTopFrame) {
        const light: [number, number, number] = [255, 255, 255];
        // If browser affected by Chromium Issue 501582, set dark background on html
        // Or if browser is Firefox v102+
        const bgColor = (!hasPatchForChromiumIssue501582() && !hasFirefoxNewRootBehavior()) && config.mode === FilterMode.dark ?
            applyColorMatrix(light, createFilterMatrix(config)).map(Math.round) :
            light;
        lines.push('');
        lines.push('/* Page background */');
        lines.push('html {');
        lines.push(`  background: rgb(${bgColor.join(',')}) !important;`);
        lines.push('}');
    }

    if (fix.css && fix.css.length > 0 && config.mode === FilterMode.dark) {
        lines.push('');
        lines.push('/* Custom rules */');
        lines.push(fix.css);
    }

    lines.push('');
    lines.push('}');

    return lines.join('\n');
}

export function getCSSFilterValue(config: Theme): string | null {
    const filters: string[] = [];

    if (config.mode === FilterMode.dark) {
        filters.push('invert(100%) hue-rotate(180deg)');
    }
    if (config.brightness !== 100) {
        filters.push(`brightness(${config.brightness}%)`);
    }
    if (config.contrast !== 100) {
        filters.push(`contrast(${config.contrast}%)`);
    }
    if (config.grayscale !== 0) {
        filters.push(`grayscale(${config.grayscale}%)`);
    }
    if (config.sepia !== 0) {
        filters.push(`sepia(${config.sepia}%)`);
    }

    if (filters.length === 0) {
        return null;
    }

    return filters.join(' ');
}

function createLeadingRule(filterRoot: string, filterValue: string): string {
    return [
        `${filterRoot} {`,
        `  -webkit-filter: ${filterValue} !important;`,
        `  filter: ${filterValue} !important;`,
        '}',
    ].join('\n');
}

function joinSelectors(selectors: string[]): string {
    return selectors.map((s) => s.replace(/\,$/, '')).join(',\n');
}

function createReverseRule(reverseFilterValue: string, fix: InversionFix): string {
    const lines: string[] = [];

    if (fix.invert.length > 0) {
        lines.push(`${joinSelectors(fix.invert)} {`);
        lines.push(`  -webkit-filter: ${reverseFilterValue} !important;`);
        lines.push(`  filter: ${reverseFilterValue} !important;`);
        lines.push('}');
    }

    if (fix.noinvert.length > 0) {
        lines.push(`${joinSelectors(fix.noinvert)} {`);
        lines.push('  -webkit-filter: none !important;');
        lines.push('  filter: none !important;');
        lines.push('}');
    }

    if (fix.removebg.length > 0) {
        lines.push(`${joinSelectors(fix.removebg)} {`);
        lines.push('  background: white !important;');
        lines.push('}');
    }

    return lines.join('\n');
}

/**
* Returns fixes for a given URL.
* If no matches found, common fixes will be returned.
* @param url Site URL.
* @param inversionFixes List of inversion fixes.
*/
export function getInversionFixesFor(url: string, fixes: string, index: SiteFixesIndex): InversionFix {
    const inversionFixes = getSitesFixesFor(url, fixes, index, parseInversionFixes);

    const common = {
        url: inversionFixes[0].url,
        invert: inversionFixes[0].invert || [],
        noinvert: inversionFixes[0].noinvert || [],
        removebg: inversionFixes[0].removebg || [],
        css: inversionFixes[0].css || '',
    };

    if (url) {
        // Search for match with given URL
        const matches = inversionFixes
            .slice(1)
            .filter((s) => isURLInList(url, s.url))
            .sort((a, b) => b.url[0].length - a.url[0].length);
        if (matches.length > 0) {
            const found = matches[0];
            return {
                url: found.url,
                invert: common.invert.concat(found.invert || []),
                noinvert: common.noinvert.concat(found.noinvert || []),
                removebg: common.removebg.concat(found.removebg || []),
                css: [common.css, found.css].filter((s) => s).join('\n'),
            };
        }
    }
    return common;
}

const inversionFixesCommands: { [key: string]: keyof InversionFix } = {
    'INVERT': 'invert',
    'NO INVERT': 'noinvert',
    'REMOVE BG': 'removebg',
    'CSS': 'css',
};

export function parseInversionFixes(text: string): InversionFix[] {
    return parseSitesFixesConfig<InversionFix>(text, {
        commands: Object.keys(inversionFixesCommands),
        getCommandPropName: (command) => inversionFixesCommands[command],
        parseCommandValue: (command, value) => {
            if (command === 'CSS') {
                return value.trim();
            }
            return parseArray(value);
        },
    });
}

export function formatInversionFixes(inversionFixes: InversionFix[]): string {
    const fixes = inversionFixes.slice().sort((a, b) => compareURLPatterns(a.url[0], b.url[0]));

    return formatSitesFixesConfig(fixes, {
        props: Object.values(inversionFixesCommands),
        getPropCommandName: (prop) => Object.entries(inversionFixesCommands).find(([, p]) => p === prop)![0],
        formatPropValue: (prop, value) => {
            if (prop === 'css') {
                return (value as string).trim().replace(/\n+/g, '\n');
            }
            return formatArray(value as string[]).trim();
        },
        shouldIgnoreProp: (prop, value) => {
            if (prop === 'css') {
                return !value;
            }
            return !(Array.isArray(value) && value.length > 0);
        },
    });
}

[evidence record sha256:f15717eca9c9c693c148f17ed0b03c07a78766d0d5d3a35235b2c5d40ded73ac kind tool-call:read]
step 7: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/config/dynamic-theme-fixes.config"}
tool read ok: *

INVERT
c-wiz div > svg > circle
.jfk-bubble.gtx-bubble
.captcheck_answer_label > input + img
span#closed_text > img[src^="https://www.gstatic.com/images/branding/googlelogo"]
span[data-href^="https://www.hcaptcha.com/"] > #icon
img.Wirisformula
a[data-testid="headerMediumLogo"]>svg
.d2l-navigation-link-image-container
.d2l-iframe-loading-container
div.mc-ip-hide[style*="background: rgb(255, 255, 255) !important"]
[style*="color: rgb(0, 0, 1) !important;"]

CSS
c-wiz div {
    --action-items-action-item-background-color: var(--darkreader-neutral-background) !important;
}
.jfk-bubble.gtx-bubble {
    background-color: white !important;
}
.vimvixen-hint {
    background-color: ${#ffd76e} !important;
    border-color: ${#c59d00} !important;
    color: ${#302505} !important;
}
#vimvixen-console-frame {
    color-scheme: light !important;
}
::placeholder {
    opacity: 0.5 !important;
}
#edge-translate-panel-body,
.MuiTypography-body1,
.nfe-quote-text {
    color: var(--darkreader-neutral-text) !important;
}
gr-main-header {
    background-color: ${lightblue} !important;
}
.tou-z65h9k,
.tou-mignzq,
.tou-1b6i2ox,
.tou-lnqlqk {
    background-color: var(--darkreader-neutral-background) !important;
}
.tou-75mvi {
    background-color: ${rgb(207, 236, 245)} !important;
}
.tou-ta9e87,
.tou-1w3fhi0,
.tou-1b8t2us,
.tou-py7lfi,
.tou-1lpmd9d,
.tou-1frrtv8,
.tou-17ezmgn {
    background-color: ${rgb(245, 245, 245)} !important;
}
.tou-uknfeu {
    background-color: ${rgb(250, 237, 218)} !important;
}
.tou-6i3zyv {
    background-color: ${rgb(133, 195, 216)} !important;
}
div.mermaid-viewer-control-panel .btn {
    background-color: var(--darkreader-neutral-background);
    fill: var(--darkreader-neutral-text);
}
svg g rect.er {
    fill: var(--darkreader-neutral-background) !important;
}
svg g rect.er.entityBox {
    fill: var(--darkreader-neutral-background) !important;
}
svg g rect.er.attributeBoxOdd {
    fill: var(--darkreader-neutral-background) !important;
}
svg g rect.er.attributeBoxEven {
    fill: var(--darkreader-selection-background);
    fill-opacity: 0.8 !important;
}
svg rect.er.relationshipLabelBox {
    fill: var(--darkreader-neutral-background) !important;
}
svg g g.nodes rect,
svg g g.nodes polygon {
    fill: var(--darkreader-neutral-background) !important;
}
svg g rect.task {
    fill: var(--darkreader-selection-background) !important;
}
svg line.messageLine0,
svg line.messageLine1 {
    stroke: var(--darkreader-neutral-text) !important;
}
div.mermaid .actor {
    fill: var(--darkreader-neutral-background) !important;
}
mitid-authenticators-code-app > .code-app-container {
    background-color: white !important;
    padding-top: 1rem;
}
iframe#unpaywall[src$="unpaywall.html"] {
    color-scheme: light !important;
}
select {
    --darkreader-bg--form-control-background-color: rgba(22, 22, 22, 0) !important;
}
body#tumblr {
    --darkreader-bg--secondary-accent: 31, 32, 34 !important;
    --darkreader-bg--white: 23, 23, 23 !important;
    --darkreader-text--black: 228, 224, 218 !important;
}
:host {
    --d2l-border-color: var(--darkreader-bg--d2l-color-gypsum) !important;
    --d2l-button-icon-background-color-hover: var(--darkreader-bg--d2l-color-gypsum) !important;
    --d2l-color-ferrite: var(--darkreader-neutral-text) !important;
    --d2l-color-sylvite: var(--darkreader-bg--d2l-color-sylvite) !important;
    --d2l-dropdown-background-color: var(--darkreader-neutral-background) !important;
    --d2l-dropdown-border-color: var(--darkreader-border--d2l-color-mica) !important;
    --d2l-input-backgroud-color: var(--darkreader-neutral-background) !important;
    --d2l-menu-border-color: var(--darkreader-bg--d2l-color-gypsum) !important;
    --d2l-tooltip-background-color: var(--darkreader-neutral-background) !important;
    --d2l-tooltip-border-color: var(--darkreader-bg--d2l-color-gypsum) !important;
}
:host([_floating]) .d2l-floating-buttons-container {
    background-color: var(--darkreader-neutral-background) !important;
    border-top-color: var(--darkreader-border--d2l-color-mica) !important;
    opacity: 0.88 !important;
}
d2l-card {
    background: var(--darkreader-neutral-background) !important;
    border-color: var(--darkreader-border--d2l-color-gypsum) !important;
}
d2l-dropdown-content > div,
d2l-menu-item {
    background-color: var(--darkreader-neutral-background) !important;
    border-radius: 10px !important;
}
d2l-empty-state-simple {
    border-color: var(--darkreader-bg--d2l-color-gypsum) !important;
}
.d2l-button-filter > ul > li > a.vui-button {
    border-color: var(--darkreader-border--d2l-color-mica) !important;
}
.d2l-label-text:has(.d2l-button-subtle-content):hover,
.d2l-label-text:has(.d2l-button-subtle-content):focus,
.d2l-label-text:has(.d2l-button-subtle-content):active {
    background-color: var(--darkreader-bg--d2l-color-gypsum) !important;
}
.d2l-navigation-centerer {
    color: inherit !important;
}
.d2l-tabs-layout {
    border-color: var(--darkreader-border--d2l-color-gypsum) !important;
}
.d2l-input,
.d2l-calendar-date,
.d2l-htmleditor-container {
    background-color: var(--darkreader-neutral-background) !important;
}
.d2l-collapsible-panel {
    border: 1px solid var(--darkreader-border--d2l-color-mica) !important;
    border-radius: 0.4rem !important;
}
.d2l-collapsible-panel-divider {
    border-bottom: 1px solid var(--darkreader-border--d2l-color-mica) !important;
}
.d2l-w2d-flex {
    border-bottom: 2px solid var(--darkreader-border--d2l-color-mica) !important;
}
.d2l-collapsible-panel scrolled,
.d2l-collapsible-panel-header,
.d2l-w2d-collection-fixed {
    background-color: var(--darkreader-neutral-background) !important;
}
.d2l-loading-spinner-bg {
    fill: var(--darkreader-bg--d2l-color-gypsum) !important;
}
.d2l-loading-spinner-bg-stroke {
    stroke: var(--darkreader-border--d2l-color-mica) !important;
}
.d2l-loading-spinner-wrapper svg path,
.d2l-loading-spinner-wrapper svg circle {
    fill: var(--darkreader-neutral-background) !important;
}
.d2l-twopanelselector-side.d2l-twopanelselector-side-sep {
    background: var(--darkreader-bg--d2l-color-mica) !important;
}
.d2l-le-TreeAccordionItem-anchor::before {
    background: var(--darkreader-bg--d2l-color-corundum) !important;
}
table[class|="moz-header"] {
    background: none;
}
*[style*="color: rgba(0,0,0,"]:not([style*="color: rgba(0,0,0,0)"]),
*[style*="color: rgba(0, 0, 0,"]:not([style*="color: rgba(0, 0, 0, 0)"]),
*[style*="color:#000"]:not(.cell-input > span),
*[style*="color:black"]:not(.cell-input > span),
*[style*="color:#282828"]:not(.cell-input > span),
*[style*="color:#444"]:not(.cell-input > span),
*[style*="color: #222222"]:not(.cell-input > span) {
    color: var(--darkreader-neutral-text) !important;
}
*[style*="background:#fff"],
*[style*="background-color:#fff"],
*[style*="background: #fff"],
*[style*="background: rgb(255, 255, 255)"] {
    background: var(--darkreader-neutral-background) !important;
}
*[bgcolor="#F5F5F5"],
*[style*="background-color: #F5F5F5"] {
    background: ${#F5F5F5} !important;
}
*[style*="background: #e6e6e6"] {
    background: ${#e6e6e6} !important;
}
body[style*="background: rgb(255, 255, 255) !important"] *:not(a),
.body[style*="background-color: rgb(254, 254, 254) !important"] *:not(a) {
    background-color: var(--darkreader-neutral-background) !important;
}
div[style*="www.gstatic.com/android/"] {
    background: none !important;
}
*[style*="background:#f9f9f9"] {
    background: ${#F9F9F9} !important;
}
body.mediawiki.skin-vector #mw-page-base {
    background-image: none !important;
}
.overflow-hidden .spinning-bg,
.overflow-hidden .solid-bg {
    background: transparent !important;
}
*[style*="color: rgb(0,0,0) !imoprtant"][style*="--darkreader-inline-color"],
*[style*="color: rgb(0, 0, 0) !important"][style*="--darkreader-inline-color"] {
    -webkit-text-fill-color: var(--darkreader-inline-color) !important;
}

IGNORE CSS URL
^https://fonts.googleapis.com/

================================

*.abc.net.au

INVERT
[data-component="ABCNewsLogo"] *

IGNORE INLINE STYLE
[data-component="ABCLogo"] *

================================

*.acesso.gov.pt
*.portaldasfinancas.gov.pt

INVERT
img[src$="/logo-at.png"]
img[src$="/logo-at.svg"]
img[src$="/FatSorte_logo.png"]
img[src$="/at_logo.svg"]
img[src$="/logo-at_small.svg"]
img[src$="/logo_e_balcao_small.png"]
img[src$="/logo_direitos_contribuinte_38.png"]
img[src$="/bullet_ebalcao.png"]
img[src$="/bullet_apm.png"]
.logo-efatura
.logo-sgdt

CSS
html[data-darkreader-scheme="dark"] table#main_Table {
    background-color: black !important;
}
html[data-darkreader-scheme="dark"] table#header {
    position: relative !important;
    z-index: 10 !important;
}
html[data-darkreader-scheme="dark"] table#header::before {
    background-color: #001053 !important;
    bottom: 0 !important;
    content: "" !important;
    left: 50% !important;
    position: absolute !important;
    top: 0 !important;
    transform: translateX(-50%) !important;
    width: 100vw !important;
    z-index: -1 !important;
}
body {
    background-color: transparent !important;
}

================================

*.altronics.com.au

CSS
.picture {
    background-color: rgba(255, 255, 255, 1) !important;
}
#main {
    z-index: auto !important;
}

================================

*.americanexpress.com

INVERT
img[alt*="FDIC-Insured"]

CSS
select[aria-labelledby="bankAccount-label"] > option {
    background-color: var(--darkreader-neutral-background) !important;
}

================================

*.archlinux.org

INVERT
img[src*="icons/"]
img[src="/svg/calendar.svg"]
.cdx-search-input .cdx-text-input__icon.cdx-text-input__start-icon
.cdx-button--icon-only .vector-icon

CSS
.vector-sticky-pinned-container::after {
    background: inherit;
}
body {
    height: fit-content;
}

================================

*.arxiv.org
arxiv.org

INVERT
img.ds-funder-logo

CSS
img.ds-funder-logo {
    background-color: white !important;
}

================================

*.autotask.net

CSS
.bg-background-primary {
    background-color: ${rgb(255 255 255)} !important;
}
.bg-background-hover {
    background-color: ${rgb(207, 217, 226)} !important;
}

================================

*.babbel.com

IGNORE INLINE STYLE
#radix-\:r2\: > svg:nth-child(1) *
#radix-\:r3\: > div > div > div > svg *
#\32 53PcCLJv1hu747b7LM72J > div > div > div > div > div > a > div > svg *
#\35 1RrI7tAWynOXHmNFDQeaT > div > div > div > div > div > a > div > svg *

================================

*.bambulab.com

CSS
.bannerTextWrap .title,
.bannerTextWrap .subtitle {
    text-shadow: ${rgb(225, 212, 201)} 1px 1px 0px !important;
}

================================

*.bancoctt.pt

INVERT
header h1.brand img
footer ul.logos img
img[src^="/Content/Themes/BCTT/logo.png"]
path[d^="M83.897 7.128c6.053"][fill="#000"]
div.header__title a.header__logo-link svg path[fill="#333333"]
a.menu-icon img.h-icon
g#BANCOCTT image

CSS
div#home-locations.map-center3:not([data-darkreader-inline-bgimage]) {
    background-image: url("/application/themes/images/map/centro3.jpg") !important;
}
div.card-container img {
    background-color: white !important;
}

IGNORE INLINE STYLE
div.card-container *
div.header__title a.header__logo-link *
a[href^="https://play.google.com/store/apps/"] svg *

================================

*.ben-anna.de
ben-anna.de

INVERT
a.header__logo--image img
div.certification-list img
div.st_bundle-box.active div.st_input-circle
div.promotion__item-image div.blocks-radius-circle img
img.gP50U

IGNORE INLINE STYLE
div.footer__payment *

================================

*.bitrix24.ru

INVERT
#ws-canvas

================================

*.cnrtl.fr

CSS
.tlf_cdefinition {
    background-color: ${rgb(255, 255, 0)} !important;
}
.tlf_cdomaine {
    background-color: ${rgb(255, 176, 96)} !important;
}
.tlf_csyntagme {
    background-color: ${rgb(192, 255, 192)} !important;
}

================================

*.discogs.com

INVERT
[class*="logo"]

CSS
.swiper-pagination-bullet {
    background: var(--swiper-pagination-bullet-inactive-color, #FFFFFF) !important;
}
.bg-\[linear-gradient\(to_right\,transparent_var\(--fill-stop\)\,\#f2f2f2_var\(--fill-stop\)\)\] {
    background-image: linear-gradient(to right,transparent var(--fill-stop),${#d2d2d2} var(--fill-stop)) !important;
}

================================

*.dnoticias.pt

INVERT
span.nav-menu-btn
span.panel-slide_close

================================

*.docs.kubernetes.io

CSS
.highlight pre code > span[style*="text-decoration: underline"] {
    text-decoration: none !important;
}

================================

*.dreamwidth.org

INVERT
#tagform input[type="image"]

CSS
body {
    background-color: var(--darkreader-neutral-background) !important;
}
.tropo nav,
.tropo footer,
#intro-box-main {
    background-image: none !important;
}
html[data-darkreader-scheme="dark"] .tropo #logo {
    filter: invert(90%) hue-rotate(180deg) !important;
}
html[data-darkreader-scheme="dimmed"] .tropo #logo {
    filter: brightness(85%) !important;
}
.ContextualPopup {
    background: var(--darkreader-neutral-background) !important;
}
[class*='ui-widget'],
.gradient,
.taginfo {
    background-image: none !important;
}
*[style*="color: rgba(0,0,0,"]:not([style*="color: rgba(0,0,0,0)"]),
*[style*="color: rgba(0, 0, 0,"]:not([style*="color: rgba(0, 0, 0, 0)"]),
*[style*="color:#000"],
*[style*="color:black"],
*[style*="color:#282828"],
*[style*="color:#444"],
*[style*="color: #222222"] {
    color: #333 !important;
}
*[style*="background:#fff"],
*[style*="background-color:#fff"],
*[style*="background: #fff"],
*[bgcolor="#F5F5F5"],
*[style*="background-color: #F5F5F5"],
*[style*="background: #e6e6e6"],
*[style*="background:#f9f9f9"] {
    background-color: #eee !important;
}

IGNORE INLINE STYLE
.entry-content *
.comment-content *

IGNORE IMAGE ANALYSIS
*

================================

*.euronews.com

INVERT
label.c-burger-button
div.o-site-hr__sidebar div.c-find-us__list
div.o-site-hr__first-level label.c-language-switcher__btn:after
span.c-article-breadcrumbs__separator::after
div[class^=speakup-theme-] div#progress-container
p.c-footer-search__tag-title img
img.u-cursor-pointer

CSS
div[class^=speakup-theme-] div.speakup-song div#speakup-song-image div#previous {
    background-image: var(--button-prev-bg) !important;
}
div[class^=speakup-theme-] div.speakup-song div#speakup-song-image div#next {
    background-image: var(--button-next-bg) !important;
}
section.speakup-container > div[class^=speakup-theme-] a.speakup-tooltip {
    background-image: var(--button-tooltip-logo) !important;
}
div[class^=speakup-theme-] div.speakup-boxed-player #play-pause.amplitude-paused {
    background-image: var(--button-play-bg) !important;
}
div[class^=speakup-theme-] div.speakup-boxed-player #play-pause.amplitude-playing {
    background-image: var(--button-pause) !important;
}
div[class^=speakup-theme-] div.speakup-boxed-player div.control-container div.time-progress div#prev-10 {
    background-color: transparent !important;
    background-image: var(--button-skip-prev-10) !important;
    filter: invert(100%) hue-rotate(180deg) !important;
}
div[class^=speakup-theme-] div.speakup-boxed-player div.control-container div.time-progress div#next-10 {
    background-color: transparent !important;
    background-image: var(--button-skip-next-10) !important;
    filter: invert(100%) hue-rotate(180deg) !important;
}

================================

*.galaxus.de

INVERT
#logo

CSS
#sidebarMenu div {
    background: var(--darkreader-neutral-background) !important;
}

================================

*.gamer.com.tw

INVERT
.sidenav__icon

CSS
body {
    background-color: transparent !important;
    background-image: none !important;
}
.main-nav__logo {
    background-color: currentColor !important;
}

IGNORE IMAGE ANALYSIS
.service__icon.icon-arrow
.MSG-mainpic
#BH-main_menu
#BH-master h4
.BH-slave_btns .BH-slave_btnA
#BH-slave h5

================================

*.globo.com

INVERT
.header__brand__link[href*=extra]
.header__brand__link[href*=umsoplaneta] path[fill=black]
.header__brand__link[href*=umsoplaneta] path[stroke=black]
.header__brand__link[href*=marieclaire]
.header__brand__link[href*=revistaquem]
.header__brand__link[href*=gq]
#logo-valor_100-anos
.pages-footer img[src$="logo_edg.png"]
.pages-footer img[src$="logo-Conde-Nast.png"]
.pages-footer img[src$="logo_condenast.png"]
.pages-footer img[src$="Rádio_wordmark.png"]
.header__menu__icon_background_color

CSS
.bar-scrubber .bar-scrubber-icon,
.bar-background .bar-fill-2 {
    background-color: var(--darkreader-neutral-text) !important;
}
.bar-background .bar-fill-1 {
    background-color: rgba(255, 255, 255, .3) !important;
}
.multicontent {
    background-color: var(--darkreader-neutral-background) !important;
    color: var(--darkreader-neutral-text) !important;
}
span.bstn-hl-summary {
    color: var(--darkreader-neutral-text) !important;
}
.glb-grid .tabela-body {
    background-color: var(--darkreader-neutral-background) !important;
}
.bstn-hl.with-photo::before {
    background-image: var(--bstn-hl-cover) !important;
}
.footer__logo__wrapper {
    background: var(--darkreader-bg--custom-footer-background) !important;
}

IGNORE INLINE STYLE
.poster__play-wrapper *
#Logo_Valor_Economico_Branco *

IGNORE IMAGE ANALYSIS
.barra-globocom .barra-itens li .barra-item-videos

================================

*.hom.com

INVERT
img.logoimg
img.header-logo__image
img.sub-footer__brands-image
img.sub-footer__certifications-image
img.retina_size[src^="//www.hom.com/cdn/shop/files/HOM_Infinity_Level_Icons"]
img.gP50U
div.R-EmbeddedIcon div.s3-uploaded-icon img
div.cart-drawer__empty-cart svg
button.product-popup-modal__button svg.icon
summary.mobile-toggle span
div.R-RatingStars__stars.u-marginBottom--none i.stars__icon
div.R-RatingStars__stars.u-marginRight--none i[class^="stars__icon stars__icon--"]
div.collapsible__content-care-info img
div.R-SliderIndicator__inner
collapsible-row.product__accordion summary span
div.product-information--line-item--image-richtext img
button.accelerated-checkout-button.light.logo-only svg path[style="fill:#000"]
.accordion summary span

CSS
div.sub-footer,
div.shopify-section-group-footer-group div.row.full-width-row-full,
div.image-with-text__content,
div.email-signup {
    background-color: var(--darkreader-neutral-background) !important;
}
div.image-with-text-overlay--bg::after {
    background-color: rgba(var(--color-overlay-rgb),var(--overlay-opacity)) !important;
}
div.header__bg__overlay {
    background-image: none !important;
}
div.gallery--item figure::after,
div.revealed-media--media::after,
div.email-signup--image:after {
    background: rgba(var(--overlay-color-rgb),var(--overlay-opacity)) !important;
}
div.R-ReviewsList-container .item__inner {
    background: transparent !important;
}
div.ruk_rating_snippet * {
    color: var(--darkreader-neutral-text) !important;
}

IGNORE INLINE STYLE
div.sub-footer__socials *
div.footer-payment-icons *
div.cart-drawer__empty-cart *
div.payment-icons *

================================

*.hypothes.is

INVERT
a[href="https://hypothes.is"] > svg[aria-labelledby="logo-title"] > g > path[fill-rule="nonzero"]
img[class="fusion-standard-logo"]
.pdfViewer .canvasWrapper

CSS
.pdfViewer .textLayer {
    opacity: 1 !important;
}
.pdfViewer .hypothesis-highlight {
    background-color: var(--darkreader-bg--highlight-color) !important;
}
.pdfViewer .hypothesis-shape-highlight {
    border-color: rgba(128,128,128,0.3) !important;
    outline: none !important;
}
.toolbarButton::before,
.secondaryToolbarButton::before,
.dropdownToolbarButton::after,
.treeItemToggler::before {
    background-color: var(--toolbar-icon-bg-color) !important;
}

================================

*.iefp.pt

INVERT
img[src^="/image/company_logo"]
img[src$="/museu_virtual.png"]
img[src*="/Lado_Lado.png"]
img[src$="/iefponline_logo.png"]
footer div.container img
div.map-portlet div.area
div.map-portlet div.area > *
canvas.ol-unselectable

CSS
div.map-portlet div.area {
    background-image: url(/Map-portlet/img/fake-mapa_ol.jpg) !important;
}
body {
    background-color: transparent !important;
}

IGNORE IMAGE ANALYSIS
.divImgAmbiente
.logoIEFP
.logoCRC
#bg12653424
.sobre-iefp-img
.links-hero-img
.menu_left_item_image.survey

================================

*.iherb.com

INVERT
img:is([alt$="icon"], [class$="icon"]):not(.extra-info-icon, .info-icon)
div[class$="icon"] > img
:is(a, div).header-link img
a.carousel-control:not([href="#carousel-plp-module-specials"]) > span > i::before
div.live-container use.tooltip-icon
svg.product-ai-wellness-guide__icon
button.arrow:is(.left, .right) svg
div[data-qa-element^="rewards-landing-faq-item-collapse"]::before
div[data-qa-element^="rewards-landing-faq-item-collapse"]::after
div.policy-accordion-item img
div.cms-accordion-switch-btn
div.myaccount-container div[data-an-element="base-info"] > div:first-of-type svg
div.house-brand-content-container div.section-2-img img:not([alt$="icon"])
div#hamburger-menu-base img
a[class$="SocialIcons"] img
img[src$="/iHerb_Vitacost.png"]
div.swiper-button-prev.transaction-filter-prev-btn svg
div.swiper-button-next.transaction-filter-next-btn svg
button.lt-menu-toggle
img[src$="/blog-content-type/video.png"]
img.extra-info-icon
img.info-icon
#cartv2 svg[data-qa-element="empty-cart-icon"] path
div.content-description-images img

CSS
a[href$="/flash-deals"] h4,
div.personalized-reorder h3.flash-deals-title,
div.personalized-reorder p.flash-deals-subtitle,
div.personalized-reorder span.view-all-label,
div.app-landing-header-lg-title,
div.app-landing-header-lg-description,
div:is(.cms-banner-container, .banner-tool-carousel, #catalog-application) div.custom-flex-box-item,
div:is(.cms-banner-container, .banner-tool-carousel, #catalog-application) div.custom-flex-box-item *:not(.custom-button, .cms-digit, .cms-bubble-text),
div.live-container span.live-title bdi,
div.content-left,
div.content-left span,
div.shipping-textbox-subheader,
div.shipping-textbox-disclaimer,
a.menu-link.menu-pill-wrapper span,
div[data-qa-element="SubscribeListContainer"] > div > div > div > div > h4,
div.slider-container a > div:nth-of-type(2),
div.container-fluid div.mobile-title,
div[class$="ProductsCarouselContentCard"]
  > div[class$="ProductsCarouselContentCard"],
div[data-qa-element="SubscribeListMobileContainer"]
  > div:first-of-type > div > div > div:first-of-type > h2 > div,
div.professional-brands-intro div.brands-header:not(:has(> div > div > img)) *,
section.content-wrapper.brandsintro *:not(div.sports-page-extra-container *),
div.entrance-title-wrapper *,
div[data-qa-element="new-rec-carousel"] div :is(strong, svg),
div.slider-container div[class$="BundleCarousel"] div + div *:not(button):not(button *) {
    color: black !important;
}
div.logo-grid a,
div.featured-brands-image-container,
div.top-affiliate-network-grid img,
img.payment-sprite,
a.menu-link.menu-pill-wrapper,
div.brand-logo-wrapper,
div[class$="BrandsCarousel"] a[class$="BrandItem"] img,
section[class$="Shipping"] img,
div.slider-container div[class$="TrendingBrandsCarousel"] a > div,
div[class$="SectionContainer"] + div > a,
a[href^="/pressreleases/"] img {
    background-color: #f7f8f7 !important;
}
img {
    mix-blend-mode: normal !important;
}
div.self-service-item svg path,
div.ugc-pdp-question-and-answer-desktop-box svg path {
    fill: var(--darkreader-neutral-text) !important;
}
div.shipping-textbox-header,
div[data-qa-element="SubscribeListContainer"] div:has(+ h4),
div[data-qa-element="SubscribeListContainer"] h4 strong,
div[data-qa-element="SubscribeListMobileContainer"]
  > div:first-of-type > div > div > div:first-of-type * {
    color: #2c7500 ! important;
}
div.brand-logo-circle {
    background-color: var(--cb-item-bg-color) !important;
}
div.house-brand-content-container div:is(.section-1, .section-2) {
    background-image: none !important;
}
div:has(> div.quality-description) {
    background-color: var(--darkreader-background-ffffff) !important;
    padding: 20px;
    position: relative;
    z-index: 2;
}
div:has(> div > div.section-2-mobile-img) {
    background-color: var(--darkreader-background-ffffff) !important;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    padding: 20px;
    position: relative;
    width: 100vw;
    z-index: 2;
}
div.quality-icons,
div.section-1-mobile-content {
    background-color: var(--darkreader-background-ffffff) !important;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    width: 100vw;
}
div.buynow-modal-content {
    background-color: var(--darkreader-background-ffffff) !important;
}
div.hp-banners-v2.using-banner-tool {
    background-color: var(--darkreader-inline-bgcolor) !important;
}
div.cms-banner-container div.custom-flex-box-item span.custom-button {
    color: var(--darkreader-neutral-text) !important;
}

IGNORE INLINE STYLE
div[class^="scan-qr-login_qrCode"] svg *
div.shipping-textbox-subheader span
div.sc-social-media-list *
:is(section, div).footer-banner-container *
#cartv2 svg[data-qa-element="empty-cart-icon"] *

IGNORE IMAGE ANALYSIS
*

================================

*.indeed.com

INVERT
#indeed-globalnav-logo

CSS
.jobsearch-Layout--gradientBg {
    background-image: none !important;
}

================================

*.instructure.com

CSS
.css-vrgbjj-textArea {
    background: var(--darkreader-neutral-background) !important;
    color: var(--darkreader-neutral-text) !important;
}
.css-4y58qe-textArea {
    background: var(--darkreader-neutral-background) !important;
}

================================

*.jornaldenegocios.pt

INVERT
:is(header.header, div#mainMenu, div.headerBar) button span
div.navbar-main-nav a.toggleMenuButton
div.header_top a.logo
nav.header_canais div.canais::before
nav.header_canais div.canais::after
img[src^="/i/"]
button.closeBtn span
footer a.logo_footer
footer a.reclamacoes_logo

IGNORE IMAGE ANALYSIS
.header:not(li) .header_top .logo
.scrollingPage .header:not(li) .header_top .logo
.footer .links .logo_footer
.simplificado .links .icons_footer li .reclamacoes_logo
.simplificado #ic_notificacoes .icon

================================

*.ldlc.com
*.ldlc.pro

INVERT
header .burger-menu span.icon-burger
.landing section div.container .picto
.config-contentLeft img
.eco-contentLeft img
.promo-contentLeft img
.landing #page img:is(.opacity-half, .reveal.gif, .opacity-40)

CSS
section.home-universe .bloc-universe {
    background-color: initial !important;
}
.img-transparent img,
.main.landing section.tag div.container .listing-product ul li .pic {
    mix-blend-mode: normal !important;
}
.main .category-content p {
    color: black !important;
}

IGNORE IMAGE ANALYSIS
.main .category-content:nth-of-type(1)
.main .category-content:nth-of-type(2)
.main .category-content:nth-of-type(3)
.main .category-content:nth-of-type(4)
.main .category-content:nth-of-type(5)
.main .category-content:nth-of-type(6)

================================

*.maricopa.edu

CSS
#background-content {
    background: var(--darkreader-neutral-background) !important;
}

================================

*.msi.com
funtoro.com

INVERT
img[src$="/logo.png"]
img[src$="-logo.png"]
img[src$="logo.svg"]
img[src$="/logo-msi.png"]
article#MSI_Support section.main-support div.card-content span.icon-style
article#MSI_Support section.main-contact-support span.icon-style
article#MSI_Support.Page_faq span.item-icon img
article#MSI_Support img#faq_icon-image
li[data-id="#lt-twitter"] svg
img[src$="/HDMILogo_note.png"]
div#msi-microsite-eps div.epsWhereToBuy__cardList img
div#msi-microsite-eps div.epsPartners a img
section.topheader a.topheader__toplogo img.logo__img
main#Copilot-plus-PC-For-Commercial div.header-copilot-plus img
main#Copilot-plus-PC-For-Commercial div.header-business-ready
main#Windows-11-Pro div.header-windows11 img
main#Windows-11-Pro div.header-what-s-your
img[src$="/norton-icon.png"]
article.support section.supportCard div.supportCard-icon img

CSS
html[data-darkreader-scheme="dark"] main#news_list figure.template__card__img img.card__img,
html[data-darkreader-scheme="dark"] article#newslist div.tab-content#Exhibitions img {
    background-color: white !important;
}
article#solutions section.industry :is(
    .industry__kvTxtBox-title,
    .industry__kvTxtBox-content,
    .industry__kvTxtBox-list
),
div#msi-microsite-amr h1.baseBannerTitle,
div.page:is(#ODMService, #Product_index) section.index-s4 div.txt-center *,
div#msi-app section.businessSupportTitle div.baseBanner h1.baseBannerTitle,
div#MSI-Center section#kv.block :is(h2, p),
article#contact-us figure.kv-banner div.kv-text :is(h1, p),
main.about header#msi-key-visual.kv div.kv__content h1 {
    color: black !important;
}

================================

*.my.salesforce-setup.com

CSS
body .rich-tabhdr-cell-active > table[id$="shifted"] td.rich-tabhdr-side-cell,
body .rich-tabhdr-cell-inactive > table[id$="shifted"] td.rich-tabhdr-side-cell,
body .rich-tabhdr-cell-active > table[id$="shifted"] td.rich-tabhdr-side-cell td.rich-tab-active,
body .rich-tabhdr-cell-inactive > table[id$="shifted"] td.rich-tabhdr-side-cell td.rich-tab-inactive {
    background-image: none !important;
}
body .rich-tabhdr-cell-inactive > table[id$="shifted"] td.rich-tabhdr-side-cell {
    background-color: color-mix(in srgb, var(--darkreader-neutral-background) 90%, gray) !important;
    border: 1px solid var(--darkreader-neutral-text) !important;
    border-bottom: none !important;
}
body .rich-tabhdr-cell-active > table[id$="shifted"] td.rich-tabhdr-side-cell {
    background-color: color-mix(in srgb, var(--darkreader-neutral-background) 80%, white) !important;
    border: 1px solid var(--darkreader-neutral-text) !important;
    border-bottom: none !important;
}
body .rich-tab-header {
    color: var(--darkreader-neutral-text) !important;
}

================================

*.myconnectwise.net

CSS
.cwsvg {
    fill: var(--darkreader-neutral-text) !important;
}

================================

*.myworkday.com

INVERT
.WIF3
.WIF3:hover
.WIG3
.WIG3:hover
.WFD3 .WGL3
.WAJS
.WAJS:hover
.WJG3
.WHL3
.WKFP

================================

*.naturitas.*

INVERT
div.footer__bottom div:is(.bcorp, .seals-trusted) img
div.shipping-method span.image img
svg.icon.ico-customer-checked

CSS
div.footer__bottom div.payment-methods img,
div[class^="footer_footerPayments"] svg,
li.checkout-conditions-summary__payment-logo {
    background-color: white !important;
}
div[class^="footer_footerPayments"] svg path[fill="currentColor"] {
    fill: black !important;
}

IGNORE INLINE STYLE
ul[class^="footer_footerColumnList"] *
div[class^="footer_footerPayments"] svg path

================================

*.palletsprojects.com

CSS
span.w {
    color: var(--darkreader-neutral-background) !important;
}

================================

*.rtp.pt

INVERT
img[src$="/rtppalco-dark_2026.svg"]
.navbar-toggler-icon
.uninav-menu-toggle-line
.uninav-menu-toggle::before
.uninav-menu-toggle::after
.uninav-search.is-open .uninav-search-toggle::before
.uninav-search.is-open .uninav-search-toggle::after
.epg-channel-inner-header::before
.epg-channel-inner-header::after
.navbar-container .navbar-brand:has(> .ensina-logo)
.footer-menu .left-section:has(> a[href="https://ensina.rtp.pt/"])
.worldnav-menu-toggle-line
.worldnav-menu-toggle::before
.worldnav-menu-toggle::after

CSS
#nav-icon3 span {
    background-color: #ffffff !important;
}

================================

*.sapo.pt
forum.pplware.com
sapo.pt
viagenseresorts.pt

INVERT
div.bsu-v4-sub-menu-splitter
:is(div, h1).logo img[alt^="SAPO"]
body:not(.home) header div.logo a[aria-label^="AutoSAPO"]
footer div.logo a[aria-label^="AutoSAPO"]
img[src$="/logo_vendaja_black.png"]
img.img-logo[src^="https://avozdecastelobranco.sapo.pt"]
body.wp-theme-zox-news div.mvp-fly-but-wrap span
body.wp-theme-zox-news div.mvp-search-but-wrap span
img[src$="/econtas-logo.png"]
img[src$="/ED_LOGO-900x183.png"]
img[src$="/ED_LOGO.png"]
img[src$="/2016-logo-risco-cor.png"]
img[src$="/AutoM-cor-1-no-bg.png"]
img[src$="/E-goi-logo.png"]
img[src$="/E-goi-logo-150x150.png"]
img[src$="/Beira-Alta-TV-2023-preto.png"]
img.tie-logo-img[src^="https://diariodistrito.sapo.pt"]
img[src$="/forever-young-logo-1.png"]
img.logo[alt="Green eFact"]
div.logo img[src^="https://estrelaseouricos.sapo.pt"]
img[src$="/viagens_preto-1920x664.png"]
span[class$="-accordion-chevron"]
span[class$="-accordion-icon"]
div.toggle-header-search span
a#mobile-menu-icon span.tie-mobile-menu-icon

CSS
svg#sapoLogo path:is([d^="M34.56"], [d^="M63.99"]),
li.logo svg path:is([d^="M33.96"], [d^="M63.39"]) {
    fill: #000000 !important;
}
html[data-darkreader-scheme="dark"] div#bsu-footer.bsu-footer-light a.bsu-footer-logo {
    background-position: 0 -60px !important;
}
html[data-theme="dark"][data-darkreader-scheme="dark"] div#bsu-footer div.bsu-footer-text {
    filter: none !important;
}

IGNORE IMAGE ANALYSIS
.wrapper.ink-grid
.barrita .extras .info

================================

*.seg-social.pt

INVERT
img[src^="/ptss/ii-pssd-library/assets/logos/"]
img[src^="/ptss/ii-uxds-theme-primevue-ssng/assets/pictograms/"]
img[src^="../ii-uxds-theme-primevue-ssng/assets/pictograms/"]
img[src^="../ii-uxds-theme-primevue-ssng/assets/images/"]
img[src^="/sso/images/Logo"]
img[src="/sso/images/logo.svg"]
img[src="/sso/images/pic_Question.svg"]
img[src^="https://www.seg-social.pt/ptss/ii-pssd-footer/"]
img[src^="/ptss/javax.faces.resource/ci/images/canaisDePagamento/"]
img.stats-img
footer img[src^="assets/img/"]
section#section-logo svg
svg.img-logo

================================

*.seoul.go.kr

INVERT
.h-logo
.s-live-icon

================================

*.service-now.com

INVERT
.highcharts-legend-item text
.palette-content.trees .tree_spacer
.palette-content.trees img.tree
.palette-content.trees img.wf-list-icon

CSS
.cm-s-snc span.cm-string {
    color: #cf947b !important;
}
.cm-s-snc span.cm-def {
    color: #60a4d8 !important;
}
.cm-s-snc span.cm-property {
    color: white !important;
}
.cm-s-snc_readonly span.cm-string {
    color: #cf947b !important;
}
#hierarchy-menu {
    background-color: #797774 !important;
}
.sn-ng-bsm svg {
    fill: #FFF !important;
}
.ui-refresh .btn-inline-form,
.ui-refresh .btn-inline-form-attached {
    background-color: #797774;
}
.node-outline {
    fill: #797774 !important;
}
.sn-polaris-nav {
    background-color: #000 !important;
    color: #FFF !important;
}
.snf-collapsible-list-header {
    background-color: #000 !important;
    color: #FFF !important;
}
.sn-polaris-nav-list-items a.item-label .item-icon {
    background-color: #000 !important;
    color: #FFF !important;
}
.snf-collapsible-list-items,
.snf-collapsible-list-items a {
    background-color: #000 !important;
    color: #FFF !important;
}
.sn-history-menu .menu-item > .menu-item-label > span.label {
    background-color: #000 !important;
    color: #FFF !important;
}
.sn-history-menu .menu-item > .menu-item-label > span.menu-item-description {
    background-color: #000 !important;
    color: #FFF !important;
}
div >  .sn-history-menu mark.filter-match,
.sn-history-menu mark.filter-match-fuzzy {
    color: #FFF !important;
}
div >  .sn-history-menu .is-filtered .label {
    color: #FFF !important;
}
span.is-filtered .label {
    color: #FFF !important;
}
.is-filtered .item-icon .label {
    color: #FFF !important;
}
span > mark.filter-match,
mark.filter-match-fuzzy {
    color: #FFF !important;
}
.tox .tox-tbtn svg {
    fill: #FFF !important;
}
.user-menu-label {
    color: #FFF !important;
}
.sn-polaris-tab.is-active {
    background-color: #000;
    color: #fff !important;
}
.grid-container svg path {
    fill: #000 !important;
}

================================

*.sloggi.com
*.triumph.com

INVERT
div.header__logo a.header__logo--triumph svg.svgIcon__brandlogo path
div.footer__logos svg
div.brand-switcher svg.svgIcon__triumph
div.sustainability__logo img
div.pd__body--7 div.pd__image img
div.footer__bottom ul.stay-tuned svg
div.brands__text img
button.navbar-toggler
div.header__icon svg.svgIcon.svgIcon__menuClose

CSS
div.footer__logos svg {
    color: var(--color-black) !important;
}
div.productTile div.colorDotSwatch--plp {
    background: var(--swatch-color) !important;
}
.experience-component > * {
    color: var(--darkreader-neutral-text) !important;
}
div.colorDotSwatch img {
    mix-blend-mode: normal !important;
}

IGNORE INLINE STYLE
div.footer__logos svg *
div.brand-switcher svg.svgIcon__triumph *
div.footer__bottom ul.stay-tuned svg *
div.header__icon svg.svgIcon.svgIcon__menuClose *

================================

*.speedtestcustom.com

CSS
.stroke-primary {
    stroke: #003b5c !important;
}
.result-graph-svg {
    fill: #003b5c !important;
}

================================

*.tommy.com

INVERT
img[class*="Footer_SocialIcon"]

================================

*.tomshardware.com

INVERT
img[src$="/toms-hardware-logo.png"]
img[src$="/brand_logo.svg"]
img.widget-commercial-logo.src-logo
img.th-premium-join-logo
img[x-show="!isUserPremium"]
img[src$="/TH_logo.svg"]

IGNORE INLINE STYLE
div[data-testid="buttons-social"] *
nav.button-social-group.person__social-buttons *

================================

*.visualcapitalist.com

INVERT
div.mvp-fly-but-wrap span
div.mvp-search-but-wrap span
img[src$="/DecarbChannel_LogoHeader_Mar8.png"]
div#mvp-fly-menu-wrap img:is([src^="/wp-content/uploads/2021/03/Hamburger-Menu"], [src$="/DC-logo-flyout.png"])
div.eltd-vertical-menu-area-inner div.eltd-logo-wrapper img

================================

*.webex.com

CSS
body {
    background: var(--darkreader-neutral-background) !important;
}
.wxp-chapter-bar-item-progress {
    background: var(--mds-color-decorative-violet-50) !important;
}

================================

01net.com

CSS
html,
body {
    color: ${#090702} !important;
}

================================

1001fonts.com

INVERT
picture.txt-preview

================================

10fastfingers.com

CSS
#speedtest-main .hide-time {
    color: transparent !important;
}
#inputfield {
    background: var(--darkreader-neutral-background) !important;
    color: var(--darkreader-neutral-text) !important;
}
body,
.container-modified > .row,
#practice-main,
#top1000-index-container,
#text-practice,
#content-bg {
    background: var(--darkreader-neutral-background) !important;
}
#main-content-trenner {
    background: var(--darkreader-neutral-background) !important;
    border-bottom: 1px solid rgb(151, 141, 127) !important;
}

================================

10minutemail.com

CSS
#main_content {
    background-image: none !important;
}

================================

123-3d.nl
123accu.nl
123inkt.nl
123led.nl
123schoon.nl

CSS
.main-panel-left,
.main-panel-right {
    background: var(--darkreader-neutral-background) !important;
}

================================

123mathe.de

INVERT
.entry-content img

CSS
body,
.post-inner,
ul.sub-menu {
    background-color: var(--darkreader-neutral-background) !important;
}
ul.sub-menu::after {
    border-bottom-color: var(--darkreader-neutral-background) !important;
}
.progress-wrap {
    box-shadow: var(--darkreader-neutral-background) 0px 0px 0px 3px inset !important;
}

================================

1337x.st
1337x.to
x1337x.eu
x1337x.se
x1337x.ws

CSS
.torrent-tabs .tab-nav {
    background-color: var(--darkreader-neutral-background) !important;
    background-image: none !important;
    border-bottom-color: var(--darkreader-neutral-background) !important;
}

================================

1917.com

CSS
body {
    background-color: var(--darkreader-neutral-background) !important;
    background-image: none !important;
}

================================

1fichier.com

CSS
body {
    background-image: none !important;
}

================================

1password.community

INVERT
div[class*="NodeBannerWidget_lia-container-bg"]
img[alt="Brand Logo"]

CSS
div[data-testid="HtmlCustomComponentContent"] * {
    color: var(--darkreader-neutral-text) !important;
}

================================

2700chess.com

IGNORE IMAGE ANALYSIS
.cg-wrap piece.rook.black
.cg-wrap piece.knight.black
.cg-wrap piece.bishop.black
.cg-wrap piece.queen.black
.cg-wrap piece.king.black
.cg-wrap piece.knight.black
.cg-wrap piece.pawn.black

================================

2gis.*

INVERT
#map
path[d^="M34.8"]
._oow7vi
path[d^="M15.759"]

CSS
a,
abbr,
acronym,
address,
applet,
article,
aside,
audio,
b,
big,
blockquote,
body,
canvas,
caption,
center,
cite,
code,
dd,
del,
details,
dfn,
div,
dl,
dt,
em,
embed,
fieldset,
figcaption,
figure,
footer,
form,
h1,
h2,
h3,
h4,
h5,
h6,
header,
hgroup,
html,
i,
iframe,
img,
ins,
kbd,
label,
legend,
li,
main,
mark,
menu,
nav,
object,
ol,
output,
p,
pre,
q,
ruby,
s,
samp,
section,
small,
span,
strike,
strong,
sub,
summary,
sup,
table,
tbody,
td,
tfoot,
th,
thead,
time,
tr,
tt,
u,
ul,
var,
video {
    color: var(--darkreader-neutral-text) !important;
}
div[style^="--bg-color"] {
    --bg-color: var(--darkreader-neutral-background) !important;
}
div[style="transform:rotateX(0deg)"] > svg[width="38"] path {
    fill: ${black} !important;
}
button[data-hamburger] span {
    background-color: ${black} !important;
}

IGNORE INLINE STYLE
a[href="/"] > svg *

================================

3.basecamp.com

CSS
body,
.nav__main {
    background-color: ${white};
}
@media screen and (min-width: 768px) {
    .panel--perma,
    .panel--project {
        box-shadow: rgba(0, 0, 0, 0.05) 0px -1px 10px, rgba(0, 0, 0, 0.1) 0px 1px 4px, rgb(24, 26, 27) 0px 10px 30px;
    }
}

================================

300gospodarka.pl
300polityka.pl

INVERT
#logo
img[alt="300Gospodarka"]
img[alt="Zespół 300Gospodarki"]

================================

338canada.com

CSS
svg text:not([fill]) {
    fill: var(--darkreader-neutral-text);
}

================================

350.org
map.350.org

INVERT
.dark\:bg-gray-700
.dark\:bg-gray-700::after
.dark\:text-gray-300
.mapboxgl-canvas
.mapboxgl-ctrl-compass > .mapboxgl-ctrl-icon
.mapboxgl-ctrl-logo
.mapboxgl-marker

CSS
mapbox-search-box > input {
    --darkreader-bg--boxShadow: 0 0 10px 2px ${rgba(0, 0, 0, 0.05)}, 0 0 6px 1px ${rgba(0, 0, 0, 0.1)}, 0 0 0 1px ${rgba(0, 0, 0, 0.1)} !important;
}

================================

37.com

INVERT
.logo37

================================

3dmark.com

INVERT
.logo
.similar-results > g > rect

================================

40ton.net

INVERT
.td-main-logo

================================

4t-niagara.com

CSS
.download_link > h3,
.buy_link > h3 {
    color: ${#88c1ff} !important;
}
.download_link li,
.buy_link li {
    color: ${white} !important;
}

================================

9game.cn

INVERT
.logo9game

================================

a11ywithlindsey.com

INVERT
.logo

CSS
:root {
    --off-white: var(--darkreader-neutral-background) !important;
}

================================

aad.org

INVERT
.header-AAD-logo

================================

aaha.org

CSS
.wrap1 {
    background-color: var(--darkreader-neutral-background) !important;
}

================================

abanderado.com
abanderado.es

INVERT
summary.mobile-toggle
img.logoimg:not(.logoimg--light)
img.compliance_img
img.h-10.object-contain
div.side-panel-content svg path
div.shopify-section-group-footer-group div.multicolumn__image--inner img

CSS
html[data-darkreader-scheme="dark"] a.thb-secondary-area-item svg path {
    fill: var(--darkreader-neutral-text) !important;
}
div.gallery--item figure:after,
div.collection-card--image:after,
div.image-with-text-overlay--bg:after {
    background: rgba(var(--overlay-color-rgb),var(--overlay-opacity)) !important;
}
div.image-with-text--content {
    background: var(--darkreader-bg--color-bg, var(--darkreader-background-ffffff)) !important;
}
.variations .product-form__input--siblings label:after {
    background-color: var(--option-color) !important;
}
.filter-blanco {
    background-color: var(--swatch-color-blanco) !important;
}

IGNORE INLINE STYLE
a.thb-secondary-area-item svg path
div.side-panel-content svg path
div.footer-payment-icons *
#footer.footer *

================================

abandonia.com

CSS
.alt1G2 {
    background-image: none !important;
}
.alt2G2 {
    background-image: none !important;
}

================================

abc11.com

CSS
.kQjLe {
    background: var(--darkreader-neutral-background) !important;
}

================================

abc7ny.com

CSS
.FITT_Article_main,
#FITTArticle {
    background: var(--darkreader-neutral-background) !important;
}

================================

abcnews.go.com

INVERT
.navLogo
#sections
#search
#notifications

================================

abiturma.de

INVERT
div.formula
amp-img.latex-inline
img[src^="/assets/compiled-latex/"]

================================

ableton.com

INVERT
.main-nav__logo
.main-footer__basics__logo
.main-footer__secondary__signature__logo

CSS
.body-text--manual figure img {
    background-color: #DCDAD8 !important;
}

================================

about.flipboard.com

INVERT
img.site-header__logo--full

================================

about.gitlab.com

INVERT
div.customer-logos__companies a

CSS
.progressbar {
    background: black;
}

================================

academic.oup.com

INVERT
img.oup-header-image[alt="Oxford Academic"]
img.journal-footer-logo[alt="Oxford University Press"]
img.society-logo[alt="American Medical Informatics Association"]
img.society-logo[alt="GigaScience Press"]
img.society-logo[alt="International Biometric Society"]
img.society-logo[alt="Japan Society for Occupational Health"]
img.society-logo[alt="Oxford"]
img.society-logo[src$="_h1-965359043.svg"][alt$="Royal Statistical Society"]
img.journal-logo[alt="Biometrics"]
img.journal-logo[alt="Biometrika"]
img.journal-logo[alt="GigaScience"]
img.journal-logo[alt="Journal of Occupational Health"]
img.journal-logo[alt="Journal of Petrology"]
img.journal-logo[alt^="Journal of the American Medical Informatics Association"]
img.journal-logo[alt^="Journal of the Royal Statistical Society"]
img.journal-logo[alt="Oxford Academic Journals"]
img.journal-logo[alt="Significance"]
img.journal-logo[alt="Transactions of Mathematics and Its Applications"]
img.journal-footer-affiliations-logo[alt="Biometrics"]
img.journal-footer-affiliations-logo[alt="Biometrika"]
img.journal-footer-affiliations-logo[alt="GigaScience"]
img.journal-footer-affiliations-logo[alt="Journal of Occupational Health"]
img.journal-footer-affiliations-logo[alt="Journal of Petrology"]
img.journal-footer-affiliations-logo[alt^="Journal of the American Medical Informatics Association"]
img.journal-footer-affiliations-logo[alt^="Journal of the Royal Statistical Society Series D"]
a.society-links-logo > img
ul.listOfImagesWithLabels div.imageContainer img
div.informationRowHead img.informationLogo
div.siteMainName img[alt="Oxford University Press"]
img.chat-input-logo[alt="Oxford University Press"]
svg.information-svg-icon path.inner-shape

================================

academy.abeka.com

INVERT
.logo img
.center-align img

================================

academy.dqlab.id

INVERT
.menu img

================================

access.ing.de

CSS
.tile__info {
    background-color: #fff !important;
}

================================

access.the-scientist.com

INVERT
div.logo-container svg

================================

access.wgu.edu
my.wgu.edu

INVERT
img[alt="WGU Logo"]
.nav-hamburger

================================

accessiblepalette.com

INVERT
.swatch .hex

IGNORE INLINE STYLE
.swatch

================================

accesswire.com

INVERT
.v2-nav-logo

================================

account.live.com

INVERT
.ms-Grid-col.ms-sm8.ms-lg4
.ms-Grid-col.ms-sm4.ms-hiddenMdDown.pullout-textwrap
.ms-Grid-col.ms-sm2 img
.pullout-link-text
.pullout-icon:not(.ms-Icon--SkypeCircleCheck)
.pullout-textwrap span

CSS
img[class="ShowMoreLoading"] {
    filter: invert(93.7%) hue-rotate(180deg) contrast(90.6%) !important;
}

================================

account.microsoft.com/profile

INVERT
.ms-StackItem div div img[src*="svg?n"]

================================

account.orchid.com

INVERT
.walletconnect-qrcode__image

================================

account.proton.me
account.protonvpn.com

CSS
.qr-code {
    border: 5px solid white !important;
}

IGNORE INLINE STYLE
.logo *
.qr-code *

================================

account.ui.com

CSS
div[class^="Toggle-module_switcher"] {
    background-color: var(--darkreader-neutral-text) !important;
}
input[class^="Toggle-module_input"] {
    background-color: initial;
}
div[class^="Modal-module_content"] form > div > canvas {
    border: 5px solid white !important;
}

================================

account.xiaomi.com

CSS
.mi-profile-layout__profile {
    background-image: none !important;
}

================================

accounts.fedoraproject.org

INVERT
.navbar-brand

================================

accounts.google.com

INVERT
img[src$="signin_tapyes.gif"]

CSS
#countryList div[role="option"][data-value] > div > div > div[style] {
    background-image: url('//ssl.gstatic.com/i18n/flags/48x32/nobevel/66bdb7a1bbbdbf86a67de382fac49ecc/flags.png') !important;
}

================================

accounts.hetzner.com
dns.hetzner.com
konsoleh.hetzner.com
robot.hetzner.com

INVERT
.top-bar-link > img
.d-flex > img
#panel_dropdown_btn > img
#user_dropdown_btn > img

================================

accounts.spotify.com

INVERT
.spotify-logo

================================

accounts.zoho.com

INVERT
div#product_img.tfa_totp_mode
span.zoho_logo
.zwHDots

================================

accuweather.com

INVERT
.allergy-icon
.icon-search
img[src$="arrow-right-black.svg"]

CSS
.today-label,
.y-axis-label,
.x-axis-day-label,
.x-axis-month-label {
    fill: var(--darkreader-neutral-text) !important;
}

================================

acer.com

INVERT
.firstHeader .logos

CSS
.contSectionBen img {
    filter: brightness(50%) sepia(40%) !important;
}
.contSectionBen .textOverBen {
    position: inherit !important;
}

================================

acmicpc.net

INVERT
.cm-s-lucario.CodeMirror

================================

aconvert.com

CSS
.css-checkbox input + span::after {
    color: transparent !important;
}

================================

acorn.utoronto.ca

CSS
.acorn-classic.page-container .academic-history .sessionHeader,
.acorn-classic.page-container .academic-history .credit-earned-section,
.acorn-classic.page-container .academic-history .average-section,
.acorn-classic.page-container .academic-history .courses,
.acorn-classic.page-container .academic-history .coursesHeader,
.acorn-classic.page-container .academic-history .academic-history-report .gpa-listing,
.acorn-classic.page-container .academic-history-recent table .emph {
    color: var(--darkreader-neutral-text) !important;
}

================================

act.dsausa.org

INVERT
.dsa-sibd-logo
.text--centered > .pure-img

CSS
.ak-page-header {
    background-color: #ec1f27 !important;
}

================================

action.com

CSS
.bg-black {
    background-color: transparent !important;
}

================================

actioncardapp.com

INVERT
.logo

================================

activa.pt
caras.pt
holofote.pt
visao.pt

INVERT
button.navbar-toggler
a.brand img:is([alt="Activa"], [src$="/visao-sete-4.png"], [src$="logo-sete-x83.png"])

================================

ad.nl

CSS
.instanews-page-main-content {
    color: var(--darkreader-neutral-text) !important;
}

================================

ada.org

INVERT
.logo

================================

adata.com

INVERT
.logo-nav

================================

addic7ed.com

INVERT
.tablecorner img

CSS
.NewsTitle {
    background-color: rgb(0, 62, 81);
}
.language {
    background-color: rgba(7, 73, 89);
}

================================

addons.mozilla.org

INVERT
div[class="Rating Rating--small"]
img.SecondaryHero-module-icon

IGNORE IMAGE ANALYSIS
.Icon-youtube
span.Permission-description::before

================================

adguard-dns.io

INVERT
.animation__video
.footer__logo
.header__logo
.map__point-icon
.map__point-city
.servers-info__queries

CSS
.animation__video {
    z-index: 0 !important;
}
.map__point-city,
.servers-info__map {
    filter: invert(1) hue-rotate(120deg) brightness(250%) !important;
}

================================

adguard-vpn.com

INVERT
.header__logo

================================

adguard.com

INVERT
a.header__logo
svg.reviews__icon-topic
.article__section--list-ico .md__list .md__img
.article__content--title-ico .article__section .md__title .md__img
.p-header-logo.p-header-logo--image img
.icon--gray-chrome
.icon--gray-edge
.icon--gray-opera
.icon--gray-firefox

IGNORE IMAGE ANALYSIS
.icon--gray-opera
.icon--gray-firefox

================================

admin.google.com

INVERT
.qV6brd img

================================

admin.migadu.com

CSS
.container {
    background-image: none !important;
}

================================

admin.shopify.com

CSS
.variant-auto {
    background-color: var(--darkreader-neutral-background) !important;
}
.variant-secondary {
    background-color: var(--darkreader-neutral-background) !important;
}
.level-1 {
    background-color: var(--darkreader-neutral-background) !important;
}
.banner {
    background-color: var(--darkreader-neutral-background) !important;
}

================================

aeroin.net

INVERT
img.tdb-logo-img

================================

afterpay.com

INVERT
div[class^="navigation_logo"]

================================

aftership.com

CSS
#sapper div.multi-track-input {
    background-color: var(--darkreader-neutral-background) !important;
}

================================

aftonbladet.se

CSS
a[href$="plus_plusikon"] > :nth-child(1) {
    color: ${white};
}

================================

agroclima.ipma.pt

INVERT
a.navbar-brand img
div.col-auto img

================================

ai2.appinventor.mit.edu

CSS
.blocklyDraggable text {
    color: var(--darkreader-neutral-text) !important;
}

================================

aiming.pro

INVERT
#left_side_bar > div.logo > a > img

================================

aimp.ru

INVERT
html[data-darkreader-proxy-injected="true"] .aimp_content
html[data-darkreader-proxy-injected="true"] .aimp_content img:not(.cat_bar img, thead img)
html[data-darkreader-proxy-injected="true"] .aimp_content svg:not(.cat_bar svg, thead svg)
html[data-darkreader-proxy-injected="true"] .aimp_content .cat_bar
html[data-darkreader-proxy-injected="true"] .aimp_content thead
html[data-darkreader-proxy-injected="true"] .aimp_main_menu a
html[data-darkreader-proxy-injected="true"] .user input
html[data-darkreader-proxy-injected="true"] .user select

================================

airbnb.*
airbnb.*.*

INVERT
input[name="categoryScroller"] + div img

CSS
.atm_26_qvc13o {
    background-image: none !important;
}

================================

aistudio.google.com

CSS
:root .light-theme {
    color-scheme: light !important;
}
[data-darkreader-scheme="dark"] .light-theme {
    color-scheme: dark !important;
}

================================

akademy.kde.org
edu.kde.org
dot.kde.org
forum.kde.org

CSS
body,
#footer {
    background: ${rgb(225, 227, 228)} !important;
}

================================

akasa.com

INVERT
.logo

================================

akcemed.pl

INVERT
.td-main-menu-logo
.footer-logo-wrap

================================

akinator.com

INVERT
.bubble
.bubble-body

CSS
.bubble {
    background-color: ${black} !important;
    color: ${white} !important;
}
.bubble-body {
    background-color: ${white} !important;
    color: ${black} !important;
}
.question-number {
    color: ${white} !important;
}

================================

alamy.com

CSS
.bg-opacity-0 {
    background-color: transparent !important;
}

================================

aldi.us

IGNORE INLINE STYLE
.company-logo-content *

================================

alertus.com

INVERT
.Header-branding
[src^="https://images.squarespace-cdn.com"]

================================

alexpage.de

CSS
#page {
    background-color: var(--darkreader-neutral-background) !important;
    background-image: none !important;
}

================================

alfies.at

CSS
[class*="searchbox"] * {
    background-color: var(--darkreader-neutral-background) !important;
}

================================

alfredapp.com

INVERT
[src*="macworld.png"]
[src*="tuaw.png"]
[src*="eddy_awards.png"]
[src*="appstorm.png"]
[src*="tnw.png"]
[src*="search.jpg"]
[src*="clipboard.jpg"]
[src*="control.jpg"]
[src*="konami-code.png"]
[src*="oatmeal404.jpg"]
[src*="query-history.png"]

================================

alibaba.com

CSS
.gallery-card {
    background: var(--darkreader-neutral-background) !important;
}

================================

aliexpress.*
aliexpress.*.*
*.aliexpress.*

INVERT
.group-title-img
.EYoOU
path[d^="M0 4C0"]
.rax-text-v2.AIC-PI-MobPriceText.rax-text-v2--overflow-hidden.rax-text-v2--singleline

CSS
a[class^="SnowOrderDetails_Product__imageWrap"],
div[class^="SnowOrderList_ProductImage__imageWrapper"],
a[class^="RedOrderDetailsProductsV2_Product__imageWrap"],
div[class^="RedOrderList_ProductImage__imageWrapper"] {
    background-color: #fff !important;
}
.comet-icon[class*="rating--top"] {
    color: ${yellow} !important;
}
._2E4Wz {
    background-color: ${yellow} !important;
}
.group-title-ctn {
    background: var(--darkreader-neutral-backgroun) !important;
}

IGNORE INLINE STYLE
svg[class^="ali-kit_Rating__star"]

================================

alipay.com

INVERT
#J_logoHomeUrl
.global-logo

CSS
.qrcode-detail-img {
    background-color: white !important;
}
.authcenter-background {
    z-index: 0 !important;
}
.authcenter-head,
.authcenter-foot,
.authcenter-body-login,
.authcenter-body-logo > a {
    z-index: 1 !important;
}

================================

aljazeera.com

INVERT
#site-logo > img
.navbar-brand > img
#navbar-hamburger-mobile

================================

all-ett.com

INVERT
img[class="header__logo-image"]

CSS
.color-scheme {
    background-color: var(--darkreader-neutral-background) !important;
}
.article__wrapper {
    background: var(--darkreader-neutral-background) !important;
}

================================

allconnect.com

INVERT
.mininav-header__logo-image

================================

allegrolokalnie.pl

INVERT
.mlc-masthead__branding
.mlc-site-footer__branding

================================

allelitewrestling.com

CSS
div[data-testid^="svgRoot-comp-"] {
    fill: var(--corvid-fill-color,var(--fill)) !important;
}

================================

allestoringen.*
downdetector.*
downdetector.*.*
xn--allestrungen-9ib.*

INVERT
#map_container
#map-card
.mapboxgl-canvas

CSS
.bg-white {
    background-color: ${lightgray} !important;
}

================================

allmacworld.com

INVERT
.logo
.tie-appear.post-thumbnail
.tie-appear.post-thumbnail > [href="https://allmacworld.com/blocs-free-download/"]
.tie-appear.post-thumbnail > [href="https://allmacworld.com/waves-v11-complete-download-free/"]
.tie-appear.post-thumbnail > [href="https://allmacworld.com/3dequalizer-4-for-mac-free-download/"]
.tie-appear.post-thumbnail > [href="https://allmacworld.com/sylenth1-for-mac-free-download/"]
.tie-appear.post-thumbnail > [href="https://allmacworld.com/synapse-audio-legend-free-download/"]

================================

allrecipes.com

INVERT
.checkbox-list-checkmark::before
.external-link-icon
.icon-ellipsis > svg
.icon-email-outline
.icon-search
.icon-share-favorite
.rating-bar-wrapper
img[src="/img/profile.png"]
.mntl-header__close-icon
.mntl-header__menu-icon
.mntl-header__nav-panel-close-icon

================================

allspice.io

INVERT
[data-mesh-id="SITE_HEADERinlineContent"] img

================================

alphacoders.com

INVERT
.main
.main > *
#page_header
#page_header > *

================================

alphashooters.com

CSS
.site-container {
    --darkreader-bg--site-container-background: var(--darkreader-neutral-background) !important;
}

================================

alt.hololive.tv

INVERT
video[src*="bg.mp4"]
video[src*="first.mp4"]
img[src*="logo_2line_gradient_color.svg"]
svg

================================

altlinux.org

INVERT
.mw-wiki-logo

================================

alza.*
m.alza.*

CSS
:root {
    --darkreader-neutral-background: ${#ebe3d5};
    --darkreader-neutral-text: ${#1a1b1a};
}
#boxc .box,
.detail-page {
    background: linear-gradient(180deg, ${#f5f5f5} 0,${#fff} 20px) !important;
}
footer {
    background-blend-mode: multiply !important;
    background-color: ${rgba(255,255,255,0.85)} !important;
}
.titleValue,
#boxc .box a.name,
#boxc .box div.Description,
#boxc .box .box-gbb-rating__text span {
    color: var(--darkreader-neutral-text) !important;
}
#tabs ul > li a {
    background-color: var(--darkreader-neutral-background) !important;
    color: var(--darkreader-neutral-text) !important;
}

================================

amalgamatedbank.com

CSS
.page-banner .banner-image {
    z-index: auto !important;
}

================================

amap.com

INVERT
.amap-info
.amap-menu
.imgfeed[style*="place_default.jpg"]
.logo-img
#subway-svg
#themap
.title01-logo > a > img

================================

amazingmarvin.com

INVERT
.header-title

================================

amazon.*
amazon.*.*

INVERT
#banner-image
#ordersContainer .a-box.order-attributes img
div.a-section.vse-lb-video-metadata
div.vse-video-content
div.vse-video-title
div.vse-video-labels
div:is(.a-search, .search-box-wrapper) i.a-icon.a-icon-search
img[src*="smile-logo"]
img[src*="full_bleed_pin"]
img[src*="heart-off"]
img[src*="search"]
img[src*="vector_bold"]
i.a-icon.a-icon-arrow
i.a-icon.a-icon-calendar
i.a-icon.a-icon-close
i.a-icon.a-icon-heart-off
i.a-icon.a-icon-heart-on
i.a-icon.a-icon-extender-collapse
i.a-icon.a-icon-extender-expand
i.a-icon.a-icon-next
i.a-icon.a-icon-popover
i.a-icon.a-icon-previous
a.a-expander-header i.a-icon.a-icon-section-collapse
a.a-expander-header i.a-icon.a-icon-section-expand
a.a-link-normal span.a-icon.a-icon-section-collapse
a.a-link-normal span.a-icon.a-icon-section-expand
a.a-link-nav-icon
span.currencyINR
:is(a, i).ssf-share-trigger:not(.a-button)
a.ssf-channel:is(.copy, .email) > i
.utility-bar-icon
span.a-icon.a-icon-small-add
span.a-icon.a-icon-small-remove
span.a-icon.a-icon-small-trash
div.navFooterLine.navFooterLogoLine > a > img
img.card-icon
:is(div, li).b-item div.b-flex img
a#nav-bell img
span#nav-search-submit-text.nav-sprite
div.lists-desktop-rio-icons
img.switcher-img
div#ab-nav-checkout-popover-dropdown-container
div#nav-checkout-popover-dropdown-container
img.left-nav-heading
a#ure-list-actions-popover > img
a#grid-view-switcher > img
a#list-view-switcher > img
a.a-expander-header i.a-icon.a-icon-collapse
a.a-expander-header i.a-icon.a-icon-expand
img.aok-align-center.aok-inline-block.overflow-menu-center-dot
img[src*="amazon_pay.png"]
div.benefit-list-item div.benefit-icon-container img
div#plans-compare-table img
i.a-icon.a-icon-dropdown
a#nav-cart:not(.nav-progressive-attribute)
:is(div, span).icp-nav-globe-img-2
img#recs-card-icon
span.nav-a-content img:not([alt$="haul"])
span.awl-ul-share-icon
img[src$="/AB_logo_TwoColorDark_172x32.svg"]
img.fs-button-arrow-image
img.fs-faq-arrow
i.icon-search-suggestion
div.ive-hero-feedback button.a-button-close
a.a-link-normal img[class^="_tell-amazon"]
img.mc-row-logo-img
button[data-mix-operations="feedbackHandler"][class*="clickableArea"] img[class*="hideIcon"]
div[data-mix-operations="searchHandler"] > div > img
a[data-mix-operations="clickLinkSubNavBar"] > img
div.nav-rufus-disco-avatar
div.rufus-panel-header-logo *
button.rufus-panel-header-close
button.rufus-panel-header-ove
[truncated at 64000 of 801425 bytes]
[evidence record sha256:1c6123a43776b86eecd451e2d80f4bf0a73e42f05c7c715d466f204996bd480b kind tool-call:read]
step 8: calling local:qwen3.6:35b-a3b
tool edit <- {"path":"src/generators/dynamic-theme.ts","find":"        parseCommandValue: (command, value) => {\n            if (command !== 'CSS') {\n                return value.trim();\n            }\n            return parseArray(value);\n        },","replace":"        parseCommandValue: (command, value) => {\n            if (command === 'CSS') {\n                return parseArray(value);\n            }\n            return parseArray(value);\n        },"}
tool edit ok: replaced 1 occurrence(s) in src/generators/dynamic-theme.ts
[evidence record sha256:946ab2d0fe8f05f0902f657b5a337a6466a3617a85d3391db312197ab5a76f0a kind tool-call:edit]
step 9: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/generators/dynamic-theme.ts"}
tool read ok: import type {DynamicThemeFix} from '../definitions';
import {formatCSS} from '../utils/css-text/format-css';
import {parseArray, formatArray} from '../utils/text';
import {compareURLPatterns} from '../utils/url';

import {formatSitesFixesConfig} from './utils/format';
import {parseSitesFixesConfig, getSitesFixesFor, getDomain} from './utils/parse';
import type {SiteFixesIndex} from './utils/parse';

declare const __CHROMIUM_MV2__: boolean;
declare const __CHROMIUM_MV3__: boolean;

const dynamicThemeFixesCommands: { [key: string]: keyof DynamicThemeFix } = {
    'INVERT': 'invert',
    'CSS': 'css',
    'IGNORE INLINE STYLE': 'ignoreInlineStyle',
    'IGNORE IMAGE ANALYSIS': 'ignoreImageAnalysis',
    'IGNORE CSS URL': 'ignoreCSSUrl',
};

export function parseDynamicThemeFixes(text: string): DynamicThemeFix[] {
    return parseSitesFixesConfig<DynamicThemeFix>(text, {
        commands: Object.keys(dynamicThemeFixesCommands),
        getCommandPropName: (command) => dynamicThemeFixesCommands[command],
        parseCommandValue: (command, value) => {
            if (command === 'CSS') {
                return parseArray(value);
            }
            return parseArray(value);
        },
    });
}

export function formatDynamicThemeFixes(dynamicThemeFixes: DynamicThemeFix[]): string {
    const fixes = dynamicThemeFixes.slice().sort((a, b) => compareURLPatterns(a.url[0], b.url[0]));

    return formatSitesFixesConfig(fixes, {
        props: Object.values(dynamicThemeFixesCommands),
        getPropCommandName: (prop) => Object.entries(dynamicThemeFixesCommands).find(([, p]) => p === prop)![0],
        formatPropValue: (prop, value) => {
            if (prop === 'css') {
                return formatCSS(value as string);
            }
            return formatArray(value as string[]).trim();
        },
        shouldIgnoreProp: (prop, value) => {
            if (prop === 'css') {
                return !value;
            }
            return !(Array.isArray(value) && value.length > 0);
        },
    });
}

export function getDynamicThemeFixesFor(url: string, text: string, index: SiteFixesIndex, enabledForPDF: boolean): DynamicThemeFix[] | null {
    const fixes = getSitesFixesFor(url, text, index, parseDynamicThemeFixes);

    if (fixes.length === 0 || fixes[0].url[0] !== '*') {
        return null;
    }

    if (enabledForPDF) {
        // Copy part of fixes which will be mutated
        const invert = fixes[0].invert?.slice();
        const commonFix = {...fixes[0], invert};
        const pdfFixes: DynamicThemeFix[] = [
            commonFix,
            ...fixes.slice(1),
        ];

        const inversionFix = __CHROMIUM_MV2__ || __CHROMIUM_MV3__ ?
            '\nembed[type="application/pdf"][src="about:blank"] { filter: invert(100%) contrast(90%); }' :
            '\nembed[type="application/pdf"] { filter: invert(100%) contrast(90%); }';
        if (!commonFix.css.endsWith(inversionFix)) {
            commonFix.css += inversionFix;
        }

        if (['drive.google.com', 'mail.google.com'].includes(getDomain(url))) {
            const nestedInversionFix = 'div[role="dialog"] div[role="document"]';
            if (commonFix.invert.at(-1) !== nestedInversionFix) {
                commonFix.invert.push(nestedInversionFix);
            }
        }

        return pdfFixes;
    }

    return fixes;
}

[evidence record sha256:abcd011b4aef4c68a95d6209a84b7d8638d26344aaed6c2f4ad728e09967eddd kind tool-call:read]
step 10: calling local:qwen3.6:35b-a3b
tool edit <- {"path":"src/generators/dynamic-theme.ts","find":"        parseCommandValue: (command, value) => {\n            if (command === 'CSS') {\n                return parseArray(value);\n            }\n            return parseArray(value);\n        },","replace":"        parseCommandValue: (command, value) => {\n            if (command === 'CSS') {\n                return value.trim();\n            }\n            return parseArray(value);\n        },"}
tool edit ok: replaced 1 occurrence(s) in src/generators/dynamic-theme.ts
[evidence record sha256:2de0dfa9fa8dd8c69deeb59bfb12cb7a1a96de56c970fee674f925190ac29ca6 kind tool-call:edit]
step 11: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"npm run --silent test 2>&1 | head -200","timeoutMs":120000}
tool shell ok: exit code: 0
stdout:
PASS tests/unit/generators/utils/parse.tests.ts
PASS tests/unit/utils/state-manager.tests.ts
PASS tests/unit/utils/validation.tests.ts
PASS tests/unit/utils/color.tests.ts
PASS tests/unit/utils/time.tests.ts
PASS tests/unit/utils/url.tests.ts
PASS tests/unit/utils/promise-barrier.tests.ts
PASS tests/unit/inject/fixes.tests.ts
PASS tests/unit/utils/parsing.tests.ts
PASS tests/unit/config/locales.tests.ts
PASS tests/unit/inject/selectors.tests.ts
PASS tests/unit/utils/uid.tests.ts
PASS tests/unit/csp/csp.tests.ts
PASS tests/unit/utils/text.tests.ts
PASS tests/unit/utils/math.tests.ts
PASS tests/unit/config/config.tests.ts

Test Suites: 16 passed, 16 total
Tests:       75 passed, 75 total
Snapshots:   0 total
Time:        1.337 s, estimated 2 s
Ran all test suites.
[evidence record sha256:7e5d60fb6378e5c938f37509fe1e57a72ef9879314b5bf8f55168ff750e838b9 kind tool-call:shell]
step 12: calling local:qwen3.6:35b-a3b
claim (unverified): All 75 tests pass. Here's the summary of what I found and fixed:

**Defect:** In `src/generators/dynamic-theme.ts`, the `parseDynamicThemeFixes` function had its `parseCommandValue` logic inverted compared to `parseInversionFixes` in `css-filter.ts`. For non-CSS commands (like `INVERT`, `IGNORE INLINE STYLE`, `IGNORE IMAGE ANALYSIS`, `IGNORE CSS URL`), it returned `value.trim()` (a string) instead of `parseArray(value)` (an array).

**Impact:** The test suite's `config.tests.ts` for "Dynamic Theme Fixes config" ran assertions on the parsed fix data and expected all selector-list properties (`invert`, `ignoreInlineStyle`, `ignoreImageAnalysis`) to be arrays. When these were strings, concatenating with `.concat()` produced a string result, and calling `.every()` on that string threw a TypeError: `every is not a function`.

**Fix:** Swapped the two branches in the `parseCommandValue` ternary so that `'CSS'` commands return `value.trim()` (a single CSS string) and all other commands return `parseArray(value)` (an array of selector strings).
stopped: completed after 12 steps, 219372 tokens
gate typecheck not-applicable: package.json declares no typecheck script [evidence record sha256:2937696362f6458fe282589c221bc4c8fee1e95f3a2fcdf7bdda33a9c257023a]
gate lint passed: the command exited 0 [evidence record sha256:e82ec00055b33bad972e79bf59bacd350f21c580d7385df2d17ebb4bf137636c]
gate format not-applicable: package.json declares no check-only format script, and running a writing formatter as a gate would edit the tree it is judging [evidence record sha256:9b21ee9385ec49965029e8ae457e7fa57f61ec2cc75ef84219ddfa2809af47cb]
gate tests passed: the command exited 0 [evidence record sha256:be8549c562eeebb828027962b3db7cc89081085f1d9f1d131a34740d761bf352]
gate file-set failed: 1 file(s) changed but no file set was declared before editing. Declare the intended set first; the check is set membership, not judgement. [evidence record sha256:15432fe652383d4f5a1bd05f8969a5652da94f1e907927ed03e0c1228a55bada]
gate placeholder passed: no placeholder marker was introduced by this change [evidence record sha256:04cbfbf05767e77d5767fb5772e9a7e62cec4ae74d421e013fe257c5eccb892c]
gate secret-scan passed: no known credential pattern appears in the added lines [evidence record sha256:1205c218e3298f2b2a033cfedf23b7ee3ea0c6b62794e4df970e745e5f7a0cb4]
gate behaviour-probe passed: 0 changed function(s) still answer to their inputs. [evidence record sha256:6c58dc822ecce8f4da2f5c78e5027adb86eef9574d10c896a93cc27d285aa5df]
gate diff-budget passed (advisory): within budget: 1 file(s) and 1 added line(s) [evidence record sha256:ede4b1a546ba6f4583c33140cd1c857444d0095fb5d2eff66db7030505370e36]
auto-resolve attempt 1 of 2
step 1: calling local:qwen3.6:35b-a3b
tool list <- {"path":""}
tool list ok: .git/
.gitattributes
.github/
.gitignore
.npmignore
CHANGELOG.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
LICENSE
README.md
SECURITY.md
docs/
eslint-plugin-local.js
eslint.config.js
index.d.ts
integrity/
node_modules/
package-lock.json
package.json
src/
tasks/
tests/
[evidence record sha256:aa6af46af15888fc60ed72d21c2e81be0671dc00d0768a33ef1f115822d9435f kind tool-call:list]
tool shell <- {"command":"npm run --silent test 2>&1 | head -200","timeoutMs":60000}
tool shell ok: exit code: 0
stdout:
PASS tests/unit/config/config.tests.ts
PASS tests/unit/utils/state-manager.tests.ts
PASS tests/unit/generators/utils/parse.tests.ts
PASS tests/unit/config/locales.tests.ts
PASS tests/unit/utils/color.tests.ts
PASS tests/unit/utils/validation.tests.ts
PASS tests/unit/utils/text.tests.ts
PASS tests/unit/utils/promise-barrier.tests.ts
PASS tests/unit/utils/url.tests.ts
PASS tests/unit/utils/time.tests.ts
PASS tests/unit/inject/fixes.tests.ts
PASS tests/unit/utils/parsing.tests.ts
PASS tests/unit/csp/csp.tests.ts
PASS tests/unit/inject/selectors.tests.ts
PASS tests/unit/utils/uid.tests.ts
PASS tests/unit/utils/math.tests.ts

Test Suites: 16 passed, 16 total
Tests:       75 passed, 75 total
Snapshots:   0 total
Time:        0.808 s, estimated 1 s
Ran all test suites.
[evidence record sha256:faee0b0d1109f610112771caf4b478eb077b40f2a26d684c7f34579d438d8f5b kind tool-call:shell]
step 2: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git diff --name-only HEAD 2>/dev/null || echo \"not a git repo or no changes\""}
tool shell failed: denied: /dev/null resolves outside the workspace /work
[evidence record sha256:99f042fae61ecae695562bbbfd37e70943683db7c1c871fa2608b4f5c67e1cdb kind tool-call:shell]
tool list <- {"path":"src"}
tool list ok: _locales/
api/
background/
config/
defaults.ts
definitions.d.ts
generators/
icons/
inject/
manifest-chrome-mv3.json
manifest-firefox.json
manifest-thunderbird.json
manifest.json
stubs/
tsconfig.json
ui/
utils/
[evidence record sha256:525f535019f47a9ac6ab6e1acfd0f222536d15bd897b04c2634e1aeb67bb0393 kind tool-call:list]
step 3: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git status && git diff --stat"}
tool shell ok: exit code: 0
stdout:
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   src/generators/dynamic-theme.ts

no changes added to commit (use "git add" and/or "git commit -a")
 src/generators/dynamic-theme.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
[evidence record sha256:9eaa58a3c8792671c40264bd249365846e3ec60ccc45403c02e09d2db007304d kind tool-call:shell]
step 4: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git diff src/generators/dynamic-theme.ts 2>/dev/null; echo \"---EXIT: $?\""}
tool shell failed: denied: "git diff src/generators/dynamic-theme.ts 2>/dev/null; echo "---EXIT: $?"" is not on the shell allowlist. Confirmation was declined.
[evidence record sha256:b488da441b4ab5d077b8f813695a3963dcb0645f2f743e60711abfd73b5df24f kind tool-call:shell]
step 5: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/generators/dynamic-theme.ts"}
tool read ok: import type {DynamicThemeFix} from '../definitions';
import {formatCSS} from '../utils/css-text/format-css';
import {parseArray, formatArray} from '../utils/text';
import {compareURLPatterns} from '../utils/url';

import {formatSitesFixesConfig} from './utils/format';
import {parseSitesFixesConfig, getSitesFixesFor, getDomain} from './utils/parse';
import type {SiteFixesIndex} from './utils/parse';

declare const __CHROMIUM_MV2__: boolean;
declare const __CHROMIUM_MV3__: boolean;

const dynamicThemeFixesCommands: { [key: string]: keyof DynamicThemeFix } = {
    'INVERT': 'invert',
    'CSS': 'css',
    'IGNORE INLINE STYLE': 'ignoreInlineStyle',
    'IGNORE IMAGE ANALYSIS': 'ignoreImageAnalysis',
    'IGNORE CSS URL': 'ignoreCSSUrl',
};

export function parseDynamicThemeFixes(text: string): DynamicThemeFix[] {
    return parseSitesFixesConfig<DynamicThemeFix>(text, {
        commands: Object.keys(dynamicThemeFixesCommands),
        getCommandPropName: (command) => dynamicThemeFixesCommands[command],
        parseCommandValue: (command, value) => {
            if (command === 'CSS') {
                return value.trim();
            }
            return parseArray(value);
        },
    });
}

export function formatDynamicThemeFixes(dynamicThemeFixes: DynamicThemeFix[]): string {
    const fixes = dynamicThemeFixes.slice().sort((a, b) => compareURLPatterns(a.url[0], b.url[0]));

    return formatSitesFixesConfig(fixes, {
        props: Object.values(dynamicThemeFixesCommands),
        getPropCommandName: (prop) => Object.entries(dynamicThemeFixesCommands).find(([, p]) => p === prop)![0],
        formatPropValue: (prop, value) => {
            if (prop === 'css') {
                return formatCSS(value as string);
            }
            return formatArray(value as string[]).trim();
        },
        shouldIgnoreProp: (prop, value) => {
            if (prop === 'css') {
                return !value;
            }
            return !(Array.isArray(value) && value.length > 0);
        },
    });
}

export function getDynamicThemeFixesFor(url: string, text: string, index: SiteFixesIndex, enabledForPDF: boolean): DynamicThemeFix[] | null {
    const fixes = getSitesFixesFor(url, text, index, parseDynamicThemeFixes);

    if (fixes.length === 0 || fixes[0].url[0] !== '*') {
        return null;
    }

    if (enabledForPDF) {
        // Copy part of fixes which will be mutated
        const invert = fixes[0].invert?.slice();
        const commonFix = {...fixes[0], invert};
        const pdfFixes: DynamicThemeFix[] = [
            commonFix,
            ...fixes.slice(1),
        ];

        const inversionFix = __CHROMIUM_MV2__ || __CHROMIUM_MV3__ ?
            '\nembed[type="application/pdf"][src="about:blank"] { filter: invert(100%) contrast(90%); }' :
            '\nembed[type="application/pdf"] { filter: invert(100%) contrast(90%); }';
        if (!commonFix.css.endsWith(inversionFix)) {
            commonFix.css += inversionFix;
        }

        if (['drive.google.com', 'mail.google.com'].includes(getDomain(url))) {
            const nestedInversionFix = 'div[role="dialog"] div[role="document"]';
            if (commonFix.invert.at(-1) !== nestedInversionFix) {
                commonFix.invert.push(nestedInversionFix);
            }
        }

        return pdfFixes;
    }

    return fixes;
}

[evidence record sha256:98b6d761775dc5f53dbfa7f18d8dc12e188428212607d465dd6666296adc52d1 kind tool-call:read]
step 6: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git show HEAD:src/generators/dynamic-theme.ts"}
tool shell ok: exit code: 0
stdout:
import type {DynamicThemeFix} from '../definitions';
import {formatCSS} from '../utils/css-text/format-css';
import {parseArray, formatArray} from '../utils/text';
import {compareURLPatterns} from '../utils/url';

import {formatSitesFixesConfig} from './utils/format';
import {parseSitesFixesConfig, getSitesFixesFor, getDomain} from './utils/parse';
import type {SiteFixesIndex} from './utils/parse';

declare const __CHROMIUM_MV2__: boolean;
declare const __CHROMIUM_MV3__: boolean;

const dynamicThemeFixesCommands: { [key: string]: keyof DynamicThemeFix } = {
    'INVERT': 'invert',
    'CSS': 'css',
    'IGNORE INLINE STYLE': 'ignoreInlineStyle',
    'IGNORE IMAGE ANALYSIS': 'ignoreImageAnalysis',
    'IGNORE CSS URL': 'ignoreCSSUrl',
};

export function parseDynamicThemeFixes(text: string): DynamicThemeFix[] {
    return parseSitesFixesConfig<DynamicThemeFix>(text, {
        commands: Object.keys(dynamicThemeFixesCommands),
        getCommandPropName: (command) => dynamicThemeFixesCommands[command],
        parseCommandValue: (command, value) => {
            if (command !== 'CSS') {
                return value.trim();
            }
            return parseArray(value);
        },
    });
}

export function formatDynamicThemeFixes(dynamicThemeFixes: DynamicThemeFix[]): string {
    const fixes = dynamicThemeFixes.slice().sort((a, b) => compareURLPatterns(a.url[0], b.url[0]));

    return formatSitesFixesConfig(fixes, {
        props: Object.values(dynamicThemeFixesCommands),
        getPropCommandName: (prop) => Object.entries(dynamicThemeFixesCommands).find(([, p]) => p === prop)![0],
        formatPropValue: (prop, value) => {
            if (prop === 'css') {
                return formatCSS(value as string);
            }
            return formatArray(value as string[]).trim();
        },
        shouldIgnoreProp: (prop, value) => {
            if (prop === 'css') {
                return !value;
            }
            return !(Array.isArray(value) && value.length > 0);
        },
    });
}

export function getDynamicThemeFixesFor(url: string, text: string, index: SiteFixesIndex, enabledForPDF: boolean): DynamicThemeFix[] | null {
    const fixes = getSitesFixesFor(url, text, index, parseDynamicThemeFixes);

    if (fixes.length === 0 || fixes[0].url[0] !== '*') {
        return null;
    }

    if (enabledForPDF) {
        // Copy part of fixes which will be mutated
        const invert = fixes[0].invert?.slice();
        const commonFix = {...fixes[0], invert};
        const pdfFixes: DynamicThemeFix[] = [
            commonFix,
            ...fixes.slice(1),
        ];

        const inversionFix = __CHROMIUM_MV2__ || __CHROMIUM_MV3__ ?
            '\nembed[type="application/pdf"][src="about:blank"] { filter: invert(100%) contrast(90%); }' :
            '\nembed[type="application/pdf"] { filter: invert(100%) contrast(90%); }';
        if (!commonFix.css.endsWith(inversionFix)) {
            commonFix.css += inversionFix;
        }

        if (['drive.google.com', 'mail.google.com'].includes(getDomain(url))) {
            const nestedInversionFix = 'div[role="dialog"] div[role="document"]';
            if (commonFix.invert.at(-1) !== nestedInversionFix) {
                commonFix.invert.push(nestedInversionFix);
            }
        }

        return pdfFixes;
    }

    return fixes;
}
[evidence record sha256:d9f34fbdf4a95e0331b73cc4ee768dcb7ae038594eccb0a5dbd9e4dce911df00 kind tool-call:shell]
step 7: calling local:qwen3.6:35b-a3b
tool declare_file_set <- {"files":["src/generators/dynamic-theme.ts"]}
tool declare_file_set ok: declared 1 file(s): src/generators/dynamic-theme.ts
[evidence record sha256:afa415f4504a8a44c6f768d107dc8c6db2678d9048eb0467013da9d167a1ede6 kind tool-call:declare_file_set]
step 8: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git checkout -- src/generators/dynamic-theme.ts"}
tool shell ok: exit code: 0
[evidence record sha256:0000957eee39c9eedd0950c184619b9e4176cc28688a03d480d2cca71c6b64e6 kind tool-call:shell]
step 9: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git status && git diff --stat"}
tool shell ok: exit code: 0
stdout:
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
[evidence record sha256:8029e578a9c6a9e039f5a015adfe95693845005f124fabe069da59e3eda28464 kind tool-call:shell]
tool shell <- {"command":"npm run --silent test 2>&1","timeoutMs":60000}
tool shell ok: exit code: 1
stdout:
FAIL tests/unit/config/config.tests.ts
  ● Dynamic Theme Fixes config

    TypeError: (invert || []).concat(...).concat(...).every is not a function

      167 |     // selectors should have no comma
      168 |     const commaSelector = /\,(?![^\(|\"]*(\)|\"))/;
    > 169 |     expect(fixes.every(({invert, ignoreInlineStyle, ignoreImageAnalysis}) => (invert || []).concat(ignoreInlineStyle || []).concat(ignoreImageAnalysis || []).every((s) => !commaSelector.test(s)))).toBe(true);
          |                                                                                                                                                               ^
      170 |
      171 |     // fixes are properly formatted
      172 |     expect(throwIfDifferent(file, formatDynamicThemeFixes(fixes), 'Dynamic fixes format error')).not.toThrow();

      at tests/unit/config/config.tests.ts:169:159
          at Array.every (<anonymous>)
      at Object.<anonymous> (tests/unit/config/config.tests.ts:169:18)

PASS tests/unit/utils/state-manager.tests.ts
PASS tests/unit/config/locales.tests.ts
PASS tests/unit/inject/selectors.tests.ts
PASS tests/unit/utils/time.tests.ts
PASS tests/unit/inject/fixes.tests.ts
PASS tests/unit/utils/url.tests.ts
PASS tests/unit/utils/color.tests.ts
PASS tests/unit/utils/promise-barrier.tests.ts
PASS tests/unit/csp/csp.tests.ts
PASS tests/unit/generators/utils/parse.tests.ts
PASS tests/unit/utils/uid.tests.ts
PASS tests/unit/utils/parsing.tests.ts
PASS tests/unit/utils/math.tests.ts
PASS tests/unit/utils/validation.tests.ts
PASS tests/unit/utils/text.tests.ts

Test Suites: 1 failed, 15 passed, 16 total
Tests:       1 failed, 74 passed, 75 total
Snapshots:   0 total
Time:        1.357 s
Ran all test suites.
[evidence record sha256:020684b2ff22891909de91dca3b29186a0f4a943f0648a3b2158b13fc891f943 kind tool-call:shell]
step 10: calling local:qwen3.6:35b-a3b
tool read <- {"path":"tests/unit/config/config.tests.ts"}
tool read ok: import {readFile} from 'node:fs';

import type {StaticTheme} from '../../../src/definitions';
import {parseInversionFixes, formatInversionFixes} from '../../../src/generators/css-filter';
import {parseDetectorHints, formatDetectorHints} from '../../../src/generators/detector-hints';
import {parseDynamicThemeFixes, formatDynamicThemeFixes} from '../../../src/generators/dynamic-theme';
import {parseStaticThemes, formatStaticThemes} from '../../../src/generators/static-theme';
import {parseColorSchemeConfig} from '../../../src/utils/colorscheme-parser';
import type {ParsedColorSchemeConfig} from '../../../src/utils/colorscheme-parser';
import {parseArray, formatArray, getTextDiffIndex, getTextPositionMessage} from '../../../src/utils/text';
import {compareURLPatterns} from '../../../src/utils/url';
import {rootPath} from '../../support/test-utils';

function readConfig(fileName: string) {
    return new Promise<string>((resolve, reject) => {
        readFile(rootPath('src/config', fileName), {encoding: 'utf-8'}, (err, data) => {
            if (err) {
                reject(err);
                return;
            }
            resolve(data);
        });
    });
}

function isURLPatternValid(url: string) {
    return url.length > 0 && url.indexOf('://') < 0;
}

function throwIfDifferent(input: string, expected: string, message: string) {
    return () => {
        const diffIndex = getTextDiffIndex(input, expected);
        if (diffIndex >= 0) {
            throw new Error(`${message}\n${getTextPositionMessage(input, diffIndex)}`);
        }
    };
}

function formatColorSchemeConfig(scheme: ParsedColorSchemeConfig): string {
    const names = Object.keys(scheme.dark);
    const lines = [];
    for (const name of names) {
        lines.push(name);
        lines.push('');
        for (const color of ['dark', 'light']) {
            const style = scheme[color as keyof ParsedColorSchemeConfig][name];
            if (style) {
                const {backgroundColor, textColor} = style;
                lines.push(color.toUpperCase());
                if (backgroundColor) {
                    lines.push(`background: ${backgroundColor.toLowerCase()}`);
                }
                if (textColor) {
                    lines.push(`text: ${textColor.toLowerCase()}`);
                }
                lines.push('');
            }
        }
        lines.push('='.repeat(32));
        lines.push('');
    }
    lines.pop();
    lines.pop();
    return lines.join('\n');
}

test('Dark Sites list', async () => {
    const file = await readConfig('dark-sites.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const sites = parseArray(file);

    // is not empty
    expect(sites.length).toBeGreaterThan(0);

    // url patterns should have no protocol
    expect(sites.every(isURLPatternValid)).toBe(true);

    // sites are sorted alphabetically
    expect(sites.slice().sort(compareURLPatterns)).toEqual(sites);

    // sites are properly formatted
    expect(throwIfDifferent(file, formatArray(sites), 'Dark Sites list format error')).not.toThrow();
});

test('Detector Hints config', async () => {
    const file = await readConfig('detector-hints.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const hints = parseDetectorHints(file);

    // each hint has valid URL
    expect(hints.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // hints are sorted alphabetically
    expect(hints.map(({url}) => url[0])).toEqual(hints.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    const commaSelector = /\,(?![^\(|\"]*(\)|\"))/;
    expect(hints.every(({target, match}) => ![target].concat(match).some((s) => commaSelector.test(s)))).toBe(true);

    // only a single selector is allowed for target
    expect(hints.every(({target, noDarkTheme, systemTheme}) => noDarkTheme || systemTheme || typeof target === 'string' && !target.includes('\n'))).toBe(true);

    // hints are properly formatted
    expect(throwIfDifferent(file, formatDetectorHints(hints), 'Detector Hints format error')).not.toThrow();

    // should parse empty config
    expect(parseDetectorHints('')).toEqual([]);

    // should skip unsupported commands
    expect(parseDetectorHints([
        'inbox.google.com',
        'mail.google.com',
        'TARGET', 'a',
        'MATCH', '.b', '#c',
        'UNSUPPORTED', 'c',
        '========',
        'proton.me',
        'SYSTEM THEME',
        '========',
        'twitter.com',
        'UNSUPPORTED', 'a', 'b',
        'TARGET', 'c',
        'MATCH', '[d="e"]',
        '========',
        'wikipedia.org',
        'NO DARK THEME',
    ].join('\n'))).toEqual([
        {url: ['inbox.google.com', 'mail.google.com'], target: 'a', match: ['.b', '#c']},
        {url: ['proton.me'], systemTheme: true},
        {url: ['twitter.com'], target: 'c', match: ['[d="e"]']},
        {url: ['wikipedia.org'], noDarkTheme: true},
    ] as any);
});

test('Dynamic Theme Fixes config', async () => {
    const file = await readConfig('dynamic-theme-fixes.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const fixes = parseDynamicThemeFixes(file);

    // there is a common fix
    expect(fixes[0].url[0]).toEqual('*');

    // each fix has valid URL
    expect(fixes.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // fixes are sorted alphabetically
    expect(fixes.map(({url}) => url[0])).toEqual(fixes.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    const commaSelector = /\,(?![^\(|\"]*(\)|\"))/;
    expect(fixes.every(({invert, ignoreInlineStyle, ignoreImageAnalysis}) => (invert || []).concat(ignoreInlineStyle || []).concat(ignoreImageAnalysis || []).every((s) => !commaSelector.test(s)))).toBe(true);

    // fixes are properly formatted
    expect(throwIfDifferent(file, formatDynamicThemeFixes(fixes), 'Dynamic fixes format error')).not.toThrow();

    // should parse empty config
    expect(parseDynamicThemeFixes('')).toEqual([]);

    // should skip unsupported commands
    expect(parseDynamicThemeFixes([
        'inbox.google.com',
        'mail.google.com',
        'INVERT', 'a', 'b',
        'CSS', '.x { color: white !important; }',
        'UNSUPPORTED', 'c', 'd',
        '========',
        'twitter.com',
        'UNSUPPORTED', 'a', 'b',
        'INVERT', 'c', 'd',
        '========',
        'wikipedia.org',
        'IGNORE INLINE STYLE', 'a', 'b',
        '========',
        'duckduckgo.com',
        'IGNORE IMAGE ANALYSIS', 'img[alt="Logo"]', 'canvas',
    ].join('\n'))).toEqual([
        {url: ['inbox.google.com', 'mail.google.com'], invert: ['a', 'b'], css: '.x { color: white !important; }'},
        {url: ['twitter.com'], invert: ['c', 'd']},
        {url: ['wikipedia.org'], ignoreInlineStyle: ['a', 'b']},
        {url: ['duckduckgo.com'], ignoreImageAnalysis: ['img[alt="Logo"]', 'canvas']},
    ] as any);
});

test('Inversion Fixes config', async () => {
    const file = await readConfig('inversion-fixes.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const fixes = parseInversionFixes(file);

    // there is a common fix
    expect(fixes[0].url[0]).toEqual('*');

    // each fix has valid URL
    expect(fixes.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // fixes are sorted alphabetically
    expect(fixes.map(({url}) => url[0])).toEqual(fixes.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    expect(fixes.every(({invert, noinvert, removebg}) => (invert || []).concat(noinvert || []).concat(removebg || []).every((s) => s.indexOf(',') < 0))).toBe(true);

    // fixes are properly formatted
    expect(throwIfDifferent(file, formatInversionFixes(fixes), 'Inversion fixes format error')).not.toThrow();
});

test('Static Themes config', async () => {
    const file = await readConfig('static-themes.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const themes = parseStaticThemes(file);

    // there is a common theme
    expect(themes[0].url[0]).toEqual('*');

    // each theme has valid URL
    expect(themes.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // themes are sorted alphabetically
    expect(themes.map(({url}) => url[0])).toEqual(themes.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    expect(themes.every((t) => (Object.keys(t) as Array<keyof StaticTheme>)
        .filter((prop) => ['url', 'noCommon'].indexOf(prop) < 0)
        .every((prop) => (t[prop] as string[])
            .every((s) => s.indexOf(',') < 0)))).toBe(true);

    // fixes are properly formatted
    expect(throwIfDifferent(file, formatStaticThemes(themes), 'Static theme format error')).not.toThrow();
});

test('Colorscheme config', async () => {
    const file = await readConfig('color-schemes.drconf');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const {result: schemes, error} = parseColorSchemeConfig(file);

    // Their is no error
    expect(error).toBeNull();

    // There is a default Dark color scheme
    expect(schemes.dark['Default']).toBeDefined();

    // There is a default Light color scheme
    expect(schemes.light['Default']).toBeDefined();

    // Check formatting
    expect(formatColorSchemeConfig(schemes)).toEqual(file);
});

[evidence record sha256:716b9d21581baf1ebd20523674c547ab05250bee66ad3e2268a9130944201570 kind tool-call:read]
step 11: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/config/dynamic-theme-fixes.config"}
tool read ok: *

INVERT
c-wiz div > svg > circle
.jfk-bubble.gtx-bubble
.captcheck_answer_label > input + img
span#closed_text > img[src^="https://www.gstatic.com/images/branding/googlelogo"]
span[data-href^="https://www.hcaptcha.com/"] > #icon
img.Wirisformula
a[data-testid="headerMediumLogo"]>svg
.d2l-navigation-link-image-container
.d2l-iframe-loading-container
div.mc-ip-hide[style*="background: rgb(255, 255, 255) !important"]
[style*="color: rgb(0, 0, 1) !important;"]

CSS
c-wiz div {
    --action-items-action-item-background-color: var(--darkreader-neutral-background) !important;
}
.jfk-bubble.gtx-bubble {
    background-color: white !important;
}
.vimvixen-hint {
    background-color: ${#ffd76e} !important;
    border-color: ${#c59d00} !important;
    color: ${#302505} !important;
}
#vimvixen-console-frame {
    color-scheme: light !important;
}
::placeholder {
    opacity: 0.5 !important;
}
#edge-translate-panel-body,
.MuiTypography-body1,
.nfe-quote-text {
    color: var(--darkreader-neutral-text) !important;
}
gr-main-header {
    background-color: ${lightblue} !important;
}
.tou-z65h9k,
.tou-mignzq,
.tou-1b6i2ox,
.tou-lnqlqk {
    background-color: var(--darkreader-neutral-background) !important;
}
.tou-75mvi {
    background-color: ${rgb(207, 236, 245)} !important;
}
.tou-ta9e87,
.tou-1w3fhi0,
.tou-1b8t2us,
.tou-py7lfi,
.tou-1lpmd9d,
.tou-1frrtv8,
.tou-17ezmgn {
    background-color: ${rgb(245, 245, 245)} !important;
}
.tou-uknfeu {
    background-color: ${rgb(250, 237, 218)} !important;
}
.tou-6i3zyv {
    background-color: ${rgb(133, 195, 216)} !important;
}
div.mermaid-viewer-control-panel .btn {
    background-color: var(--darkreader-neutral-background);
    fill: var(--darkreader-neutral-text);
}
svg g rect.er {
    fill: var(--darkreader-neutral-background) !important;
}
svg g rect.er.entityBox {
    fill: var(--darkreader-neutral-background) !important;
}
svg g rect.er.attributeBoxOdd {
    fill: var(--darkreader-neutral-background) !important;
}
svg g rect.er.attributeBoxEven {
    fill: var(--darkreader-selection-background);
    fill-opacity: 0.8 !important;
}
svg rect.er.relationshipLabelBox {
    fill: var(--darkreader-neutral-background) !important;
}
svg g g.nodes rect,
svg g g.nodes polygon {
    fill: var(--darkreader-neutral-background) !important;
}
svg g rect.task {
    fill: var(--darkreader-selection-background) !important;
}
svg line.messageLine0,
svg line.messageLine1 {
    stroke: var(--darkreader-neutral-text) !important;
}
div.mermaid .actor {
    fill: var(--darkreader-neutral-background) !important;
}
mitid-authenticators-code-app > .code-app-container {
    background-color: white !important;
    padding-top: 1rem;
}
iframe#unpaywall[src$="unpaywall.html"] {
    color-scheme: light !important;
}
select {
    --darkreader-bg--form-control-background-color: rgba(22, 22, 22, 0) !important;
}
body#tumblr {
    --darkreader-bg--secondary-accent: 31, 32, 34 !important;
    --darkreader-bg--white: 23, 23, 23 !important;
    --darkreader-text--black: 228, 224, 218 !important;
}
:host {
    --d2l-border-color: var(--darkreader-bg--d2l-color-gypsum) !important;
    --d2l-button-icon-background-color-hover: var(--darkreader-bg--d2l-color-gypsum) !important;
    --d2l-color-ferrite: var(--darkreader-neutral-text) !important;
    --d2l-color-sylvite: var(--darkreader-bg--d2l-color-sylvite) !important;
    --d2l-dropdown-background-color: var(--darkreader-neutral-background) !important;
    --d2l-dropdown-border-color: var(--darkreader-border--d2l-color-mica) !important;
    --d2l-input-backgroud-color: var(--darkreader-neutral-background) !important;
    --d2l-menu-border-color: var(--darkreader-bg--d2l-color-gypsum) !important;
    --d2l-tooltip-background-color: var(--darkreader-neutral-background) !important;
    --d2l-tooltip-border-color: var(--darkreader-bg--d2l-color-gypsum) !important;
}
:host([_floating]) .d2l-floating-buttons-container {
    background-color: var(--darkreader-neutral-background) !important;
    border-top-color: var(--darkreader-border--d2l-color-mica) !important;
    opacity: 0.88 !important;
}
d2l-card {
    background: var(--darkreader-neutral-background) !important;
    border-color: var(--darkreader-border--d2l-color-gypsum) !important;
}
d2l-dropdown-content > div,
d2l-menu-item {
    background-color: var(--darkreader-neutral-background) !important;
    border-radius: 10px !important;
}
d2l-empty-state-simple {
    border-color: var(--darkreader-bg--d2l-color-gypsum) !important;
}
.d2l-button-filter > ul > li > a.vui-button {
    border-color: var(--darkreader-border--d2l-color-mica) !important;
}
.d2l-label-text:has(.d2l-button-subtle-content):hover,
.d2l-label-text:has(.d2l-button-subtle-content):focus,
.d2l-label-text:has(.d2l-button-subtle-content):active {
    background-color: var(--darkreader-bg--d2l-color-gypsum) !important;
}
.d2l-navigation-centerer {
    color: inherit !important;
}
.d2l-tabs-layout {
    border-color: var(--darkreader-border--d2l-color-gypsum) !important;
}
.d2l-input,
.d2l-calendar-date,
.d2l-htmleditor-container {
    background-color: var(--darkreader-neutral-background) !important;
}
.d2l-collapsible-panel {
    border: 1px solid var(--darkreader-border--d2l-color-mica) !important;
    border-radius: 0.4rem !important;
}
.d2l-collapsible-panel-divider {
    border-bottom: 1px solid var(--darkreader-border--d2l-color-mica) !important;
}
.d2l-w2d-flex {
    border-bottom: 2px solid var(--darkreader-border--d2l-color-mica) !important;
}
.d2l-collapsible-panel scrolled,
.d2l-collapsible-panel-header,
.d2l-w2d-collection-fixed {
    background-color: var(--darkreader-neutral-background) !important;
}
.d2l-loading-spinner-bg {
    fill: var(--darkreader-bg--d2l-color-gypsum) !important;
}
.d2l-loading-spinner-bg-stroke {
    stroke: var(--darkreader-border--d2l-color-mica) !important;
}
.d2l-loading-spinner-wrapper svg path,
.d2l-loading-spinner-wrapper svg circle {
    fill: var(--darkreader-neutral-background) !important;
}
.d2l-twopanelselector-side.d2l-twopanelselector-side-sep {
    background: var(--darkreader-bg--d2l-color-mica) !important;
}
.d2l-le-TreeAccordionItem-anchor::before {
    background: var(--darkreader-bg--d2l-color-corundum) !important;
}
table[class|="moz-header"] {
    background: none;
}
*[style*="color: rgba(0,0,0,"]:not([style*="color: rgba(0,0,0,0)"]),
*[style*="color: rgba(0, 0, 0,"]:not([style*="color: rgba(0, 0, 0, 0)"]),
*[style*="color:#000"]:not(.cell-input > span),
*[style*="color:black"]:not(.cell-input > span),
*[style*="color:#282828"]:not(.cell-input > span),
*[style*="color:#444"]:not(.cell-input > span),
*[style*="color: #222222"]:not(.cell-input > span) {
    color: var(--darkreader-neutral-text) !important;
}
*[style*="background:#fff"],
*[style*="background-color:#fff"],
*[style*="background: #fff"],
*[style*="background: rgb(255, 255, 255)"] {
    background: var(--darkreader-neutral-background) !important;
}
*[bgcolor="#F5F5F5"],
*[style*="background-color: #F5F5F5"] {
    background: ${#F5F5F5} !important;
}
*[style*="background: #e6e6e6"] {
    background: ${#e6e6e6} !important;
}
body[style*="background: rgb(255, 255, 255) !important"] *:not(a),
.body[style*="background-color: rgb(254, 254, 254) !important"] *:not(a) {
    background-color: var(--darkreader-neutral-background) !important;
}
div[style*="www.gstatic.com/android/"] {
    background: none !important;
}
*[style*="background:#f9f9f9"] {
    background: ${#F9F9F9} !important;
}
body.mediawiki.skin-vector #mw-page-base {
    background-image: none !important;
}
.overflow-hidden .spinning-bg,
.overflow-hidden .solid-bg {
    background: transparent !important;
}
*[style*="color: rgb(0,0,0) !imoprtant"][style*="--darkreader-inline-color"],
*[style*="color: rgb(0, 0, 0) !important"][style*="--darkreader-inline-color"] {
    -webkit-text-fill-color: var(--darkreader-inline-color) !important;
}

IGNORE CSS URL
^https://fonts.googleapis.com/

================================

*.abc.net.au

INVERT
[data-component="ABCNewsLogo"] *

IGNORE INLINE STYLE
[data-component="ABCLogo"] *

================================

*.acesso.gov.pt
*.portaldasfinancas.gov.pt

INVERT
img[src$="/logo-at.png"]
img[src$="/logo-at.svg"]
img[src$="/FatSorte_logo.png"]
img[src$="/at_logo.svg"]
img[src$="/logo-at_small.svg"]
img[src$="/logo_e_balcao_small.png"]
img[src$="/logo_direitos_contribuinte_38.png"]
img[src$="/bullet_ebalcao.png"]
img[src$="/bullet_apm.png"]
.logo-efatura
.logo-sgdt

CSS
html[data-darkreader-scheme="dark"] table#main_Table {
    background-color: black !important;
}
html[data-darkreader-scheme="dark"] table#header {
    position: relative !important;
    z-index: 10 !important;
}
html[data-darkreader-scheme="dark"] table#header::before {
    background-color: #001053 !important;
    bottom: 0 !important;
    content: "" !important;
    left: 50% !important;
    position: absolute !important;
    top: 0 !important;
    transform: translateX(-50%) !important;
    width: 100vw !important;
    z-index: -1 !important;
}
body {
    background-color: transparent !important;
}

================================

*.altronics.com.au

CSS
.picture {
    background-color: rgba(255, 255, 255, 1) !important;
}
#main {
    z-index: auto !important;
}

================================

*.americanexpress.com

INVERT
img[alt*="FDIC-Insured"]

CSS
select[aria-labelledby="bankAccount-label"] > option {
    background-color: var(--darkreader-neutral-background) !important;
}

================================

*.archlinux.org

INVERT
img[src*="icons/"]
img[src="/svg/calendar.svg"]
.cdx-search-input .cdx-text-input__icon.cdx-text-input__start-icon
.cdx-button--icon-only .vector-icon

CSS
.vector-sticky-pinned-container::after {
    background: inherit;
}
body {
    height: fit-content;
}

================================

*.arxiv.org
arxiv.org

INVERT
img.ds-funder-logo

CSS
img.ds-funder-logo {
    background-color: white !important;
}

================================

*.autotask.net

CSS
.bg-background-primary {
    background-color: ${rgb(255 255 255)} !important;
}
.bg-background-hover {
    background-color: ${rgb(207, 217, 226)} !important;
}

================================

*.babbel.com

IGNORE INLINE STYLE
#radix-\:r2\: > svg:nth-child(1) *
#radix-\:r3\: > div > div > div > svg *
#\32 53PcCLJv1hu747b7LM72J > div > div > div > div > div > a > div > svg *
#\35 1RrI7tAWynOXHmNFDQeaT > div > div > div > div > div > a > div > svg *

================================

*.bambulab.com

CSS
.bannerTextWrap .title,
.bannerTextWrap .subtitle {
    text-shadow: ${rgb(225, 212, 201)} 1px 1px 0px !important;
}

================================

*.bancoctt.pt

INVERT
header h1.brand img
footer ul.logos img
img[src^="/Content/Themes/BCTT/logo.png"]
path[d^="M83.897 7.128c6.053"][fill="#000"]
div.header__title a.header__logo-link svg path[fill="#333333"]
a.menu-icon img.h-icon
g#BANCOCTT image

CSS
div#home-locations.map-center3:not([data-darkreader-inline-bgimage]) {
    background-image: url("/application/themes/images/map/centro3.jpg") !important;
}
div.card-container img {
    background-color: white !important;
}

IGNORE INLINE STYLE
div.card-container *
div.header__title a.header__logo-link *
a[href^="https://play.google.com/store/apps/"] svg *

================================

*.ben-anna.de
ben-anna.de

INVERT
a.header__logo--image img
div.certification-list img
div.st_bundle-box.active div.st_input-circle
div.promotion__item-image div.blocks-radius-circle img
img.gP50U

IGNORE INLINE STYLE
div.footer__payment *

================================

*.bitrix24.ru

INVERT
#ws-canvas

================================

*.cnrtl.fr

CSS
.tlf_cdefinition {
    background-color: ${rgb(255, 255, 0)} !important;
}
.tlf_cdomaine {
    background-color: ${rgb(255, 176, 96)} !important;
}
.tlf_csyntagme {
    background-color: ${rgb(192, 255, 192)} !important;
}

================================

*.discogs.com

INVERT
[class*="logo"]

CSS
.swiper-pagination-bullet {
    background: var(--swiper-pagination-bullet-inactive-color, #FFFFFF) !important;
}
.bg-\[linear-gradient\(to_right\,transparent_var\(--fill-stop\)\,\#f2f2f2_var\(--fill-stop\)\)\] {
    background-image: linear-gradient(to right,transparent var(--fill-stop),${#d2d2d2} var(--fill-stop)) !important;
}

================================

*.dnoticias.pt

INVERT
span.nav-menu-btn
span.panel-slide_close

================================

*.docs.kubernetes.io

CSS
.highlight pre code > span[style*="text-decoration: underline"] {
    text-decoration: none !important;
}

================================

*.dreamwidth.org

INVERT
#tagform input[type="image"]

CSS
body {
    background-color: var(--darkreader-neutral-background) !important;
}
.tropo nav,
.tropo footer,
#intro-box-main {
    background-image: none !important;
}
html[data-darkreader-scheme="dark"] .tropo #logo {
    filter: invert(90%) hue-rotate(180deg) !important;
}
html[data-darkreader-scheme="dimmed"] .tropo #logo {
    filter: brightness(85%) !important;
}
.ContextualPopup {
    background: var(--darkreader-neutral-background) !important;
}
[class*='ui-widget'],
.gradient,
.taginfo {
    background-image: none !important;
}
*[style*="color: rgba(0,0,0,"]:not([style*="color: rgba(0,0,0,0)"]),
*[style*="color: rgba(0, 0, 0,"]:not([style*="color: rgba(0, 0, 0, 0)"]),
*[style*="color:#000"],
*[style*="color:black"],
*[style*="color:#282828"],
*[style*="color:#444"],
*[style*="color: #222222"] {
    color: #333 !important;
}
*[style*="background:#fff"],
*[style*="background-color:#fff"],
*[style*="background: #fff"],
*[bgcolor="#F5F5F5"],
*[style*="background-color: #F5F5F5"],
*[style*="background: #e6e6e6"],
*[style*="background:#f9f9f9"] {
    background-color: #eee !important;
}

IGNORE INLINE STYLE
.entry-content *
.comment-content *

IGNORE IMAGE ANALYSIS
*

================================

*.euronews.com

INVERT
label.c-burger-button
div.o-site-hr__sidebar div.c-find-us__list
div.o-site-hr__first-level label.c-language-switcher__btn:after
span.c-article-breadcrumbs__separator::after
div[class^=speakup-theme-] div#progress-container
p.c-footer-search__tag-title img
img.u-cursor-pointer

CSS
div[class^=speakup-theme-] div.speakup-song div#speakup-song-image div#previous {
    background-image: var(--button-prev-bg) !important;
}
div[class^=speakup-theme-] div.speakup-song div#speakup-song-image div#next {
    background-image: var(--button-next-bg) !important;
}
section.speakup-container > div[class^=speakup-theme-] a.speakup-tooltip {
    background-image: var(--button-tooltip-logo) !important;
}
div[class^=speakup-theme-] div.speakup-boxed-player #play-pause.amplitude-paused {
    background-image: var(--button-play-bg) !important;
}
div[class^=speakup-theme-] div.speakup-boxed-player #play-pause.amplitude-playing {
    background-image: var(--button-pause) !important;
}
div[class^=speakup-theme-] div.speakup-boxed-player div.control-container div.time-progress div#prev-10 {
    background-color: transparent !important;
    background-image: var(--button-skip-prev-10) !important;
    filter: invert(100%) hue-rotate(180deg) !important;
}
div[class^=speakup-theme-] div.speakup-boxed-player div.control-container div.time-progress div#next-10 {
    background-color: transparent !important;
    background-image: var(--button-skip-next-10) !important;
    filter: invert(100%) hue-rotate(180deg) !important;
}

================================

*.galaxus.de

INVERT
#logo

CSS
#sidebarMenu div {
    background: var(--darkreader-neutral-background) !important;
}

================================

*.gamer.com.tw

INVERT
.sidenav__icon

CSS
body {
    background-color: transparent !important;
    background-image: none !important;
}
.main-nav__logo {
    background-color: currentColor !important;
}

IGNORE IMAGE ANALYSIS
.service__icon.icon-arrow
.MSG-mainpic
#BH-main_menu
#BH-master h4
.BH-slave_btns .BH-slave_btnA
#BH-slave h5

================================

*.globo.com

INVERT
.header__brand__link[href*=extra]
.header__brand__link[href*=umsoplaneta] path[fill=black]
.header__brand__link[href*=umsoplaneta] path[stroke=black]
.header__brand__link[href*=marieclaire]
.header__brand__link[href*=revistaquem]
.header__brand__link[href*=gq]
#logo-valor_100-anos
.pages-footer img[src$="logo_edg.png"]
.pages-footer img[src$="logo-Conde-Nast.png"]
.pages-footer img[src$="logo_condenast.png"]
.pages-footer img[src$="Rádio_wordmark.png"]
.header__menu__icon_background_color

CSS
.bar-scrubber .bar-scrubber-icon,
.bar-background .bar-fill-2 {
    background-color: var(--darkreader-neutral-text) !important;
}
.bar-background .bar-fill-1 {
    background-color: rgba(255, 255, 255, .3) !important;
}
.multicontent {
    background-color: var(--darkreader-neutral-background) !important;
    color: var(--darkreader-neutral-text) !important;
}
span.bstn-hl-summary {
    color: var(--darkreader-neutral-text) !important;
}
.glb-grid .tabela-body {
    background-color: var(--darkreader-neutral-background) !important;
}
.bstn-hl.with-photo::before {
    background-image: var(--bstn-hl-cover) !important;
}
.footer__logo__wrapper {
    background: var(--darkreader-bg--custom-footer-background) !important;
}

IGNORE INLINE STYLE
.poster__play-wrapper *
#Logo_Valor_Economico_Branco *

IGNORE IMAGE ANALYSIS
.barra-globocom .barra-itens li .barra-item-videos

================================

*.hom.com

INVERT
img.logoimg
img.header-logo__image
img.sub-footer__brands-image
img.sub-footer__certifications-image
img.retina_size[src^="//www.hom.com/cdn/shop/files/HOM_Infinity_Level_Icons"]
img.gP50U
div.R-EmbeddedIcon div.s3-uploaded-icon img
div.cart-drawer__empty-cart svg
button.product-popup-modal__button svg.icon
summary.mobile-toggle span
div.R-RatingStars__stars.u-marginBottom--none i.stars__icon
div.R-RatingStars__stars.u-marginRight--none i[class^="stars__icon stars__icon--"]
div.collapsible__content-care-info img
div.R-SliderIndicator__inner
collapsible-row.product__accordion summary span
div.product-information--line-item--image-richtext img
button.accelerated-checkout-button.light.logo-only svg path[style="fill:#000"]
.accordion summary span

CSS
div.sub-footer,
div.shopify-section-group-footer-group div.row.full-width-row-full,
div.image-with-text__content,
div.email-signup {
    background-color: var(--darkreader-neutral-background) !important;
}
div.image-with-text-overlay--bg::after {
    background-color: rgba(var(--color-overlay-rgb),var(--overlay-opacity)) !important;
}
div.header__bg__overlay {
    background-image: none !important;
}
div.gallery--item figure::after,
div.revealed-media--media::after,
div.email-signup--image:after {
    background: rgba(var(--overlay-color-rgb),var(--overlay-opacity)) !important;
}
div.R-ReviewsList-container .item__inner {
    background: transparent !important;
}
div.ruk_rating_snippet * {
    color: var(--darkreader-neutral-text) !important;
}

IGNORE INLINE STYLE
div.sub-footer__socials *
div.footer-payment-icons *
div.cart-drawer__empty-cart *
div.payment-icons *

================================

*.hypothes.is

INVERT
a[href="https://hypothes.is"] > svg[aria-labelledby="logo-title"] > g > path[fill-rule="nonzero"]
img[class="fusion-standard-logo"]
.pdfViewer .canvasWrapper

CSS
.pdfViewer .textLayer {
    opacity: 1 !important;
}
.pdfViewer .hypothesis-highlight {
    background-color: var(--darkreader-bg--highlight-color) !important;
}
.pdfViewer .hypothesis-shape-highlight {
    border-color: rgba(128,128,128,0.3) !important;
    outline: none !important;
}
.toolbarButton::before,
.secondaryToolbarButton::before,
.dropdownToolbarButton::after,
.treeItemToggler::before {
    background-color: var(--toolbar-icon-bg-color) !important;
}

================================

*.iefp.pt

INVERT
img[src^="/image/company_logo"]
img[src$="/museu_virtual.png"]
img[src*="/Lado_Lado.png"]
img[src$="/iefponline_logo.png"]
footer div.container img
div.map-portlet div.area
div.map-portlet div.area > *
canvas.ol-unselectable

CSS
div.map-portlet div.area {
    background-image: url(/Map-portlet/img/fake-mapa_ol.jpg) !important;
}
body {
    background-color: transparent !important;
}

IGNORE IMAGE ANALYSIS
.divImgAmbiente
.logoIEFP
.logoCRC
#bg12653424
.sobre-iefp-img
.links-hero-img
.menu_left_item_image.survey

================================

*.iherb.com

INVERT
img:is([alt$="icon"], [class$="icon"]):not(.extra-info-icon, .info-icon)
div[class$="icon"] > img
:is(a, div).header-link img
a.carousel-control:not([href="#carousel-plp-module-specials"]) > span > i::before
div.live-container use.tooltip-icon
svg.product-ai-wellness-guide__icon
button.arrow:is(.left, .right) svg
div[data-qa-element^="rewards-landing-faq-item-collapse"]::before
div[data-qa-element^="rewards-landing-faq-item-collapse"]::after
div.policy-accordion-item img
div.cms-accordion-switch-btn
div.myaccount-container div[data-an-element="base-info"] > div:first-of-type svg
div.house-brand-content-container div.section-2-img img:not([alt$="icon"])
div#hamburger-menu-base img
a[class$="SocialIcons"] img
img[src$="/iHerb_Vitacost.png"]
div.swiper-button-prev.transaction-filter-prev-btn svg
div.swiper-button-next.transaction-filter-next-btn svg
button.lt-menu-toggle
img[src$="/blog-content-type/video.png"]
img.extra-info-icon
img.info-icon
#cartv2 svg[data-qa-element="empty-cart-icon"] path
div.content-description-images img

CSS
a[href$="/flash-deals"] h4,
div.personalized-reorder h3.flash-deals-title,
div.personalized-reorder p.flash-deals-subtitle,
div.personalized-reorder span.view-all-label,
div.app-landing-header-lg-title,
div.app-landing-header-lg-description,
div:is(.cms-banner-container, .banner-tool-carousel, #catalog-application) div.custom-flex-box-item,
div:is(.cms-banner-container, .banner-tool-carousel, #catalog-application) div.custom-flex-box-item *:not(.custom-button, .cms-digit, .cms-bubble-text),
div.live-container span.live-title bdi,
div.content-left,
div.content-left span,
div.shipping-textbox-subheader,
div.shipping-textbox-disclaimer,
a.menu-link.menu-pill-wrapper span,
div[data-qa-element="SubscribeListContainer"] > div > div > div > div > h4,
div.slider-container a > div:nth-of-type(2),
div.container-fluid div.mobile-title,
div[class$="ProductsCarouselContentCard"]
  > div[class$="ProductsCarouselContentCard"],
div[data-qa-element="SubscribeListMobileContainer"]
  > div:first-of-type > div > div > div:first-of-type > h2 > div,
div.professional-brands-intro div.brands-header:not(:has(> div > div > img)) *,
section.content-wrapper.brandsintro *:not(div.sports-page-extra-container *),
div.entrance-title-wrapper *,
div[data-qa-element="new-rec-carousel"] div :is(strong, svg),
div.slider-container div[class$="BundleCarousel"] div + div *:not(button):not(button *) {
    color: black !important;
}
div.logo-grid a,
div.featured-brands-image-container,
div.top-affiliate-network-grid img,
img.payment-sprite,
a.menu-link.menu-pill-wrapper,
div.brand-logo-wrapper,
div[class$="BrandsCarousel"] a[class$="BrandItem"] img,
section[class$="Shipping"] img,
div.slider-container div[class$="TrendingBrandsCarousel"] a > div,
div[class$="SectionContainer"] + div > a,
a[href^="/pressreleases/"] img {
    background-color: #f7f8f7 !important;
}
img {
    mix-blend-mode: normal !important;
}
div.self-service-item svg path,
div.ugc-pdp-question-and-answer-desktop-box svg path {
    fill: var(--darkreader-neutral-text) !important;
}
div.shipping-textbox-header,
div[data-qa-element="SubscribeListContainer"] div:has(+ h4),
div[data-qa-element="SubscribeListContainer"] h4 strong,
div[data-qa-element="SubscribeListMobileContainer"]
  > div:first-of-type > div > div > div:first-of-type * {
    color: #2c7500 ! important;
}
div.brand-logo-circle {
    background-color: var(--cb-item-bg-color) !important;
}
div.house-brand-content-container div:is(.section-1, .section-2) {
    background-image: none !important;
}
div:has(> div.quality-description) {
    background-color: var(--darkreader-background-ffffff) !important;
    padding: 20px;
    position: relative;
    z-index: 2;
}
div:has(> div > div.section-2-mobile-img) {
    background-color: var(--darkreader-background-ffffff) !important;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    padding: 20px;
    position: relative;
    width: 100vw;
    z-index: 2;
}
div.quality-icons,
div.section-1-mobile-content {
    background-color: var(--darkreader-background-ffffff) !important;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    width: 100vw;
}
div.buynow-modal-content {
    background-color: var(--darkreader-background-ffffff) !important;
}
div.hp-banners-v2.using-banner-tool {
    background-color: var(--darkreader-inline-bgcolor) !important;
}
div.cms-banner-container div.custom-flex-box-item span.custom-button {
    color: var(--darkreader-neutral-text) !important;
}

IGNORE INLINE STYLE
div[class^="scan-qr-login_qrCode"] svg *
div.shipping-textbox-subheader span
div.sc-social-media-list *
:is(section, div).footer-banner-container *
#cartv2 svg[data-qa-element="empty-cart-icon"] *

IGNORE IMAGE ANALYSIS
*

================================

*.indeed.com

INVERT
#indeed-globalnav-logo

CSS
.jobsearch-Layout--gradientBg {
    background-image: none !important;
}

================================

*.instructure.com

CSS
.css-vrgbjj-textArea {
    background: var(--darkreader-neutral-background) !important;
    color: var(--darkreader-neutral-text) !important;
}
.css-4y58qe-textArea {
    background: var(--darkreader-neutral-background) !important;
}

================================

*.jornaldenegocios.pt

INVERT
:is(header.header, div#mainMenu, div.headerBar) button span
div.navbar-main-nav a.toggleMenuButton
div.header_top a.logo
nav.header_canais div.canais::before
nav.header_canais div.canais::after
img[src^="/i/"]
button.closeBtn span
footer a.logo_footer
footer a.reclamacoes_logo

IGNORE IMAGE ANALYSIS
.header:not(li) .header_top .logo
.scrollingPage .header:not(li) .header_top .logo
.footer .links .logo_footer
.simplificado .links .icons_footer li .reclamacoes_logo
.simplificado #ic_notificacoes .icon

================================

*.ldlc.com
*.ldlc.pro

INVERT
header .burger-menu span.icon-burger
.landing section div.container .picto
.config-contentLeft img
.eco-contentLeft img
.promo-contentLeft img
.landing #page img:is(.opacity-half, .reveal.gif, .opacity-40)

CSS
section.home-universe .bloc-universe {
    background-color: initial !important;
}
.img-transparent img,
.main.landing section.tag div.container .listing-product ul li .pic {
    mix-blend-mode: normal !important;
}
.main .category-content p {
    color: black !important;
}

IGNORE IMAGE ANALYSIS
.main .category-content:nth-of-type(1)
.main .category-content:nth-of-type(2)
.main .category-content:nth-of-type(3)
.main .category-content:nth-of-type(4)
.main .category-content:nth-of-type(5)
.main .category-content:nth-of-type(6)

================================

*.maricopa.edu

CSS
#background-content {
    background: var(--darkreader-neutral-background) !important;
}

================================

*.msi.com
funtoro.com

INVERT
img[src$="/logo.png"]
img[src$="-logo.png"]
img[src$="logo.svg"]
img[src$="/logo-msi.png"]
article#MSI_Support section.main-support div.card-content span.icon-style
article#MSI_Support section.main-contact-support span.icon-style
article#MSI_Support.Page_faq span.item-icon img
article#MSI_Support img#faq_icon-image
li[data-id="#lt-twitter"] svg
img[src$="/HDMILogo_note.png"]
div#msi-microsite-eps div.epsWhereToBuy__cardList img
div#msi-microsite-eps div.epsPartners a img
section.topheader a.topheader__toplogo img.logo__img
main#Copilot-plus-PC-For-Commercial div.header-copilot-plus img
main#Copilot-plus-PC-For-Commercial div.header-business-ready
main#Windows-11-Pro div.header-windows11 img
main#Windows-11-Pro div.header-what-s-your
img[src$="/norton-icon.png"]
article.support section.supportCard div.supportCard-icon img

CSS
html[data-darkreader-scheme="dark"] main#news_list figure.template__card__img img.card__img,
html[data-darkreader-scheme="dark"] article#newslist div.tab-content#Exhibitions img {
    background-color: white !important;
}
article#solutions section.industry :is(
    .industry__kvTxtBox-title,
    .industry__kvTxtBox-content,
    .industry__kvTxtBox-list
),
div#msi-microsite-amr h1.baseBannerTitle,
div.page:is(#ODMService, #Product_index) section.index-s4 div.txt-center *,
div#msi-app section.businessSupportTitle div.baseBanner h1.baseBannerTitle,
div#MSI-Center section#kv.block :is(h2, p),
article#contact-us figure.kv-banner div.kv-text :is(h1, p),
main.about header#msi-key-visual.kv div.kv__content h1 {
    color: black !important;
}

================================

*.my.salesforce-setup.com

CSS
body .rich-tabhdr-cell-active > table[id$="shifted"] td.rich-tabhdr-side-cell,
body .rich-tabhdr-cell-inactive > table[id$="shifted"] td.rich-tabhdr-side-cell,
body .rich-tabhdr-cell-active > table[id$="shifted"] td.rich-tabhdr-side-cell td.rich-tab-active,
body .rich-tabhdr-cell-inactive > table[id$="shifted"] td.rich-tabhdr-side-cell td.rich-tab-inactive {
    background-image: none !important;
}
body .rich-tabhdr-cell-inactive > table[id$="shifted"] td.rich-tabhdr-side-cell {
    background-color: color-mix(in srgb, var(--darkreader-neutral-background) 90%, gray) !important;
    border: 1px solid var(--darkreader-neutral-text) !important;
    border-bottom: none !important;
}
body .rich-tabhdr-cell-active > table[id$="shifted"] td.rich-tabhdr-side-cell {
    background-color: color-mix(in srgb, var(--darkreader-neutral-background) 80%, white) !important;
    border: 1px solid var(--darkreader-neutral-text) !important;
    border-bottom: none !important;
}
body .rich-tab-header {
    color: var(--darkreader-neutral-text) !important;
}

================================

*.myconnectwise.net

CSS
.cwsvg {
    fill: var(--darkreader-neutral-text) !important;
}

================================

*.myworkday.com

INVERT
.WIF3
.WIF3:hover
.WIG3
.WIG3:hover
.WFD3 .WGL3
.WAJS
.WAJS:hover
.WJG3
.WHL3
.WKFP

================================

*.naturitas.*

INVERT
div.footer__bottom div:is(.bcorp, .seals-trusted) img
div.shipping-method span.image img
svg.icon.ico-customer-checked

CSS
div.footer__bottom div.payment-methods img,
div[class^="footer_footerPayments"] svg,
li.checkout-conditions-summary__payment-logo {
    background-color: white !important;
}
div[class^="footer_footerPayments"] svg path[fill="currentColor"] {
    fill: black !important;
}

IGNORE INLINE STYLE
ul[class^="footer_footerColumnList"] *
div[class^="footer_footerPayments"] svg path

================================

*.palletsprojects.com

CSS
span.w {
    color: var(--darkreader-neutral-background) !important;
}

================================

*.rtp.pt

INVERT
img[src$="/rtppalco-dark_2026.svg"]
.navbar-toggler-icon
.uninav-menu-toggle-line
.uninav-menu-toggle::before
.uninav-menu-toggle::after
.uninav-search.is-open .uninav-search-toggle::before
.uninav-search.is-open .uninav-search-toggle::after
.epg-channel-inner-header::before
.epg-channel-inner-header::after
.navbar-container .navbar-brand:has(> .ensina-logo)
.footer-menu .left-section:has(> a[href="https://ensina.rtp.pt/"])
.worldnav-menu-toggle-line
.worldnav-menu-toggle::before
.worldnav-menu-toggle::after

CSS
#nav-icon3 span {
    background-color: #ffffff !important;
}

================================

*.sapo.pt
forum.pplware.com
sapo.pt
viagenseresorts.pt

INVERT
div.bsu-v4-sub-menu-splitter
:is(div, h1).logo img[alt^="SAPO"]
body:not(.home) header div.logo a[aria-label^="AutoSAPO"]
footer div.logo a[aria-label^="AutoSAPO"]
img[src$="/logo_vendaja_black.png"]
img.img-logo[src^="https://avozdecastelobranco.sapo.pt"]
body.wp-theme-zox-news div.mvp-fly-but-wrap span
body.wp-theme-zox-news div.mvp-search-but-wrap span
img[src$="/econtas-logo.png"]
img[src$="/ED_LOGO-900x183.png"]
img[src$="/ED_LOGO.png"]
img[src$="/2016-logo-risco-cor.png"]
img[src$="/AutoM-cor-1-no-bg.png"]
img[src$="/E-goi-logo.png"]
img[src$="/E-goi-logo-150x150.png"]
img[src$="/Beira-Alta-TV-2023-preto.png"]
img.tie-logo-img[src^="https://diariodistrito.sapo.pt"]
img[src$="/forever-young-logo-1.png"]
img.logo[alt="Green eFact"]
div.logo img[src^="https://estrelaseouricos.sapo.pt"]
img[src$="/viagens_preto-1920x664.png"]
span[class$="-accordion-chevron"]
span[class$="-accordion-icon"]
div.toggle-header-search span
a#mobile-menu-icon span.tie-mobile-menu-icon

CSS
svg#sapoLogo path:is([d^="M34.56"], [d^="M63.99"]),
li.logo svg path:is([d^="M33.96"], [d^="M63.39"]) {
    fill: #000000 !important;
}
html[data-darkreader-scheme="dark"] div#bsu-footer.bsu-footer-light a.bsu-footer-logo {
    background-position: 0 -60px !important;
}
html[data-theme="dark"][data-darkreader-scheme="dark"] div#bsu-footer div.bsu-footer-text {
    filter: none !important;
}

IGNORE IMAGE ANALYSIS
.wrapper.ink-grid
.barrita .extras .info

================================

*.seg-social.pt

INVERT
img[src^="/ptss/ii-pssd-library/assets/logos/"]
img[src^="/ptss/ii-uxds-theme-primevue-ssng/assets/pictograms/"]
img[src^="../ii-uxds-theme-primevue-ssng/assets/pictograms/"]
img[src^="../ii-uxds-theme-primevue-ssng/assets/images/"]
img[src^="/sso/images/Logo"]
img[src="/sso/images/logo.svg"]
img[src="/sso/images/pic_Question.svg"]
img[src^="https://www.seg-social.pt/ptss/ii-pssd-footer/"]
img[src^="/ptss/javax.faces.resource/ci/images/canaisDePagamento/"]
img.stats-img
footer img[src^="assets/img/"]
section#section-logo svg
svg.img-logo

================================

*.seoul.go.kr

INVERT
.h-logo
.s-live-icon

================================

*.service-now.com

INVERT
.highcharts-legend-item text
.palette-content.trees .tree_spacer
.palette-content.trees img.tree
.palette-content.trees img.wf-list-icon

CSS
.cm-s-snc span.cm-string {
    color: #cf947b !important;
}
.cm-s-snc span.cm-def {
    color: #60a4d8 !important;
}
.cm-s-snc span.cm-property {
    color: white !important;
}
.cm-s-snc_readonly span.cm-string {
    color: #cf947b !important;
}
#hierarchy-menu {
    background-color: #797774 !important;
}
.sn-ng-bsm svg {
    fill: #FFF !important;
}
.ui-refresh .btn-inline-form,
.ui-refresh .btn-inline-form-attached {
    background-color: #797774;
}
.node-outline {
    fill: #797774 !important;
}
.sn-polaris-nav {
    background-color: #000 !important;
    color: #FFF !important;
}
.snf-collapsible-list-header {
    background-color: #000 !important;
    color: #FFF !important;
}
.sn-polaris-nav-list-items a.item-label .item-icon {
    background-color: #000 !important;
    color: #FFF !important;
}
.snf-collapsible-list-items,
.snf-collapsible-list-items a {
    background-color: #000 !important;
    color: #FFF !important;
}
.sn-history-menu .menu-item > .menu-item-label > span.label {
    background-color: #000 !important;
    color: #FFF !important;
}
.sn-history-menu .menu-item > .menu-item-label > span.menu-item-description {
    background-color: #000 !important;
    color: #FFF !important;
}
div >  .sn-history-menu mark.filter-match,
.sn-history-menu mark.filter-match-fuzzy {
    color: #FFF !important;
}
div >  .sn-history-menu .is-filtered .label {
    color: #FFF !important;
}
span.is-filtered .label {
    color: #FFF !important;
}
.is-filtered .item-icon .label {
    color: #FFF !important;
}
span > mark.filter-match,
mark.filter-match-fuzzy {
    color: #FFF !important;
}
.tox .tox-tbtn svg {
    fill: #FFF !important;
}
.user-menu-label {
    color: #FFF !important;
}
.sn-polaris-tab.is-active {
    background-color: #000;
    color: #fff !important;
}
.grid-container svg path {
    fill: #000 !important;
}

================================

*.sloggi.com
*.triumph.com

INVERT
div.header__logo a.header__logo--triumph svg.svgIcon__brandlogo path
div.footer__logos svg
div.brand-switcher svg.svgIcon__triumph
div.sustainability__logo img
div.pd__body--7 div.pd__image img
div.footer__bottom ul.stay-tuned svg
div.brands__text img
button.navbar-toggler
div.header__icon svg.svgIcon.svgIcon__menuClose

CSS
div.footer__logos svg {
    color: var(--color-black) !important;
}
div.productTile div.colorDotSwatch--plp {
    background: var(--swatch-color) !important;
}
.experience-component > * {
    color: var(--darkreader-neutral-text) !important;
}
div.colorDotSwatch img {
    mix-blend-mode: normal !important;
}

IGNORE INLINE STYLE
div.footer__logos svg *
div.brand-switcher svg.svgIcon__triumph *
div.footer__bottom ul.stay-tuned svg *
div.header__icon svg.svgIcon.svgIcon__menuClose *

================================

*.speedtestcustom.com

CSS
.stroke-primary {
    stroke: #003b5c !important;
}
.result-graph-svg {
    fill: #003b5c !important;
}

================================

*.tommy.com

INVERT
img[class*="Footer_SocialIcon"]

================================

*.tomshardware.com

INVERT
img[src$="/toms-hardware-logo.png"]
img[src$="/brand_logo.svg"]
img.widget-commercial-logo.src-logo
img.th-premium-join-logo
img[x-show="!isUserPremium"]
img[src$="/TH_logo.svg"]

IGNORE INLINE STYLE
div[data-testid="buttons-social"] *
nav.button-social-group.person__social-buttons *

================================

*.visualcapitalist.com

INVERT
div.mvp-fly-but-wrap span
div.mvp-search-but-wrap span
img[src$="/DecarbChannel_LogoHeader_Mar8.png"]
div#mvp-fly-menu-wrap img:is([src^="/wp-content/uploads/2021/03/Hamburger-Menu"], [src$="/DC-logo-flyout.png"])
div.eltd-vertical-menu-area-inner div.eltd-logo-wrapper img

================================

*.webex.com

CSS
body {
    background: var(--darkreader-neutral-background) !important;
}
.wxp-chapter-bar-item-progress {
    background: var(--mds-color-decorative-violet-50) !important;
}

================================

01net.com

CSS
html,
body {
    color: ${#090702} !important;
}

================================

1001fonts.com

INVERT
picture.txt-preview

================================

10fastfingers.com

CSS
#speedtest-main .hide-time {
    color: transparent !important;
}
#inputfield {
    background: var(--darkreader-neutral-background) !important;
    color: var(--darkreader-neutral-text) !important;
}
body,
.container-modified > .row,
#practice-main,
#top1000-index-container,
#text-practice,
#content-bg {
    background: var(--darkreader-neutral-background) !important;
}
#main-content-trenner {
    background: var(--darkreader-neutral-background) !important;
    border-bottom: 1px solid rgb(151, 141, 127) !important;
}

================================

10minutemail.com

CSS
#main_content {
    background-image: none !important;
}

================================

123-3d.nl
123accu.nl
123inkt.nl
123led.nl
123schoon.nl

CSS
.main-panel-left,
.main-panel-right {
    background: var(--darkreader-neutral-background) !important;
}

================================

123mathe.de

INVERT
.entry-content img

CSS
body,
.post-inner,
ul.sub-menu {
    background-color: var(--darkreader-neutral-background) !important;
}
ul.sub-menu::after {
    border-bottom-color: var(--darkreader-neutral-background) !important;
}
.progress-wrap {
    box-shadow: var(--darkreader-neutral-background) 0px 0px 0px 3px inset !important;
}

================================

1337x.st
1337x.to
x1337x.eu
x1337x.se
x1337x.ws

CSS
.torrent-tabs .tab-nav {
    background-color: var(--darkreader-neutral-background) !important;
    background-image: none !important;
    border-bottom-color: var(--darkreader-neutral-background) !important;
}

================================

1917.com

CSS
body {
    background-color: var(--darkreader-neutral-background) !important;
    background-image: none !important;
}

================================

1fichier.com

CSS
body {
    background-image: none !important;
}

================================

1password.community

INVERT
div[class*="NodeBannerWidget_lia-container-bg"]
img[alt="Brand Logo"]

CSS
div[data-testid="HtmlCustomComponentContent"] * {
    color: var(--darkreader-neutral-text) !important;
}

================================

2700chess.com

IGNORE IMAGE ANALYSIS
.cg-wrap piece.rook.black
.cg-wrap piece.knight.black
.cg-wrap piece.bishop.black
.cg-wrap piece.queen.black
.cg-wrap piece.king.black
.cg-wrap piece.knight.black
.cg-wrap piece.pawn.black

================================

2gis.*

INVERT
#map
path[d^="M34.8"]
._oow7vi
path[d^="M15.759"]

CSS
a,
abbr,
acronym,
address,
applet,
article,
aside,
audio,
b,
big,
blockquote,
body,
canvas,
caption,
center,
cite,
code,
dd,
del,
details,
dfn,
div,
dl,
dt,
em,
embed,
fieldset,
figcaption,
figure,
footer,
form,
h1,
h2,
h3,
h4,
h5,
h6,
header,
hgroup,
html,
i,
iframe,
img,
ins,
kbd,
label,
legend,
li,
main,
mark,
menu,
nav,
object,
ol,
output,
p,
pre,
q,
ruby,
s,
samp,
section,
small,
span,
strike,
strong,
sub,
summary,
sup,
table,
tbody,
td,
tfoot,
th,
thead,
time,
tr,
tt,
u,
ul,
var,
video {
    color: var(--darkreader-neutral-text) !important;
}
div[style^="--bg-color"] {
    --bg-color: var(--darkreader-neutral-background) !important;
}
div[style="transform:rotateX(0deg)"] > svg[width="38"] path {
    fill: ${black} !important;
}
button[data-hamburger] span {
    background-color: ${black} !important;
}

IGNORE INLINE STYLE
a[href="/"] > svg *

================================

3.basecamp.com

CSS
body,
.nav__main {
    background-color: ${white};
}
@media screen and (min-width: 768px) {
    .panel--perma,
    .panel--project {
        box-shadow: rgba(0, 0, 0, 0.05) 0px -1px 10px, rgba(0, 0, 0, 0.1) 0px 1px 4px, rgb(24, 26, 27) 0px 10px 30px;
    }
}

================================

300gospodarka.pl
300polityka.pl

INVERT
#logo
img[alt="300Gospodarka"]
img[alt="Zespół 300Gospodarki"]

================================

338canada.com

CSS
svg text:not([fill]) {
    fill: var(--darkreader-neutral-text);
}

================================

350.org
map.350.org

INVERT
.dark\:bg-gray-700
.dark\:bg-gray-700::after
.dark\:text-gray-300
.mapboxgl-canvas
.mapboxgl-ctrl-compass > .mapboxgl-ctrl-icon
.mapboxgl-ctrl-logo
.mapboxgl-marker

CSS
mapbox-search-box > input {
    --darkreader-bg--boxShadow: 0 0 10px 2px ${rgba(0, 0, 0, 0.05)}, 0 0 6px 1px ${rgba(0, 0, 0, 0.1)}, 0 0 0 1px ${rgba(0, 0, 0, 0.1)} !important;
}

================================

37.com

INVERT
.logo37

================================

3dmark.com

INVERT
.logo
.similar-results > g > rect

================================

40ton.net

INVERT
.td-main-logo

================================

4t-niagara.com

CSS
.download_link > h3,
.buy_link > h3 {
    color: ${#88c1ff} !important;
}
.download_link li,
.buy_link li {
    color: ${white} !important;
}

================================

9game.cn

INVERT
.logo9game

================================

a11ywithlindsey.com

INVERT
.logo

CSS
:root {
    --off-white: var(--darkreader-neutral-background) !important;
}

================================

aad.org

INVERT
.header-AAD-logo

================================

aaha.org

CSS
.wrap1 {
    background-color: var(--darkreader-neutral-background) !important;
}

================================

abanderado.com
abanderado.es

INVERT
summary.mobile-toggle
img.logoimg:not(.logoimg--light)
img.compliance_img
img.h-10.object-contain
div.side-panel-content svg path
div.shopify-section-group-footer-group div.multicolumn__image--inner img

CSS
html[data-darkreader-scheme="dark"] a.thb-secondary-area-item svg path {
    fill: var(--darkreader-neutral-text) !important;
}
div.gallery--item figure:after,
div.collection-card--image:after,
div.image-with-text-overlay--bg:after {
    background: rgba(var(--overlay-color-rgb),var(--overlay-opacity)) !important;
}
div.image-with-text--content {
    background: var(--darkreader-bg--color-bg, var(--darkreader-background-ffffff)) !important;
}
.variations .product-form__input--siblings label:after {
    background-color: var(--option-color) !important;
}
.filter-blanco {
    background-color: var(--swatch-color-blanco) !important;
}

IGNORE INLINE STYLE
a.thb-secondary-area-item svg path
div.side-panel-content svg path
div.footer-payment-icons *
#footer.footer *

================================

abandonia.com

CSS
.alt1G2 {
    background-image: none !important;
}
.alt2G2 {
    background-image: none !important;
}

================================

abc11.com

CSS
.kQjLe {
    background: var(--darkreader-neutral-background) !important;
}

================================

abc7ny.com

CSS
.FITT_Article_main,
#FITTArticle {
    background: var(--darkreader-neutral-background) !important;
}

================================

abcnews.go.com

INVERT
.navLogo
#sections
#search
#notifications

================================

abiturma.de

INVERT
div.formula
amp-img.latex-inline
img[src^="/assets/compiled-latex/"]

================================

ableton.com

INVERT
.main-nav__logo
.main-footer__basics__logo
.main-footer__secondary__signature__logo

CSS
.body-text--manual figure img {
    background-color: #DCDAD8 !important;
}

================================

about.flipboard.com

INVERT
img.site-header__logo--full

================================

about.gitlab.com

INVERT
div.customer-logos__companies a

CSS
.progressbar {
    background: black;
}

================================

academic.oup.com

INVERT
img.oup-header-image[alt="Oxford Academic"]
img.journal-footer-logo[alt="Oxford University Press"]
img.society-logo[alt="American Medical Informatics Association"]
img.society-logo[alt="GigaScience Press"]
img.society-logo[alt="International Biometric Society"]
img.society-logo[alt="Japan Society for Occupational Health"]
img.society-logo[alt="Oxford"]
img.society-logo[src$="_h1-965359043.svg"][alt$="Royal Statistical Society"]
img.journal-logo[alt="Biometrics"]
img.journal-logo[alt="Biometrika"]
img.journal-logo[alt="GigaScience"]
img.journal-logo[alt="Journal of Occupational Health"]
img.journal-logo[alt="Journal of Petrology"]
img.journal-logo[alt^="Journal of the American Medical Informatics Association"]
img.journal-logo[alt^="Journal of the Royal Statistical Society"]
img.journal-logo[alt="Oxford Academic Journals"]
img.journal-logo[alt="Significance"]
img.journal-logo[alt="Transactions of Mathematics and Its Applications"]
img.journal-footer-affiliations-logo[alt="Biometrics"]
img.journal-footer-affiliations-logo[alt="Biometrika"]
img.journal-footer-affiliations-logo[alt="GigaScience"]
img.journal-footer-affiliations-logo[alt="Journal of Occupational Health"]
img.journal-footer-affiliations-logo[alt="Journal of Petrology"]
img.journal-footer-affiliations-logo[alt^="Journal of the American Medical Informatics Association"]
img.journal-footer-affiliations-logo[alt^="Journal of the Royal Statistical Society Series D"]
a.society-links-logo > img
ul.listOfImagesWithLabels div.imageContainer img
div.informationRowHead img.informationLogo
div.siteMainName img[alt="Oxford University Press"]
img.chat-input-logo[alt="Oxford University Press"]
svg.information-svg-icon path.inner-shape

================================

academy.abeka.com

INVERT
.logo img
.center-align img

================================

academy.dqlab.id

INVERT
.menu img

================================

access.ing.de

CSS
.tile__info {
    background-color: #fff !important;
}

================================

access.the-scientist.com

INVERT
div.logo-container svg

================================

access.wgu.edu
my.wgu.edu

INVERT
img[alt="WGU Logo"]
.nav-hamburger

================================

accessiblepalette.com

INVERT
.swatch .hex

IGNORE INLINE STYLE
.swatch

================================

accesswire.com

INVERT
.v2-nav-logo

================================

account.live.com

INVERT
.ms-Grid-col.ms-sm8.ms-lg4
.ms-Grid-col.ms-sm4.ms-hiddenMdDown.pullout-textwrap
.ms-Grid-col.ms-sm2 img
.pullout-link-text
.pullout-icon:not(.ms-Icon--SkypeCircleCheck)
.pullout-textwrap span

CSS
img[class="ShowMoreLoading"] {
    filter: invert(93.7%) hue-rotate(180deg) contrast(90.6%) !important;
}

================================

account.microsoft.com/profile

INVERT
.ms-StackItem div div img[src*="svg?n"]

================================

account.orchid.com

INVERT
.walletconnect-qrcode__image

================================

account.proton.me
account.protonvpn.com

CSS
.qr-code {
    border: 5px solid white !important;
}

IGNORE INLINE STYLE
.logo *
.qr-code *

================================

account.ui.com

CSS
div[class^="Toggle-module_switcher"] {
    background-color: var(--darkreader-neutral-text) !important;
}
input[class^="Toggle-module_input"] {
    background-color: initial;
}
div[class^="Modal-module_content"] form > div > canvas {
    border: 5px solid white !important;
}

================================

account.xiaomi.com

CSS
.mi-profile-layout__profile {
    background-image: none !important;
}

================================

accounts.fedoraproject.org

INVERT
.navbar-brand

================================

accounts.google.com

INVERT
img[src$="signin_tapyes.gif"]

CSS
#countryList div[role="option"][data-value] > div > div > div[style] {
    background-image: url('//ssl.gstatic.com/i18n/flags/48x32/nobevel/66bdb7a1bbbdbf86a67de382fac49ecc/flags.png') !important;
}

================================

accounts.hetzner.com
dns.hetzner.com
konsoleh.hetzner.com
robot.hetzner.com

INVERT
.top-bar-link > img
.d-flex > img
#panel_dropdown_btn > img
#user_dropdown_btn > img

================================

accounts.spotify.com

INVERT
.spotify-logo

================================

accounts.zoho.com

INVERT
div#product_img.tfa_totp_mode
span.zoho_logo
.zwHDots

================================

accuweather.com

INVERT
.allergy-icon
.icon-search
img[src$="arrow-right-black.svg"]

CSS
.today-label,
.y-axis-label,
.x-axis-day-label,
.x-axis-month-label {
    fill: var(--darkreader-neutral-text) !important;
}

================================

acer.com

INVERT
.firstHeader .logos

CSS
.contSectionBen img {
    filter: brightness(50%) sepia(40%) !important;
}
.contSectionBen .textOverBen {
    position: inherit !important;
}

================================

acmicpc.net

INVERT
.cm-s-lucario.CodeMirror

================================

aconvert.com

CSS
.css-checkbox input + span::after {
    color: transparent !important;
}

================================

acorn.utoronto.ca

CSS
.acorn-classic.page-container .academic-history .sessionHeader,
.acorn-classic.page-container .academic-history .credit-earned-section,
.acorn-classic.page-container .academic-history .average-section,
.acorn-classic.page-container .academic-history .courses,
.acorn-classic.page-container .academic-history .coursesHeader,
.acorn-classic.page-container .academic-history .academic-history-report .gpa-listing,
.acorn-classic.page-container .academic-history-recent table .emph {
    color: var(--darkreader-neutral-text) !important;
}

================================

act.dsausa.org

INVERT
.dsa-sibd-logo
.text--centered > .pure-img

CSS
.ak-page-header {
    background-color: #ec1f27 !important;
}

================================

action.com

CSS
.bg-black {
    background-color: transparent !important;
}

================================

actioncardapp.com

INVERT
.logo

================================

activa.pt
caras.pt
holofote.pt
visao.pt

INVERT
button.navbar-toggler
a.brand img:is([alt="Activa"], [src$="/visao-sete-4.png"], [src$="logo-sete-x83.png"])

================================

ad.nl

CSS
.instanews-page-main-content {
    color: var(--darkreader-neutral-text) !important;
}

================================

ada.org

INVERT
.logo

================================

adata.com

INVERT
.logo-nav

================================

addic7ed.com

INVERT
.tablecorner img

CSS
.NewsTitle {
    background-color: rgb(0, 62, 81);
}
.language {
    background-color: rgba(7, 73, 89);
}

================================

addons.mozilla.org

INVERT
div[class="Rating Rating--small"]
img.SecondaryHero-module-icon

IGNORE IMAGE ANALYSIS
.Icon-youtube
span.Permission-description::before

================================

adguard-dns.io

INVERT
.animation__video
.footer__logo
.header__logo
.map__point-icon
.map__point-city
.servers-info__queries

CSS
.animation__video {
    z-index: 0 !important;
}
.map__point-city,
.servers-info__map {
    filter: invert(1) hue-rotate(120deg) brightness(250%) !important;
}

================================

adguard-vpn.com

INVERT
.header__logo

================================

adguard.com

INVERT
a.header__logo
svg.reviews__icon-topic
.article__section--list-ico .md__list .md__img
.article__content--title-ico .article__section .md__title .md__img
.p-header-logo.p-header-logo--image img
.icon--gray-chrome
.icon--gray-edge
.icon--gray-opera
.icon--gray-firefox

IGNORE IMAGE ANALYSIS
.icon--gray-opera
.icon--gray-firefox

================================

admin.google.com

INVERT
.qV6brd img

================================

admin.migadu.com

CSS
.container {
    background-image: none !important;
}

================================

admin.shopify.com

CSS
.variant-auto {
    background-color: var(--darkreader-neutral-background) !important;
}
.variant-secondary {
    background-color: var(--darkreader-neutral-background) !important;
}
.level-1 {
    background-color: var(--darkreader-neutral-background) !important;
}
.banner {
    background-color: var(--darkreader-neutral-background) !important;
}

================================

aeroin.net

INVERT
img.tdb-logo-img

================================

afterpay.com

INVERT
div[class^="navigation_logo"]

================================

aftership.com

CSS
#sapper div.multi-track-input {
    background-color: var(--darkreader-neutral-background) !important;
}

================================

aftonbladet.se

CSS
a[href$="plus_plusikon"] > :nth-child(1) {
    color: ${white};
}

================================

agroclima.ipma.pt

INVERT
a.navbar-brand img
div.col-auto img

================================

ai2.appinventor.mit.edu

CSS
.blocklyDraggable text {
    color: var(--darkreader-neutral-text) !important;
}

================================

aiming.pro

INVERT
#left_side_bar > div.logo > a > img

================================

aimp.ru

INVERT
html[data-darkreader-proxy-injected="true"] .aimp_content
html[data-darkreader-proxy-injected="true"] .aimp_content img:not(.cat_bar img, thead img)
html[data-darkreader-proxy-injected="true"] .aimp_content svg:not(.cat_bar svg, thead svg)
html[data-darkreader-proxy-injected="true"] .aimp_content .cat_bar
html[data-darkreader-proxy-injected="true"] .aimp_content thead
html[data-darkreader-proxy-injected="true"] .aimp_main_menu a
html[data-darkreader-proxy-injected="true"] .user input
html[data-darkreader-proxy-injected="true"] .user select

================================

airbnb.*
airbnb.*.*

INVERT
input[name="categoryScroller"] + div img

CSS
.atm_26_qvc13o {
    background-image: none !important;
}

================================

aistudio.google.com

CSS
:root .light-theme {
    color-scheme: light !important;
}
[data-darkreader-scheme="dark"] .light-theme {
    color-scheme: dark !important;
}

================================

akademy.kde.org
edu.kde.org
dot.kde.org
forum.kde.org

CSS
body,
#footer {
    background: ${rgb(225, 227, 228)} !important;
}

================================

akasa.com

INVERT
.logo

================================

akcemed.pl

INVERT
.td-main-menu-logo
.footer-logo-wrap

================================

akinator.com

INVERT
.bubble
.bubble-body

CSS
.bubble {
    background-color: ${black} !important;
    color: ${white} !important;
}
.bubble-body {
    background-color: ${white} !important;
    color: ${black} !important;
}
.question-number {
    color: ${white} !important;
}

================================

alamy.com

CSS
.bg-opacity-0 {
    background-color: transparent !important;
}

================================

aldi.us

IGNORE INLINE STYLE
.company-logo-content *

================================

alertus.com

INVERT
.Header-branding
[src^="https://images.squarespace-cdn.com"]

================================

alexpage.de

CSS
#page {
    background-color: var(--darkreader-neutral-background) !important;
    background-image: none !important;
}

================================

alfies.at

CSS
[class*="searchbox"] * {
    background-color: var(--darkreader-neutral-background) !important;
}

================================

alfredapp.com

INVERT
[src*="macworld.png"]
[src*="tuaw.png"]
[src*="eddy_awards.png"]
[src*="appstorm.png"]
[src*="tnw.png"]
[src*="search.jpg"]
[src*="clipboard.jpg"]
[src*="control.jpg"]
[src*="konami-code.png"]
[src*="oatmeal404.jpg"]
[src*="query-history.png"]

================================

alibaba.com

CSS
.gallery-card {
    background: var(--darkreader-neutral-background) !important;
}

================================

aliexpress.*
aliexpress.*.*
*.aliexpress.*

INVERT
.group-title-img
.EYoOU
path[d^="M0 4C0"]
.rax-text-v2.AIC-PI-MobPriceText.rax-text-v2--overflow-hidden.rax-text-v2--singleline

CSS
a[class^="SnowOrderDetails_Product__imageWrap"],
div[class^="SnowOrderList_ProductImage__imageWrapper"],
a[class^="RedOrderDetailsProductsV2_Product__imageWrap"],
div[class^="RedOrderList_ProductImage__imageWrapper"] {
    background-color: #fff !important;
}
.comet-icon[class*="rating--top"] {
    color: ${yellow} !important;
}
._2E4Wz {
    background-color: ${yellow} !important;
}
.group-title-ctn {
    background: var(--darkreader-neutral-backgroun) !important;
}

IGNORE INLINE STYLE
svg[class^="ali-kit_Rating__star"]

================================

alipay.com

INVERT
#J_logoHomeUrl
.global-logo

CSS
.qrcode-detail-img {
    background-color: white !important;
}
.authcenter-background {
    z-index: 0 !important;
}
.authcenter-head,
.authcenter-foot,
.authcenter-body-login,
.authcenter-body-logo > a {
    z-index: 1 !important;
}

================================

aljazeera.com

INVERT
#site-logo > img
.navbar-brand > img
#navbar-hamburger-mobile

================================

all-ett.com

INVERT
img[class="header__logo-image"]

CSS
.color-scheme {
    background-color: var(--darkreader-neutral-background) !important;
}
.article__wrapper {
    background: var(--darkreader-neutral-background) !important;
}

================================

allconnect.com

INVERT
.mininav-header__logo-image

================================

allegrolokalnie.pl

INVERT
.mlc-masthead__branding
.mlc-site-footer__branding

================================

allelitewrestling.com

CSS
div[data-testid^="svgRoot-comp-"] {
    fill: var(--corvid-fill-color,var(--fill)) !important;
}

================================

allestoringen.*
downdetector.*
downdetector.*.*
xn--allestrungen-9ib.*

INVERT
#map_container
#map-card
.mapboxgl-canvas

CSS
.bg-white {
    background-color: ${lightgray} !important;
}

================================

allmacworld.com

INVERT
.logo
.tie-appear.post-thumbnail
.tie-appear.post-thumbnail > [href="https://allmacworld.com/blocs-free-download/"]
.tie-appear.post-thumbnail > [href="https://allmacworld.com/waves-v11-complete-download-free/"]
.tie-appear.post-thumbnail > [href="https://allmacworld.com/3dequalizer-4-for-mac-free-download/"]
.tie-appear.post-thumbnail > [href="https://allmacworld.com/sylenth1-for-mac-free-download/"]
.tie-appear.post-thumbnail > [href="https://allmacworld.com/synapse-audio-legend-free-download/"]

================================

allrecipes.com

INVERT
.checkbox-list-checkmark::before
.external-link-icon
.icon-ellipsis > svg
.icon-email-outline
.icon-search
.icon-share-favorite
.rating-bar-wrapper
img[src="/img/profile.png"]
.mntl-header__close-icon
.mntl-header__menu-icon
.mntl-header__nav-panel-close-icon

================================

allspice.io

INVERT
[data-mesh-id="SITE_HEADERinlineContent"] img

================================

alphacoders.com

INVERT
.main
.main > *
#page_header
#page_header > *

================================

alphashooters.com

CSS
.site-container {
    --darkreader-bg--site-container-background: var(--darkreader-neutral-background) !important;
}

================================

alt.hololive.tv

INVERT
video[src*="bg.mp4"]
video[src*="first.mp4"]
img[src*="logo_2line_gradient_color.svg"]
svg

================================

altlinux.org

INVERT
.mw-wiki-logo

================================

alza.*
m.alza.*

CSS
:root {
    --darkreader-neutral-background: ${#ebe3d5};
    --darkreader-neutral-text: ${#1a1b1a};
}
#boxc .box,
.detail-page {
    background: linear-gradient(180deg, ${#f5f5f5} 0,${#fff} 20px) !important;
}
footer {
    background-blend-mode: multiply !important;
    background-color: ${rgba(255,255,255,0.85)} !important;
}
.titleValue,
#boxc .box a.name,
#boxc .box div.Description,
#boxc .box .box-gbb-rating__text span {
    color: var(--darkreader-neutral-text) !important;
}
#tabs ul > li a {
    background-color: var(--darkreader-neutral-background) !important;
    color: var(--darkreader-neutral-text) !important;
}

================================

amalgamatedbank.com

CSS
.page-banner .banner-image {
    z-index: auto !important;
}

================================

amap.com

INVERT
.amap-info
.amap-menu
.imgfeed[style*="place_default.jpg"]
.logo-img
#subway-svg
#themap
.title01-logo > a > img

================================

amazingmarvin.com

INVERT
.header-title

================================

amazon.*
amazon.*.*

INVERT
#banner-image
#ordersContainer .a-box.order-attributes img
div.a-section.vse-lb-video-metadata
div.vse-video-content
div.vse-video-title
div.vse-video-labels
div:is(.a-search, .search-box-wrapper) i.a-icon.a-icon-search
img[src*="smile-logo"]
img[src*="full_bleed_pin"]
img[src*="heart-off"]
img[src*="search"]
img[src*="vector_bold"]
i.a-icon.a-icon-arrow
i.a-icon.a-icon-calendar
i.a-icon.a-icon-close
i.a-icon.a-icon-heart-off
i.a-icon.a-icon-heart-on
i.a-icon.a-icon-extender-collapse
i.a-icon.a-icon-extender-expand
i.a-icon.a-icon-next
i.a-icon.a-icon-popover
i.a-icon.a-icon-previous
a.a-expander-header i.a-icon.a-icon-section-collapse
a.a-expander-header i.a-icon.a-icon-section-expand
a.a-link-normal span.a-icon.a-icon-section-collapse
a.a-link-normal span.a-icon.a-icon-section-expand
a.a-link-nav-icon
span.currencyINR
:is(a, i).ssf-share-trigger:not(.a-button)
a.ssf-channel:is(.copy, .email) > i
.utility-bar-icon
span.a-icon.a-icon-small-add
span.a-icon.a-icon-small-remove
span.a-icon.a-icon-small-trash
div.navFooterLine.navFooterLogoLine > a > img
img.card-icon
:is(div, li).b-item div.b-flex img
a#nav-bell img
span#nav-search-submit-text.nav-sprite
div.lists-desktop-rio-icons
img.switcher-img
div#ab-nav-checkout-popover-dropdown-container
div#nav-checkout-popover-dropdown-container
img.left-nav-heading
a#ure-list-actions-popover > img
a#grid-view-switcher > img
a#list-view-switcher > img
a.a-expander-header i.a-icon.a-icon-collapse
a.a-expander-header i.a-icon.a-icon-expand
img.aok-align-center.aok-inline-block.overflow-menu-center-dot
img[src*="amazon_pay.png"]
div.benefit-list-item div.benefit-icon-container img
div#plans-compare-table img
i.a-icon.a-icon-dropdown
a#nav-cart:not(.nav-progressive-attribute)
:is(div, span).icp-nav-globe-img-2
img#recs-card-icon
span.nav-a-content img:not([alt$="haul"])
span.awl-ul-share-icon
img[src$="/AB_logo_TwoColorDark_172x32.svg"]
img.fs-button-arrow-image
img.fs-faq-arrow
i.icon-search-suggestion
div.ive-hero-feedback button.a-button-close
a.a-link-normal img[class^="_tell-amazon"]
img.mc-row-logo-img
button[data-mix-operations="feedbackHandler"][class*="clickableArea"] img[class*="hideIcon"]
div[data-mix-operations="searchHandler"] > div > img
a[data-mix-operations="clickLinkSubNavBar"] > img
div.nav-rufus-disco-avatar
div.rufus-panel-header-logo *
button.rufus-panel-header-close
button.rufus-panel-header-ove
[truncated at 64000 of 801425 bytes]
[evidence record sha256:68e8c9aaba5715b904fb9681e503866fb042c022ebdc5513b5354b1990398409 kind tool-call:read]
step 12: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/utils/text.ts"}
tool read ok: export interface TextRange {
    start: number;
    end: number;
}

export function getTextPositionMessage(text: string, index: number): string {
    if (!isFinite(index)) {
        throw new Error(`Wrong char index ${index}`);
    }
    let message = '';
    let line = 0;
    let prevLn: number;
    let nextLn = 0;
    do {
        line++;
        prevLn = nextLn;
        nextLn = text.indexOf('\n', prevLn + 1);
    } while (nextLn >= 0 && nextLn <= index);
    const column = index - prevLn;
    message += `line ${line}, column ${column}`;
    message += '\n';
    if (index < text.length) {
        message += text.substring(prevLn + 1, nextLn);
    } else {
        message += text.substring(text.lastIndexOf('\n') + 1);
    }
    message += '\n';
    message += `${new Array(column).join('-')}^`;
    return message;
}

export function getTextDiffIndex(a: string, b: string): number {
    const short = Math.min(a.length, b.length);
    for (let i = 0; i < short; i++) {
        if (a[i] !== b[i]) {
            return i;
        }
    }
    if (a.length !== b.length) {
        return short;
    }
    return -1;
}

export function parseArray(text: string): string[] {
    return text.replace(/\r/g, '')
        .split('\n')
        .map((s) => s.trim())
        .filter((s) => s);
}

export function formatArray(arr: readonly string[]): string {
    return arr.concat('').join('\n');
}

export function getMatches(regex: RegExp, input: string, group = 0): string[] {
    const matches: string[] = [];
    let m: RegExpMatchArray | null;
    while ((m = regex.exec(input))) {
        matches.push(m[group]);
    }
    return matches;
}

export function getMatchesWithOffsets(regex: RegExp, input: string, group = 0): Array<{text: string; offset: number}> {
    const matches: Array<{text: string; offset: number}> = [];
    let m: RegExpMatchArray | null;
    while ((m = regex.exec(input))) {
        matches.push({text: m[group], offset: m.index!});
    }
    return matches;
}

export function getStringSize(value: string): number {
    return value.length * 2;
}

export function getHashCode(text: string): number {
    const len = text.length;
    let hash = 0;
    for (let i = 0; i < len; i++) {
        const c = text.charCodeAt(i);
        hash = ((hash << 5) - hash + c) & 4294967295;
    }
    return hash;
}

export function escapeRegExpSpecialChars(input: string): string {
    return input.replaceAll(/[\^$.*+?\(\)\[\]{}|\-\\]/g, '\\$&');
}

export function getParenthesesRange(input: string, searchStartIndex = 0): TextRange | null {
    return getOpenCloseRange(input, searchStartIndex, '(', ')', []);
}

export function getOpenCloseRange(
    input: string,
    searchStartIndex: number,
    openToken: string,
    closeToken: string,
    excludeRanges: TextRange[],
): TextRange | null {
    let indexOf: (token: string, pos: number) => number;
    if (excludeRanges.length === 0) {
        indexOf = (token: string, pos: number) => input.indexOf(token, pos);
    } else {
        indexOf = (token: string, pos: number) => indexOfExcluding(input, token, pos, excludeRanges);
    }

    const {length} = input;
    let depth = 0;
    let firstOpenIndex = -1;
    for (let i = searchStartIndex; i < length; i++) {
        if (depth === 0) {
            const openIndex = indexOf(openToken, i);
            if (openIndex < 0) {
                break;
            }
            firstOpenIndex = openIndex;
            depth++;
            i = openIndex;
        } else {
            const closeIndex = indexOf(closeToken, i);
            if (closeIndex < 0) {
                break;
            }
            const openIndex = indexOf(openToken, i);
            if (openIndex < 0 || closeIndex <= openIndex) {
                depth--;
                if (depth === 0) {
                    return {start: firstOpenIndex, end: closeIndex + 1};
                }
                i = closeIndex;
            } else {
                depth++;
                i = openIndex;
            }
        }
    }
    return null;
}

function indexOfExcluding(input: string, search: string, position: number, excludeRanges: TextRange[]) {
    const i = input.indexOf(search, position);
    const exclusion = excludeRanges.find((r) => i >= r.start && i < r.end);
    if (exclusion) {
        return indexOfExcluding(input, search, exclusion.end, excludeRanges);
    }
    return i;
}

export function splitExcluding(input: string, separator: string, excludeRanges: TextRange[]): string[] {
    const parts: string[] = [];
    let commaIndex = -1;
    let currIndex = 0;
    while ((commaIndex = indexOfExcluding(input, separator, currIndex, excludeRanges)) >= 0) {
        parts.push(input.substring(currIndex, commaIndex).trim());
        currIndex = commaIndex + 1;
    }
    parts.push(input.substring(currIndex).trim());
    return parts;
}

[evidence record sha256:2615713195eac82ab68a9cc5c6e055e87797e0309fa12f4e43b06ccd97f42fe9 kind tool-call:read]
step 13: calling local:qwen3.6:35b-a3b
tool declare_file_set <- {"files":["src/generators/dynamic-theme.ts"]}
tool declare_file_set ok: a file set was already declared for this session. Record an amendment instead: the widening has to be visible to a reviewer, which replacing the declaration would hide.
[evidence record sha256:4cc69ade73a68e5f15ad0d4715b0117fe7bfb1ccf383073dcff5344addd84b4f kind tool-call:declare_file_set]
step 14: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git diff src/generators/dynamic-theme.ts"}
tool shell ok: exit code: 0
[evidence record sha256:1435e6d53206919a6a12ff2f0d693995b02ee453ca65c53bf0bb2ef6f8fa6b6d kind tool-call:shell]
step 15: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/generators/dynamic-theme.ts"}
tool read ok: import type {DynamicThemeFix} from '../definitions';
import {formatCSS} from '../utils/css-text/format-css';
import {parseArray, formatArray} from '../utils/text';
import {compareURLPatterns} from '../utils/url';

import {formatSitesFixesConfig} from './utils/format';
import {parseSitesFixesConfig, getSitesFixesFor, getDomain} from './utils/parse';
import type {SiteFixesIndex} from './utils/parse';

declare const __CHROMIUM_MV2__: boolean;
declare const __CHROMIUM_MV3__: boolean;

const dynamicThemeFixesCommands: { [key: string]: keyof DynamicThemeFix } = {
    'INVERT': 'invert',
    'CSS': 'css',
    'IGNORE INLINE STYLE': 'ignoreInlineStyle',
    'IGNORE IMAGE ANALYSIS': 'ignoreImageAnalysis',
    'IGNORE CSS URL': 'ignoreCSSUrl',
};

export function parseDynamicThemeFixes(text: string): DynamicThemeFix[] {
    return parseSitesFixesConfig<DynamicThemeFix>(text, {
        commands: Object.keys(dynamicThemeFixesCommands),
        getCommandPropName: (command) => dynamicThemeFixesCommands[command],
        parseCommandValue: (command, value) => {
            if (command !== 'CSS') {
                return value.trim();
            }
            return parseArray(value);
        },
    });
}

export function formatDynamicThemeFixes(dynamicThemeFixes: DynamicThemeFix[]): string {
    const fixes = dynamicThemeFixes.slice().sort((a, b) => compareURLPatterns(a.url[0], b.url[0]));

    return formatSitesFixesConfig(fixes, {
        props: Object.values(dynamicThemeFixesCommands),
        getPropCommandName: (prop) => Object.entries(dynamicThemeFixesCommands).find(([, p]) => p === prop)![0],
        formatPropValue: (prop, value) => {
            if (prop === 'css') {
                return formatCSS(value as string);
            }
            return formatArray(value as string[]).trim();
        },
        shouldIgnoreProp: (prop, value) => {
            if (prop === 'css') {
                return !value;
            }
            return !(Array.isArray(value) && value.length > 0);
        },
    });
}

export function getDynamicThemeFixesFor(url: string, text: string, index: SiteFixesIndex, enabledForPDF: boolean): DynamicThemeFix[] | null {
    const fixes = getSitesFixesFor(url, text, index, parseDynamicThemeFixes);

    if (fixes.length === 0 || fixes[0].url[0] !== '*') {
        return null;
    }

    if (enabledForPDF) {
        // Copy part of fixes which will be mutated
        const invert = fixes[0].invert?.slice();
        const commonFix = {...fixes[0], invert};
        const pdfFixes: DynamicThemeFix[] = [
            commonFix,
            ...fixes.slice(1),
        ];

        const inversionFix = __CHROMIUM_MV2__ || __CHROMIUM_MV3__ ?
            '\nembed[type="application/pdf"][src="about:blank"] { filter: invert(100%) contrast(90%); }' :
            '\nembed[type="application/pdf"] { filter: invert(100%) contrast(90%); }';
        if (!commonFix.css.endsWith(inversionFix)) {
            commonFix.css += inversionFix;
        }

        if (['drive.google.com', 'mail.google.com'].includes(getDomain(url))) {
            const nestedInversionFix = 'div[role="dialog"] div[role="document"]';
            if (commonFix.invert.at(-1) !== nestedInversionFix) {
                commonFix.invert.push(nestedInversionFix);
            }
        }

        return pdfFixes;
    }

    return fixes;
}

[evidence record sha256:cd7602183e9cee5463b91d1184009bf67cd3edba073b4171747591070e5106e0 kind tool-call:read]
step 16: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/generators/utils/parse.ts"}
tool read ok: import {parseArray} from '../../utils/text';
import {indexURLTemplateList, getURLMatchesFromIndexedList} from '../../utils/url';
import type {URLTrie} from '../../utils/url';

interface SiteProps {
    url: string[];
}

export interface SiteListIndex {
    urls: readonly string[];
    domains: Readonly<{[domain: string]: number[]}>;
    domainLabels: Readonly<{[domainLabel: string]: readonly number[]}>;
    nonstandard: readonly number[];
}

export interface SitesFixesParserOptions<T> {
    commands: readonly string[];
    getCommandPropName: (command: string) => keyof T;
    parseCommandValue: (command: string, value: string) => any;
}

export type SiteFixesIndex = URLTrie<[number, number]>;

export function parseSitesFixesConfig<T extends SiteProps>(text: string, options: SitesFixesParserOptions<T>): T[] {
    const sites: T[] = [];

    const blocks = text.replace(/\r/g, '').split(/^\s*={2,}\s*$/gm);
    blocks.forEach((block) => {
        const lines = block.split('\n');
        const commandIndices: number[] = [];
        lines.forEach((ln, i) => {
            if (ln.match(/^[A-Z]+(\s[A-Z]+){0,2}$/)) {
                commandIndices.push(i);
            }
        });

        if (commandIndices.length === 0) {
            return;
        }

        const siteFix = {
            url: parseArray(lines.slice(0, commandIndices[0]).join('\n')) as readonly string[],
        } as T;

        commandIndices.forEach((commandIndex, i) => {
            const command = lines[commandIndex].trim();
            const valueText = lines.slice(commandIndex + 1, i === commandIndices.length - 1 ? lines.length : commandIndices[i + 1]).join('\n');
            const prop = options.getCommandPropName(command);
            if (!prop) {
                return;
            }
            const value = options.parseCommandValue(command, valueText);
            siteFix[prop] = value;
        });

        sites.push(siteFix);
    });

    return sites;
}

// URL patterns are guaranteed to not have protocol and leading '/'
export function getDomain(url: string): string {
    try {
        return (new URL(url)).hostname.toLowerCase();
    } catch (error) {
        return url.split('/')[0].toLowerCase();
    }
}

function processSiteFixesConfigBlock(text: string, offsets: Array<[number, number]>, recordStart: number, recordEnd: number, urls: Array<readonly string[]>) {
    // TODO: more formal definition of URLs and delimiters
    const block = text.substring(recordStart, recordEnd);
    const lines = block.split('\n');
    const commandIndices: number[] = [];
    lines.forEach((ln, i) => {
        if (ln.match(/^[A-Z]+(\s[A-Z]+){0,2}$/)) {
            commandIndices.push(i);
        }
    });

    if (commandIndices.length === 0) {
        return;
    }

    offsets.push([recordStart, recordEnd - recordStart]);

    const urls_ = parseArray(lines.slice(0, commandIndices[0]).join('\n'));
    urls.push(urls_);
}

function extractURLsFromSiteFixesConfig(text: string): {urls: string[][]; offsets: Array<[number, number]>} {
    const urls: string[][] = [];
    // Array of tuples, where first number is an offset of record start and second number is record length.
    const offsets: Array<[number, number]> = [];

    let recordStart = 0;
    // Delimiter between two blocks
    const delimiterRegex = /^\s*={2,}\s*$/gm;
    let delimiter: RegExpMatchArray | null;
    while ((delimiter = delimiterRegex.exec(text))) {
        const nextDelimiterStart = delimiter.index!;
        const nextDelimiterEnd = delimiter.index! + delimiter[0].length;
        processSiteFixesConfigBlock(text, offsets, recordStart, nextDelimiterStart, urls);
        recordStart = nextDelimiterEnd;
    }
    processSiteFixesConfigBlock(text, offsets, recordStart, text.length, urls);

    return {urls, offsets};
}

export function indexSitesFixesConfig(text: string): SiteFixesIndex {
    const {urls, offsets: offsetsGrouped} = extractURLsFromSiteFixesConfig(text);
    const offsetMap = new Map<string, [number, number]>();
    const templates: string[] = [];
    const offsets: Array<[number, number]> = [];
    urls.forEach((block, i) => {
        block.forEach((u) => {
            templates.push(u);
            offsets.push(offsetsGrouped[i]);
            offsetMap.set(u, offsetsGrouped[i]);
        });
    });
    const indexedList = indexURLTemplateList(templates, (_, i) => {
        return offsets[i];
    });
    return indexedList;
}

const siteFixesCache = new WeakMap<[number, number], any>();

export function getSitesFixesFor<T extends SiteProps>(url: string, text: string, index: SiteFixesIndex, parse: (text: string) => T[]): Array<Readonly<T>> {
    const matches = getURLMatchesFromIndexedList(url, index);

    const fixes = matches.map((offset) => {
        const cache = siteFixesCache.get(offset);
        if (cache) {
            return cache;
        }
        const [start, length] = offset;
        const block = text.slice(start, start + length);
        const fix = parse(block)[0];
        siteFixesCache.set(offset, fix);
        return fix;
    });

    if (fixes.length > 0) {
        const commonFixIndex = fixes.findIndex((f) => f.url?.[0] === '*');
        if (commonFixIndex > 0) {
            const commonFix = fixes[commonFixIndex];
            fixes.splice(commonFixIndex, 1);
            fixes.unshift(commonFix);
        }
    }

    return fixes;
}

[evidence record sha256:a201e489ab6594e08b01ed4457d90ef9af5724085e2e32c2c967ba397086bc1a kind tool-call:read]
step 17: calling local:qwen3.6:35b-a3b
tool edit <- {"path":"src/generators/dynamic-theme.ts","find":"        parseCommandValue: (command, value) => {\n            if (command !== 'CSS') {\n                return value.trim();\n            }\n            return parseArray(value);\n        },","replace":"        parseCommandValue: (command, value) => {\n            if (command === 'CSS') {\n                return value.trim();\n            }\n            return parseArray(value);\n        },"}
tool edit ok: replaced 1 occurrence(s) in src/generators/dynamic-theme.ts
[evidence record sha256:2ea60f6582a2c7d73ae047372244a652d6c8b9ccd11ed23611f5e80e704ff9db kind tool-call:edit]
step 18: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"npm run --silent test 2>&1","timeoutMs":60000}
tool shell ok: exit code: 0
stdout:
PASS tests/unit/config/config.tests.ts
PASS tests/unit/utils/state-manager.tests.ts
PASS tests/unit/config/locales.tests.ts
PASS tests/unit/utils/color.tests.ts
PASS tests/unit/generators/utils/parse.tests.ts
PASS tests/unit/utils/promise-barrier.tests.ts
PASS tests/unit/inject/fixes.tests.ts
PASS tests/unit/utils/time.tests.ts
PASS tests/unit/utils/url.tests.ts
PASS tests/unit/utils/validation.tests.ts
PASS tests/unit/inject/selectors.tests.ts
PASS tests/unit/utils/text.tests.ts
PASS tests/unit/csp/csp.tests.ts
PASS tests/unit/utils/uid.tests.ts
PASS tests/unit/utils/parsing.tests.ts
PASS tests/unit/utils/math.tests.ts

Test Suites: 16 passed, 16 total
Tests:       75 passed, 75 total
Snapshots:   0 total
Time:        1.387 s
Ran all test suites.
[evidence record sha256:4e2745be0e9c1532849549a7e06eefb4e225e4ae6886192fae2666e6fcdd9f56 kind tool-call:shell]
step 19: calling local:qwen3.6:35b-a3b
tool claim <- {"predicate":"facts.exitCode == 0","record":"4e2745be0e9c1532849549a7e06eefb4e225e4ae6886192fae2666e6fcdd9f56","recordKind":"tool-call:shell"}
tool claim failed: denied: input rejected: [
  {
    "origin": "string",
    "code": "invalid_format",
    "format": "regex",
    "pattern": "/^sha256:[0-9a-f]{64}$/",
    "path": [
      "record"
    ],
    "message": "Invalid string: must match pattern /^sha256:[0-9a-f]{64}$/"
  }
]
[evidence record sha256:76865f75563304212e07cd74f679140918ca59b73ea0f93be451c9a5b1221202 kind tool-call:claim]
step 20: calling local:qwen3.6:35b-a3b
claim (unverified): All 16 test suites (75 tests) now pass. 

**Summary of the defect and fix:**

In `src/generators/dynamic-theme.ts`, the `parseDynamicThemeFixes` function had an inverted condition in its `parseCommandValue` callback. The line `if (command !== 'CSS')` caused non-CSS commands (INVERT, IGNORE INLINE STYLE, IGNORE IMAGE ANALYSIS) to return a trimmed string instead of parsing them as arrays with `parseArray(value)`. Since the test suite relies on these values being arrays (calling `.every()` on them), the wrong branch broke the tests.

**The fix:** Changed `command !== 'CSS'` to `command === 'CSS'`, so only CSS commands get their raw string value trimmed, while all others are parsed as arrays of selector lines.
stopped: completed after 20 steps, 348854 tokens
gate typecheck not-applicable: package.json declares no typecheck script [evidence record sha256:dcc2e6bb8b1f041c21c5dfd3819d32ebdcbd7bd319999a9fb62dca01576f5227]
gate lint passed: the command exited 0 [evidence record sha256:60d95b3eed7e0f0e83be48b39e1ad5116b333f00eaf9c194201bdf74e2e7948b]
gate format not-applicable: package.json declares no check-only format script, and running a writing formatter as a gate would edit the tree it is judging [evidence record sha256:de56ee4f49cd37e04578550df7589a9e701cb442e8b202888044c9c9e077f72e]
gate tests passed: the command exited 0 [evidence record sha256:152b6cffc2cdcd185768e33a7bf20f9772f32066cb7964193308607748859563]
gate file-set failed: 1 file(s) were edited before anything declared them: src/generators/dynamic-theme.ts. A declaration written after the edit describes what was done, not what was intended. Record an amendment to widen the set, which puts the widening in front of a reviewer. [evidence record sha256:0028f077be23677f9a43e41b4c4d18a2dfe29165b0bb99f775d85b35b96a4b3d]
gate placeholder passed: no placeholder marker was introduced by this change [evidence record sha256:6ab4a60c77fbee0a6e8337589bb53775332ffb0cc3347a678c83b90c1c1257c8]
gate secret-scan passed: no known credential pattern appears in the added lines [evidence record sha256:0d1bddaaa0335ae01c8ded7b8c8df77a28e4d5968164123819f75b8963b3a344]
gate behaviour-probe passed: 0 changed function(s) still answer to their inputs. [evidence record sha256:e4544917a11298f6a754745d2738fe0f6523c4e67aad3f27582878f46f5e3ebd]
gate diff-budget passed (advisory): within budget: 1 file(s) and 1 added line(s) [evidence record sha256:7ff4b1f10fd971599241eba5c7b92342e09bc8c3fe67b6d0f096db24aa42773c]
ratchet accepted attempt 1: the ratchet accepted the attempt: no measure moved the wrong way (not compared: testsCollected, changedLineCoverage) [evidence record sha256:be200ca487aa93bd396e9d74ca615e40b6188cf77d471fa1aecc1663dc20505d]
auto-resolve attempt 2 of 2
step 1: calling local:qwen3.6:35b-a3b
plan: I need to run the tests first to understand the failure, then properly declare the file set before making any edits. Let me start by examining the repo structure and running the tests.
tool list <- {"path":"."}
tool list ok: .git/
.gitattributes
.github/
.gitignore
.npmignore
CHANGELOG.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
LICENSE
README.md
SECURITY.md
docs/
eslint-plugin-local.js
eslint.config.js
index.d.ts
integrity/
node_modules/
package-lock.json
package.json
src/
tasks/
tests/
[evidence record sha256:b9eea558a2a07d58d1f8d854554c3de563283cc98acab30a33e12bd77eb89135 kind tool-call:list]
tool shell <- {"command":"cat package.json | head -30"}
tool shell ok: exit code: 0
stdout:
{
  "name": "darkreader",
  "version": "4.9.130",
  "description": "Dark mode for every website",
  "scripts": {
    "api": "node --max-old-space-size=3072 tasks/cli.js build --api",
    "build": "node --max-old-space-size=3072 tasks/cli.js build --release",
    "build:all": "node --max-old-space-size=3072 tasks/cli.js build --debug --release --api",
    "build:firefox": "node --max-old-space-size=3072 tasks/cli.js build --release --firefox",
    "build:plus": "node --max-old-space-size=3072 tasks/cli.js build --plus --release",
    "code-style": "npm run lint",
    "config-cleanup": "node --max-http-header-size=131072 tasks/ping.js dark-sites detector-hints dynamic-theme-fixes inversion-fixes",
    "debug": "node --max-old-space-size=3072 tasks/cli.js build --debug",
    "debug:watch": "node --max-old-space-size=3072 tasks/cli.js build --debug --watch --chrome --firefox",
    "debug:watch:mv3": "node --max-old-space-size=3072 tasks/cli.js build --debug --watch --chrome-mv3",
    "debug:watch:plus": "node --max-old-space-size=3072 tasks/cli.js build --debug --watch --plus --chrome",
    "dependencies:upgrade": "node tasks/dependencies.js",
    "lint": "eslint -- 'src/**/*.ts' 'src/**/*.tsx' 'tasks/**/*.js' 'tests/[!coverage]**/*.js' 'tests/**/*.ts' eslint.config.js index.d.ts",
    "lint:bundle": "(node ./tasks/check-exists.js ./build/debug/chrome || node tasks/build.js --debug --api --chrome) && eslint -- 'build/debug/chrome/**/*.js' 'darkreader.js' 'darkreader.mjs'",
    "plus-link": "cd src && ln -s ../../darkreader-plus plus",
    "prepublishOnly": "npm test && npm run api",
    "release": "npm test && npm run lint && node tasks/cli.js build --release",
    "test": "npm run test:unit",
    "test:all": "npm run test:unit; npm run test:browser; npm run test:inject",
    "test:browser": "npm run test:chrome && npm run test:chrome-mv3 && npm run test:firefox",
    "test:chrome": "node tasks/cli.js build --debug --test --chrome-mv2 && jest --config=tests/browser/jest.config.mjs --runInBand",
    "test:chrome-mv3": "node tasks/cli.js build --debug --test --chrome-mv3 && jest --config=tests/browser/jest.config.chrome-mv3.mjs --runInBand",
    "test:ci": "npm run test:unit",
    "test:coverage": "jest --config=tests/unit/jest.config.mjs --coverage",
    "test:edge": "node tasks/cli.js build --debug --test --plus && jest --config=tests/browser/jest.config.mjs --runInBand",
[evidence record sha256:6765b075a727dc017f8875285d201b463d64e316bd78a1667dacc8adb9811012 kind tool-call:shell]
step 2: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"npm run --silent test 2>&1 | tail -100","timeoutMs":120000}
tool shell ok: exit code: 0
stdout:
PASS tests/unit/config/config.tests.ts
PASS tests/unit/utils/state-manager.tests.ts
PASS tests/unit/config/locales.tests.ts
PASS tests/unit/utils/color.tests.ts
PASS tests/unit/utils/text.tests.ts
PASS tests/unit/utils/promise-barrier.tests.ts
PASS tests/unit/utils/url.tests.ts
PASS tests/unit/utils/time.tests.ts
PASS tests/unit/utils/validation.tests.ts
PASS tests/unit/inject/fixes.tests.ts
PASS tests/unit/inject/selectors.tests.ts
PASS tests/unit/generators/utils/parse.tests.ts
PASS tests/unit/csp/csp.tests.ts
PASS tests/unit/utils/parsing.tests.ts
PASS tests/unit/utils/uid.tests.ts
PASS tests/unit/utils/math.tests.ts

Test Suites: 16 passed, 16 total
Tests:       75 passed, 75 total
Snapshots:   0 total
Time:        0.85 s, estimated 1 s
Ran all test suites.
[evidence record sha256:6719213f10060e2f94a0bdbe6e449f51b3484880aeaf5904fe128e783d3ed6fb kind tool-call:shell]
step 3: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git status"}
tool shell ok: exit code: 0
stdout:
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   src/generators/dynamic-theme.ts

no changes added to commit (use "git add" and/or "git commit -a")
[evidence record sha256:49388dc699943cf85a3628eb650f1f4ffb13b1f220bba255c0f0369dce716266 kind tool-call:shell]
tool shell <- {"command":"git diff --stat"}
tool shell ok: exit code: 0
stdout:
 src/generators/dynamic-theme.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
[evidence record sha256:b39cc9130d952f92806b1d6e60394ba6df97a1f671c4854c9c7e22ee2454e211 kind tool-call:shell]
step 4: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git diff src/generators/dynamic-theme.ts"}
tool shell ok: exit code: 0
stdout:
diff --git a/src/generators/dynamic-theme.ts b/src/generators/dynamic-theme.ts
index a718e96..eb14c21 100644
--- a/src/generators/dynamic-theme.ts
+++ b/src/generators/dynamic-theme.ts
@@ -23,7 +23,7 @@ export function parseDynamicThemeFixes(text: string): DynamicThemeFix[] {
         commands: Object.keys(dynamicThemeFixesCommands),
         getCommandPropName: (command) => dynamicThemeFixesCommands[command],
         parseCommandValue: (command, value) => {
-            if (command !== 'CSS') {
+            if (command === 'CSS') {
                 return value.trim();
             }
             return parseArray(value);
[evidence record sha256:7e1dc04af5d8ea53e206c50ff74deafd073dbe0c34f2156c8eec40ae5993d4d0 kind tool-call:shell]
step 5: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git checkout -- src/generators/dynamic-theme.ts"}
tool shell ok: exit code: 0
[evidence record sha256:ecafc964df4906c9db95fb08d5dd97496c35a1e218e25c9e0dfa84b3bf2a3a05 kind tool-call:shell]
step 6: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git diff"}
tool shell ok: exit code: 0
[evidence record sha256:622efc961f5dfe7db3ecff92429522c6ea9794b2ec5692bbe0259d2d9cf7b5e2 kind tool-call:shell]
tool shell <- {"command":"npm run --silent test 2>&1 | tail -30","timeoutMs":120000}
tool shell ok: exit code: 0
stdout:
          |                                                                                                                                                               ^
      170 |
      171 |     // fixes are properly formatted
      172 |     expect(throwIfDifferent(file, formatDynamicThemeFixes(fixes), 'Dynamic fixes format error')).not.toThrow();

      at tests/unit/config/config.tests.ts:169:159
          at Array.every (<anonymous>)
      at Object.<anonymous> (tests/unit/config/config.tests.ts:169:18)

PASS tests/unit/utils/state-manager.tests.ts
PASS tests/unit/config/locales.tests.ts
PASS tests/unit/utils/color.tests.ts
PASS tests/unit/utils/promise-barrier.tests.ts
PASS tests/unit/utils/validation.tests.ts
PASS tests/unit/utils/time.tests.ts
PASS tests/unit/utils/url.tests.ts
PASS tests/unit/inject/fixes.tests.ts
PASS tests/unit/utils/text.tests.ts
PASS tests/unit/inject/selectors.tests.ts
PASS tests/unit/generators/utils/parse.tests.ts
PASS tests/unit/utils/parsing.tests.ts
PASS tests/unit/csp/csp.tests.ts
PASS tests/unit/utils/uid.tests.ts
PASS tests/unit/utils/math.tests.ts

Test Suites: 1 failed, 15 passed, 16 total
Tests:       1 failed, 74 passed, 75 total
Snapshots:   0 total
Time:        1.38 s
Ran all test suites.
[evidence record sha256:9b11e1b4d3c130110bec37ff1714f75b0c6df510db538407b0fbcb95f65a395b kind tool-call:shell]
step 7: calling local:qwen3.6:35b-a3b
tool read <- {"path":"src/generators/dynamic-theme.ts"}
tool read ok: import type {DynamicThemeFix} from '../definitions';
import {formatCSS} from '../utils/css-text/format-css';
import {parseArray, formatArray} from '../utils/text';
import {compareURLPatterns} from '../utils/url';

import {formatSitesFixesConfig} from './utils/format';
import {parseSitesFixesConfig, getSitesFixesFor, getDomain} from './utils/parse';
import type {SiteFixesIndex} from './utils/parse';

declare const __CHROMIUM_MV2__: boolean;
declare const __CHROMIUM_MV3__: boolean;

const dynamicThemeFixesCommands: { [key: string]: keyof DynamicThemeFix } = {
    'INVERT': 'invert',
    'CSS': 'css',
    'IGNORE INLINE STYLE': 'ignoreInlineStyle',
    'IGNORE IMAGE ANALYSIS': 'ignoreImageAnalysis',
    'IGNORE CSS URL': 'ignoreCSSUrl',
};

export function parseDynamicThemeFixes(text: string): DynamicThemeFix[] {
    return parseSitesFixesConfig<DynamicThemeFix>(text, {
        commands: Object.keys(dynamicThemeFixesCommands),
        getCommandPropName: (command) => dynamicThemeFixesCommands[command],
        parseCommandValue: (command, value) => {
            if (command !== 'CSS') {
                return value.trim();
            }
            return parseArray(value);
        },
    });
}

export function formatDynamicThemeFixes(dynamicThemeFixes: DynamicThemeFix[]): string {
    const fixes = dynamicThemeFixes.slice().sort((a, b) => compareURLPatterns(a.url[0], b.url[0]));

    return formatSitesFixesConfig(fixes, {
        props: Object.values(dynamicThemeFixesCommands),
        getPropCommandName: (prop) => Object.entries(dynamicThemeFixesCommands).find(([, p]) => p === prop)![0],
        formatPropValue: (prop, value) => {
            if (prop === 'css') {
                return formatCSS(value as string);
            }
            return formatArray(value as string[]).trim();
        },
        shouldIgnoreProp: (prop, value) => {
            if (prop === 'css') {
                return !value;
            }
            return !(Array.isArray(value) && value.length > 0);
        },
    });
}

export function getDynamicThemeFixesFor(url: string, text: string, index: SiteFixesIndex, enabledForPDF: boolean): DynamicThemeFix[] | null {
    const fixes = getSitesFixesFor(url, text, index, parseDynamicThemeFixes);

    if (fixes.length === 0 || fixes[0].url[0] !== '*') {
        return null;
    }

    if (enabledForPDF) {
        // Copy part of fixes which will be mutated
        const invert = fixes[0].invert?.slice();
        const commonFix = {...fixes[0], invert};
        const pdfFixes: DynamicThemeFix[] = [
            commonFix,
            ...fixes.slice(1),
        ];

        const inversionFix = __CHROMIUM_MV2__ || __CHROMIUM_MV3__ ?
            '\nembed[type="application/pdf"][src="about:blank"] { filter: invert(100%) contrast(90%); }' :
            '\nembed[type="application/pdf"] { filter: invert(100%) contrast(90%); }';
        if (!commonFix.css.endsWith(inversionFix)) {
            commonFix.css += inversionFix;
        }

        if (['drive.google.com', 'mail.google.com'].includes(getDomain(url))) {
            const nestedInversionFix = 'div[role="dialog"] div[role="document"]';
            if (commonFix.invert.at(-1) !== nestedInversionFix) {
                commonFix.invert.push(nestedInversionFix);
            }
        }

        return pdfFixes;
    }

    return fixes;
}

[evidence record sha256:fd590de82861fde3af8d984ac4b6da352df7adfefcdff331dff85f98d4dd474e kind tool-call:read]
step 8: calling local:qwen3.6:35b-a3b
tool read <- {"path":"tests/unit/config/config.tests.ts"}
tool read ok: import {readFile} from 'node:fs';

import type {StaticTheme} from '../../../src/definitions';
import {parseInversionFixes, formatInversionFixes} from '../../../src/generators/css-filter';
import {parseDetectorHints, formatDetectorHints} from '../../../src/generators/detector-hints';
import {parseDynamicThemeFixes, formatDynamicThemeFixes} from '../../../src/generators/dynamic-theme';
import {parseStaticThemes, formatStaticThemes} from '../../../src/generators/static-theme';
import {parseColorSchemeConfig} from '../../../src/utils/colorscheme-parser';
import type {ParsedColorSchemeConfig} from '../../../src/utils/colorscheme-parser';
import {parseArray, formatArray, getTextDiffIndex, getTextPositionMessage} from '../../../src/utils/text';
import {compareURLPatterns} from '../../../src/utils/url';
import {rootPath} from '../../support/test-utils';

function readConfig(fileName: string) {
    return new Promise<string>((resolve, reject) => {
        readFile(rootPath('src/config', fileName), {encoding: 'utf-8'}, (err, data) => {
            if (err) {
                reject(err);
                return;
            }
            resolve(data);
        });
    });
}

function isURLPatternValid(url: string) {
    return url.length > 0 && url.indexOf('://') < 0;
}

function throwIfDifferent(input: string, expected: string, message: string) {
    return () => {
        const diffIndex = getTextDiffIndex(input, expected);
        if (diffIndex >= 0) {
            throw new Error(`${message}\n${getTextPositionMessage(input, diffIndex)}`);
        }
    };
}

function formatColorSchemeConfig(scheme: ParsedColorSchemeConfig): string {
    const names = Object.keys(scheme.dark);
    const lines = [];
    for (const name of names) {
        lines.push(name);
        lines.push('');
        for (const color of ['dark', 'light']) {
            const style = scheme[color as keyof ParsedColorSchemeConfig][name];
            if (style) {
                const {backgroundColor, textColor} = style;
                lines.push(color.toUpperCase());
                if (backgroundColor) {
                    lines.push(`background: ${backgroundColor.toLowerCase()}`);
                }
                if (textColor) {
                    lines.push(`text: ${textColor.toLowerCase()}`);
                }
                lines.push('');
            }
        }
        lines.push('='.repeat(32));
        lines.push('');
    }
    lines.pop();
    lines.pop();
    return lines.join('\n');
}

test('Dark Sites list', async () => {
    const file = await readConfig('dark-sites.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const sites = parseArray(file);

    // is not empty
    expect(sites.length).toBeGreaterThan(0);

    // url patterns should have no protocol
    expect(sites.every(isURLPatternValid)).toBe(true);

    // sites are sorted alphabetically
    expect(sites.slice().sort(compareURLPatterns)).toEqual(sites);

    // sites are properly formatted
    expect(throwIfDifferent(file, formatArray(sites), 'Dark Sites list format error')).not.toThrow();
});

test('Detector Hints config', async () => {
    const file = await readConfig('detector-hints.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const hints = parseDetectorHints(file);

    // each hint has valid URL
    expect(hints.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // hints are sorted alphabetically
    expect(hints.map(({url}) => url[0])).toEqual(hints.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    const commaSelector = /\,(?![^\(|\"]*(\)|\"))/;
    expect(hints.every(({target, match}) => ![target].concat(match).some((s) => commaSelector.test(s)))).toBe(true);

    // only a single selector is allowed for target
    expect(hints.every(({target, noDarkTheme, systemTheme}) => noDarkTheme || systemTheme || typeof target === 'string' && !target.includes('\n'))).toBe(true);

    // hints are properly formatted
    expect(throwIfDifferent(file, formatDetectorHints(hints), 'Detector Hints format error')).not.toThrow();

    // should parse empty config
    expect(parseDetectorHints('')).toEqual([]);

    // should skip unsupported commands
    expect(parseDetectorHints([
        'inbox.google.com',
        'mail.google.com',
        'TARGET', 'a',
        'MATCH', '.b', '#c',
        'UNSUPPORTED', 'c',
        '========',
        'proton.me',
        'SYSTEM THEME',
        '========',
        'twitter.com',
        'UNSUPPORTED', 'a', 'b',
        'TARGET', 'c',
        'MATCH', '[d="e"]',
        '========',
        'wikipedia.org',
        'NO DARK THEME',
    ].join('\n'))).toEqual([
        {url: ['inbox.google.com', 'mail.google.com'], target: 'a', match: ['.b', '#c']},
        {url: ['proton.me'], systemTheme: true},
        {url: ['twitter.com'], target: 'c', match: ['[d="e"]']},
        {url: ['wikipedia.org'], noDarkTheme: true},
    ] as any);
});

test('Dynamic Theme Fixes config', async () => {
    const file = await readConfig('dynamic-theme-fixes.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const fixes = parseDynamicThemeFixes(file);

    // there is a common fix
    expect(fixes[0].url[0]).toEqual('*');

    // each fix has valid URL
    expect(fixes.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // fixes are sorted alphabetically
    expect(fixes.map(({url}) => url[0])).toEqual(fixes.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    const commaSelector = /\,(?![^\(|\"]*(\)|\"))/;
    expect(fixes.every(({invert, ignoreInlineStyle, ignoreImageAnalysis}) => (invert || []).concat(ignoreInlineStyle || []).concat(ignoreImageAnalysis || []).every((s) => !commaSelector.test(s)))).toBe(true);

    // fixes are properly formatted
    expect(throwIfDifferent(file, formatDynamicThemeFixes(fixes), 'Dynamic fixes format error')).not.toThrow();

    // should parse empty config
    expect(parseDynamicThemeFixes('')).toEqual([]);

    // should skip unsupported commands
    expect(parseDynamicThemeFixes([
        'inbox.google.com',
        'mail.google.com',
        'INVERT', 'a', 'b',
        'CSS', '.x { color: white !important; }',
        'UNSUPPORTED', 'c', 'd',
        '========',
        'twitter.com',
        'UNSUPPORTED', 'a', 'b',
        'INVERT', 'c', 'd',
        '========',
        'wikipedia.org',
        'IGNORE INLINE STYLE', 'a', 'b',
        '========',
        'duckduckgo.com',
        'IGNORE IMAGE ANALYSIS', 'img[alt="Logo"]', 'canvas',
    ].join('\n'))).toEqual([
        {url: ['inbox.google.com', 'mail.google.com'], invert: ['a', 'b'], css: '.x { color: white !important; }'},
        {url: ['twitter.com'], invert: ['c', 'd']},
        {url: ['wikipedia.org'], ignoreInlineStyle: ['a', 'b']},
        {url: ['duckduckgo.com'], ignoreImageAnalysis: ['img[alt="Logo"]', 'canvas']},
    ] as any);
});

test('Inversion Fixes config', async () => {
    const file = await readConfig('inversion-fixes.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const fixes = parseInversionFixes(file);

    // there is a common fix
    expect(fixes[0].url[0]).toEqual('*');

    // each fix has valid URL
    expect(fixes.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // fixes are sorted alphabetically
    expect(fixes.map(({url}) => url[0])).toEqual(fixes.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    expect(fixes.every(({invert, noinvert, removebg}) => (invert || []).concat(noinvert || []).concat(removebg || []).every((s) => s.indexOf(',') < 0))).toBe(true);

    // fixes are properly formatted
    expect(throwIfDifferent(file, formatInversionFixes(fixes), 'Inversion fixes format error')).not.toThrow();
});

test('Static Themes config', async () => {
    const file = await readConfig('static-themes.config');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const themes = parseStaticThemes(file);

    // there is a common theme
    expect(themes[0].url[0]).toEqual('*');

    // each theme has valid URL
    expect(themes.every(({url}) => url.every(isURLPatternValid))).toBe(true);

    // themes are sorted alphabetically
    expect(themes.map(({url}) => url[0])).toEqual(themes.map(({url}) => url[0]).sort(compareURLPatterns));

    // selectors should have no comma
    expect(themes.every((t) => (Object.keys(t) as Array<keyof StaticTheme>)
        .filter((prop) => ['url', 'noCommon'].indexOf(prop) < 0)
        .every((prop) => (t[prop] as string[])
            .every((s) => s.indexOf(',') < 0)))).toBe(true);

    // fixes are properly formatted
    expect(throwIfDifferent(file, formatStaticThemes(themes), 'Static theme format error')).not.toThrow();
});

test('Colorscheme config', async () => {
    const file = await readConfig('color-schemes.drconf');

    // there is no \r character
    expect(file.indexOf('\r')).toEqual(-1);

    // there are no trailing spaces
    expect(file.indexOf(' \n')).toEqual(-1);

    const {result: schemes, error} = parseColorSchemeConfig(file);

    // Their is no error
    expect(error).toBeNull();

    // There is a default Dark color scheme
    expect(schemes.dark['Default']).toBeDefined();

    // There is a default Light color scheme
    expect(schemes.light['Default']).toBeDefined();

    // Check formatting
    expect(formatColorSchemeConfig(schemes)).toEqual(file);
});

[evidence record sha256:dc8579013782f47744d8bd29422c6820cc62b86bc845735fb1680af6acfaca1a kind tool-call:read]
step 9: calling local:qwen3.6:35b-a3b
tool declare_file_set <- {"files":["src/generators/dynamic-theme.ts"]}
tool declare_file_set ok: a file set was already declared for this session. Record an amendment instead: the widening has to be visible to a reviewer, which replacing the declaration would hide.
[evidence record sha256:cc6fab149a9c6a43f9f7c1a3dadf262fa350c4898a23c12adab49a6739f2571f kind tool-call:declare_file_set]
step 10: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"git diff --stat"}
tool shell ok: exit code: 0
[evidence record sha256:d21fe52487b56360e2c8735aeaf8f30eac77ff56465646eeb9c513b7ee2f0640 kind tool-call:shell]
step 11: calling local:qwen3.6:35b-a3b
tool amend_file_set <- {"files":["src/generators/dynamic-theme.ts"],"reason":"The first attempt edited src/generators/dynamic-theme.ts without declaring it, causing the file-set gate to fail. I have restored the original file and now need to declare this file before re-applying the fix to change '!=' to '===' on the command check for CSS parsing."}
tool amend_file_set ok: the declared file set now covers 1 file(s)
[evidence record sha256:efbd0d0b285d49216335061a5265e8827608212b9d228e226cb6a45b49079041 kind tool-call:amend_file_set]
step 12: calling local:qwen3.6:35b-a3b
tool edit <- {"path":"src/generators/dynamic-theme.ts","find":"            if (command !== 'CSS') {","replace":"            if (command === 'CSS') {"}
tool edit ok: replaced 1 occurrence(s) in src/generators/dynamic-theme.ts
[evidence record sha256:31311e897cf1ff299950e49e70885d36f9955fffae13e73d4d37f2b8fcbffc8b kind tool-call:edit]
step 13: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"npm run --silent test 2>&1 | tail -30","timeoutMs":120000}
tool shell ok: exit code: 0
stdout:
PASS tests/unit/config/config.tests.ts
PASS tests/unit/utils/state-manager.tests.ts
PASS tests/unit/config/locales.tests.ts
PASS tests/unit/utils/promise-barrier.tests.ts
PASS tests/unit/utils/color.tests.ts
PASS tests/unit/utils/validation.tests.ts
PASS tests/unit/utils/url.tests.ts
PASS tests/unit/utils/time.tests.ts
PASS tests/unit/utils/text.tests.ts
PASS tests/unit/inject/fixes.tests.ts
PASS tests/unit/generators/utils/parse.tests.ts
PASS tests/unit/inject/selectors.tests.ts
PASS tests/unit/utils/parsing.tests.ts
PASS tests/unit/utils/uid.tests.ts
PASS tests/unit/csp/csp.tests.ts
PASS tests/unit/utils/math.tests.ts

Test Suites: 16 passed, 16 total
Tests:       75 passed, 75 total
Snapshots:   0 total
Time:        1.39 s
Ran all test suites.
[evidence record sha256:da61080766bf0be2da0af8c3bdc15424e730bb4786deb895584cbe6c1138c905 kind tool-call:shell]
step 14: calling local:qwen3.6:35b-a3b
tool claim <- {"predicate":"facts.exitCode == 0","record":"da61080766bf0be2da0af8c3bdc15424e730bb4786deb895584cbe6c1138c905","recordKind":"tool-call:shell"}
tool claim failed: denied: input rejected: [
  {
    "origin": "string",
    "code": "invalid_format",
    "format": "regex",
    "pattern": "/^sha256:[0-9a-f]{64}$/",
    "path": [
      "record"
    ],
    "message": "Invalid string: must match pattern /^sha256:[0-9a-f]{64}$/"
  }
]
[evidence record sha256:c9fa9ec132e07c34ded1c92b80d4ee8356068b51b066f7e53fc171e31eaac26c kind tool-call:claim]
step 15: calling local:qwen3.6:35b-a3b
tool claim <- {"predicate":"facts.exitCode == 0","record":"sha256:da61080766bf0be2da0af8c3bdc15424e730bb4786deb895584cbe6c1138c905","recordKind":"tool-call:shell"}
tool claim ok: VERIFIED: the harness evaluated the predicate against the cited tool-call:shell record and it held
[evidence record sha256:eddcc43b85dfb3f5cfed742084d3fb14dc3b551b6136906d4b984ed63f304615 kind tool-call:claim]
step 16: calling local:qwen3.6:35b-a3b
claim (unverified): Summary of the fix:

**Defect:** In `src/generators/dynamic-theme.ts` line 26, the condition in `parseDynamicThemeFixes` was inverted. The code checked `if (command !== 'CSS')` which returned a trimmed string for non-CSS commands and called `parseArray(value)` for CSS properties.

**Bug impact:** This meant CSS values were parsed as arrays (e.g., `[".selector", "!important"]`) instead of as formatted strings, causing the "Dynamic fixes format error" test failure when comparing parse → format round-trips.

**Fix:** Changed `command !== 'CSS'` to `command === 'CSS'`, so the CSS command returns a trimmed string value and all other commands (INVERT, IGNORE INLINE STYLE, IGNORE IMAGE ANALYSIS) go through `parseArray()` which correctly returns arrays.

Result: All 75 tests across 16 test suites pass.
stopped: completed after 16 steps, 117162 tokens
gate typecheck not-applicable: package.json declares no typecheck script [evidence record sha256:81e5bc34c76ccd066aba574f815550ddb8a53ef241292bcee176472f2a07b09a]
gate lint passed: the command exited 0 [evidence record sha256:130e86046469a397805b0e14ec37c9f9c2d8f3a654e09fff138c7233b03c92ea]
gate format not-applicable: package.json declares no check-only format script, and running a writing formatter as a gate would edit the tree it is judging [evidence record sha256:6920e5a176ea5e96d174e1f9daeb0b28dc3ee2ec8a64abe88be1f4c54d7534a6]
gate tests passed: the command exited 0 [evidence record sha256:0f11fc702806bd7249856f824cff6b168cac32a8a1c72908d578dcdd00ad7ff3]
gate file-set passed: all 1 changed file(s) are inside the declared set of 1, and every one of them was declared before it was edited [evidence record sha256:4835b39a7e90bdf18e1dff952af13b9c11e513795c474f106540a6c9f4e5e26b]
gate placeholder passed: no placeholder marker was introduced by this change [evidence record sha256:80a69ddf538b2edff3530ed1afc787650dc7d826a04eded035e165077cbe6257]
gate secret-scan passed: no known credential pattern appears in the added lines [evidence record sha256:48401cbfcc12987dfae6c002c84fc54a4e94fc5d6e443f68ed699bb2fc400bbf]
gate behaviour-probe passed: 0 changed function(s) still answer to their inputs. [evidence record sha256:d10ec5b4c8a1d40b28d094707e71408003a41b576e152d86d5eeb98612fa9caa]
gate diff-budget passed (advisory): within budget: 1 file(s) and 1 added line(s) [evidence record sha256:d0f1c50406283703bcb20cc9d89ca2fc2bd86d79187be45e836de427e0b167ac]
ratchet accepted attempt 2: the ratchet accepted the attempt: no measure moved the wrong way (not compared: testsCollected, changedLineCoverage) [evidence record sha256:7348127920affa0e598b6aa9e091f7148094101d1b0394965c36e1b1e8820505]

gates:
  n/a      typecheck: package.json declares no typecheck script
  passed   lint: the command exited 0
  n/a      format: package.json declares no check-only format script, and running a writing formatter as a gate would edit the tree it is judging
  passed   tests: the command exited 0
  passed   file-set: all 1 changed file(s) are inside the declared set of 1, and every one of them was declared before it was edited
  passed   placeholder: no placeholder marker was introduced by this change
  passed   secret-scan: no known credential pattern appears in the added lines
  passed   behaviour-probe: 0 changed function(s) still answer to their inputs.
  passed   diff-budget (advisory): within budget: 1 file(s) and 1 added line(s)
attempt 1: accepted - the ratchet accepted the attempt: no measure moved the wrong way (not compared: testsCollected, changedLineCoverage)
attempt 2: accepted - the ratchet accepted the attempt: no measure moved the wrong way (not compared: testsCollected, changedLineCoverage)

routing reward: 0.137 (green with 2 retries, 317s, and $0.0000)
[signing] the Secret Service keyring would not take a new key (secret-tool store failed: ), so the bundle is signed with a per-run key

evidence bundle: /out/bundle
verify it anywhere: node /out/bundle/verify.mjs /out/bundle
review it: open /out/bundle/review.html
what this run produced

  the page a person reads: /out/bundle/review.html
  the bundle a stranger verifies: /out/bundle
  its own verifier, needing nothing installed: node /out/bundle/verify.mjs /out/bundle
  the chain every record is on: /out/bundle/ledger.jsonl

  201 records. The harness verified 2 claim(s) and refused 0.
  bundle verified in this run: verify.mjs exited 0
[chokepoint] refusing shell without a terminal to confirm on: "git diff src/generators/dynamic-theme.ts 2>/dev/null; echo "---EXIT: $?"" is not on the shell allowlist.
