Torn Wiki Dark

Dark-gray + cyan skin for *all* pages on wiki.torn.com.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Torn Wiki Dark
// @namespace    https://github.com/skillerious
// @version      2.6
// @description  Dark-gray + cyan skin for *all* pages on wiki.torn.com.
//               • Static sidebar, centred content column
//               • Cyan headings & links, darker logo tile
//               • Cyan scrollbar, zero white leaks
//               • 64 px progress-ring “Back to Top” button, perfectly centred, clickable & smooth-scrolling
//               2025-07-12 build 🔵⬆️🌑
// @author       Robin Doak (Skillerious)
// @match        https://wiki.torn.com/wiki/*
// @match        https://wiki.torn.com/*
// @include      /^https:\/\/wiki\.torn\.com\/.*$/
// @grant        none
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(() => {
  /*───────────────────────────────────────────────────────────────
    1.  GLOBAL CSS THEME
  ───────────────────────────────────────────────────────────────*/
  const css = `
  /* ─── Colour palette & constants ───────────────────────────── */
  :root {
    --bg          : #1b1b1b;
    --surface     : #242424;
    --surface-2   : #2e2e2e;
    --card        : #282828;

    --cyan        : #55c3ff;
    --cyan-light  : #7ad0ff;

    --border      : #3d3d3d;
    --text-main   : #d5d7da;
    --text-muted  : #9ca2a8;

    --radius      : 6px;
    --shadow      : 0 3px 10px rgb(0 0 0 / 0.5);
    --max-read    : 950px;
  }

  /* ─── Base layout & typography ─────────────────────────────── */
  body,
  #content,
  .container,
  .row,
  .content-area-wrapper,
  .mw-parser-output,
  .mw-body {
    background: var(--bg) !important;
    color: var(--text-main) !important;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                 Arial, sans-serif;
  }

  .content-area-wrapper {
    flex: 1 1 auto !important;
    padding: 0 1rem;
  }

  #content {
    max-width: var(--max-read);
    margin: 0 auto;
  }

  h1, h2, h3, h4, h5, h6 {
    color: var(--cyan) !important;
    font-weight: 700;
    line-height: 1.3;
    margin: 1.2em 0 0.6em;
  }

  h1 { font-size: 2.15rem; border: none; }
  h2 { font-size: 1.55rem; border-bottom: 1px solid var(--cyan); padding-bottom: 0.4rem; }
  h3 { font-size: 1.25rem; }
  h4, h5, h6 { font-size: 1.1rem; }

  /* ─── Links ────────────────────────────────────────────────── */
  a {
    color: var(--cyan);
    text-decoration: none;
    transition: color 0.15s;
  }

  a:hover {
    color: var(--cyan-light);
    text-decoration: underline;
  }

  a[target="_blank"]::after {
    content: "↗";
    font-size: 0.75em;
    margin-left: 2px;
    vertical-align: super;
    color: var(--text-muted);
  }

  /* ─── Sidebar & logo tile ─────────────────────────────────── */
  .side-panel-wrapper {
    background: var(--surface);
    border-right: 1px solid var(--border);
  }

  .side-panel-wrapper .card {
    background: var(--surface) !important;
    border: none !important;
  }

  .card.torn-navigation-header {
    background: var(--surface-2) !important;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 1.4rem 0 1rem;
  }

  .torn-title-text {
    font-size: 2.35rem;
    font-weight: 900;
    line-height: 1;
    color: var(--cyan) !important;
    letter-spacing: 1px;
  }

  .torn-title-text span {
    font-weight: 300;
    margin-left: 0.25rem;
    color: var(--cyan) !important;
  }

  .torn-title-text::after {
    content: "";
    display: block;
    width: 80%;
    height: 4px;
    background: var(--cyan);
    margin: 0.45rem auto 0;
    border-radius: 2px;
  }

  .torn-back-button {
    margin-top: 0.85rem;
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--text-main);
    display: flex;
    align-items: center;
    gap: 4px;
    text-decoration: none;
  }

  .torn-back-button svg path { fill: #b0b0b0; }
  .torn-back-button:hover { color: var(--cyan); }
  .torn-back-button:hover svg path { fill: var(--cyan); }

  /* Navigation links inside sidebar */
  .torn-navigation-panel nav a.nav-link {
    color: var(--text-muted);
    border-radius: var(--radius);
    margin: 0.13rem 0;
    padding: 0.32rem 0.8rem;
    transition: background 0.15s, color 0.15s;
  }

  .torn-navigation-panel nav a.nav-link:hover,
  .torn-navigation-panel nav a.nav-link.active {
    background: var(--surface-2);
    color: var(--text-main);
  }

  .torn-navigation-panel nav a.nav-link.disabled {
    color: var(--cyan) !important;
    font-weight: 700;
    cursor: default;
  }

  /* ─── Table of Contents ────────────────────────────────────── */
  #toc,
  .toc {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.9rem 1rem 1rem;
    margin-bottom: 1.5rem;
  }

  #toc .toctitle h2 {
    margin: 0 0 0.55rem;
    font-size: 1.2rem;
    color: var(--cyan);
    border: none;
  }

  #toc ul,
  .toc ul { padding-left: 1.25rem; margin: 0; }

  #toc li,
  .toc li { line-height: 1.5; }

  /* ─── Tables ──────────────────────────────────────────────── */
  table, th, td { border-color: var(--border) !important; }

  table {
    background: var(--surface) !important;
    border-collapse: collapse !important;
  }

  th, td {
    background: var(--card) !important;
    color: var(--text-main) !important;
    padding: 6px 8px !important;
  }

  th[style*="background"],
  td[style*="background"] { background: var(--card) !important; }

  tr:nth-child(even) td { background: var(--surface) !important; }

  .mw-collapsible-toggle a { color: var(--cyan); font-weight: 600; }

  /* ─── Info / alert boxes ─────────────────────────────────── */
  .alert,
  .ambox,
  .mbox,
  .infobox,
  .new-infobox {
    background: var(--surface);
    border: 1px solid var(--border) !important;
    color: var(--text-main) !important;
  }

  .alert-warning,
  .alert.alert-warning {
    background: var(--surface-2) !important;
    color: var(--text-main) !important;
    border: 1px solid var(--border) !important;
  }

  .infobox th,
  .new-infobox-heading {
    background: var(--surface-2) !important;
    color: var(--text-main) !important;
  }

  /* ─── Code blocks ────────────────────────────────────────── */
  pre,
  code {
    background: var(--surface-2) !important;
    color: var(--text-main) !important;
    border: 1px solid var(--border) !important;
    border-radius: var(--radius);
  }

  pre { padding: 10px; overflow: auto; }

  /* ─── Forms ──────────────────────────────────────────────── */
  input,
  textarea,
  select {
    background: var(--surface-2) !important;
    color: var(--text-main) !important;
    border: 1px solid var(--border) !important;
  }

  input::placeholder,
  textarea::placeholder { color: var(--text-muted); }

  /* ─── Footer & scrollbar ─────────────────────────────────── */
  #footer,
  #footer-info,
  #footer-places {
    background: var(--bg) !important;
    color: var(--text-muted) !important;
  }

  #footer a { color: var(--cyan); }

  ::-webkit-scrollbar { width: 12px; height: 12px; }
  ::-webkit-scrollbar-track { background: var(--bg); }
  ::-webkit-scrollbar-thumb {
    background: var(--cyan);
    border-radius: 6px;
    transition: background 0.2s;
  }
  ::-webkit-scrollbar-thumb:hover { background: var(--cyan-light); }

  html {
    scrollbar-width: thin;
    scrollbar-color: var(--cyan) var(--bg);
  }

  /* ─── Hide Torn’s built-in back-to-top ───────────────────── */
  #torn-back-to-top { display: none !important; }

  /* ─── Back-to-Top FAB animation (no overshoot) ───────────── */
  @keyframes twPop {
    0%   { transform: scale(0.4); opacity: 0;   }
    100% { transform: scale(1);   opacity: 0.95; }
  }

  /* ─── FAB container (64 × 64 px) ─────────────────────────── */
  #tw-b2t {
    position: fixed;
    right: 1.4rem;
    bottom: 1.4rem;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    backdrop-filter: blur(8px);
    background: rgba(85, 195, 255, 0.12);
    box-shadow: var(--shadow);
    cursor: pointer;

    opacity: 0;
    pointer-events: none;
    transform: scale(0.4);
    transition: box-shadow 0.25s;
    z-index: 3000;
  }

  #tw-b2t.show {
    animation: twPop 0.33s ease-out forwards;
    pointer-events: auto;   /* <— makes it clickable */
  }

  #tw-b2t:hover {
    box-shadow: 0 0 14px var(--cyan-light), var(--shadow);
  }

  /* Progress ring */
  #tw-b2t svg.ring {
    position: absolute;
    top: 0;
    left: 0;
    width: 64px;
    height: 64px;
    transform: rotate(-90deg);
  }

  #tw-ring-track {
    stroke: rgba(255, 255, 255, 0.07);
    stroke-width: 8;
    fill: none;
  }

  #tw-ring-progress {
    stroke: var(--cyan);
    stroke-width: 8;
    stroke-linecap: round;
    fill: none;
    transition: stroke-dashoffset 0.1s;
  }

  /* Arrow */
  .tw-arrow {
    position: absolute;
    width: 26px;
    height: 26px;
    fill: var(--cyan);
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    transition: transform 0.25s;
  }

  #tw-b2t:hover .tw-arrow {
    transform: translate(-50%, -55%);
  }
  `;
  document.head.appendChild(document.createElement('style')).textContent = css;

  /*───────────────────────────────────────────────────────────────
    2.  Make external links open in a new tab
  ───────────────────────────────────────────────────────────────*/
  document.querySelectorAll('a[href]').forEach(link => {
    const href = link.getAttribute('href') || '';
    if (href.startsWith('#') || href.toLowerCase().startsWith('javascript')) return;

    /* treat as external if hostname differs */
    if (link.hostname && link.hostname !== location.hostname) {
      link.target = '_blank';
      link.rel = 'noopener';
    }
  });

  /*───────────────────────────────────────────────────────────────
    3.  Build smaller (64 px) Back-to-Top FAB
  ───────────────────────────────────────────────────────────────*/
  const SIZE        = 64;  // px
  const STROKE      = 8;   // px
  const RADIUS      = 28;  //  (28 × 2) + 8 = 64
  const CIRCUMFERENCE = 2 * Math.PI * RADIUS;

  /* container */
  const fab = document.createElement('div');
  fab.id = 'tw-b2t';

  /* inner SVG (ring) + arrow */
  fab.innerHTML = `
    <svg class="ring" viewBox="0 0 ${SIZE} ${SIZE}">
      <circle
        cx="${SIZE / 2}"
        cy="${SIZE / 2}"
        r="${RADIUS}"
        stroke-width="${STROKE}"
        fill="none"
        stroke="rgba(255,255,255,0.07)"
      ></circle>

      <circle
        id="tw-ring-progress"
        cx="${SIZE / 2}"
        cy="${SIZE / 2}"
        r="${RADIUS}"
        stroke-width="${STROKE}"
        fill="none"
        stroke="var(--cyan)"
        stroke-linecap="round"
        stroke-dasharray="${CIRCUMFERENCE}"
        stroke-dashoffset="${CIRCUMFERENCE}"
      ></circle>
    </svg>

    <svg class="tw-arrow" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path d="M12 6 6 12l-1.4-1.4L12 3.2l7.4 7.4L18 12z"></path>
    </svg>
  `;
  document.body.appendChild(fab);

  const ring = fab.querySelector('#tw-ring-progress');

  /* smooth scroll behaviour */
  fab.addEventListener('click', () => {
    window.scrollTo({
      top: 0,
      behavior: 'smooth'
    });
  });

  /* update ring offset + FAB visibility on scroll */
  const updateFab = () => {
    const max = document.documentElement.scrollHeight - window.innerHeight;
    const pct = max ? Math.min(window.scrollY / max, 1) : 0;

    ring.style.strokeDashoffset = CIRCUMFERENCE * (1 - pct);
    fab.classList.toggle('show', window.scrollY > 150);
  };

  window.addEventListener('scroll', updateFab, { passive: true });
  updateFab();   // run once on load

  console.info('[Torn Wiki Dark-Gray] v2.6 loaded – FAB clickable & smaller');
})();