// ==UserScript==
// @name AO3 Dark Mode Reskin
// @name:de AO3 Dunkelmodus
// @name:fr Mode Sombre pour AO3
// @name:es Modo Oscuro para AO3
// @name:ja AO3ダークモード
// @name:zh-CN AO3暗黑模式
// @name:it Modalità Scura per AO3
// @name:ru Тёмный режим для AO3
// @name:pt-BR Modo Escuro para AO3
// @name:pt-PT Modo Escuro para AO3
// @name:ko AO3 다크 모드
// @namespace ko-fi.com/awesome97076
// @version 1.3
// @license MIT
// @description A modern, accessible dark theme for Ao3
// @description:de Ein modernes, zugängliches dunkles Theme für Ao3
// @description:fr Un thème sombre moderne et accessible pour Ao3
// @description:es Un tema oscuro moderno y accesible para Ao3
// @description:ja Ao3のためのモダンでアクセシブルなダークテーマ
// @description:zh-CN 为Ao3设计的现代化、易访问的暗黑主题
// @description:it Un tema scuro moderno e accessibile per Ao3
// @description:ru Современная, доступная тёмная тема для Ao3
// @description:pt-BR Um tema escuro moderno e acessível para Ao3
// @description:pt-PT Um tema escuro moderno e acessível para Ao3
// @description:ko Ao3를 위한 현대적이고 접근성 있는 다크 테마
// @author Awesome
// @match https://archiveofourown.org/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=archiveofourown.org
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
"use strict";
// Add styles for the modern dark theme
const style = document.createElement("style");
style.innerHTML = `
:root {
--background-color: #121212;
--primary-bg-color: #1c1c1c;
--secondary-bg-color: #2a2a2a;
--tertiary-bg-color: #444;
--quaternary-bg-color: #555;
--highlight-bg-color: #111111;
--hover-bg-color: #444444;
--background-primary: #121212;
--background-secondary: #1e1e1e;
--background-tertiary: #2a2a2a;
--background-highlight: #333333;
--text-color: #e0e0e0;
--text-secondary: #bbbbbb;
--text-tertiary: #999999;
--text-muted: #777777;
--link-color: rgb(21, 184, 190);
--link-visited: #c87cffcc;
--accent-primary: #e05b5b;
--accent-secondary: #b74040;
--accent-tertiary: #973535;
--ao3-red-dark: #8c1c1c;
--ao3-red-medium: #a82828;
--ao3-red-light: #c43535;
--alert-error: #cf6679;
--alert-warning: #ffe066;
--alert-success: #81c784;
--alert-info: #64b5f6;
--border-primary: #424242;
--border-secondary: #333333;
--shadow-color: rgba(0, 0, 0, 0.4);
--box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
--hover-box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
--transition: all 0.2s ease;
--header-background: #202020;
--footer-background: #1a1a1a;
--font-family: 'Inter', 'Roboto', -apple-system, BlinkMacSystemFont, 'Lucida Grande', 'Lucida Sans Unicode', Verdana, Helvetica, sans-serif, 'GNU Unifont';
--font-size-small: 0.9rem;
--font-size-base: 1rem;
--font-size-large: 1.5em;
--font-size-larger: 1.8rem;
--font-size-xlarge: 2.2rem;
--border-radius: 8px;
--border-radius-large: 12px
}
@media only screen and (max-width: 42em), handheld {
:root {
--font-size-small: 0.3rem;
--font-size-base: 0.5rem;
--font-size-large: 0.8em;
--font-size-larger: 1rem;
--font-size-xlarge: 1.2rem;
}
}
@media (max-width: 768px) {
:root {
--font-size-small: 0.5rem;
--font-size-base: 0.7rem;
--font-size-large: 1em;
--font-size-larger: 1.2rem;
--font-size-xlarge: 1.4rem;
}
}
@media (max-width: 810px) {
:root {
--font-size-small: 0.6rem;
--font-size-base: 0.8rem;
--font-size-large: 1em;
--font-size-larger: 1.2rem;
--font-size-xlarge: 1.4rem;
}
}
@media (max-width: 1080px) {
:root {
--font-size-small: 0.7rem;
--font-size-base: 0.9rem;
--font-size-large: 1.1em;
--font-size-larger: 1.3rem;
--font-size-xlarge: 1.5rem;
}
}
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td {
border: 0;
outline: 0;
font-weight: inherit;
font-style: inherit;
font-size: var(--font-size-base);
font-family: inherit;
vertical-align: baseline;
list-style: none;
margin: 0;
padding: 0;
max-width: 100%;
}
/* Base responsive font sizing */
html {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
body {
background: var(--background-primary)
}
/* Override AO3's mobile styles */
@media only screen and (max-width: 42em), handheld {
#outer {
background: var(--background-color) !important;
font-size: 0.875em;
}
body .narrow-shown {
display: block !important;
color: var(--text-color);
}
.javascript .narrow-hidden {
display: none !important;
}
}
.filtered .index {
width: 70%;
float: left;
}
@media (max-width: 768px) {
.filtered .index {
width: 100% !important;
float: none !important;
}
}
@media (max-width: 480px) {
html {
font-size: 14px;
}
}
@media (min-width: 1200px) {
html {
font-size: 18px;
}
}
#header a, #header a:visited, #header .primary .open a, #header .primary .dropdown:hover a, #header .primary .dropdown a:focus {
color: var(--text-color)
}
#dashboard, #dashboard.own, .error, .comment_error, .kudos_error, #header ul.primary, .LV_invalid, .LV_invalid_field, input.LV_invalid_field:hover, input.LV_invalid_field:active, textarea.LV_invalid_field:hover, textarea.LV_invalid_field:active, #header .primary a, #header .primary input, #header .search input {
border-color: var(--border-primary) !important
}
#header ul.primary, #footer, .autocomplete .dropdown ul li:hover, .autocomplete .dropdown li.selected, a.tag:hover {
background:var(--background-color)
}
.actions a:visited, .action:visited, .action a:link, .action a:visited {
color: var(--text-tertiary)
}
form.verbose legend, .verbose form legend {
background: var(--background-color);
color: var(--text-color);
border: 1px solid var(--border-primary);
box-shadow: 1px 2px 3px #999
}
#outer, .javascript, .statistics .index li:nth-of-type(2n), #tos_prompt, .announcement input[type="submit"], .nomination dt {
background: var(--background-color)
}
body, html {
background: var(--background-color);
color: var(--text-color);
font-family: var(--font-family);
margin: 0;
padding: 0;
line-height: 1.5;
scroll-behavior: smooth;
overflow-x: hidden;
}
#outer {
background: var(--background-color);
min-height: 100vh;
position: relative;
}
#main {
font-size: 1.1em;
padding: 0;
margin: 0 auto;
max-width: 95%;
width: 95%;
background: var(--background-color);
box-sizing: border-box;
position: static !important;
}
#main.dashboard {
max-width: 85%;
width: 100%;
margin-left: 14em;
padding-left: 1em;
position: static !important;
}
/* Mobile main layout */
@media only screen and (max-width: 42em), handheld {
#main, #main.dashboard {
position: static !important;
width: 100% !important;
max-width: 100% !important;
margin-left: 0 !important;
padding: 0.5em !important;
}
#main.errors {
background-position: center !important;
}
#main.session {
background-image: none !important;
}
#main.errors p, #main.errors .heading {
margin-right: 0 !important;
}
#main.errors p:last-child {
margin-bottom: 500px !important;
}
}
h1, h2, h3, h4, h5, h6, .heading {
color: var(--text-color);
font-family: Georgia, serif;
font-weight: 400;
line-height: 1.2;
margin-bottom: 0.6em;
word-wrap: break-word;
overflow-wrap: break-word;
word-break: break-word;
}
p {
margin-bottom: 1em;
text-align: justify;
letter-spacing: 0.02em;
word-wrap: break-word;
overflow-wrap: break-word;
}
a, a:link {
color: var(--link-color);
text-decoration: none;
border-bottom: 1px solid var(--accent-secondary);
transition: color var(--transition), border-color var(--transition);
word-wrap: break-word;
overflow-wrap: break-word;
}
a:visited {
color: var(--link-visited);
border-bottom: 1px dashed var(--accent-tertiary)
}
a:hover, a:focus {
color: var(--text-secondary);
border-color: var(--accent-tertiary);
text-decoration: none
}
a:focus, button:focus, input:focus, textarea:focus, select:focus {
outline: 2px solid var(--link-color);
outline-offset: 2px
}
#header {
background: var(--header-background);
margin: 0 0 1em;
border-bottom: 1px solid var(--border-primary);
font-size: 0.875em;
position: relative;
z-index: 100;
width: 100%;
box-sizing: border-box;
}
#header .primary {
background: var(--ao3-red-dark);
box-shadow: inset 0 -6px 10px rgba(0, 0, 0, 0.35), 1px 1px 3px -1px rgba(0, 0, 0, 0.25);
position: relative;
overflow-x: auto;
white-space: nowrap;
}
#header .primary a {
color: var(--text-color);
padding: 0.429em 0.75em;
border-bottom: none;
display: inline-block;
white-space: nowrap;
}
#header .heading a {
color: var(--ao3-red-light);
font-size: 1.714em;
line-height: 1.75em;
border-bottom: none
}
#header .dropdown .menu, #small_login {
background: var(--background-secondary);
border: 1px solid var(--border-primary);
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
z-index: 9999;
max-width: 90vw;
overflow-x: auto;
position: fixed !important;
display: none;
margin-bottom: 10px;
}
#header .dropdown .menu a {
color: var(--text-color);
border-bottom: none;
border-bottom-color: currentcolor;
display: block;
white-space: nowrap;
z-index: 999;
padding: 0;
margin: 1px 0;
}
#header .dropdown .menu a:hover, #header .dropdown .menu a:focus {
background: var(--background-highlight);
color: var(--accent-primary)
}
/* Mobile header adjustments */
@media only screen and (max-width: 42em), handheld {
#header .logo {
height: 1.75em !important;
}
#header .dropdown a:focus {
outline: none !important;
background: transparent !important;
color: #111 !important;
}
#header .primary > li:first-of-type {
margin-left: 0 !important;
}
#header .open a:focus {
background: #ddd !important;
}
#header .primary .dropdown a:focus {
color: #fff !important;
}
#header .primary .open a:focus {
color: #111 !important;
}
#header .user .open a:focus {
color: #900 !important;
}
#header h2.collections {
padding: 1% !important;
margin: 0 !important;
}
#header #small_login {
margin-left: 45px !important;
}
#header .dropdown, #greeting .user {
position: static !important;
}
#header .menu {
width: 100% !important;
position: absolute !important;
left: 0 !important;
}
}
.header.module {
position: relative;
padding: 1em 0;
margin-bottom: 1em;
display: grid;
grid-template-areas:
"tags title date"
"fandoms";
grid-template-columns: auto 1fr auto;
gap: 0.5em 1em;
align-items: start;
min-height: 3em;
}
.header.module ul.required-tags {
position: absolute;
grid-area: tags;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, auto);
gap: 0.25em;
margin: 0;
padding: 0;
width: 60px;
align-self: start;
grid-column: 1;
grid-row: 1;
}
.header.module h4.heading {
grid-area: title;
margin: 0;
line-height: 1.3;
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-word;
hyphens: auto;
align-self: start;
grid-column: 1;
grid-row: 2;
margin-top: 3em !important;
}
.header.module p.datetime {
grid-area: date;
margin: 0;
text-align: right;
white-space: nowrap;
align-self: start;
font-size: 0.9em;
color: var(--text-tertiary);
grid-column: 2;
grid-row: 1;
}
.header.module h5.fandoms {
grid-area: fandoms;
margin: 0;
padding: 0;
}
/* Mobile layout - stack everything */
@media (max-width: 768px) {
.header.module {
display: flex;
flex-direction: column;
gap: 0.5em;
padding: 0.5em 0;
}
.header.module ul.required-tags {
display: flex;
flex-wrap: wrap;
gap: 0.25em;
width: auto;
order: 1;
position: relative;
}
.header.module h4.heading {
order: 2;
}
.header.module h5.fandoms {
order: 3;
}
.header.module p.datetime {
order: 4;
text-align: left;
}
}
.header.module ul.required-tags li span {
display: block;
width: 25px;
height: 25px
}
#footer {
background: var(--footer-background);
border-top: 2px solid var(--ao3-red-dark);
padding: 1em;
color: var(--text-color);
width: 100%;
box-sizing: border-box;
}
#footer a {
color: var(--text-color);
border-bottom: 1px solid var(--text-tertiary)
}
#footer a:hover, #footer a:focus {
color: var(--accent-primary);
background: transparent;
border-color: var(--accent-primary)
}
input, textarea, select, button {
font-family: var(--font-family);
box-sizing: border-box;
}
input, textarea {
width: 100%;
max-width: 100%;
background: var(--tertiary-bg-color);
color: var(--text-color);
border: 1px solid var(--border-primary);
border-radius: var(--border-radius);
padding: 0.5em;
transition: var(--transition)
}
input:focus, textarea:focus, select:focus {
background: var(--quaternary-bg-color) !important;
border-color: var(--link-color) !important;
color: var(--text-color) !important;
box-shadow: 0 0 0 2px rgba(21, 184, 190, 0.25) !important;
outline: none
}
select {
vertical-align: text-top;
width: 100%;
min-width: 10.5em;
appearance: none;
background: var(--tertiary-bg-color);
color: var(--text-color);
border: 1px solid var(--border-primary);
border-radius: var(--border-radius);
padding: 5px 7px;
font-size: var(--font-size-base);
font-weight: 500;
cursor: pointer;
transition: var(--transition);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
padding-right: 12px;
box-sizing: border-box;
}
select:hover {
background-color: var(--quaternary-bg-color);
border-color: var(--border-primary);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
transform: scale(1.02);
z-index: 999
}
option {
background: var(--tertiary-bg-color);
color: var(--text-color);
padding: 5px
}
fieldset, form dl {
background: var(--primary-bg-color);
border: 1px solid var(--border-primary);
border-radius: var(--border-radius);
margin: 0.3em 0.3em;
width: 95%;
overflow: unset;
}
/* Mobile form adjustments */
@media only screen and (max-width: 42em), handheld {
.filtered .index, form.filters, form dd, form dt, form .meta dd, form .meta dt, form.inbox {
width: 100% !important;
max-width: 100% !important;
min-width: 0 !important;
float: none !important;
}
}
.action, .action:link, .actions a, .actions a:link, .actions button, .actions input, .actions label, button, input[type="submit"] {
background: var(--background-tertiary);
color: var(--text-color);
border: 1px solid var(--border-primary);
font-size: var(--font-size-base);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.04em;
border-radius: var(--border-radius);
cursor: pointer;
transition: var(--transition);
display: inline-flex;
align-items: center;
justify-content: center;
text-decoration: none;
margin: 4px;
padding: 0.4em 0.6em;
box-shadow: none;
text-shadow: none;
box-sizing: border-box;
white-space: nowrap;
}
input[type="submit"] {
height: fit-content;
padding: 0 0.6em;
}
.action:hover, .actions a:hover, .actions button:hover, .actions input:hover, button:hover, input[type=submit]:hover {
background: var(--background-highlight);
border-color: var(--accent-primary);
color: var(--accent-primary);
transform: translateY(-1px)
}
.group-group, #main li.blurb {
display: flex;
gap: 12px;
padding: 10px;
margin: 8px 0;
border-radius: var(--border-radius-large);
background: var(--primary-bg-color);
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.15);
position: relative;
transition: all 0.2s ease;
flex-wrap: wrap;
flex-direction: column;
align-items: stretch;
width: 100%;
box-sizing: border-box;
}
/* Prevent nested group-group from having additional shadows */
.group-group .group-group {
box-shadow: none;
background: transparent;
padding: 0;
margin: 0;
border-radius: 0;
}
#main li.blurb:hover {
transform: scale(1.02);
box-shadow: var(--hover-box-shadow);
background: var(--secondary-bg-color)
}
.blurb .header {
display: flex;
margin-bottom: 8px;
flex-direction: column;
flex-wrap: wrap;
gap: 0.5em;
min-height: auto;
}
.blurb h4.heading a {
font-size: var(--font-size-large) !important;
color: var(--link-color);
text-decoration: none;
transition: color var(--transition);
line-height: 1.3;
white-space: normal;
border-bottom: none;
margin: 0 15px;
word-wrap: break-word;
overflow-wrap: break-word;
}
.blurb h4.heading a:hover {
color: var(--text-secondary)
}
h5:nth-child(2) > a {
font-size: var(--font-size-large) !important
}
#outer .group .heading {
font-size: var(--font-size-large);
margin: 0 auto;
line-height: 1.3;
display: flex;
flex-wrap: wrap;
position: relative;
justify-content: flex-start;
flex-grow: 1;
word-wrap: break-word;
overflow-wrap: break-word;
}
.blurb .datetime {
font-size: var(--font-size-large);
margin: 0
}
h5.heading {
order: 4 !important
}
.category-group, .relationships-group, .characters-group, .meta dd {
position: relative;
padding: 5px;
margin: 0;
border: none;
border-radius: var(--border-radius);
background: var(--secondary-bg-color);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
display: flex;
gap: 8px;
max-height: 10em;
overflow-y: auto;
font-size: var(--font-size-base);
overflow-x: hidden;
scrollbar-width: thin;
flex-direction: row;
flex-wrap: wrap;
align-content: flex-start;
max-width: 100%;
justify-content: flex-start;
box-sizing: border-box;
}
.blurb ul li, .blurb dd ul li {
border: 3px solid #000;
border-radius: var(--border-radius);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1)
}
.blurb ul li a, .blurb dd ul li a {
border: none;
text-decoration: none;
padding: 0.2em 0.6em
}
li.relationships a {
background: none
}
a.tag {
display: inline-block;
background: var(--background-tertiary);
color: var(--text-color);
padding: 0.2em 0.6em;
margin: 0.2em;
border-radius: 3px;
border-bottom: none;
transition: background-color 0.2s ease, color 0.2s ease;
font-weight: 500;
font-size: var(--font-size-base);
line-height: 1.4;
white-space: nowrap;
max-height: none;
overflow: visible;
word-wrap: break-word;
overflow-wrap: break-word;
}
a.tag:hover {
background: var(--accent-primary);
color: var(--text-color);
transform: translateY(-1px);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
text-decoration: none
}
.commas li {
display: inline-block;
margin-right: 0px;
margin-bottom: 0px
}
.commas li:after {
font-size: 6px;
content: ""
}
.tags li {
padding-left: 0;
padding-right: 0
}
dl.stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
gap: 8px;
margin: 6px 0 3px;
padding: 0;
line-height: 1.4;
float: none;
clear: both;
text-align: left;
width: 100%;
box-sizing: border-box;
}
dl.stats > div {
align-items: flex-start;
margin-right: 0;
margin-bottom: 0.15em;
display: flex !important;
flex-direction: column !important;
min-width: 0;
}
.words-group, .chapters-group, .comments-group, .kudos-group, .bookmarks-group, .hits-group, .collections-group, .language-group, .published-group, .status-group {
width: auto;
min-width: 80px;
flex-grow: 1;
flex-shrink: 1
}
.stats dt, .stats dd {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background: transparent;
width: auto;
min-width: 0;
display: inline;
clear: none;
float: none;
margin: auto
}
.blurb ul.required-tags {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, auto);
gap: 3px;
list-style: none;
padding: 0;
margin: 0;
position: relative;
opacity: 0.9;
width: auto
}
.blurb ul.required-tags li:nth-child(1) {
grid-column: 1;
grid-row: 1
}
.blurb ul.required-tags li:nth-child(2) {
grid-column: 1;
grid-row: 2
}
.blurb ul.required-tags li:nth-child(3) {
grid-column: 2;
grid-row: 1
}
.blurb ul.required-tags li:nth-child(4) {
grid-column: 2;
grid-row: 2
}
.blurb ul.required-tags li+li+li, .blurb ul.required-tags li+li+li+li {
position: relative;
left: 0
}
.blurb ul.required-tags li+li+li+li {
top: 0
}
.blurb ul.required-tags li, .blurb ul.required-tags li a, .blurb ul.required-tags li span {
border: none;
box-shadow: none
}
/* Mobile blurb adjustments */
@media only screen and (max-width: 42em), handheld {
.blurb dl.tags dt, .blurb dl.tags dd, dl.meta dt, dl.meta dd, .alphabet .listbox li, .media .listbox {
float: none !important;
}
.blurb dl.tags dd, dl.meta dd {
margin: auto;
width: 95%;
}
.alphabet .listbox li {
display: block !important;
}
}
#workskin {
margin: 0 auto !important;
background: var(--background-primary) !important;
color: var(--text-color) !important;
padding: 1em !important;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
font-size: var(--font-size-large);
line-height: 1.6;
max-width: 72em;
overflow-x: auto;
overflow-y: hidden;
width: 100%;
box-sizing: border-box;
}
/* Mobile workskin adjustments */
@media only screen and (max-width: 42em), handheld {
#workskin {
margin: auto !important;
}
}
.preface {
background: var(--background-secondary);
border-radius: 4px;
border-top: none !important;
padding: 1em !important;
margin: 1em 0 !important;
float: none;
width: 100%;
box-sizing: border-box;
}
.userstuff {
line-height: 1.6;
word-wrap: break-word;
overflow-wrap: break-word;
}
.userstuff p, .userstuff details {
margin: 1.5em 0;
padding: 0;
text-rendering: optimizelegibility;
word-wrap: break-word;
overflow-wrap: break-word;
}
.userstuff a {
color: var(--accent-primary)
}
.userstuff blockquote {
background: var(--background-tertiary);
border-left: 3px solid var(--accent-primary);
padding: 1em;
margin: 1em 0;
border-radius: 0 var(--border-radius) var(--border-radius) 0;
width: 100%;
box-sizing: border-box;
overflow-x: auto;
}
.userstuff h3 {
font-weight: 500;
padding: .125em;
border-bottom: .25em double var(--border-primary);
word-wrap: break-word;
overflow-wrap: break-word;
}
.userstuff code, .userstuff pre {
background: var(--background-tertiary);
color: var(--text-color);
font-family: "Monaco", "Consolas", Courier, monospace;
padding: 0.2em 0.4em;
border-radius: 3px;
border: 1px solid var(--border-primary);
word-wrap: break-word;
overflow-wrap: break-word;
}
.userstuff pre {
padding: 1em;
overflow-x: auto;
width: 100%;
box-sizing: border-box;
}
.userstuff p:only-child:empty, .userstuff p:only-child:blank, .userstuff details:only-child:empty, .userstuff details:only-child:blank {
margin: 0;
padding: 0;
height: 0.5em;
min-height: 0.5em;
line-height: 0.5
}
ol.thread {
list-style: none;
padding: 0;
margin: 0;
width: 100%;
box-sizing: border-box;
}
li.comment {
position: relative;
background: var(--background-secondary);
border-radius: 4px;
margin-bottom: 16px;
padding: 12px 16px 12px 60px;
box-shadow: 0 1px 3px var(--shadow-color);
transition: transform 0.2s ease, box-shadow 0.2s ease;
border: 1px solid var(--border-primary);
overflow: visible;
width: 100%;
box-sizing: border-box;
}
.comment div.icon {
float: none;
border: none;
left: -50px;
}
.comment .icon {
position: relative;
width: 40px;
height: 40px;
border: none;
overflow: hidden;
z-index: 1;
}
/* Mobile comment icon adjustments */
@media only screen and (max-width: 42em), handheld {
.comment .icon {
height: 55px !important;
margin-bottom: 0 !important;
width: 55px !important;
}
.comment .icon .anonymous {
background: url(/images/imageset.png) no-repeat -75px -395px !important;
}
.comment .icon .visitor {
background: url(/images/imageset.png) no-repeat -130px -395px !important;
}
.comment h4.byline {
padding-left: 62px !important;
}
.comment div.icon {
float: none;
border: none;
left: -29.4px;
top: -46.0px;
}
}
.comment .icon img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
.comment .icon .visitor {
width: 100%;
height: 100%;
background: var(--background-tertiary);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2em;
color: var(--text-tertiary);
}
.comment .icon .visitor::before {
content: "👤";
}
.comment h4.byline {
background: transparent;
padding: 0;
margin: 0 0 8px 0;
border-radius: 0;
width: 100%;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 8px;
}
.comment .heading.byline a {
color: var(--accent-primary);
font-weight: 600;
text-decoration: none;
border-bottom: none;
word-wrap: break-word;
overflow-wrap: break-word;
}
.comment .heading.byline a:hover {
text-decoration: underline;
}
.comment .heading.byline span:not(.posted) {
color: var(--text-secondary);
font-weight: normal;
}
.comment .posted.datetime {
font-size: 0.85rem;
color: var(--text-tertiary);
margin-left: auto;
white-space: nowrap;
flex-shrink: 0;
}
li.comment:hover {
transform: translateY(-2px);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2)
}
li.odd.comment {
background: var(--background-secondary)
}
li.even.comment {
background: var(--background-highlight)
}
.comment blockquote.userstuff {
clear: both;
background: var(--background-tertiary);
border-radius: var(--border-radius);
border-left: 3px solid var(--accent-primary);
padding: 12px;
margin: 10px 0;
font-size: 1.1rem;
line-height: 1.6;
color: var(--text-color);
width: 100%;
box-sizing: border-box;
}
.comment blockquote.userstuff p {
margin-bottom: 0.75em
}
.comment blockquote.userstuff p:last-child {
margin-bottom: 0
}
/* Mobile comment adjustments */
@media only screen and (max-width: 42em), handheld {
.thread .thread {
margin-left: 1em !important;
}
.comment .userstuff {
min-height: 0 !important;
}
}
.thread .thread {
margin-left: 2em;
border-left: 2px solid var(--border-primary);
width: calc(100% - 2em);
box-sizing: border-box;
}
ol.thread ol.thread {
margin-left: 20px;
position: relative;
width: calc(100% - 20px);
}
ol.thread ol.thread::before {
content: '';
position: absolute;
left: -20px;
top: 0;
bottom: 0;
width: 2px;
background: var(--border-primary);
border-radius: 1px
}
ol.thread ol.thread li.comment::before {
content: '';
position: absolute;
left: -20px;
top: 20px;
width: 18px;
height: 2px;
background: var(--border-primary);
border-radius: 1px
}
form.filters {
width: 29%;
border-radius: var(--border-radius);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.15);
float: right;
box-sizing: border-box;
}
/* JavaScript filter positioning for mobile */
@media only screen and (max-width: 42em), handheld {
.javascript {
background: #ddd !important;
}
.javascript form.filters {
margin: 0 !important;
position: absolute;
top: 0 !important;
right: -60% !important;
width: 100% !important;
z-index: 400 !important;
}
.javascript .filters fieldset {
border: none !important;
margin: 0 !important;
position: relative !important;
z-index: 450 !important;
box-shadow: none !important;
width: 80% !important;
}
.javascript .filters p.narrow-shown {
position: relative !important;
}
.filtering {
right: 14em !important;
}
.filtering .filters #leave_filters {
background: transparent none !important;
border-bottom: none !important;
position: fixed !important;
top: -101em !important;
bottom: -101em !important;
left: -10em !important;
right: -10em !important;
z-index: 0 !important;
}
.filtering #leave_filters:focus {
outline: none !important;
}
.filters .expanded .expander {
background-image: url("/images/arrow-down.gif");
background-size: 8px;
}
}
/* Mobile form.filters adjustments */
@media only screen and (max-width: 42em), handheld {
form.filters dl {
width: auto !important;
}
}
.filters .expander {
background: var(--tertiary-bg-color);
border: none;
border-radius: var(--border-radius);
color: var(--text-color);
width: 100%;
box-sizing: border-box;
}
.filters .expander::before {
content: "⮞";
color: var(--text-color);
position: absolute;
left: 2%;
top: 50%;
transform: translateY(-50%);
font-size: 1em
}
.filters .expanded .expander::before {
content: "⮟";
color: var(--text-color);
position: absolute;
left: 2%;
top: 50%;
transform: translateY(-50%);
font-size: 1em
}
.filters .expander:hover {
transform: scale(1.05);
z-index: 999
}
.filters .indicator:before {
background: var(--tertiary-bg-color);
color: var(--text-tertiary);
display: inline-block;
border: 1px solid var(--border-primary);
margin-right: .25em;
text-align: center
}
.filters .exclude .indicator:before {
content: " ✕";
padding: 2px 5px;
border-radius: 3px
}
.filters .include .indicator:before {
content: " ✓";
padding: 2px 5px;
border-radius: 3px
}
.filters .exclude .indicator:hover::before {
content: " ✕";
background-color: rgba(203, 144, 144, 0.3);
color: rgb(204, 110, 110);
padding: 2px 5px;
border-radius: 3px
}
.filters .include .indicator:hover::before {
content: " ✓";
background-color: rgba(156, 203, 144, 0.3);
color: rgb(112, 204, 110);
padding: 2px 5px;
border-radius: 3px
}
.filters .indicator span {
font-size: var(--font-size-base);
white-space: normal;
display: inline-block;
margin-left: 14px;
line-height: 1.4;
word-wrap: break-word;
overflow-wrap: break-word;
}
#dashboard {
background: var(--background-secondary);
width: 11.25em;
float: left;
padding: 1em;
border-right: 1px solid var(--border-primary);
box-sizing: border-box;
}
/* Mobile dashboard adjustments */
@media only screen and (max-width: 42em), handheld {
#dashboard, #dashboard.own {
border-bottom-width: 7px !important;
border-top-width: 7px !important;
padding: 0.25em 0 !important;
width: 100% !important;
float: none !important;
border-right: none !important;
margin-bottom: 1em !important;
}
.dashboard .index {
float: none !important;
}
.dashboard .landmark {
clear: both !important;
}
}
#dashboard a, #dashboard span {
color: var(--text-color);
display: block;
white-space: normal;
height: auto;
line-height: 2;
padding: 0.5em;
margin: 0;
border: 0;
border-radius: 3px;
background: transparent;
vertical-align: middle;
word-wrap: break-word;
box-shadow: none;
overflow-wrap: break-word;
}
#dashboard a:hover {
background: var(--background-highlight);
color: var(--accent-primary)
}
#dashboard .current {
background: var(--background-highlight);
color: var(--accent-primary);
border-left: 3px solid var(--accent-primary)
}
.notice, .comment_notice, .kudos_notice {
background: var(--background-secondary);
border: 1px solid var(--border-primary);
border-left: 3px solid var(--alert-info);
color: var(--text-color);
padding: 1em;
margin: 1em 0;
border-radius: 3px;
width: 100%;
box-sizing: border-box;
}
.alert.flash, .error, .comment_error, .kudos_error {
background: var(--background-secondary);
border: 1px solid var(--border-primary);
border-left: 3px solid var(--alert-error);
color: var(--alert-error);
padding: 1em;
margin: 1em 0;
border-radius: 3px;
width: 100%;
box-sizing: border-box;
}
.caution {
background: var(--background-secondary);
border: 1px solid var(--border-primary);
border-left: 3px solid var(--alert-warning);
color: var(--alert-warning);
padding: 1em;
margin: 1em 0;
border-radius: 3px;
width: 100%;
box-sizing: border-box;
}
/* Mobile listbox adjustments */
@media only screen and (max-width: 42em), handheld {
.listbox .index {
width: auto !important;
}
}
.pagination a, .pagination span {
display: inline-block;
padding: 0.3em 0.7em;
margin: 0.1em;
border-radius: var(--border-radius);
min-width: 2em;
text-align: center;
}
.pagination a {
background: var(--tertiary-bg-color);
color: var(--text-color);
border: 1px solid var(--border-primary)
}
.pagination a:hover {
background: var(--quaternary-bg-color);
color: var(--link-color)
}
.pagination .current {
background: var(--link-color);
color: var(--text-color);
border: 1px solid var(--border-primary)
}
.pagination .current a {
margin: auto;
}
/* Splash page mobile adjustments */
@media only screen and (max-width: 42em), handheld {
.splash {
padding: 0 !important;
}
.splash div.module, .logged-in .splash div.module {
clear: both !important;
margin-left: 0 !important;
margin-right: 0 !important;
width: 100% !important;
}
.splash .intro {
padding-top: 0 !important;
}
.splash .intro h2 {
font-size: 1.5em !important;
word-break: normal !important;
}
.session #signin {
margin-left: 0 !important;
width: 100% !important;
}
}
/* Messages mobile adjustments */
@media only screen and (max-width: 42em), handheld {
.announcement .userstuff {
margin: 1% !important;
}
.announcement p.submit {
bottom: -0.5em !important;
right: 1% !important;
}
.announcement .thermometer-content {
width: 80% !important;
}
.announcement .goal .amount {
display: none !important;
}
.announcement .thermometer .progress .amount {
left: 0 !important;
right: auto !important;
}
}
::-webkit-scrollbar {
width: 12px;
height: 12px;
background: var(--background-primary)
}
::-webkit-scrollbar-track {
background: var(--background-primary)
}
::-webkit-scrollbar-thumb {
background: var(--background-tertiary);
border-radius: 6px;
border: 3px solid var(--background-primary)
}
::-webkit-scrollbar-thumb:hover {
background: var(--background-highlight)
}
.category-group::-webkit-scrollbar, .relationships-group::-webkit-scrollbar, .characters-group::-webkit-scrollbar {
width: 6px;
height: 6px
}
.category-group::-webkit-scrollbar-thumb, .relationships-group::-webkit-scrollbar-thumb, .characters-group::-webkit-scrollbar-thumb {
border-width: 1px
}
.work.meta.group {
display: flex;
gap: 12px;
float: none;
padding: 10px;
margin: 8px 0;
border-radius: 10px;
background: var(--primary-bg-color);
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.15);
position: relative;
transition: all 0.2s ease;
flex-wrap: wrap;
align-items: baseline;
flex-direction: column;
width: 100%;
box-sizing: border-box;
}
.work.meta.group:hover {
background: var(--secondary-bg-color);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
transform: translateY(-2px)
}
.meta dt {
min-width: 0;
width: 100%;
text-align: left;
font-weight: bold;
margin-bottom: 0.5em;
}
.meta dd {
width: 100%;
margin-left: 0;
}
.draft, .draft .wrapper, .unread, .child, .unreviewed, .unwrangled {
background: var(--tertiary-bg-color);
border: 1px dashed var(--border-primary);
border-radius: var(--border-radius);
opacity: 0.95
}
span.claimed, span.unread {
color: var(--link-color)
}
.replied, span.claimed, span.unread {
background: var(--tertiary-bg-color);
border: 1px solid var(--border-primary)
}
table {
background: var(--primary-bg-color);
border-collapse: collapse;
margin: auto;
width: 100%;
border-radius: var(--border-radius);
overflow: hidden;
box-sizing: border-box;
overflow-x: auto;
display: block;
white-space: nowrap;
}
table tbody, table thead, table tfoot {
display: table;
width: 100%;
table-layout: fixed;
}
th {
background: var(--secondary-bg-color);
color: var(--text-color);
padding: 0.5em;
text-align: left;
border-bottom: 1px solid var(--border-primary);
word-wrap: break-word;
overflow-wrap: break-word;
}
td {
padding: 0.5em;
background: var(--primary-bg-color);
border-bottom: 1px solid var(--border-secondary);
word-wrap: break-word;
overflow-wrap: break-word;
}
tr:hover {
background: var(--tertiary-bg-color)
}
.group-group .userstuff {
padding: 6px;
border-radius: var(--border-radius);
background: var(--secondary-bg-color);
max-height: 13em;
overflow-y: auto;
font-size: var(--font-size-large);
line-height: 1.6;
width: 100%;
box-sizing: border-box;
word-wrap: break-word;
overflow-wrap: break-word;
}
.group-group::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, var(--primary-bg-color), var(--secondary-bg-color), var(--primary-bg-color));
border-radius: 10px 10px 0 0;
opacity: 0.7
}
.group-group > div:not(:last-child) {
margin-bottom: 8px
}
.announcement .userstuff a, .announcement .userstuff a:link, .announcement {
color: var(--accent-secondary)
}
.userstuff a:visited:hover {
color: var(--accent-primary)
}
/* Additional color overrides for consistency */
body, .toggled form, .dynamic form, .secondary, .dropdown {
background: var(--background-primary);
color: var(--text-color)
}
#header, #footer, #main, #dashboard {
background: var(--background-primary)
}
a, a:link, a:visited:hover {
color: var(--accent-primary);
border-bottom-color: var(--accent-secondary)
}
a:visited {
color: var(--link-visited);
border-bottom-color: var(--accent-tertiary)
}
a:hover, a:focus {
color: var(--accent-tertiary)
}
a:active, a:focus, button:focus {
outline: 1px dotted var(--accent-primary)
}
fieldset, form dl, fieldset dl dl, fieldset fieldset fieldset, fieldset fieldset dl dl, dd.hideme, form blockquote.userstuff {
background: var(--background-secondary);
border-color: var(--border-secondary);
box-shadow: inset 1px 0 5px var(--shadow-color)
}
fieldset fieldset, fieldset dl dl, form blockquote.userstuff {
background: var(--background-tertiary)
}
form dt {
border-bottom-color: var(--border-secondary)
}
input, textarea, select {
background: var(--background-tertiary);
color: var(--text-color);
border-color: var(--border-primary)
}
input:focus, textarea:focus, select:focus {
background: var(--background-highlight) !important;
border-color: var(--accent-primary) !important;
box-shadow: 0 0 0 1px var(--accent-secondary)
}
.LV_invalid {
background: #efd1d1;
border-color: var(--alert-error);
color: var(--alert-error);
box-shadow: 1px 1px 2px var(--shadow-color)
}
.autocomplete div.dropdown ul {
background: var(--background-primary);
border-color: var(--border-secondary);
box-shadow: 1px 3px 5px var(--shadow-color);
color: var(--text-color);
max-width: 90vw;
overflow-x: auto;
}
.autocomplete .dropdown ul li:hover, .autocomplete .dropdown li.selected {
background: var(--accent-primary);
color: var(--text-color)
}
.ui-sortable li {
background: var(--background-tertiary);
border-color: var(--border-primary)
}
.ui-sortable li:hover {
background: var(--background-highlight);
border-color: var(--border-primary);
box-shadow: 1px 1px 3px var(--shadow-color)
}
#header .actions a:hover, #header .actions a:focus, #header .dropdown:hover a, #header .open a {
background: var(--background-highlight)
}
#header .menu, #small_login {
background: var(--background-secondary);
box-shadow: 1px 1px 3px -1px var(--shadow-color)
}
#header .menu li {
border-bottom-color: var(--border-primary)
}
#header h2 {
border-top-color: var(--border-primary);
color: var(--text-color)
}
#dashboard ul {
border-top-color: var(--border-primary)
}
#dashboard.own {
background: transparent;
border-top-color: var(--ao3-red-dark);
border-bottom-color: var(--ao3-red-dark)
}
#main.errors {
background-position: top right;
background-repeat: no-repeat
}
#main.errors p, #main.errors .heading {
color: var(--text-color)
}
thead, tfoot {
border-bottom-color: var(--border-primary)
}
tfoot td {
border-top-color: var(--border-primary)
}
tbody tr {
border-bottom-color: var(--background-highlight)
}
thead td {
background: var(--background-tertiary);
border-bottom-color: var(--background-highlight)
}
th, tr:hover, col.name {
background: var(--background-secondary);
border-color: var(--border-primary)
}
.actions a, .actions a:link, .action, .action:link, .actions button, .actions input, input[type="submit"], button, .current, .actions label {
background: var(--background-tertiary);
color: var(--text-color);
border: 1px solid var(--border-primary);
border-bottom: 1px solid var(--border-secondary);
background-image: none;
box-shadow: none
}
.actions a:hover, .actions button:hover, .actions input:hover, .actions a:focus, .actions button:focus, .actions input:focus, label.action:hover, .action:hover, .action:focus {
color: var(--accent-primary);
border-top-color: var(--border-primary);
border-left-color: var(--border-primary);
box-shadow: inset 2px 2px 2px var(--shadow-color)
}
.actions a:active, .current, a.current, a:link.current, .current a:visited {
color: var(--text-color);
background: var(--background-highlight);
border-color: var(--text-secondary);
box-shadow: inset 1px 1px 3px var(--shadow-color)
}
.actions label.disabled {
background: var(--background-tertiary);
color: var(--text-muted)
}
li.blurb, .blurb .blurb {
border-color: var(--border-primary);
background: var(--background-secondary);
box-shadow: 0 1px 3px var(--shadow-color)
}
.blurb h4 a:link, .blurb h4 img {
color: var(--accent-primary)
}
.own, .draft, .draft .wrapper, .unread, .child, .unwrangled, .unreviewed {
background: var(--background-tertiary);
opacity: 0.95
}
span.unread, .replied, span.claimed, .actions span.defaulted {
background: var(--background-secondary);
color: var(--accent-primary);
border-color: var(--border-primary)
}
.canonical, li.requested {
font-weight: 700;
color: var(--accent-primary)
}
.draggable, .droppable, span.requested, .nominations .rejected {
color: var(--alert-error)
}
span.offered, .replied, .nominations .approved {
color: var(--alert-success)
}
.nominations .approved {
background: rgba(129, 199, 132, 0.2)
}
.nominations .rejected {
background: rgba(207, 102, 121, 0.2)
}
div.comment, li.comment {
border-color: var(--border-primary);
background: var(--background-secondary)
}
.thread .even {
background: var(--background-highlight)
}
.comment .userstuff {
color: var(--text-color)
}
.notice, .comment_notice, .kudos_notice, ul.notes, .caution, .error, .comment_error, .kudos_error, .alert.flash {
background: var(--background-secondary);
border-color: var(--alert-info);
box-shadow: inset 1px 1px 2px var(--shadow-color);
color: var(--text-color)
}
.error, .comment_error, .kudos_error, .alert.flash {
background: var(--background-secondary);
border-color: var(--alert-error);
color: var(--alert-error)
}
.caution {
border-color: var(--alert-warning);
color: var(--alert-warning)
}
.announcement .userstuff {
background: var(--background-tertiary);
border-color: var(--border-primary);
color: var(--text-color)
}
.event .userstuff {
background: var(--ao3-red-dark);
border-color: var(--ao3-red-medium);
color: var(--text-color)
}
.event .userstuff a {
color: var(--text-secondary)
}
.alert .userstuff {
background: var(--alert-warning);
border-color: var(--alert-warning);
color: #333
}
.userstuff {
color: var(--text-color)
}
.userstuff h2 {
color: var(--text-color)
}
.userstuff hr {
border-color: var(--border-primary);
width: 100%
}
.userstuff blockquote {
border-color: var(--border-primary)
}
dl.meta {
border-color: var(--border-primary);
background: var(--background-secondary)
}
#modal-bg {
background: rgba(0, 0, 0, 0.7)
}
#modal {
background: var(--background-secondary);
border-color: var(--background-tertiary);
color: var(--text-color);
box-shadow: 0 0 8px 0 var(--shadow-color);
max-width: 90vw;
max-height: 90vh;
overflow: auto;
}
#modal .content {
border-bottom-color: var(--border-primary)
}
a.tag:hover, .listbox .heading a.tag:visited:hover {
background: var(--accent-primary);
color: var(--text-color)
}
span.symbol {
color: var(--accent-primary);
border-color: var(--accent-primary)
}
.question a:hover {
background: var(--accent-primary);
border-color: var(--accent-secondary);
color: var(--text-color)
}
span.question {
background: var(--background-tertiary);
border-color: var(--accent-primary)
}
/* Additional responsive fixes for very small screens */
@media (max-width: 320px) {
html {
font-size: 13px;
}
#main {
width: 100%;
padding: 0 2px;
}
.group-group, #main li.blurb {
gap: 4px;
padding: 6px;
margin: 2px 0;
}
.blurb h4.heading a {
font-size: var(--font-size-base) !important;
}
a.tag {
font-size: 0.8rem;
padding: 0.1em 0.3em;
}
.action, .action:link, .actions a, .actions a:link, .actions button, .actions input, .actions label, button, input[type=submit] {
padding: 0.3em 0.5em;
font-size: 0.8rem;
}
dl.stats {
grid-template-columns: 1fr;
gap: 2px;
}
.pagination a, .pagination span {
padding: 0.2em 0.3em;
min-width: 1.2em;
font-size: 0.8rem;
}
}
/* Print styles */
@media print {
* {
background: white !important;
color: black !important;
box-shadow: none !important;
text-shadow: none !important;
}
#header, #footer, #dashboard, form.filters, .actions {
display: none !important;
}
#main {
width: 100% !important;
margin: 0 !important;
padding: 0 !important;
}
.group-group, #main li.blurb {
break-inside: avoid;
page-break-inside: avoid;
}
a {
text-decoration: underline !important;
border-bottom: none !important;
}
.userstuff {
font-size: 12pt !important;
line-height: 1.4 !important;
}
}
/* Focus management for keyboard navigation */
.skip-link {
position: absolute;
top: -40px;
left: 6px;
background: var(--accent-primary);
color: var(--text-color);
padding: 8px;
text-decoration: none;
border-radius: 4px;
z-index: 1000;
}
.skip-link:focus {
top: 6px;
}
/* Improved touch targets for mobile */
@media (max-width: 768px) {
a, button, input, select, textarea, .action {
min-height: 24px;
min-width: 24px;
display: inline-flex;
align-items: center;
justify-content: center;
}
a.tag {
min-height: 20px;
min-width: auto;
}
}
/* Landscape orientation adjustments for tablets */
@media (min-width: 481px) and (max-width: 1024px) and (orientation: landscape) {
#main.dashboard {
margin-left: 12em;
width: calc(100% - 12em);
}
#dashboard {
width: 10em;
float: left;
border-right: 1px solid var(--border-primary);
border-bottom: none;
}
form.filters {
width: 25%;
float: right;
}
}
/* RTL language support */
[dir="rtl"] .blurb .header .heading,
[dir="rtl"] .blurb .header ul {
margin: .375em 65px 0 5.25em;
}
[dir="rtl"] .header.module ul.required-tags {
right: 0;
left: auto;
}
[dir="rtl"] .header.module p.datetime {
left: 0;
right: auto;
text-align: left;
}
[dir="rtl"] .header.module h4.heading {
margin: 0 50px 0.5em 100px;
}
[dir="rtl"] #dashboard.own {
border-right-color: var(--ao3-red-dark);
border-left-color: var(--ao3-red-dark);
}
[dir="rtl"] .meta dt {
text-align: left;
}
[dir="rtl"] form.filters {
float: left;
}
[dir="rtl"] #main.dashboard {
margin-right: 14em;
margin-left: 0;
padding-right: 1em;
padding-left: 0;
}
/* Dark mode image optimization */
@media (prefers-color-scheme: dark) {
img {
opacity: 0.9;
transition: opacity 0.2s ease;
}
img:hover {
opacity: 1;
}
}
/* Reduced data mode - simplified styles */
@media (prefers-reduced-data: reduce) {
.group-group::before {
display: none;
}
.box-shadow,
.hover-box-shadow,
box-shadow {
box-shadow: none !important;
}
.transition {
transition: none !important;
}
}
/* Container queries for modern browsers */
@supports (container-type: inline-size) {
.blurb {
container-type: inline-size;
}
@container (max-width: 400px) {
.blurb .header {
flex-direction: column;
gap: 0.25em;
}
.blurb h4.heading a {
font-size: var(--font-size-base) !important;
}
}
}
/* Force hardware acceleration for smooth animations */
.group-group,
#main li.blurb,
.work.meta.group,
li.comment,
.action,
.actions a,
.actions button,
a.tag {
transform: translateZ(0);
backface-visibility: hidden;
perspective: 1000;
}
/* Improved scrollbar for mobile webkit */
@media (max-width: 768px) {
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-thumb {
border: 1px solid var(--background-primary);
}
}
/* Mobile-specific improvements */
@media (max-width: 480px) {
#main {
width: 98%;
padding: 0 4px;
margin: 0;
}
#main.dashboard {
margin-left: 0;
padding-left: 0.5em;
width: 100%;
}
form.filters {
width: 100%;
float: none;
margin: 0 0 16px 0;
order: -1;
}
#dashboard {
width: 100%;
float: none;
border-right: none;
border-bottom: 1px solid var(--border-primary);
margin-bottom: 1em;
padding: 0.5em;
}
.meta dt {
width: 100%;
text-align: left;
margin-bottom: 0.25em;
}
.meta dd {
width: 100%;
margin-left: 0;
margin-bottom: 1em;
}
dl.stats {
grid-template-columns: repeat(3, 1fr);
gap: 4px;
}
.words-group, .chapters-group, .comments-group, .kudos-group, .bookmarks-group, .hits-group, .collections-group, .language-group, .published-group, .status-group {
min-width: 60px;
}
ol.thread ol.thread {
margin-left: 5px;
width: calc(100% - 5px);
}
ol.thread ol.thread::before {
left: -5px;
}
ol.thread ol.thread li.comment::before {
left: -5px;
width: 3px;
}
.thread .thread {
margin-left: 1em;
width: calc(100% - 1em);
}
.blurb h4.heading a {
font-size: 1.1rem !important;
}
h5:nth-child(2) > a {
font-size: var(--font-size-base) !important;
}
#outer .group .heading {
font-size: var(--font-size-base);
}
a.tag {
font-size: 0.9rem;
padding: 0.15em 0.4em;
margin: 0.1em;
}
.category-group, .relationships-group, .characters-group, .meta dd {
font-size: var(--font-size-base);
gap: 4px;
padding: 3px;
}
#workskin {
font-size: 1.1rem;
padding: 0.5em !important;
}
.userstuff blockquote {
padding: 0.5em;
margin: 0.5em 0;
}
.comment blockquote.userstuff {
font-size: var(--font-size-base);
padding: 8px;
}
.group-group .userstuff {
font-size: var(--font-size-base);
padding: 4px;
}
.blurb .header {
gap: 0.25em;
}
.group-group, #main li.blurb {
gap: 8px;
padding: 8px;
margin: 4px 0;
}
.action, .action:link, .actions a, .actions a:link, .actions button, .actions input, .actions label, button, input[type=submit] {
padding: 0.4em 0.8em;
margin: 2px;
font-size: 0.9rem;
}
fieldset, form dl {
margin: 0.3em;
padding: 0.5em;
}
.pagination a, .pagination span {
padding: 0.25em 0.5em;
min-width: 1.5em;
font-size: 0.9rem;
}
#header .primary a {
padding: 0.3em 0.5em;
font-size: 0.9rem;
}
#header .heading a {
font-size: 1.4em;
}
#footer {
padding: 0.5em;
font-size: 0.9rem;
}
table {
font-size: 0.9rem;
}
th, td {
padding: 0.3em;
}
li.comment {
padding: 8px 12px 8px 50px;
}
.comment h4.byline {
flex-direction: column;
align-items: flex-start;
gap: 4px;
}
.comment .posted.datetime {
margin-left: 0;
font-size: 0.8rem;
}
}
@media (max-width: 320px) {
li.comment {
padding: 6px 8px 6px 40px;
}
.comment .icon {
width: 28px;
height: 28px;
}
}
@media (min-width: 481px) and (max-width: 768px) {
#main {
width: 95%;
padding: 0 6px;
}
#main.dashboard {
margin-left: 0;
padding-left: 1em;
width: 100%;
}
form.filters {
width: 100%;
float: none;
margin-left: 0;
margin-bottom: 16px;
}
#dashboard {
width: 100%;
float: none;
border-right: none;
border-bottom: 1px solid var(--border-primary);
margin-bottom: 1em;
}
.meta dt {
width: 100%;
text-align: left;
}
.meta dd {
width: 70%;
}
.work.meta.group {
flex-direction: row;
align-items: flex-start;
}
dl.stats {
grid-template-columns: repeat(4, 1fr);
}
ol.thread ol.thread {
margin-left: 10px;
width: calc(100% - 10px);
}
ol.thread ol.thread::before {
left: -10px;
}
ol.thread ol.thread li.comment::before {
left: -10px;
width: 8px;
}
}
@media (min-width: 769px) and (max-width: 1024px) {
#main {
width: 92%;
}
form.filters {
max-width: 30%;
width: 30%;
}
.meta dt {
width: 15%;
text-align: right;
}
.meta dd {
width: 80%;
}
.work.meta.group {
flex-direction: row;
align-items: baseline;
}
dl.stats {
grid-template-columns: repeat(4, 1fr);
}
}
@media (min-width: 1025px) {
.meta dt {
width: 9%;
text-align: right;
}
.meta dd {
width: 90%;
}
.work.meta.group {
flex-direction: row;
align-items: baseline;
}
dl.stats {
display: flex;
flex-wrap: wrap;
}
}
@media (prefers-color-scheme: dark) {
#workskin img {
box-shadow: 0 0 0 1px var(--border-primary);
border-radius: var(--border-radius);
max-width: 100%;
height: auto;
}
}
/* Accessibility improvements */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
#main li.blurb:hover {
transform: none;
}
.work.meta.group:hover {
transform: none;
}
li.comment:hover {
transform: none;
}
.action:hover, .actions a:hover, .actions button:hover, .actions input:hover, button:hover, input[type=submit]:hover {
transform: none;
}
a.tag:hover {
transform: none;
}
.filters .expander:hover {
transform: none;
}
}
/* High contrast mode improvements */
@media (prefers-contrast: high) {
:root {
--border-primary: #ffffff;
--border-secondary: #cccccc;
--text-color: #ffffff;
--background-primary: #000000;
--background-secondary: #111111;
--background-tertiary: #222222;
--link-color: #00ffff;
--accent-primary: #ff0000;
}
}
/* Landmark elements - keeping them hidden but accessible */
h4.landmark, h5.landmark, .landmark, .landmark a, .index .heading.landmark {
font-size: 0;
line-height: 0;
height: 0;
margin: 0;
clear: both;
color: transparent;
opacity: 0;
left: -9999px;
}
.blurb .header .heading, .blurb .header ul {
margin: .375em 5.25em 0 65px
}
@media (max-width: 768px) {
.blurb .header .heading, .blurb .header ul {
margin: 0;
}
}
.blurb .header img {
position: relative;
margin: 0;
max-width: 100%;
height: auto;
}
.delete a, span.delete {
border: 0;
color: var(--alert-error);
font-weight: 700;
margin-right: .375em;
padding: 0 .1em .15em;
box-shadow: -1px -1px 2px rgba(0, 0, 0, 0.5);
border-radius: .875em
}
blockquote {
font-family: var(--font-family);
margin: .643em;
word-wrap: break-word;
overflow-wrap: break-word;
width: 100%;
box-sizing: border-box;
}
blockquote p:first-child {
margin-top: 0
}
blockquote p:last-child {
margin-bottom: 0
}
*:focus {
outline: none
}
a:focus, button:focus, input:focus, select:focus, textarea:focus {
outline: 2px solid var(--link-color);
outline-offset: 2px
}
.listbox, fieldset fieldset.listbox {
clear: right;
background: var(--secondary-bg-color);
border: 2px solid var(--border-primary);
padding: 0;
margin: 0.643em auto;
margin-right: auto;
overflow: hidden;
box-shadow: var(--box-shadow);
}
.listbox .index {
width: auto;
padding: 0.643em;
margin: 0;
float: none;
clear: right;
background: var(--secondary-bg-color);
box-shadow: inset var(--box-shadow);
}
#header .open .menu, #header .dropdown:hover .menu, .open + #small_login, #header .menu li {
display: block;
float: none;
}
`;
document.head.appendChild(style);
// Responsive image handler
function makeImagesResponsive() {
const images = document.querySelectorAll("img");
images.forEach((img) => {
if (!img.style.maxWidth) {
img.style.maxWidth = "100%";
img.style.height = "auto";
}
});
}
// Enhanced wrapping function with duplicate prevention
function safeWrapElements(parent, selectors, className) {
try {
selectors.forEach((selector) => {
const elements = parent.querySelectorAll(selector);
if (elements.length > 0) {
// Check if elements are already wrapped
const firstElement = elements[0];
if (firstElement.parentNode.classList.contains(className)) {
return; // Already wrapped, skip
}
// Create a single wrapper for all matching elements
const wrapper = document.createElement("div");
wrapper.className = className;
firstElement.parentNode.insertBefore(wrapper, firstElement);
// Move all matching elements into the wrapper
elements.forEach((el) => wrapper.appendChild(el));
}
});
} catch (error) {
console.warn("AO3 Dark Mode: Error wrapping elements:", error);
}
}
// Initialize theme with improved element handling
function initializeTheme() {
// For dl.stats elements
const statsList = document.querySelectorAll("dl.stats");
statsList.forEach((dl) => {
safeWrapElements(dl, [".status"], "status-group");
safeWrapElements(dl, [".published"], "published-group");
safeWrapElements(dl, [".language"], "language-group");
safeWrapElements(dl, [".words"], "words-group");
safeWrapElements(dl, [".chapters"], "chapters-group");
safeWrapElements(dl, [".comments"], "comments-group");
safeWrapElements(dl, [".kudos"], "kudos-group");
safeWrapElements(dl, [".bookmarks"], "bookmarks-group");
safeWrapElements(dl, [".hits"], "hits-group");
safeWrapElements(dl, [".collections"], "collections-group");
});
// For each work item - wrap ALL tag groups in a single group-group
const workItems = document.querySelectorAll(
"#main li.blurb"
);
workItems.forEach((work) => {
// Mark as processed to prevent re-processing
work.setAttribute("data-theme-processed", "true");
const tagsList = work.querySelector("ul.tags");
if (tagsList) {
// First wrap individual tag types within the tags list
safeWrapElements(
tagsList,
["li.warnings", "li.freeforms"],
"category-group"
);
safeWrapElements(tagsList, ["li.relationships"], "relationships-group");
safeWrapElements(tagsList, ["li.characters"], "characters-group");
}
// Now wrap ALL content groups AND userstuff in ONE group-group at the work level
// This includes both tag groups and summary blocks
const allContentToGroup = work.querySelectorAll(
"ul.tags .category-group, ul.tags .relationships-group, ul.tags .characters-group, blockquote.userstuff"
);
if (allContentToGroup.length > 0) {
// Find the first element to determine insertion point
const firstElement = allContentToGroup[0];
// Create single group wrapper
const groupWrapper = document.createElement("div");
groupWrapper.className = "group-group";
firstElement.parentNode.insertBefore(groupWrapper, firstElement);
// Move all content into the single wrapper
allContentToGroup.forEach((el) => groupWrapper.appendChild(el));
}
});
// Make images responsive
makeImagesResponsive();
// Add skip link for accessibility if it doesn't exist
if (!document.querySelector(".skip-link")) {
const skipLink = document.createElement("a");
skipLink.href = "#main";
skipLink.className = "skip-link";
skipLink.textContent = "Skip to main content";
document.body.insertBefore(skipLink, document.body.firstChild);
}
}
// Initialize on different load events for better compatibility
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initializeTheme);
} else {
initializeTheme();
}
// Also run on window load for dynamic content
window.addEventListener("load", () => {
setTimeout(initializeTheme, 100);
setTimeout(makeImagesResponsive, 200);
});
// Handle dynamic content loading with throttling
let observerTimeout;
const observer = new MutationObserver((mutations) => {
let shouldReinit = false;
mutations.forEach((mutation) => {
if (mutation.type === "childList" && mutation.addedNodes.length > 0) {
mutation.addedNodes.forEach((node) => {
if (
node.nodeType === 1 &&
(node.matches("li.work:not([data-theme-processed])") ||
node.querySelector("li.work:not([data-theme-processed])"))
) {
shouldReinit = true;
}
});
}
});
if (shouldReinit) {
clearTimeout(observerTimeout);
observerTimeout = setTimeout(initializeTheme, 100);
}
});
// Start observing
observer.observe(document.body, {
childList: true,
subtree: true,
});
})();