Greasy Fork is available in English.

QQ/SB/SV Mobile readability

Standardize font size to 15px and revert justified text; avoid text that is too small or too big. Replace fonts with sans-serif/serif/monospace at calibrated sizes (avoid unsupported/mismatched desktop fonts). Dodge colored text from the background and lightly pastelize to improve contrast.

// ==UserScript==
// @name        QQ/SB/SV Mobile readability
// @description Standardize font size to 15px and revert justified text; avoid text that is too small or too big. Replace fonts with sans-serif/serif/monospace at calibrated sizes (avoid unsupported/mismatched desktop fonts). Dodge colored text from the background and lightly pastelize to improve contrast. 
// @author      C89sd
// @version     1.3
// @match       https://forum.questionablequesting.com/threads/*
// @match       https://forums.spacebattles.com/threads/*
// @match       https://forums.sufficientvelocity.com/threads/*
// @namespace   https://greasyfork.org/users/1376767
// ==/UserScript==

'use strict';

const colorCache = new Map();
const adjustTextColor = (textRGBStr) => {
    if (colorCache.has(textRGBStr)) {
        return colorCache.get(textRGBStr);
    }

    function toRGB(str) { // can return up to 3 values [] to [r,g,b]
        const nums = str.match(/\d+/g);
        return nums ? nums.map(Number).slice(0, 3) : [];
    }

    let fg = toRGB(textRGBStr);
    const bg = toRGB("rgb(39, 39, 39)");

    if (fg.length !== 3) { return textRGBStr }

    const clamp = v => Math.max(0, Math.min(255, v));
    const pastelize = ([r, g, b]) => {
        const neutral = 128;
        const whiteBoost = Math.pow((r + g + b) / (3 * 255), 10);
        const factor = 0.8 + 0.1*whiteBoost;
        return [
            neutral + factor * (r - neutral),
            neutral + factor * (g - neutral),
            neutral + factor * (b - neutral)
        ].map(clamp);
    };

    fg = pastelize(fg);

    let positiveDiff = 0;
    positiveDiff += Math.max(0, fg[0] - 39);
    positiveDiff += Math.max(0, fg[1] - 39);
    positiveDiff += Math.max(0, fg[2] - 39);

    const threshold = 180;
    if (positiveDiff < threshold) {
      fg[0] = Math.max(fg[0], 39);
      fg[1] = Math.max(fg[1], 39);
      fg[2] = Math.max(fg[2], 39);

      const avg = (fg[0]+fg[1]+fg[2])/3;
      const boost = Math.min(1.0, (Math.abs(fg[0]-avg)+Math.abs(fg[1]-avg)+Math.abs(fg[2]-avg))/255/0.2); // grays = 0, colors >= 1

      let correction = Math.round((threshold - positiveDiff) / 3 + boost*40);
      fg = fg.map(c => Math.min(c + correction, 255));
    }

    const result = `rgb(${fg[0]}, ${fg[1]}, ${fg[2]})`;
    colorCache.set(textRGBStr, result);

    return result;
};


const SANS_SERIF = /arial|tahoma|trebuchet ms|verdana/;
const MONOSPACE = /courier new/;
const SERIF = /times new roman|georgia|book antiqua/;

const wrappers = document.querySelectorAll('div.bbWrapper');
for (let wrapper of wrappers) {
  wrapper.style.fontSize = '15px';

  const children = wrapper.querySelectorAll('*');
  for (let child of children) {
    const style = child.style;

    if (style.fontSize) {
      style.fontSize = '';
    }

    if (style.fontFamily) {
      const font = style.fontFamily;
      if (SANS_SERIF.test(font)) {
        style.fontFamily = 'sans-serif';
      } else if (MONOSPACE.test(font)) {
        style.fontFamily = 'monospace';
        style.fontSize = '13.5px';
      } else if (SERIF.test(font)) {
        style.fontFamily = 'serif';
      }
    }

    if (style.textAlign) {
      if (style.textAlign !== 'center' && style.textAlign !== 'right') {
        style.textAlign = '';
      }
    }

    if (style.color && style.color.startsWith('rgb')) {
      style.color = adjustTextColor(style.color);
    }
  }
}