您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Modernizes layout/typography, adds auto dark/light, improves readability across sub-sites
// ==UserScript== // @name GrometsPlaza // @namespace Gromet // @description Modernizes layout/typography, adds auto dark/light, improves readability across sub-sites // @copyright tightnshiny // @icon https://grometsplaza.net/favicon.ico // // @match https://grometsplaza.net/* // @match https://www.grometsplaza.net/* // @match https://www.selfbound.net/* // @match https://www.mummified.net/* // @match https://www.boundstories.net/* // @match https://www.latexstories.net/* // @match https://www.packagedstories.net/* // @match https://www.dollstories.net/* // @match https://www.maidbots.net/* // @match https://www.trashcanstories.net/* // @match https://www.devouredstories.net/* // // @grant none // @run-at document-start // // @license MIT // @version 1.0.0 // ==/UserScript== (function() { 'use strict'; // Settings const STORAGE_KEY = 'gp-theme'; // 'auto' | 'dark' | 'light' const READ_KEY = 'gp-reading'; // 'narrow' | 'wide' const DATA_ATTR = 'data-gp-theme'; const READING_ATTR = 'data-gp-reading'; const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)'); function getStoredMode() { try { const v = localStorage.getItem(STORAGE_KEY); return v === 'dark' || v === 'light' || v === 'auto' ? v : null; } catch (_) { return null; } } function setStoredMode(v) { try { localStorage.setItem(STORAGE_KEY, v); } catch (_) {} } function computeEffective(mode) { if (mode === 'dark' || mode === 'light') return mode; return prefersDark && prefersDark.matches ? 'dark' : 'light'; } function applyThemeAttr(mode) { const effective = computeEffective(mode); document.documentElement.setAttribute(DATA_ATTR, effective); try { document.documentElement.style.colorScheme = effective === 'dark' ? 'dark' : 'light'; } catch (_) {} } // Early paint: set initial theme and minimal background to reduce FOUC const initMode = getStoredMode() || 'auto'; applyThemeAttr(initMode); try { if (computeEffective(initMode) === 'dark') { document.documentElement.style.backgroundColor = '#0f1115'; } } catch (_) {} // React to OS theme changes in auto mode if (prefersDark && typeof prefersDark.addEventListener === 'function') { prefersDark.addEventListener('change', () => { if ((getStoredMode() || 'auto') === 'auto') applyThemeAttr('auto'); }); } // Reading width function getReadingMode() { try { const v = localStorage.getItem(READ_KEY); return v === 'wide' ? 'wide' : 'narrow'; } catch (_) { return 'narrow'; } } function setReadingMode(v) { try { localStorage.setItem(READ_KEY, v); } catch (_) {} } function applyReadingAttr(mode) { const m = mode === 'wide' ? 'wide' : 'narrow'; document.documentElement.setAttribute(READING_ATTR, m); } applyReadingAttr(getReadingMode()); // Accent per host function applyHostAccent() { const host = (location.hostname || '').replace(/^www\./, ''); const map = { 'grometsplaza.net': '#2b90d9', 'boundstories.net': '#ef4444', 'selfbound.net': '#3b82f6', 'mummified.net': '#a855f7', 'latexstories.net': '#64748b', 'packagedstories.net': '#14b8a6', 'dollstories.net': '#ec4899', 'maidbots.net': '#06b6d4', 'trashcanstories.net': '#f97316', 'devouredstories.net': '#10b981' }; const accent = map[host] || '#2b90d9'; try { document.documentElement.style.setProperty('--gp-accent', accent); } catch (_) {} document.documentElement.setAttribute('data-gp-host', host); // Mark legacy subsites that use older fixed layouts const legacyHosts = new Set([ 'boundstories.net','selfbound.net','mummified.net','latexstories.net', 'packagedstories.net','dollstories.net','maidbots.net','trashcanstories.net','devouredstories.net' ]); document.documentElement.setAttribute('data-gp-legacy', legacyHosts.has(host) ? '1' : '0'); } function applyPathContext() { const path = (location.pathname || '').toLowerCase(); const isWorld = /(^|\/)world\//.test(path); document.documentElement.setAttribute('data-gp-world', isWorld ? '1' : '0'); } applyPathContext(); // Mark root subpages that should use the "home-like" layout tweaks function applyMainlikeContext() { const path = (location.pathname || '').toLowerCase(); const mainlike = ( /^\/search\.html$/.test(path) || /^\/links\.html$/.test(path) || /^\/pages\/(writers|storycodes)\.html$/.test(path) || /^\/author_[a-z]+\.html$/.test(path) ); document.documentElement.setAttribute('data-gp-mainlike', mainlike ? '1' : '0'); } applyMainlikeContext(); applyHostAccent(); // Inject a viewport meta for better mobile layout function ensureViewport() { if (document.querySelector('meta[name="viewport"]')) return; const meta = document.createElement('meta'); meta.name = 'viewport'; meta.content = 'width=device-width, initial-scale=1'; (document.head || document.documentElement).appendChild(meta); } // Critical CSS to normalize backgrounds fast function injectCriticalStyles() { if (document.getElementById('gp-critical')) return; const style = document.createElement('style'); style.id = 'gp-critical'; style.textContent = ` html[${DATA_ATTR}="dark"], html[${DATA_ATTR}="dark"] body { background:#0f1115 !important; } `; const root = document.documentElement; if (root && root.firstChild) root.insertBefore(style, root.firstChild); else root.appendChild(style); } // Full stylesheet: typography, layout, light/dark tokens function injectFullStyles() { if (document.getElementById('gp-styles')) return; const style = document.createElement('style'); style.id = 'gp-styles'; style.textContent = ` /* Tokens: default to light */ :root { --gp-bg: #f7f8fb; --gp-surface: #ffffff; --gp-surface-2: #f3f4f6; --gp-fg: #111418; --gp-fg-muted: #4b5563; --gp-link: #0b6bcb; --gp-link-visited: #6b44b3; --gp-border: #d0d7de; --gp-accent: #2b90d9; --gp-chip-bg: #eef2ff; --gp-chip-fg: #384bfd; --gp-read-width: 66ch; /* extra taxonomy chips (light) */ --chip-package-bg:#efe9ff; --chip-package-fg:#5b21b6; --chip-package-bd:#ddd6fe; --chip-mummify-bg:#fde7f4; --chip-mummify-fg:#9d174d; --chip-mummify-bd:#fbcfe8; --chip-trash-bg:#e7f5d8; --chip-trash-fg:#166534; --chip-trash-bd:#ccebc0; --chip-doll-bg:#ffe9f6; --chip-doll-fg:#9d174d; --chip-doll-bd:#ffc7e8; --chip-machine-bg:#eeeeee; --chip-machine-fg:#374151; --chip-machine-bd:#d1d5db; --chip-buried-bg:#111111; --chip-buried-fg:#e5e7eb; --chip-buried-bd:#27272a; --chip-giant-bg:#d6ffe0; --chip-giant-fg:#065f46; --chip-giant-bd:#a7f3d0; /* taxonomy chip defaults (light) */ --chip-bound-bg: #fee2e2; --chip-bound-fg: #991b1b; --chip-bound-bd: #fecaca; --chip-sb-bg: #dbeafe; --chip-sb-fg: #1e40af; --chip-sb-bd: #bfdbfe; --chip-latex-bg: #e5e7eb; --chip-latex-fg:#374151; --chip-latex-bd:#d1d5db; --chip-erotic-bg:#fde2f3; --chip-erotic-fg:#9d174d; --chip-erotic-bd:#fbcfe8; } html[${DATA_ATTR}="dark"] { --gp-bg: #0f1115; --gp-surface: #151a21; --gp-surface-2: #12161c; --gp-fg: #e6e8eb; --gp-fg-muted: #9aa4af; --gp-link: #8ab4f8; --gp-link-visited: #c58af9; --gp-border: #2a3138; --gp-accent: #4da6ff; --gp-chip-bg: #1f2630; --gp-chip-fg: #9db7ff; /* taxonomy chip defaults (dark) */ --chip-bound-bg: #3b1f23; --chip-bound-fg: #fca5a5; --chip-bound-bd: #7f1d1d; --chip-sb-bg: #1e293b; --chip-sb-fg: #93c5fd; --chip-sb-bd: #1e3a8a; --chip-latex-bg:#1f2937; --chip-latex-fg:#cbd5e1; --chip-latex-bd:#334155; --chip-erotic-bg:#3a1f2d; --chip-erotic-fg:#f9a8d4; --chip-erotic-bd:#831843; --chip-package-bg:#2a2238; --chip-package-fg:#c4b5fd; --chip-package-bd:#4c1d95; --chip-mummify-bg:#3a1f2d; --chip-mummify-fg:#f9a8d4; --chip-mummify-bd:#831843; --chip-trash-bg:#132916; --chip-trash-fg:#86efac; --chip-trash-bd:#14532d; --chip-doll-bg:#3a1f2d; --chip-doll-fg:#f9a8d4; --chip-doll-bd:#831843; --chip-machine-bg:#1f2937; --chip-machine-fg:#cbd5e1; --chip-machine-bd:#374151; --chip-buried-bg:#0b0b0c; --chip-buried-fg:#e5e7eb; --chip-buried-bd:#27272a; --chip-giant-bg:#052e24; --chip-giant-fg:#6ee7b7; --chip-giant-bd:#065f46; } /* Base */ html[${DATA_ATTR}], html[${DATA_ATTR}] body { background: var(--gp-bg) !important; /* reset any gradients */ background-image: none !important; color: var(--gp-fg) !important; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; } html[${DATA_ATTR}] body { font-family: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif !important; font-size: 16px !important; line-height: 1.7 !important; } /* Legacy subsites (light mode): restore classic body styling for layout compatibility */ html[${DATA_ATTR}][data-gp-legacy="1"][data-gp-theme="light"] BODY { background: #F0F0F0 !important; color: #303030 !important; font-family: Arial, Helvetica, sans-serif !important; font-size: 12px !important; margin: 0 !important; padding: 0 !important; } /* Containers */ html[${DATA_ATTR}] #top, html[${DATA_ATTR}] #head-outer, html[${DATA_ATTR}] #head, html[${DATA_ATTR}] #main { background: var(--gp-surface) !important; color: var(--gp-fg) !important; box-shadow: none !important; } html[${DATA_ATTR}] #main { max-width: 1320px; margin: 0 auto; padding: 12px 16px !important; } /* Home pages: no inner padding and wider max width */ html[${DATA_ATTR}] .home #main { padding: 0 !important; max-width: 1440px !important; } /* Main-like subpages: replicate home layout tweaks */ html[${DATA_ATTR}][data-gp-mainlike="1"] #main { padding: 0 !important; max-width: 1440px !important; margin: 0 auto; } html[${DATA_ATTR}][data-gp-mainlike="1"] #main > table { width: 100% !important; table-layout: fixed !important; } html[${DATA_ATTR}][data-gp-mainlike="1"] #main > table td { vertical-align: top !important; } html[${DATA_ATTR}][data-gp-mainlike="1"] #main > table > tbody > tr > td:first-child { width: 210px !important; } html[${DATA_ATTR}][data-gp-mainlike="1"] #main > table > tbody > tr > td:last-child { width: auto !important; } html[${DATA_ATTR}][data-gp-mainlike="1"] .sidebar { width: 210px !important; min-width: 210px !important; } html[${DATA_ATTR}][data-gp-mainlike="1"] .sidebar a { white-space: normal !important; word-break: normal !important; } html[${DATA_ATTR}][data-gp-mainlike="1"] .sidebar li { line-height: 1.35; } /* Author/links/search tables on main-like pages: normalize borders and backgrounds */ html[${DATA_ATTR}][data-gp-mainlike="1"] #main table { width: 100% !important; border-collapse: collapse !important; table-layout: fixed; } html[${DATA_ATTR}][data-gp-mainlike="1"] #main th, html[${DATA_ATTR}][data-gp-mainlike="1"] #main td { border: 1px solid var(--gp-border) !important; background: transparent !important; color: var(--gp-fg) !important; padding: 4px 6px !important; vertical-align: top !important; } html[${DATA_ATTR}="dark"][data-gp-mainlike="1"] #main th { background: var(--gp-surface-2) !important; } html[${DATA_ATTR}][data-gp-mainlike="1"] #main th[bgcolor], html[${DATA_ATTR}][data-gp-mainlike="1"] #main td[bgcolor], html[${DATA_ATTR}][data-gp-mainlike="1"] #main tr[bgcolor] { background: transparent !important; color: var(--gp-fg) !important; } html[${DATA_ATTR}][data-gp-mainlike="1"] #main a { color: var(--gp-link) !important; } html[${DATA_ATTR}][data-gp-mainlike="1"] #main a:visited { color: var(--gp-link-visited) !important; } /* World pages: stabilize legacy table layout */ html[${DATA_ATTR}][data-gp-world="1"] #main { padding: 0 !important; max-width: 1440px; margin: 0 auto; } html[${DATA_ATTR}][data-gp-world="1"] center { display:block; max-width: 1440px; margin: 0 auto; } html[${DATA_ATTR}][data-gp-world="1"] body > table, html[${DATA_ATTR}][data-gp-world="1"] center > table, html[${DATA_ATTR}][data-gp-world="1"] #main > table { width: 100% !important; table-layout: fixed !important; } html[${DATA_ATTR}][data-gp-world="1"] body > table td, html[${DATA_ATTR}][data-gp-world="1"] center > table td, html[${DATA_ATTR}][data-gp-world="1"] #main > table td { vertical-align: top !important; padding: 0 8px !important; } html[${DATA_ATTR}][data-gp-world="1"] body > table > tbody > tr > td:first-child, html[${DATA_ATTR}][data-gp-world="1"] center > table > tbody > tr > td:first-child, html[${DATA_ATTR}][data-gp-world="1"] #main > table > tbody > tr > td:first-child { width: 210px !important; min-width: 210px !important; } html[${DATA_ATTR}][data-gp-world="1"] body > table > tbody > tr > td:nth-child(2), html[${DATA_ATTR}][data-gp-world="1"] center > table > tbody > tr > td:nth-child(2), html[${DATA_ATTR}][data-gp-world="1"] #main > table > tbody > tr > td:nth-child(2) { width: auto !important; } html[${DATA_ATTR}][data-gp-world="1"] body > table > tbody > tr > td:last-child, html[${DATA_ATTR}][data-gp-world="1"] center > table > tbody > tr > td:last-child, html[${DATA_ATTR}][data-gp-world="1"] #main > table > tbody > tr > td:last-child { width: 220px !important; min-width: 220px !important; } /* World pages: replace float-based layout with margin gutters */ html[${DATA_ATTR}][data-gp-world="1"] .sidebar { float: left !important; width: 210px !important; } html[${DATA_ATTR}][data-gp-world="1"] .rhsbar { float: right !important; width: 220px !important; } html[${DATA_ATTR}][data-gp-world="1"] #main { margin-left: 230px !important; /* sidebar 210 + gutters */ margin-right: 240px !important; /* rhsbar 220 + gutters */ } /* World pages: avoid dl/dt/dd clear rules interfering with columns */ html[${DATA_ATTR}][data-gp-world="1"] dt { clear: none !important; } html[${DATA_ATTR}][data-gp-world="1"] dd { clear: none !important; } /* Home page: widen layout sensibly for legacy tables */ html[${DATA_ATTR}] .home #main > table { width: 100% !important; table-layout: fixed !important; } html[${DATA_ATTR}] .home #main > table td { vertical-align: top !important; } html[${DATA_ATTR}] .home #main > table > tbody > tr > td:first-child { width: 210px !important; } html[${DATA_ATTR}] .home #main > table > tbody > tr > td:last-child { width: auto !important; } /* Boxes and cards */ html[${DATA_ATTR}] .box-outer, html[${DATA_ATTR}] .box { background: var(--gp-surface-2) !important; border: 1px solid var(--gp-border) !important; border-radius: 12px !important; box-shadow: none !important; } html[${DATA_ATTR}] .box { padding: 10px 14px !important; } /* Readable story text blocks */ html[${DATA_ATTR}] .story1, html[${DATA_ATTR}] .story1c, html[${DATA_ATTR}] .story5l, html[${DATA_ATTR}] .story6, html[${DATA_ATTR}] .storym, html[${DATA_ATTR}] .style4, html[${DATA_ATTR}] .styleDW, html[${DATA_ATTR}] .style20, html[${DATA_ATTR}] .style21, html[${DATA_ATTR}] .style22 { max-width: var(--gp-read-width); margin: 0 auto; padding: 0 12px; font-size: 17px !important; line-height: 1.8 !important; } html[${READING_ATTR}="wide"] { --gp-read-width: 132ch; } /* When in reading wide mode on story pages, hide asides and widen */ html[${READING_ATTR}="wide"][data-gp-context="story"] #main { max-width: 1600px; } html[${READING_ATTR}="wide"][data-gp-context="story"] .gp-aside { display: none !important; } html[${READING_ATTR}="wide"][data-gp-context="story"] #main .box-outer:not(.gp-aside), html[${READING_ATTR}="wide"][data-gp-context="story"] #main .box:not(.gp-aside) { float: none !important; width: auto !important; max-width: none !important; clear: both !important; } /* Headings */ html[${DATA_ATTR}] h1, html[${DATA_ATTR}] h2, html[${DATA_ATTR}] h3, html[${DATA_ATTR}] h4 { font-weight: 650 !important; color: var(--gp-fg) !important; background: transparent !important; border: none !important; margin: 1.2em 0 0.6em !important; } html[${DATA_ATTR}] h1 b, html[${DATA_ATTR}] h1 B { background: transparent !important; color: inherit !important; display: inline !important; padding: 0 !important; border-radius: 0 !important; font-weight: 700 !important; } html[${DATA_ATTR}] h1 { font-size: 1.7rem !important; } html[${DATA_ATTR}] h2 { font-size: 1.4rem !important; } html[${DATA_ATTR}] h3 { font-size: 1.15rem !important; color: var(--gp-fg-muted) !important; } /* Paragraphs and lists */ html[${DATA_ATTR}] p { margin: 0.9em 0 !important; } html[${DATA_ATTR}] li { margin: 0.25em 0; } /* Links */ html[${DATA_ATTR}] a { color: var(--gp-link) !important; } html[${DATA_ATTR}] a:visited { color: var(--gp-link-visited) !important; } html[${DATA_ATTR}] a:hover { text-decoration: underline !important; } html[${DATA_ATTR}] a { word-break: break-word; } /* Definition lists: keep simple to avoid layout breakage */ html[${DATA_ATTR}] dl { margin: 0; padding: 0; } html[${DATA_ATTR}] dt { font-weight: 600; margin-top: 1em; clear: both; } html[${DATA_ATTR}] dd { margin: 0.4em 0 0.8em 0; color: var(--gp-fg-muted); padding: 0 !important; background: transparent !important; border: 0 !important; border-radius: 0 !important; display: block; clear: both; } html[${DATA_ATTR}] dd::after { content: ""; display: block; clear: both; } /* Taxonomy chips */ html[${DATA_ATTR}] #main dd .bound, html[${DATA_ATTR}] #main dd .sb, html[${DATA_ATTR}] #main dd .latex, html[${DATA_ATTR}] #main dd .erotic, html[${DATA_ATTR}] #main dd .package, html[${DATA_ATTR}] #main dd .mummify, html[${DATA_ATTR}] #main dd .trash, html[${DATA_ATTR}] #main dd .doll, html[${DATA_ATTR}] #main dd .machine, html[${DATA_ATTR}] #main dd .buried, html[${DATA_ATTR}] #main dd .giant { display: inline-block; padding: 2px 6px; margin: 0 6px 0 0; border: 1px solid var(--gp-border); border-radius: 8px; background: var(--gp-chip-bg); color: var(--gp-chip-fg); font-size: 12px; line-height: 1.4; min-width: 96% } /* Color-coded taxonomy chips */ html[${DATA_ATTR}] #main dd .bound { background: var(--chip-bound-bg) !important; color: var(--chip-bound-fg) !important; border-color: var(--chip-bound-bd) !important; } html[${DATA_ATTR}] #main dd .sb { background: var(--chip-sb-bg) !important; color: var(--chip-sb-fg) !important; border-color: var(--chip-sb-bd) !important; } html[${DATA_ATTR}] #main dd .latex { background: var(--chip-latex-bg) !important; color: var(--chip-latex-fg) !important; border-color: var(--chip-latex-bd) !important; } html[${DATA_ATTR}] #main dd .erotic{ background: var(--chip-erotic-bg) !important;color: var(--chip-erotic-fg) !important;border-color: var(--chip-erotic-bd) !important; } html[${DATA_ATTR}] #main dd .package{ background: var(--chip-package-bg) !important; color: var(--chip-package-fg) !important; border-color: var(--chip-package-bd) !important; } html[${DATA_ATTR}] #main dd .mummify{ background: var(--chip-mummify-bg) !important; color: var(--chip-mummify-fg) !important; border-color: var(--chip-mummify-bd) !important; } html[${DATA_ATTR}] #main dd .trash { background: var(--chip-trash-bg) !important; color: var(--chip-trash-fg) !important; border-color: var(--chip-trash-bd) !important; } html[${DATA_ATTR}] #main dd .doll { background: var(--chip-doll-bg) !important; color: var(--chip-doll-fg) !important; border-color: var(--chip-doll-bd) !important; } html[${DATA_ATTR}] #main dd .machine{ background: var(--chip-machine-bg) !important; color: var(--chip-machine-fg) !important; border-color: var(--chip-machine-bd) !important; } html[${DATA_ATTR}] #main dd .buried { background: var(--chip-buried-bg) !important; color: var(--chip-buried-fg) !important; border-color: var(--chip-buried-bd) !important; } html[${DATA_ATTR}] #main dd .giant { background: var(--chip-giant-bg) !important; color: var(--chip-giant-fg) !important; border-color: var(--chip-giant-bd) !important; } /* Home page: also color .newstory when category is on the container or the item */ html[${DATA_ATTR}] .home #main dd.bound .newstory, html[${DATA_ATTR}] .home #main dd .newstory.bound { background: var(--chip-bound-bg) !important; color: var(--chip-bound-fg) !important; border: 1px solid var(--chip-bound-bd) !important; } html[${DATA_ATTR}] .home #main dd.sb .newstory, html[${DATA_ATTR}] .home #main dd .newstory.sb { background: var(--chip-sb-bg) !important; color: var(--chip-sb-fg) !important; border: 1px solid var(--chip-sb-bd) !important; } html[${DATA_ATTR}] .home #main dd.latex .newstory, html[${DATA_ATTR}] .home #main dd .newstory.latex { background: var(--chip-latex-bg) !important; color: var(--chip-latex-fg) !important; border: 1px solid var(--chip-latex-bd) !important; } html[${DATA_ATTR}] .home #main dd.erotic .newstory, html[${DATA_ATTR}] .home #main dd .newstory.erotic{ background: var(--chip-erotic-bg) !important;color: var(--chip-erotic-fg) !important;border: 1px solid var(--chip-erotic-bd) !important; } html[${DATA_ATTR}] .home #main dd.package .newstory, html[${DATA_ATTR}] .home #main dd .newstory.package{ background: var(--chip-package-bg) !important; color: var(--chip-package-fg) !important; border: 1px solid var(--chip-package-bd) !important; } html[${DATA_ATTR}] .home #main dd.mummify .newstory, html[${DATA_ATTR}] .home #main dd .newstory.mummify{ background: var(--chip-mummify-bg) !important; color: var(--chip-mummify-fg) !important; border: 1px solid var(--chip-mummify-bd) !important; } html[${DATA_ATTR}] .home #main dd.trash .newstory, html[${DATA_ATTR}] .home #main dd .newstory.trash { background: var(--chip-trash-bg) !important; color: var(--chip-trash-fg) !important; border: 1px solid var(--chip-trash-bd) !important; } html[${DATA_ATTR}] .home #main dd.doll .newstory, html[${DATA_ATTR}] .home #main dd .newstory.doll { background: var(--chip-doll-bg) !important; color: var(--chip-doll-fg) !important; border: 1px solid var(--chip-doll-bd) !important; } html[${DATA_ATTR}] .home #main dd.machine .newstory, html[${DATA_ATTR}] .home #main dd .newstory.machine{ background: var(--chip-machine-bg) !important; color: var(--chip-machine-fg) !important; border: 1px solid var(--chip-machine-bd) !important; } html[${DATA_ATTR}] .home #main dd.buried .newstory, html[${DATA_ATTR}] .home #main dd .newstory.buried { background: var(--chip-buried-bg) !important; color: var(--chip-buried-fg) !important; border: 1px solid var(--chip-buried-bd) !important; } html[${DATA_ATTR}] .home #main dd.giant .newstory, html[${DATA_ATTR}] .home #main dd .newstory.giant { background: var(--chip-giant-bg) !important; color: var(--chip-giant-fg) !important; border: 1px solid var(--chip-giant-bd) !important; } /* Images responsive */ html[${DATA_ATTR}] img { max-width: 100% !important; height: auto !important; } /* Header/logo simplification */ html[${DATA_ATTR}] .plaza #logo { background-image: none !important; } html[${DATA_ATTR}] #logo { background: var(--gp-surface) !important; background-image: none !important; min-height: 64px; text-align: center; border-bottom: 3px solid var(--gp-accent); } /* Inputs */ html[${DATA_ATTR}] input, html[${DATA_ATTR}] select, html[${DATA_ATTR}] textarea, html[${DATA_ATTR}] button { background: var(--gp-surface-2) !important; color: var(--gp-fg) !important; border: 1px solid var(--gp-border) !important; border-radius: 6px !important; padding: 6px 8px !important; } html[${DATA_ATTR}] #head input { font-size: 14px !important; cursor: pointer; } /* Tables (scoped to main content) */ html[${DATA_ATTR}] #main table { border-color: var(--gp-border) !important; } html[${DATA_ATTR}] #main td, html[${DATA_ATTR}] #main th { background: transparent !important; color: var(--gp-fg) !important; } /* Old tags (scoped): keep header layout intact */ html[${DATA_ATTR}] #main center { text-align: left !important; display: block; } html[${DATA_ATTR}] font { color: inherit !important; font: inherit !important; } /* Header search/input sizing so it doesn't overflow */ html[${DATA_ATTR}] #head input[type="text"], html[${DATA_ATTR}] #head input[type="search"] { width: 220px !important; max-width: 60vw !important; } /* Code / pre */ html[${DATA_ATTR}] pre, html[${DATA_ATTR}] code { white-space: pre-wrap; word-break: break-word; background: var(--gp-surface-2) !important; border: 1px solid var(--gp-border) !important; border-radius: 6px !important; padding: 8px 10px !important; } /* Section spacing */ html[${DATA_ATTR}] #top, html[${DATA_ATTR}] #head-outer { margin-bottom: 8px !important; } /* Remove heavy gradients from skins */ html[${DATA_ATTR}] .mummified .box-outer, html[${DATA_ATTR}] .latex .box-outer, html[${DATA_ATTR}] .bound .box-outer, html[${DATA_ATTR}] .plaza .box-outer, html[${DATA_ATTR}] .erotic .box-outer { background: var(--gp-surface-2) !important; box-shadow: none !important; border: 1px solid var(--gp-border) !important; border-radius: 12px !important; border-top: 2px solid var(--gp-accent) !important; } /* Selection */ html[${DATA_ATTR}] ::selection { background: #1f6feb55; } /* Back to Top button */ #gp-backtotop { position: fixed; bottom: 84px; right: 12px; z-index: 100000; padding: 8px 10px; font-size: 12px; line-height: 1; border-radius: 999px; cursor: pointer; border: 1px solid var(--gp-border); background: var(--gp-surface-2); color: var(--gp-fg); box-shadow: none; opacity: 0; pointer-events: none; transition: opacity .2s ease; } #gp-backtotop.visible { opacity: 1; pointer-events: auto; } /* Mini sticky header removed per user preference */ /* Header links and search tidy */ html[${DATA_ATTR}] #head p { margin: 0 !important; padding: 6px 10px !important; height: auto !important; line-height: 1.4 !important; } html[${DATA_ATTR}] #head p a { margin-right: 10px; } html[${DATA_ATTR}] #head input[type="text"], html[${DATA_ATTR}] #head input[type="search"] { height: 28px !important; padding: 4px 8px !important; } /* Home page: preserve update list rhythm */ html[${DATA_ATTR}] .home #main dl, html[${DATA_ATTR}] .home #main dt, html[${DATA_ATTR}] .home #main dd { margin: 0 !important; } html[${DATA_ATTR}] .home #main dd { padding: 0 !important; display:block; width:100%; } html[${DATA_ATTR}] .home #main dd a { display:inline-block; max-width:100%; float:none !important; } /* Old fixed-width tables in home pages: relax to fluid */ html[${DATA_ATTR}] .home #main table[width], html[${DATA_ATTR}] .home #main td[width], html[${DATA_ATTR}] .home #main table[style*="width" i] { width: auto !important; max-width: 100% !important; table-layout: auto !important; } /* Sidebar column width to prevent link wraps */ html[${DATA_ATTR}] .home .sidebar { width: 210px !important; min-width: 210px !important; } html[${DATA_ATTR}] .home .sidebar a { white-space: normal !important; word-break: normal !important; } html[${DATA_ATTR}] .home .sidebar li { line-height: 1.35; } /* Footer back-to-top link */ .gp-footer-backtop { text-align: center; margin: 18px 0 8px; } .gp-footer-backtop a { color: var(--gp-link); text-decoration: none; } .gp-footer-backtop a:hover { text-decoration: underline; } /* World pages: ensure dark-mode link and heading colors use theme tokens */ html[${DATA_ATTR}="dark"][data-gp-world="1"] a, html[${DATA_ATTR}="dark"][data-gp-world="1"] #main a, html[${DATA_ATTR}="dark"][data-gp-world="1"] .sidebar a, html[${DATA_ATTR}="dark"][data-gp-world="1"] .rhsbar a { color: var(--gp-link) !important; } html[${DATA_ATTR}="dark"][data-gp-world="1"] a:visited, html[${DATA_ATTR}="dark"][data-gp-world="1"] #main a:visited, html[${DATA_ATTR}="dark"][data-gp-world="1"] .sidebar a:visited, html[${DATA_ATTR}="dark"][data-gp-world="1"] .rhsbar a:visited { color: var(--gp-link-visited) !important; } html[${DATA_ATTR}="dark"][data-gp-world="1"] h1, html[${DATA_ATTR}="dark"][data-gp-world="1"] h2, html[${DATA_ATTR}="dark"][data-gp-world="1"] h3, html[${DATA_ATTR}="dark"][data-gp-world="1"] h4, html[${DATA_ATTR}="dark"][data-gp-world="1"] h5, html[${DATA_ATTR}="dark"][data-gp-world="1"] .sidebar h5, html[${DATA_ATTR}="dark"][data-gp-world="1"] .rhsbar h3 { color: var(--gp-fg) !important; } /* Author pages: some headings use .authors > li > div with light gradients */ html[${DATA_ATTR}="dark"] .authors div { background: var(--gp-surface-2) !important; background-image: none !important; color: var(--gp-fg) !important; border: 1px solid var(--gp-border) !important; } html[${DATA_ATTR}="dark"] .authors div a { color: var(--gp-fg) !important; } /* Multi-column lists on author and similar pages */ html[${DATA_ATTR}][data-gp-mainlike="1"] ul.stories, html[${DATA_ATTR}][data-gp-mainlike="1"] ul.authors, html[${DATA_ATTR}][data-gp-world="1"] ul.stories, html[${DATA_ATTR}][data-gp-world="1"] ul.authors { margin: 0 !important; padding: 0 8px !important; /* add small left/right gutter so first/last columns align with inner columns */ list-style: none !important; -webkit-column-count: 5 !important; -moz-column-count: 5 !important; column-count: 5 !important; -webkit-column-gap: 16px !important; -moz-column-gap: 16px !important; column-gap: 16px !important; -webkit-column-rule: 1px solid var(--gp-border) !important; -moz-column-rule: 1px solid var(--gp-border) !important; column-rule: 1px solid var(--gp-border) !important; background: transparent !important; } html[${DATA_ATTR}][data-gp-mainlike="1"] ul.stories li, html[${DATA_ATTR}][data-gp-mainlike="1"] ul.authors li, html[${DATA_ATTR}][data-gp-world="1"] ul.stories li, html[${DATA_ATTR}][data-gp-world="1"] ul.authors li { margin: 0 6px 12px 0 !important; overflow: visible !important; } /* Ensure author name blocks don't indent in the first column */ html[${DATA_ATTR}] ul.authors li > div { margin-left: 0 !important; } /* Author links: normalize spacing and line-height */ html[${DATA_ATTR}][data-gp-mainlike="1"] .authors a, html[${DATA_ATTR}][data-gp-world="1"] .authors a { font-weight: normal !important; display: block !important; margin-top: 6px !important; margin-left: 5px !important; line-height: 14px !important; text-decoration: none !important; } /* First link under each author: slightly tighter top margin */ html[${DATA_ATTR}][data-gp-mainlike="1"] #main .authors a:first-of-type, html[${DATA_ATTR}][data-gp-world="1"] #main .authors a:first-of-type { margin-top: 3px !important; } /* Fix light border on chapter separators */ html[${DATA_ATTR}][data-gp-mainlike="1"] .chN, html[${DATA_ATTR}][data-gp-world="1"] .chN { border-bottom: 1px solid var(--gp-border) !important; } /* Responsive column counts */ @media (max-width: 1200px) { html[${DATA_ATTR}][data-gp-mainlike="1"] ul.stories, html[${DATA_ATTR}][data-gp-mainlike="1"] ul.authors, html[${DATA_ATTR}][data-gp-world="1"] ul.stories, html[${DATA_ATTR}][data-gp-world="1"] ul.authors { -webkit-column-count: 4 !important; -moz-column-count: 4 !important; column-count: 4 !important; } } @media (max-width: 900px) { html[${DATA_ATTR}][data-gp-mainlike="1"] ul.stories, html[${DATA_ATTR}][data-gp-mainlike="1"] ul.authors, html[${DATA_ATTR}][data-gp-world="1"] ul.stories, html[${DATA_ATTR}][data-gp-world="1"] ul.authors { -webkit-column-count: 3 !important; -moz-column-count: 3 !important; column-count: 3 !important; } } @media (max-width: 670px) { html[${DATA_ATTR}][data-gp-mainlike="1"] ul.stories, html[${DATA_ATTR}][data-gp-mainlike="1"] ul.authors, html[${DATA_ATTR}][data-gp-world="1"] ul.stories, html[${DATA_ATTR}][data-gp-world="1"] ul.authors { -webkit-column-count: 2 !important; -moz-column-count: 2 !important; column-count: 2 !important; } } @media (max-width: 420px) { html[${DATA_ATTR}][data-gp-mainlike="1"] ul.stories, html[${DATA_ATTR}][data-gp-mainlike="1"] ul.authors, html[${DATA_ATTR}][data-gp-world="1"] ul.stories, html[${DATA_ATTR}][data-gp-world="1"] ul.authors { -webkit-column-count: 1 !important; -moz-column-count: 1 !important; column-count: 1 !important; } } html[${DATA_ATTR}] .home #main dd .bound, html[${DATA_ATTR}] .home #main dd .sb, html[${DATA_ATTR}] .home #main dd .latex, html[${DATA_ATTR}] .home #main dd .erotic { border-radius: 8px; padding: 1px 6px; } /* Category pages: avoid over-constraining list layouts */ html[${DATA_ATTR}] #main .categories dl, html[${DATA_ATTR}] #main .categories dd, html[${DATA_ATTR}] #main .categories dt { background: transparent !important; border: 0 !important; padding: 0 !important; border-radius: 0 !important; } /* Homepage-specific tweaks requested */ /* Make newstory/category pills nearly full-width on homepage */ html[${DATA_ATTR}] .home #main dd .bound, html[${DATA_ATTR}] .home #main dd .sb, html[${DATA_ATTR}] .home #main dd .latex, html[${DATA_ATTR}] .home #main dd .erotic, html[${DATA_ATTR}] .home #main dd .package, html[${DATA_ATTR}] .home #main dd .mummify, html[${DATA_ATTR}] .home #main dd .trash, html[${DATA_ATTR}] .home #main dd .doll, html[${DATA_ATTR}] .home #main dd .machine, html[${DATA_ATTR}] .home #main dd .buried, html[${DATA_ATTR}] .home #main dd .giant { display: inline-block; padding: 2px 6px; margin: 0 6px 0 0; border: 1px solid var(--gp-border); border-radius: 8px !important; background: var(--gp-chip-bg) !important; color: var(--gp-chip-fg) !important; font-size: 12px; line-height: 1.4; min-width: 96%; box-sizing: border-box; } /* Homepage header containers */ html[${DATA_ATTR}] .home #top, html[${DATA_ATTR}][data-gp-mainlike="1"] #top { max-width: 1440px; margin: 0 auto; background: #E8E8E8; border-radius: 15px; padding: 5px 0; overflow: hidden; } html[${DATA_ATTR}] .home #head, html[${DATA_ATTR}][data-gp-mainlike="1"] #head { padding: 4px 12px; height: 40px; border: 1px solid #E3E3E3; border-radius: 15px; background: #F1F1F1; /* ie9 */ background: linear-gradient(#FEFEFE,#D5D5D5); } /* Homepage banner strip (theme-aware) */ html[${DATA_ATTR}] .home .banner, html[${DATA_ATTR}][data-gp-mainlike="1"] .banner { background: var(--gp-surface-2); color: var(--gp-fg); text-align: center; padding: 3px; margin-top: 5px; } `; (document.head || document.documentElement).appendChild(style); } // Theme toggle button function injectToggle() { if (document.getElementById('gp-toggle')) return; const btn = document.createElement('button'); btn.id = 'gp-toggle'; Object.assign(btn.style, { position: 'fixed', bottom: '12px', right: '12px', zIndex: 99999, padding: '6px 8px', fontSize: '12px', lineHeight: '1', borderRadius: '8px', cursor: 'pointer', border: '1px solid var(--gp-border)', background: 'var(--gp-surface-2)', color: 'var(--gp-fg)' }); function labelFor(mode) { const eff = computeEffective(mode); const icon = eff === 'dark' ? '🌙' : '☀️'; return `GP: ${mode[0].toUpperCase()}${mode.slice(1)} ${icon}`; } let current = getStoredMode() || 'auto'; btn.textContent = labelFor(current); btn.addEventListener('click', () => { current = current === 'auto' ? 'dark' : current === 'dark' ? 'light' : 'auto'; setStoredMode(current); applyThemeAttr(current); btn.textContent = labelFor(current); }); document.documentElement.appendChild(btn); } // Reading mode toggle button function injectReadingToggle() { if (document.getElementById('gp-reading-toggle')) return; const btn = document.createElement('button'); btn.id = 'gp-reading-toggle'; Object.assign(btn.style, { position: 'fixed', bottom: '48px', right: '12px', zIndex: 99999, padding: '6px 8px', fontSize: '12px', lineHeight: '1', borderRadius: '8px', cursor: 'pointer', border: '1px solid var(--gp-border)', background: 'var(--gp-surface-2)', color: 'var(--gp-fg)' }); function labelFor(mode) { return `Read: ${mode === 'wide' ? 'Wide' : 'Narrow'}`; } let current = getReadingMode(); btn.textContent = labelFor(current); btn.addEventListener('click', () => { current = current === 'narrow' ? 'wide' : 'narrow'; setReadingMode(current); applyReadingAttr(current); btn.textContent = labelFor(current); }); document.documentElement.appendChild(btn); } // Heuristics: detect story page and tag side boxes as asides function markReadingContextAndAsides() { const storySel = '.story1, .story1c, .story5l, .story6, .storym, .style4, .styleDW, .style20, .style21, .style22'; const isStory = !!document.querySelector(storySel); document.documentElement.setAttribute('data-gp-context', isStory ? 'story' : 'other'); if (!isStory) return; // Likely aside boxes are generic .box-outer blocks with certain headings const ASIDE_HEADINGS = [ 'menu', 'premier', 'note', 'submit', 'monitor', 'search', 'rss', 'other worlds', 'stories by author', 'authors', 'links', 'forum', 'contact' ]; document.querySelectorAll('.box-outer').forEach((el) => { const h = el.querySelector('h4, h3, h2, h1'); const title = (h && (h.textContent || '')).trim().toLowerCase(); if (!title) return; if (ASIDE_HEADINGS.some(k => title.includes(k))) { el.classList.add('gp-aside'); } }); } // Back to top button function injectBackToTop() { if (document.getElementById('gp-backtotop')) return; const btn = document.createElement('button'); btn.id = 'gp-backtotop'; btn.textContent = 'Top ↑'; btn.addEventListener('click', () => { try { window.scrollTo({ top: 0, behavior: 'smooth' }); } catch (_) { window.scrollTo(0, 0); } }); document.documentElement.appendChild(btn); const onScroll = () => { const show = window.scrollY > 600; btn.classList.toggle('visible', !!show); }; window.addEventListener('scroll', onScroll, { passive: true }); onScroll(); } // Footer back to top link near the bottom of #main function injectFooterBackTop() { if (document.getElementById('gp-footer-backtop')) return; const container = document.querySelector('#main') || document.body; if (!container) return; const wrap = document.createElement('div'); wrap.className = 'gp-footer-backtop'; wrap.id = 'gp-footer-backtop'; const link = document.createElement('a'); link.href = '#'; link.textContent = 'back to the top ⤴'; link.addEventListener('click', (e) => { e.preventDefault(); try { window.scrollTo({ top: 0, behavior: 'smooth' }); } catch (_) { window.scrollTo(0, 0); } }); wrap.appendChild(link); container.appendChild(wrap); } // Mini sticky header removed per user request // Initialize function init() { ensureViewport(); injectCriticalStyles(); injectFullStyles(); injectToggle(); injectReadingToggle(); injectBackToTop(); injectFooterBackTop(); markReadingContextAndAsides(); // Remove critical after full loads const crit = document.getElementById('gp-critical'); if (crit && crit.parentNode) crit.parentNode.removeChild(crit); } if (document.readyState === 'loading') { // inject critical immediately, wait for rest injectCriticalStyles(); document.addEventListener('DOMContentLoaded', init); } else { init(); } // Handle bfcache restores window.addEventListener('pageshow', (e) => { if (e.persisted) { injectFullStyles(); } }); })();