MediaWiki:Common.css: Difference between revisions

From FusionGirl Wiki
Jump to navigationJump to search
(FusionGirl wiki theme — dark default, amber/gun-metal palette, light toggle [Mecha Jono])
Tag: Manual revert
(Install Tho'ra crossfade CSS classes (Aurora overhaul Stage 2))
 
(4 intermediate revisions by the same user not shown)
Line 1,085: Line 1,085:
}
}


/* Thumbnail captions (legacy div + modern figcaption) */
/* Thumbnail captions (legacy div + modern figcaption).
  ``[typeof^="mw:File"]`` (prefix match) catches all subtypes:
  ``mw:File``, ``mw:File/Thumb``, ``mw:File/Frame``. ``[typeof~=...]``
  (whitespace-token match) does NOT match ``mw:File/Thumb`` because that
  is a single token, not a list-token of ``mw:File``. */
.thumbcaption,
.thumbcaption,
figure.thumb > figcaption,
figure.thumb > figcaption,
figure.mw-default-size > figcaption,
figure.mw-default-size > figcaption,
figure[typeof~="mw:File"] > figcaption {
figure[typeof^="mw:File"] > figcaption,
   background-color: transparent !important;
figure[typeof~="mw:File"] > figcaption,
figure[typeof~="mw:File/Thumb"] > figcaption,
figure[typeof~="mw:File/Frame"] > figcaption,
.tmulti .thumbcaption,
.thumbinner > .thumbcaption {
   background-color: var(--fg-bg-surface) !important;
   color: var(--fg-text-secondary) !important;
   color: var(--fg-text-secondary) !important;
   font-size: 0.9em;
   font-size: 0.9em;
  border-top: 1px solid var(--fg-border);
}
/* Light-mode caption — keep cream surface, soft border */
html.fg-light-mode .thumbcaption,
html.fg-light-mode figure.thumb > figcaption,
html.fg-light-mode figure.mw-default-size > figcaption,
html.fg-light-mode figure[typeof^="mw:File"] > figcaption,
html.fg-light-mode .tmulti .thumbcaption {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-secondary) !important;
  border-top-color: var(--fg-border) !important;
}
}


Line 2,113: Line 2,134:
   }
   }
}
}
/* === BEGIN: thora-character-layout (managed by tools/setup_thora_character_layout.py) === */
/* Tho'ra character-page layout system.
  Used by Aurora Tho'ra, Jono Tho'ra, Jane Tho'ra, Amber Tho'ra and other
  character-archetype pages. Provides hero block (coordinated top-of-page
  media + identity card), section-image floats with phone-portrait
  collapse, responsive capability grid, canon-meta blocks, and pull-quote
  styling. All breakpoints centered at 720px (tablet/phone divide). */
/* === Hero block === */
.thora-hero {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5em;
    align-items: flex-start;
    margin: 0 0 1.5em 0;
    clear: both;
}
.thora-hero-media {
    flex: 2 1 360px;
    min-width: 280px;
    max-width: 540px;
}
.thora-hero-card {
    flex: 1 1 280px;
    min-width: 240px;
    max-width: 360px;
}
.thora-hero-card .infobox {
    margin: 0 !important;
    width: 100% !important;
    float: none !important;
}
/* Crossfade nested inside hero media slot fills its slot */
.thora-hero-media .thora-crossfade {
    width: 100%;
    display: block;
}
.thora-hero-media .thora-crossfade .thora-frame img {
    width: 100%;
    height: auto;
}
/* Phone portrait: identity card first, media second, lede paragraph follows.
  column-reverse so source-order media-then-card flips visually. */
@media (max-width: 720px) {
    .thora-hero {
        flex-direction: column-reverse;
        gap: 1em;
    }
    .thora-hero-media,
    .thora-hero-card {
        max-width: 100%;
        flex-basis: auto;
    }
}
/* === Section image floats === */
.thora-section-image {
    float: right;
    margin: 0 0 1em 1.5em;
    max-width: 280px;
    clear: right;
}
.thora-section-image-left {
    float: left;
    margin: 0 1.5em 1em 0;
    max-width: 280px;
    clear: left;
}
.thora-section-image img,
.thora-section-image-left img,
.thora-section-image .thora-crossfade .thora-frame img,
.thora-section-image-left .thora-crossfade .thora-frame img {
    max-width: 100%;
    height: auto;
}
.thora-section-image .caption,
.thora-section-image-left .caption {
    font-size: 0.85em;
    color: var(--fg-text-secondary);
    margin-top: 0.25em;
    line-height: 1.3;
}
/* Phone portrait: section images become full-width inline blocks below
  the prose they illustrate (source-order rendering) */
@media (max-width: 720px) {
    .thora-section-image,
    .thora-section-image-left {
        float: none;
        margin: 1em auto;
        max-width: 100%;
        display: block;
    }
}
/* === Capability grid === */
/* Wide screens: behaves as a wikitable (inherits .wikitable styles).
  Phone: collapses to vertical card stack per row. */
.thora-capability-grid {
    width: 100%;
}
.thora-capability-grid td,
.thora-capability-grid th {
    vertical-align: top;
    padding: 0.5em 0.75em;
}
@media (max-width: 720px) {
    .thora-capability-grid,
    .thora-capability-grid tbody,
    .thora-capability-grid tr,
    .thora-capability-grid td {
        display: block;
        width: 100% !important;
        box-sizing: border-box;
    }
    .thora-capability-grid thead { display: none; }
    .thora-capability-grid tr {
        border: 1px solid var(--fg-border);
        border-radius: 4px;
        margin-bottom: 0.5em;
        padding: 0.25em 0.5em;
        background-color: var(--fg-bg-surface);
    }
    .thora-capability-grid td {
        border: none !important;
        padding: 0.25em 0;
    }
    .thora-capability-grid td:first-child {
        font-weight: 600;
        color: var(--fg-text-heading);
        border-bottom: 1px solid var(--fg-border-subtle) !important;
        margin-bottom: 0.25em;
    }
}
/* === Canon-meta block === */
/* Visually distinguishes "reserved" / "open hooks" / "canon meta" content
  from established canon, so casual readers don't mistake unsettled
  questions for established lore. */
.thora-canon-meta {
    border: 1px dashed var(--fg-border-light);
    background-color: var(--fg-bg-elevated);
    padding: 0.75em 1.25em;
    margin: 1.5em 0;
    border-radius: 6px;
    position: relative;
}
.thora-canon-meta::before {
    content: "⚠ Canonical meta";
    display: block;
    font-size: 0.72em;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--fg-accent-muted);
    margin-bottom: 0.5em;
    font-weight: 700;
    font-family: 'Space Grotesk', 'Inter', sans-serif;
}
.thora-canon-meta h2,
.thora-canon-meta h3 {
    color: var(--fg-accent-muted) !important;
    border-bottom: 1px solid var(--fg-border-light) !important;
    margin-top: 0.25em !important;
}
.thora-canon-meta ul {
    margin-left: 0.5em;
}
/* === Pull-quote === */
/* Single-sentence anchor placed below a section heading to give the
  reader an at-a-glance essence-statement before the prose. */
.thora-pullquote {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 1.1em;
    line-height: 1.5;
    color: var(--fg-text-heading);
    border-left: 3px solid var(--fg-accent);
    padding: 0.25em 0 0.25em 1em;
    margin: 0.5em 0 1em 0;
    font-style: italic;
    background-color: transparent;
}
/* === Hero float-left variant === */
/* Use when a page wants classical text-wrap rather than the flex hero.
  The infobox (right-floated by default) hugs the right; this floated
  media block hugs the left; lede prose flows in the channel between.
  On phone, collapses to full-width block above prose. */
.thora-hero-float-left {
    float: left;
    width: 380px;
    max-width: 45%;
    margin: 0 1.5em 1em 0;
    clear: left;
}
.thora-hero-float-left .thora-crossfade {
    width: 100%;
}
.thora-hero-float-left .thora-crossfade img,
.thora-hero-float-left img {
    width: 100%;
    height: auto;
    max-width: 100%;
}
@media (max-width: 720px) {
    .thora-hero-float-left {
        float: none;
        width: 100%;
        max-width: 520px;
        margin: 0 auto 1em auto;
    }
}
/* === Banner image (full content-width, no float) === */
/* For mid-page anchor sections where an image deserves to span the full
  reading column rather than float beside text. Used e.g. for the
  Speeder Production banner on Aurora's page. */
.thora-banner-image {
    display: block;
    width: 100%;
    margin: 1.5em 0;
    clear: both;
}
.thora-banner-image img,
.thora-banner-image a img {
    display: block;
    width: 100%;
    height: auto;
    max-width: 100%;
    border-radius: 4px;
}
.thora-banner-image .thumbcaption,
.thora-banner-image figcaption {
    margin-top: 0.5em;
    font-size: 0.9em;
    color: var(--fg-text-secondary);
    text-align: center;
    font-style: italic;
}
/* === END: thora-character-layout === */
/* === BEGIN: thora-crossfade (managed by tools/setup_thora_crossfade.py) === */
/* Tho'ra crossfade gallery system.
  Use: <div class="thora-crossfade thora-cycle-N-tempo">
          <span class="thora-frame">[[File:...|400px]]</span> ... </span>
        </div>
  The first frame anchors the container size; subsequent frames overlay it.
  Preload strategy: every frame starts its animation at t=0 (no
  animation-delay). Each slot uses its own keyframe whose visible window is
  shifted within the cycle. This forces the browser to lay out, paint, and
  decode all frames on the first paint cycle — which prevents the "first
  loop is blank/blink" issue caused by deferred decode of opacity-0 images.
  We additionally use translateZ(0)/backface-visibility/will-change to
  promote each frame to its own compositor layer so subsequent transitions
  are GPU-composited and don't trigger re-decode. */
.thora-crossfade {
    position: relative;
    display: inline-block;
    line-height: 0;
    vertical-align: top;
}
.thora-crossfade .thora-frame {
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0;
    /* Preload + GPU-compositor hints */
    will-change: opacity;
    transform: translateZ(0);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
    animation-fill-mode: both;
    animation-delay: 0s; /* shared start so all frames decode immediately */
}
.thora-crossfade .thora-frame:first-child {
    position: relative; /* anchor: this frame defines container dimensions */
}
.thora-crossfade .thora-frame img,
.thora-crossfade .thora-frame a {
    display: block;
}
/* Hint to MediaWiki/browser: decode these images eagerly. */
.thora-crossfade .thora-frame img {
    image-rendering: auto;
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
}
/* === 2-frame medium (8s total, 4s/frame) === */
.thora-cycle-2-medium .thora-frame { animation-duration: 8s; }
.thora-cycle-2-medium .thora-frame:nth-child(1) { animation-name: thora-fade-2-1; }
.thora-cycle-2-medium .thora-frame:nth-child(2) { animation-name: thora-fade-2-2; }
@keyframes thora-fade-2-1 {
    0%, 45%  { opacity: 1; }
    55%, 95%  { opacity: 0; }
    100%      { opacity: 1; }
}
@keyframes thora-fade-2-2 {
    0%, 45%  { opacity: 0; }
    55%, 95%  { opacity: 1; }
    100%      { opacity: 0; }
}
/* === 3-frame medium (12s total, 4s/frame) === */
.thora-cycle-3-medium .thora-frame { animation-duration: 12s; }
.thora-cycle-3-medium .thora-frame:nth-child(1) { animation-name: thora-fade-3-1; }
.thora-cycle-3-medium .thora-frame:nth-child(2) { animation-name: thora-fade-3-2; }
.thora-cycle-3-medium .thora-frame:nth-child(3) { animation-name: thora-fade-3-3; }
@keyframes thora-fade-3-1 {
    0%, 30%  { opacity: 1; }
    36%, 96%  { opacity: 0; }
    100%      { opacity: 1; }
}
@keyframes thora-fade-3-2 {
    0%, 30%  { opacity: 0; }
    36%, 63%  { opacity: 1; }
    70%, 100% { opacity: 0; }
}
@keyframes thora-fade-3-3 {
    0%, 63%  { opacity: 0; }
    70%, 96%  { opacity: 1; }
    100%      { opacity: 0; }
}
/* === 5-frame brisk (12.5s total, 2.5s/frame) === suit-up urgency */
.thora-cycle-5-brisk .thora-frame { animation-duration: 12.5s; }
.thora-cycle-5-brisk .thora-frame:nth-child(1) { animation-name: thora-fade-5-1; }
.thora-cycle-5-brisk .thora-frame:nth-child(2) { animation-name: thora-fade-5-2; }
.thora-cycle-5-brisk .thora-frame:nth-child(3) { animation-name: thora-fade-5-3; }
.thora-cycle-5-brisk .thora-frame:nth-child(4) { animation-name: thora-fade-5-4; }
.thora-cycle-5-brisk .thora-frame:nth-child(5) { animation-name: thora-fade-5-5; }
/* === 5-frame slow (25s total, 5s/frame) === hangar contemplation */
.thora-cycle-5-slow .thora-frame { animation-duration: 25s; }
.thora-cycle-5-slow .thora-frame:nth-child(1) { animation-name: thora-fade-5-1; }
.thora-cycle-5-slow .thora-frame:nth-child(2) { animation-name: thora-fade-5-2; }
.thora-cycle-5-slow .thora-frame:nth-child(3) { animation-name: thora-fade-5-3; }
.thora-cycle-5-slow .thora-frame:nth-child(4) { animation-name: thora-fade-5-4; }
.thora-cycle-5-slow .thora-frame:nth-child(5) { animation-name: thora-fade-5-5; }
/* Shared 5-frame keyframes — each slot 20% of cycle, 2% fade overlap.
  All slots animate from t=0 so all frames are painted/decoded immediately. */
@keyframes thora-fade-5-1 {
    0%, 18%  { opacity: 1; }
    22%, 96%  { opacity: 0; }
    100%      { opacity: 1; }
}
@keyframes thora-fade-5-2 {
    0%, 18%  { opacity: 0; }
    22%, 38%  { opacity: 1; }
    42%, 100% { opacity: 0; }
}
@keyframes thora-fade-5-3 {
    0%, 38%  { opacity: 0; }
    42%, 58%  { opacity: 1; }
    62%, 100% { opacity: 0; }
}
@keyframes thora-fade-5-4 {
    0%, 58%  { opacity: 0; }
    62%, 78%  { opacity: 1; }
    82%, 100% { opacity: 0; }
}
@keyframes thora-fade-5-5 {
    0%, 78%  { opacity: 0; }
    82%, 98%  { opacity: 1; }
    100%      { opacity: 0; }
}
/* Accessibility: honor reduced-motion preference. Show first frame only. */
@media (prefers-reduced-motion: reduce) {
    .thora-crossfade .thora-frame {
        animation: none !important;
        opacity: 0;
    }
    .thora-crossfade .thora-frame:first-child {
        opacity: 1;
    }
}
/* === END: thora-crossfade === */

Latest revision as of 10:02, 5 May 2026

/* ================================================================
   FusionGirl Wiki Theme
   Color schema: Gun Metal · Amber/Ember · Black/White
   Matched to https://fusiongirl.app
   Dark mode default, light mode toggle via Common.js
   ================================================================ */

/* ── Google Fonts ── */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;600&family=Space+Grotesk:wght@500;600;700&display=swap');

/* ================================================================
   CSS CUSTOM PROPERTIES — DARK THEME (DEFAULT)
   ================================================================ */
:root {
  /* ── Backgrounds ── */
  --fg-bg-primary:     #0a0a0a;       /* page body — near-black              */
  --fg-bg-secondary:   #111111;       /* content area                        */
  --fg-bg-surface:     #1a1a1a;       /* cards, panels, infoboxes            */
  --fg-bg-elevated:    #222222;       /* hover states, elevated panels       */
  --fg-bg-input:       #0d0d0d;       /* input fields, search box            */
  --fg-bg-header:      #0a0a0a;       /* sticky header / top bar             */
  --fg-bg-sidebar:     #0a0a0a;       /* sidebar / navigation                */

  /* ── Gun Metal ── */
  --fg-gunmetal:       #2a3439;
  --fg-gunmetal-light: #3a4449;
  --fg-gunmetal-dark:  #1a2024;

  /* ── Amber / Orange Accent (from fusiongirl.app: #FF8C00) ── */
  --fg-accent:         #FF8C00;
  --fg-accent-hover:   #FFa030;
  --fg-accent-muted:   #cc7000;
  --fg-accent-gold:    #FFD700;
  --fg-accent-glow:    rgba(255, 140, 0, 0.12);
  --fg-accent-glow-strong: rgba(255, 140, 0, 0.25);

  /* ── Text ── */
  --fg-text-primary:   rgba(255, 255, 255, 0.87);   /* body text             */
  --fg-text-secondary: rgba(255, 255, 255, 0.50);   /* dimmed / meta         */
  --fg-text-heading:   #ffffff;                      /* headings              */
  --fg-text-link:      #FF8C00;                      /* links = amber         */
  --fg-text-link-new:  #ff6568;                      /* red-links (missing)   */
  --fg-text-link-visited: #cc7000;
  --fg-text-link-hover: #FFD700;

  /* ── Borders ── */
  --fg-border:         #2a3439;       /* gun metal border                    */
  --fg-border-light:   #3a4449;
  --fg-border-accent:  #FF8C00;
  --fg-border-subtle:  rgba(255, 255, 255, 0.08);

  /* ── Code ── */
  --fg-code-bg:        #0d0d0d;
  --fg-code-text:      #FF8C00;
  --fg-code-border:    #2a3439;

  /* ── Shadows ── */
  --fg-shadow:         0 2px 8px rgba(0, 0, 0, 0.4);
  --fg-shadow-accent:  0 0 12px rgba(255, 140, 0, 0.15);

  /* ── Transitions ── */
  --fg-transition:     0.2s ease;
}

/* ================================================================
   CSS CUSTOM PROPERTIES — LIGHT THEME (toggled)
   ================================================================ */
html.fg-light-mode {
  --fg-bg-primary:     #f4f0eb;
  --fg-bg-secondary:   #faf8f5;
  --fg-bg-surface:     #ffffff;
  --fg-bg-elevated:    #f0ece7;
  --fg-bg-input:       #ffffff;
  --fg-bg-header:      #f4f0eb;
  --fg-bg-sidebar:     #ede9e4;

  --fg-gunmetal:       #c8cdd0;
  --fg-gunmetal-light: #dde0e3;
  --fg-gunmetal-dark:  #b0b5b8;

  --fg-accent:         #b36200;
  --fg-accent-hover:   #8b4d00;
  --fg-accent-muted:   #7a4200;
  --fg-accent-gold:    #8a7208;
  --fg-accent-glow:    rgba(179, 98, 0, 0.10);
  --fg-accent-glow-strong: rgba(179, 98, 0, 0.18);

  --fg-text-primary:   #1a1a1a;
  --fg-text-secondary: #555555;
  --fg-text-heading:   #0a0a0a;
  --fg-text-link:      #8b4d00;       /* WCAG AA 5.2:1 on #f4f0eb */
  --fg-text-link-new:  #a30000;       /* WCAG AA on light bg       */
  --fg-text-link-visited: #6b3a00;
  --fg-text-link-hover: #b36200;

  --fg-border:         #d5d0cb;
  --fg-border-light:   #e5e0db;
  --fg-border-accent:  #b36200;
  --fg-border-subtle:  rgba(0, 0, 0, 0.06);

  --fg-code-bg:        #f0ece7;
  --fg-code-text:      #7a4200;
  --fg-code-border:    #d5d0cb;

  --fg-shadow:         0 2px 8px rgba(0, 0, 0, 0.08);
  --fg-shadow-accent:  0 0 12px rgba(204, 112, 0, 0.1);
}


/* ================================================================
   GLOBAL RESETS & TYPOGRAPHY
   ================================================================ */

body {
  background-color: var(--fg-bg-primary) !important;
  color: var(--fg-text-primary) !important;
  font-family: 'Inter', ui-sans-serif, system-ui, -apple-system,
               BlinkMacSystemFont, 'Segoe UI', Roboto,
               'Helvetica Neue', Arial, sans-serif !important;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background-image: radial-gradient(ellipse at center, rgba(255,140,0,0.03) 0%, transparent 70%);
  background-attachment: fixed;
  transition: background-color var(--fg-transition),
              color var(--fg-transition);
}


/* ================================================================
   CONTENT AREA
   ================================================================ */

.mw-body,
.vector-body,
.mw-page-container {
  background-color: var(--fg-bg-secondary) !important;
  color: var(--fg-text-primary) !important;
  transition: background-color var(--fg-transition);
}

.mw-body-content {
  background-color: var(--fg-bg-secondary) !important;
  color: var(--fg-text-primary);
  line-height: 1.7;
}

/* Vector 2022 main column background */
.mw-page-container-inner {
  background-color: var(--fg-bg-secondary) !important;
}


/* ================================================================
   HEADINGS
   ================================================================ */

.mw-body h1,
.mw-body h2,
.mw-body h3,
.mw-body h4,
.mw-body h5,
.mw-body h6,
.mw-first-heading {
  font-family: 'Space Grotesk', 'Inter', ui-sans-serif, system-ui, sans-serif !important;
  color: var(--fg-text-heading) !important;
  font-weight: 700;
  letter-spacing: -0.01em;
  transition: color var(--fg-transition);
}

.mw-body h1,
.mw-first-heading {
  font-size: 2em;
  border-bottom: 2px solid var(--fg-accent) !important;
  padding-bottom: 0.3em;
}

.mw-body h2 {
  font-size: 1.5em;
  border-bottom: 1px solid var(--fg-border-accent) !important;
  padding-bottom: 0.2em;
}

.mw-body h3 { font-size: 1.25em; }
.mw-body h4 { font-size: 1.1em; }

/* Section edit links */
.mw-editsection a {
  color: var(--fg-text-secondary) !important;
}
.mw-editsection a:hover {
  color: var(--fg-accent) !important;
}


/* ================================================================
   LINKS
   ================================================================ */

/* Normal links */
.mw-body a:not(.mw-ui-button):not(.new):not(.external),
.mw-body-content a:not(.new):not(.external) {
  color: var(--fg-text-link) !important;
  text-decoration: none;
  transition: color var(--fg-transition);
}
.mw-body a:not(.mw-ui-button):visited {
  color: var(--fg-text-link-visited) !important;
}
.mw-body a:not(.mw-ui-button):hover {
  color: var(--fg-text-link-hover) !important;
  text-decoration: underline;
}

/* Red links (missing pages) */
.mw-body a.new,
.mw-body-content a.new {
  color: var(--fg-text-link-new) !important;
}

/* External links */
.mw-body a.external {
  color: var(--fg-text-link) !important;
}
.mw-body a.external:hover {
  color: var(--fg-text-link-hover) !important;
}


/* ================================================================
   FOCUS STYLES (Accessibility)
   ================================================================ */

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible,
.mw-ui-button:focus-visible,
.cdx-button:focus-visible,
.cdx-text-input__input:focus-visible,
#fg-theme-toggle:focus-visible {
  outline: 2px solid var(--fg-accent) !important;
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--fg-accent-glow) !important;
}

/* Remove default outline for mouse users, keep for keyboard */
a:focus:not(:focus-visible),
button:focus:not(:focus-visible),
input:focus:not(:focus-visible) {
  outline: none;
}


/* ================================================================
   SIDEBAR / NAVIGATION
   ================================================================ */

/* Vector 2022 sidebar */
.vector-column-start,
.vector-main-menu,
nav.vector-menu-portal,
.vector-main-menu-container {
  background-color: var(--fg-bg-sidebar) !important;
  transition: background-color var(--fg-transition);
}

/* Sidebar headings */
.vector-menu-portal .vector-menu-heading,
.vector-menu-heading {
  color: var(--fg-accent) !important;
  font-family: 'Space Grotesk', 'Inter', sans-serif !important;
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.75em;
  letter-spacing: 0.08em;
}

/* Sidebar links */
.vector-menu-portal .vector-menu-content li a,
.vector-menu-content-list a {
  color: var(--fg-text-secondary) !important;
  transition: color var(--fg-transition);
}
.vector-menu-portal .vector-menu-content li a:hover,
.vector-menu-content-list a:hover {
  color: var(--fg-accent-hover) !important;
}


/* ================================================================
   HEADER / TOP BAR
   ================================================================ */

.vector-header,
.vector-sticky-header,
.vector-header-container {
  background-color: var(--fg-bg-header) !important;
  border-bottom: 1px solid var(--fg-border) !important;
  transition: background-color var(--fg-transition);
}

/* Logo text */
.mw-logo-wordmark,
.vector-header a.mw-logo-wordmark {
  color: var(--fg-accent) !important;
}

/* Tab bar */
.vector-menu-tabs .selected a,
.vector-menu-tabs li.selected a {
  color: var(--fg-accent) !important;
  border-bottom-color: var(--fg-accent) !important;
}
.vector-menu-tabs li a {
  color: var(--fg-text-secondary) !important;
}
.vector-menu-tabs li a:hover {
  color: var(--fg-accent-hover) !important;
}

/* User menu */
.vector-user-links a,
#pt-userpage a,
#pt-anonuserpage {
  color: var(--fg-text-secondary) !important;
}


/* ================================================================
   VECTOR 2022 — ADDITIONAL CHROME
   ================================================================ */

/* Notification badge */
.mw-echo-notifications-badge {
  background-color: var(--fg-accent) !important;
  color: #000 !important;
}

/* User menu dropdown + all Vector dropdowns */
.vector-user-menu-more,
.vector-dropdown-content,
#p-cactions .vector-menu-content,
#p-views .vector-menu-content {
  background-color: var(--fg-bg-surface) !important;
  border: 1px solid var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}

.vector-dropdown-content a {
  color: var(--fg-text-secondary) !important;
}
.vector-dropdown-content a:hover {
  color: var(--fg-accent) !important;
  background-color: var(--fg-accent-glow) !important;
}

/* Sticky header when scrolled */
.vector-sticky-header-visible .vector-sticky-header {
  background-color: var(--fg-bg-header) !important;
  border-bottom: 1px solid var(--fg-border) !important;
  box-shadow: var(--fg-shadow);
}

/* Page toolbar (article actions bar) */
.vector-page-toolbar,
.vector-page-toolbar-container {
  background-color: var(--fg-bg-secondary) !important;
  border-bottom: 1px solid var(--fg-border-subtle) !important;
}

/* Watchstar */
#ca-watch a,
#ca-unwatch a {
  color: var(--fg-text-secondary) !important;
}
#ca-unwatch a {
  color: var(--fg-accent) !important;
}

/* Article status indicators */
.mw-indicators {
  color: var(--fg-text-secondary);
}


/* ================================================================
   SEARCH BOX
   ================================================================ */

.cdx-text-input__input,
.vector-search-box-vue input,
.vector-search-box input[type="search"],
#searchInput {
  background-color: var(--fg-bg-input) !important;
  color: var(--fg-text-primary) !important;
  border: 1px solid var(--fg-border) !important;
  border-radius: 6px !important;
  transition: border-color var(--fg-transition),
              background-color var(--fg-transition);
}
.cdx-text-input__input:focus,
#searchInput:focus {
  border-color: var(--fg-accent) !important;
  box-shadow: 0 0 0 2px var(--fg-accent-glow) !important;
  outline: none !important;
}

/* Search suggestions dropdown */
.cdx-menu,
.suggestions,
.suggestions-results {
  background-color: var(--fg-bg-surface) !important;
  border: 1px solid var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}
.cdx-menu-item--highlighted,
.suggestions-result-current {
  background-color: var(--fg-accent-glow) !important;
}


/* ================================================================
   TABLE OF CONTENTS
   ================================================================ */

.vector-toc,
.sidebar-toc,
.vector-toc-landmark {
  background-color: var(--fg-bg-sidebar) !important;
  border-right: 1px solid var(--fg-border-subtle) !important;
}

.sidebar-toc .sidebar-toc-header {
  color: var(--fg-accent) !important;
  font-family: 'Space Grotesk', sans-serif !important;
  font-weight: 600;
}

.sidebar-toc .sidebar-toc-link {
  color: var(--fg-text-secondary) !important;
}
.sidebar-toc .sidebar-toc-link:hover {
  color: var(--fg-accent) !important;
}
.sidebar-toc .sidebar-toc-list-item-active > .sidebar-toc-link {
  color: var(--fg-accent) !important;
  border-left-color: var(--fg-accent) !important;
}


/* ================================================================
   CODE & PRE
   ================================================================ */

pre,
code,
.mw-code,
tt,
kbd,
samp {
  font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular,
               Menlo, Monaco, Consolas, 'Liberation Mono',
               'Courier New', monospace !important;
  font-size: 0.9em;
}

pre,
.mw-code {
  background-color: var(--fg-code-bg) !important;
  color: var(--fg-code-text) !important;
  border: 1px solid var(--fg-code-border) !important;
  border-radius: 6px;
  padding: 1em !important;
  overflow-x: auto;
}

code {
  background-color: var(--fg-code-bg) !important;
  color: var(--fg-code-text) !important;
  padding: 0.15em 0.4em;
  border-radius: 3px;
  border: 1px solid var(--fg-code-border) !important;
}


/* ================================================================
   TABLES
   ================================================================ */

table.wikitable {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
  border: 1px solid var(--fg-border) !important;
  border-collapse: collapse;
  margin: 1em 0;
  width: auto;
}

table.wikitable > tr > th,
table.wikitable > * > tr > th {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-accent) !important;
  border: 1px solid var(--fg-border-light) !important;
  padding: 0.5em 0.8em;
  font-family: 'Space Grotesk', 'Inter', sans-serif !important;
  font-weight: 600;
  text-align: left;
}

table.wikitable > tr > td,
table.wikitable > * > tr > td {
  border: 1px solid var(--fg-border) !important;
  padding: 0.4em 0.8em;
}

/* Alternating row striping */
table.wikitable > tr:nth-child(even),
table.wikitable > tbody > tr:nth-child(even) {
  background-color: var(--fg-bg-elevated) !important;
}


/* ================================================================
   INFOBOXES (merged from setup_wiki_infobox.py)
   ================================================================ */

.infobox {
  border: 1px solid var(--fg-border-accent) !important;
  border-spacing: 3px;
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
  margin: 0.5em 0 0.5em 1em;
  padding: 0.2em;
  float: right;
  clear: right;
  font-size: 88%;
  line-height: 1.5em;
  width: 22em;
  box-shadow: var(--fg-shadow-accent);
  border-radius: 4px;
}

.infobox .infobox-title {
  font-size: 125%;
  font-weight: bold;
  text-align: center;
  padding: 0.5em 0.3em;
  background: linear-gradient(135deg, var(--fg-gunmetal-dark), var(--fg-gunmetal)) !important;
  color: var(--fg-accent) !important;
  font-family: 'Space Grotesk', 'Inter', sans-serif !important;
  border-radius: 3px 3px 0 0;
}

.infobox .infobox-above {
  text-align: center;
  padding: 0.3em;
  font-style: italic;
  color: var(--fg-text-secondary);
}

.infobox .infobox-subheader {
  text-align: center;
  padding: 0.2em;
  font-size: 95%;
  color: var(--fg-text-secondary);
}

.infobox .infobox-image {
  text-align: center;
  padding: 0.4em 0.2em;
}

.infobox .infobox-caption {
  font-size: 90%;
  color: var(--fg-text-secondary);
  padding-top: 0.2em;
  text-align: center;
}

.infobox .infobox-header {
  text-align: center;
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-accent) !important;
  font-weight: bold;
  padding: 0.3em;
  font-family: 'Space Grotesk', 'Inter', sans-serif !important;
}

.infobox .infobox-label {
  vertical-align: top;
  text-align: left;
  padding: 0.2em 0.4em 0.2em 0.2em;
  font-weight: bold;
  white-space: nowrap;
  width: 35%;
  color: var(--fg-text-secondary);
}

.infobox .infobox-data {
  vertical-align: top;
  text-align: left;
  padding: 0.2em;
}

.infobox .infobox-data-full {
  text-align: center;
}

.infobox .infobox-below {
  text-align: center;
  padding: 0.3em;
  border-top: 1px solid var(--fg-border) !important;
  font-size: 90%;
  color: var(--fg-text-secondary);
}

.infobox-fusiongirl .infobox-title {
  background: linear-gradient(135deg, var(--fg-gunmetal-dark), var(--fg-gunmetal)) !important;
  color: var(--fg-accent) !important;
}

.infobox-fusiongirl .infobox-header {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-accent) !important;
}

@media (max-width: 720px) {
  .infobox {
    float: none;
    margin: 0.5em auto;
    width: 100%;
    max-width: 22em;
  }
}


/* ================================================================
   BLOCKQUOTES
   ================================================================ */

blockquote {
  border-left: 3px solid var(--fg-accent) !important;
  background-color: var(--fg-bg-elevated) !important;
  color: var(--fg-text-primary);
  padding: 0.8em 1.2em;
  margin: 1em 0;
  border-radius: 0 4px 4px 0;
  font-style: italic;
}


/* ================================================================
   CATEGORIES / FOOTER
   ================================================================ */

.catlinks {
  background-color: var(--fg-bg-surface) !important;
  border: 1px solid var(--fg-border) !important;
  color: var(--fg-text-secondary) !important;
  border-radius: 4px;
  padding: 0.5em 1em;
  margin-top: 1.5em;
}

.catlinks a {
  color: var(--fg-accent-muted) !important;
}
.catlinks a:hover {
  color: var(--fg-accent) !important;
}

#footer,
.vector-footer {
  background-color: var(--fg-bg-primary) !important;
  color: var(--fg-text-secondary) !important;
  border-top: 1px solid var(--fg-border) !important;
}
#footer a {
  color: var(--fg-text-secondary) !important;
}
#footer a:hover {
  color: var(--fg-accent) !important;
}


/* ================================================================
   SPECIAL PAGES & FORMS
   ================================================================ */

/* Fieldsets */
fieldset {
  border-color: var(--fg-border) !important;
}

legend {
  color: var(--fg-accent) !important;
}

/* Form inputs */
input[type="text"],
input[type="password"],
input[type="email"],
textarea,
select {
  background-color: var(--fg-bg-input) !important;
  color: var(--fg-text-primary) !important;
  border: 1px solid var(--fg-border) !important;
  border-radius: 4px;
}

input[type="text"]:focus,
input[type="password"]:focus,
textarea:focus {
  border-color: var(--fg-accent) !important;
  box-shadow: 0 0 0 2px var(--fg-accent-glow) !important;
}

/* Buttons */
.mw-ui-button,
input[type="submit"],
button {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-text-primary) !important;
  border: 1px solid var(--fg-border-light) !important;
  border-radius: 4px;
  transition: all var(--fg-transition);
}

.mw-ui-button:hover,
input[type="submit"]:hover,
button:hover {
  background-color: var(--fg-gunmetal-light) !important;
  border-color: var(--fg-accent) !important;
  color: var(--fg-accent) !important;
}

.mw-ui-button.mw-ui-progressive,
.cdx-button--action-progressive {
  background-color: var(--fg-accent) !important;
  color: #000 !important;
  border-color: var(--fg-accent) !important;
  font-weight: 600;
}

.mw-ui-button.mw-ui-progressive:hover {
  background-color: var(--fg-accent-hover) !important;
}


/* ================================================================
   OOUI WIDGET THEMING (edit forms, preferences, etc.)
   ================================================================ */

.oo-ui-widget {
  color: var(--fg-text-primary);
}

.oo-ui-textInputWidget input,
.oo-ui-textInputWidget textarea,
.oo-ui-inputWidget-input {
  background-color: var(--fg-bg-input) !important;
  color: var(--fg-text-primary) !important;
  border: 1px solid var(--fg-border) !important;
}

.oo-ui-textInputWidget input:focus,
.oo-ui-textInputWidget textarea:focus {
  border-color: var(--fg-accent) !important;
  box-shadow: 0 0 0 2px var(--fg-accent-glow) !important;
}

.oo-ui-labelWidget {
  color: var(--fg-text-primary);
}

.oo-ui-buttonElement-framed .oo-ui-buttonElement-button {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-text-primary) !important;
  border-color: var(--fg-border-light) !important;
  border-radius: 4px;
}

.oo-ui-buttonElement-framed .oo-ui-buttonElement-button:hover {
  background-color: var(--fg-gunmetal-light) !important;
  border-color: var(--fg-accent) !important;
}

.oo-ui-flaggedElement-progressive .oo-ui-buttonElement-button {
  background-color: var(--fg-accent) !important;
  color: #000 !important;
  border-color: var(--fg-accent) !important;
}

.oo-ui-flaggedElement-destructive .oo-ui-buttonElement-button {
  background-color: #8b0000 !important;
  color: #fff !important;
  border-color: #a00 !important;
}

.oo-ui-popupWidget-popup,
.oo-ui-menuSelectWidget {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}

.oo-ui-optionWidget-highlighted {
  background-color: var(--fg-accent-glow) !important;
}

.oo-ui-optionWidget-selected {
  background-color: var(--fg-accent-glow-strong) !important;
}

.oo-ui-checkboxInputWidget [type="checkbox"] + span,
.oo-ui-radioInputWidget [type="radio"] + span {
  background-color: var(--fg-bg-input) !important;
  border-color: var(--fg-border) !important;
}

.oo-ui-dropdownWidget .oo-ui-dropdownWidget-handle {
  background-color: var(--fg-bg-input) !important;
  border-color: var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}

.oo-ui-tagMultiselectWidget-input input {
  color: var(--fg-text-primary) !important;
}


/* ================================================================
   DIFF / HISTORY / SPECIAL CONTENT
   ================================================================ */

.diff-context {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
}
.diff-addedline {
  background-color: rgba(0, 180, 0, 0.15) !important;
}
.diff-deletedline {
  background-color: rgba(220, 0, 0, 0.15) !important;
}

/* Recent changes */
.mw-changeslist-line {
  border-bottom: 1px solid var(--fg-border-subtle);
}


/* ================================================================
   CONTENT NOTICES / AMBOX / NAVBOX / MESSAGE BOXES
   ================================================================ */

.ambox {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border-accent) !important;
}

/* Navbox */
.navbox {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
  border: 1px solid var(--fg-border) !important;
}

.navbox-title {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-accent) !important;
  font-family: 'Space Grotesk', 'Inter', sans-serif !important;
}

.navbox-group {
  background-color: var(--fg-gunmetal-dark) !important;
  color: var(--fg-accent-muted) !important;
  font-weight: 600;
}

.navbox-list {
  border-color: var(--fg-border) !important;
}

.navbox-even {
  background-color: var(--fg-bg-elevated) !important;
}

.navbox-odd {
  background-color: var(--fg-bg-surface) !important;
}

/* mw-datatable (Special pages) */
table.mw-datatable {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
  border: 1px solid var(--fg-border) !important;
}

table.mw-datatable th {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-accent) !important;
  border: 1px solid var(--fg-border-light) !important;
}

table.mw-datatable td {
  border: 1px solid var(--fg-border) !important;
}

table.mw-datatable tr:hover {
  background-color: var(--fg-accent-glow) !important;
}

/* Message boxes (all types) */
.messagebox,
.mbox-small,
table.ambox,
table.tmbox,
table.ombox,
table.cmbox,
table.fmbox,
table.imbox {
  background-color: var(--fg-bg-surface) !important;
  border: 1px solid var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}

/* Succession boxes, metadata */
.succession-box,
.metadata {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}


/* ================================================================
   SEARCH HIGHLIGHT / RECENT CHANGES / NOTIFICATIONS
   ================================================================ */

/* Search result match highlight */
.searchmatch {
  background-color: var(--fg-accent-glow-strong) !important;
  color: var(--fg-text-heading) !important;
  font-weight: 600;
}

/* Search results page */
.mw-search-result-heading a {
  color: var(--fg-text-link) !important;
}

/* Recent changes legend */
.mw-changeslist-legend {
  background-color: var(--fg-bg-surface) !important;
  border: 1px solid var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}

.mw-rcfilters-ui-changesListWrapperWidget .mw-changeslist {
  color: var(--fg-text-primary) !important;
}

/* RC filters panel */
.mw-rcfilters-ui-filterTagMultiselectWidget {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}

/* Echo notifications */
.mw-echo-ui-notificationBadgeButtonPopupWidget-popup {
  background-color: var(--fg-bg-surface) !important;
  border: 1px solid var(--fg-border) !important;
}

.mw-echo-ui-notificationItemWidget {
  background-color: var(--fg-bg-surface) !important;
  border-bottom: 1px solid var(--fg-border-subtle) !important;
  color: var(--fg-text-primary) !important;
}

.mw-echo-ui-notificationItemWidget:hover {
  background-color: var(--fg-bg-elevated) !important;
}

.mw-echo-ui-notificationItemWidget-unread {
  background-color: var(--fg-accent-glow) !important;
}


/* ================================================================
   THEME TOGGLE BUTTON STYLES
   ================================================================ */

#fg-theme-toggle {
  cursor: pointer;
  padding: 5px 14px;
  border: 1px solid var(--fg-accent);
  border-radius: 20px;
  background: transparent;
  color: var(--fg-accent);
  font-family: 'Inter', sans-serif;
  font-size: 0.82em;
  font-weight: 500;
  letter-spacing: 0.02em;
  transition: all var(--fg-transition);
  white-space: nowrap;
  line-height: 1.4;
  vertical-align: middle;
}

#fg-theme-toggle:hover {
  background: var(--fg-accent-glow-strong);
  color: var(--fg-accent-hover);
  box-shadow: var(--fg-shadow-accent);
}

/* Position in Monobook personal tools bar */
#pt-theme-toggle {
  display: inline-block;
  margin-left: 8px;
}


/* ================================================================
   SCROLLBAR STYLING (Webkit)
   ================================================================ */

::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-track {
  background: var(--fg-bg-primary);
}
::-webkit-scrollbar-thumb {
  background: var(--fg-gunmetal);
  border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--fg-gunmetal-light);
}


/* ================================================================
   SELECTION HIGHLIGHT
   ================================================================ */

::selection {
  background: var(--fg-accent-glow-strong);
  color: var(--fg-text-heading);
}


/* ================================================================
   IMAGE / THUMBNAIL THEMING
   ================================================================ */

/* Don't invert images — they should stay as-is */
.mw-body img {
  border-radius: 2px;
}

/* Thumbnail containers (legacy + figure-based + tmulti).
   Newer MediaWiki wraps thumbs in <figure class="mw-default-size mw-halign-right">
   with <figcaption>; older wraps as <div class="thumb tright"><div class="thumbinner">.
   Both shapes plus the multi-image layout (.tmulti) carry an inherited white
   default that needs explicit dark-theme override. */
.thumb,
.thumbinner,
figure.thumb,
figure.mw-default-size,
figure[typeof~="mw:File"],
figure[typeof~="mw:File/Thumb"],
figure[typeof~="mw:File/Frame"],
.tmulti .thumbinner,
.tmulti .tsingle,
.gallerybox .thumb {
  background-color: var(--fg-bg-surface) !important;
  border: 1px solid var(--fg-border) !important;
  border-radius: 4px;
  color: var(--fg-text-primary) !important;
}

/* Thumbnail captions (legacy div + modern figcaption).
   ``[typeof^="mw:File"]`` (prefix match) catches all subtypes:
   ``mw:File``, ``mw:File/Thumb``, ``mw:File/Frame``. ``[typeof~=...]``
   (whitespace-token match) does NOT match ``mw:File/Thumb`` because that
   is a single token, not a list-token of ``mw:File``. */
.thumbcaption,
figure.thumb > figcaption,
figure.mw-default-size > figcaption,
figure[typeof^="mw:File"] > figcaption,
figure[typeof~="mw:File"] > figcaption,
figure[typeof~="mw:File/Thumb"] > figcaption,
figure[typeof~="mw:File/Frame"] > figcaption,
.tmulti .thumbcaption,
.thumbinner > .thumbcaption {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-secondary) !important;
  font-size: 0.9em;
  border-top: 1px solid var(--fg-border);
}

/* Light-mode caption — keep cream surface, soft border */
html.fg-light-mode .thumbcaption,
html.fg-light-mode figure.thumb > figcaption,
html.fg-light-mode figure.mw-default-size > figcaption,
html.fg-light-mode figure[typeof^="mw:File"] > figcaption,
html.fg-light-mode .tmulti .thumbcaption {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-secondary) !important;
  border-top-color: var(--fg-border) !important;
}

/* The image link wrapper and the image itself — kill any inherited white.
   .thumbborder is MediaWiki's auto-applied 1px border on thumb images;
   .mw-file-element is the modern <img> class inside <figure>. */
.thumb a.image,
figure a,
.thumbinner a,
.thumbborder,
img.thumbborder,
.mw-file-element,
.mw-file-description {
  background-color: transparent !important;
  border-color: var(--fg-border) !important;
}

/* Gallery */
li.gallerybox div.thumb,
li.gallerybox .thumb,
ul.gallery .gallerybox div.thumb {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}
.gallerytext,
li.gallerybox .gallerytext {
  background-color: transparent !important;
  color: var(--fg-text-secondary) !important;
}

/* Light-mode override: keep the soft cream surface, not pure white. */
html.fg-light-mode .thumb,
html.fg-light-mode .thumbinner,
html.fg-light-mode figure.thumb,
html.fg-light-mode figure.mw-default-size,
html.fg-light-mode figure[typeof~="mw:File"],
html.fg-light-mode .tmulti .thumbinner,
html.fg-light-mode .tmulti .tsingle,
html.fg-light-mode .gallerybox .thumb,
html.fg-light-mode li.gallerybox div.thumb {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}


/* ================================================================
   MONOBOOK SKIN — COMPREHENSIVE OVERRIDES
   (wiki.fusiongirl.app uses Monobook, not Vector 2022)
   ================================================================ */

/* ── Core page wrapper ── */
#globalWrapper {
  background-color: var(--fg-bg-primary) !important;
}

#column-content {
  background-color: transparent !important;
}

/* ── Main content box — Monobook #content ── */
#content {
  background-color: var(--fg-bg-secondary) !important;
  color: var(--fg-text-primary) !important;
  border-color: var(--fg-border) !important;
}

#bodyContent,
.monobook-body {
  background-color: var(--fg-bg-secondary) !important;
  color: var(--fg-text-primary) !important;
}

#mw-content-text {
  background-color: var(--fg-bg-secondary) !important;
  color: var(--fg-text-primary) !important;
}

.mw-parser-output {
  background-color: transparent !important;
  color: var(--fg-text-primary) !important;
}

/* ── Site subtitle / content subtitle ── */
#siteSub,
#contentSub,
#mw-content-subtitle {
  color: var(--fg-text-secondary) !important;
}

/* ── Site notice ── */
#siteNotice {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
}

/* ── Monobook sidebar column ── */
#column-one {
  background-color: var(--fg-bg-sidebar) !important;
}

#sidebar {
  background-color: var(--fg-bg-sidebar) !important;
}

/* ── Portlets (navigation blocks in sidebar) ── */
.portlet {
  background-color: transparent !important;
}

.portlet .pBody {
  background-color: transparent !important;
}

/* Portlet headings */
.portlet h3,
.portlet .portlet-label,
#p-navigation h3,
#p-tb h3 {
  color: var(--fg-accent) !important;
  font-family: 'Space Grotesk', 'Inter', sans-serif !important;
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.75em;
  letter-spacing: 0.08em;
}

/* Portlet links */
.portlet .pBody a,
.portlet .pBody li a,
.portlet ul a {
  color: var(--fg-text-secondary) !important;
  transition: color var(--fg-transition);
}
.portlet .pBody a:hover,
.portlet .pBody li a:hover,
.portlet ul a:hover {
  color: var(--fg-accent-hover) !important;
}

/* Portlet lists */
.portlet .pBody ul,
.portlet .pBody li {
  color: var(--fg-text-secondary) !important;
}

/* ── Content actions / tab bar (Monobook #p-cactions) ── */
#p-cactions {
  background-color: var(--fg-bg-header) !important;
  border-color: var(--fg-border) !important;
}

#p-cactions .pBody {
  background-color: var(--fg-bg-header) !important;
  border-color: var(--fg-border) !important;
}

#p-cactions ul {
  background-color: var(--fg-bg-header) !important;
}

#p-cactions ul li {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}

#p-cactions ul li a {
  color: var(--fg-text-secondary) !important;
  background-color: transparent !important;
}

#p-cactions ul li a:hover {
  color: var(--fg-accent) !important;
}

#p-cactions ul li.selected {
  background-color: var(--fg-bg-secondary) !important;
  border-bottom-color: var(--fg-bg-secondary) !important;
}

#p-cactions ul li.selected a {
  color: var(--fg-accent) !important;
}

/* ── Personal tools (Monobook #p-personal) ── */
#p-personal {
  background-color: transparent !important;
}

#p-personal .pBody {
  background-color: transparent !important;
}

#p-personal ul li a {
  color: var(--fg-text-secondary) !important;
}

#p-personal ul li a:hover {
  color: var(--fg-accent) !important;
}

/* ── Monobook search box ── */
#p-search {
  background-color: transparent !important;
}

#searchBody {
  background-color: transparent !important;
}

#searchInput {
  background-color: var(--fg-bg-input) !important;
  color: var(--fg-text-primary) !important;
  border: 1px solid var(--fg-border) !important;
  border-radius: 6px !important;
}

.searchButton {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-text-primary) !important;
  border: 1px solid var(--fg-border) !important;
  border-radius: 4px !important;
}

.searchButton:hover {
  background-color: var(--fg-gunmetal-light) !important;
  border-color: var(--fg-accent) !important;
}

/* ── Monobook footer ── */
.mw-footer,
#footer {
  background-color: var(--fg-bg-primary) !important;
  color: var(--fg-text-secondary) !important;
  border-top: 1px solid var(--fg-border) !important;
}

#footer a,
.mw-footer a,
#f-list a {
  color: var(--fg-text-secondary) !important;
}

#footer a:hover,
.mw-footer a:hover,
#f-list a:hover {
  color: var(--fg-accent) !important;
}

#f-list li {
  color: var(--fg-text-secondary) !important;
}

/* Footer icons */
.footer-icons {
  background-color: transparent !important;
}

/* ── Mobile menu toggle (Monobook responsive) ── */
.menu-toggle {
  background-color: var(--fg-bg-header) !important;
  color: var(--fg-accent) !important;
  border-color: var(--fg-border) !important;
}

/* ── Logo area ── */
#p-logo {
  background-color: transparent !important;
}

/* Override wiki logo with uploaded FusionGirl icon */
.mw-wiki-logo {
  background-image: url('https://wiki.fusiongirl.app:443/images/e/e8/FusionGirlIcon_x512.png') !important;
  background-size: contain !important;
  background-repeat: no-repeat !important;
  background-position: center !important;
}


/* ================================================================
   TABLE OF CONTENTS — CLASSIC (non-Vector)
   ================================================================ */

.toc,
#toc,
.toccolours {
  background-color: var(--fg-bg-surface) !important;
  border: 1px solid var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}

.toc h2,
#toc h2,
.toc .toctitle {
  color: var(--fg-accent) !important;
  font-family: 'Space Grotesk', 'Inter', sans-serif !important;
}

.toc ul a,
#toc ul a {
  color: var(--fg-text-link) !important;
}

.toc ul a:hover,
#toc ul a:hover {
  color: var(--fg-text-link-hover) !important;
}

.toc .tocnumber {
  color: var(--fg-text-secondary) !important;
}


/* ================================================================
   GENERIC TABLE OVERRIDES (non-wikitable)
   ================================================================ */

/* Tables inside article content that aren't .wikitable */
.mw-parser-output table:not(.wikitable):not(.infobox):not(.navbox):not(.ambox):not(.mbox-small):not(.tmbox):not(.ombox):not(.cmbox):not(.fmbox):not(.imbox):not(.mw-datatable) {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
}

.mw-parser-output table:not(.wikitable):not(.infobox):not(.navbox) th {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-accent) !important;
}

.mw-parser-output table:not(.wikitable):not(.infobox):not(.navbox) td {
  border-color: var(--fg-border) !important;
}


/* ================================================================
   HORIZONTAL RULES
   ================================================================ */

hr {
  border-color: var(--fg-border) !important;
  background-color: var(--fg-border) !important;
}


/* ================================================================
   DEFINITION LISTS
   ================================================================ */

dl, dt, dd {
  color: var(--fg-text-primary);
}

dt {
  font-weight: 600;
  color: var(--fg-text-heading);
}


/* ================================================================
   COLLAPSIBLE SECTIONS
   ================================================================ */

.mw-collapsible {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}

.mw-collapsible-toggle {
  color: var(--fg-accent) !important;
}

.mw-collapsible-content {
  background-color: transparent !important;
}


/* ================================================================
   SPECIAL PAGES — ADDITIONAL COVERAGE
   ================================================================ */

/* AllPages */
.mw-allpages-body,
.mw-allpages-nav,
.mw-spcontent {
  background-color: transparent !important;
  color: var(--fg-text-primary) !important;
}

.mw-allpages-body a {
  color: var(--fg-text-link) !important;
}

.mw-allpages-body a:hover {
  color: var(--fg-text-link-hover) !important;
}

/* Category pages */
#mw-subcategories,
#mw-pages,
.mw-category-group {
  color: var(--fg-text-primary) !important;
}

.mw-category-group h3 {
  color: var(--fg-text-heading) !important;
}

/* Special pages list */
.mw-specialpages-list td {
  color: var(--fg-text-primary) !important;
}

/* User contributions */
.mw-contributions-list {
  color: var(--fg-text-primary) !important;
}

/* Log entries */
.mw-logline-block,
.mw-logline-delete,
.mw-logline-move,
.mw-logline-upload,
.mw-logline-newusers,
.mw-logline-patrol,
.mw-logline-protect,
.mw-logline-rights {
  color: var(--fg-text-primary) !important;
}


/* ================================================================
   EDIT PAGE / FORMS — ADDITIONAL COVERAGE
   ================================================================ */

/* Edit form wrapper */
.mw-editform,
#editform {
  background-color: transparent !important;
  color: var(--fg-text-primary) !important;
}

/* Edit options panel */
.editOptions {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}

/* Edit notices */
.mw-editnotice,
.mw-newarticletext {
  background-color: var(--fg-bg-surface) !important;
  border: 1px solid var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
  padding: 0.5em 1em;
  border-radius: 4px;
}

/* Preview note */
.previewnote {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
  border-color: var(--fg-border) !important;
}

/* Summary preview */
.mw-summary-preview {
  color: var(--fg-text-secondary) !important;
}

/* Warning boxes */
.mw-warning-with-logexcerpt,
.mw-warning,
.mw-message-box,
.mw-message-box-warning,
.mw-message-box-error,
.mw-message-box-success {
  background-color: var(--fg-bg-surface) !important;
  border: 1px solid var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}


/* ================================================================
   DIFF VIEW — COMPREHENSIVE
   ================================================================ */

table.diff {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
}

table.diff td {
  border-color: var(--fg-border) !important;
}

td.diff-marker {
  color: var(--fg-text-secondary) !important;
}

td.diff-otitle,
td.diff-ntitle {
  background-color: var(--fg-bg-elevated) !important;
  color: var(--fg-text-primary) !important;
}

.diffchange {
  color: var(--fg-accent) !important;
}

#mw-diff-otitle1, #mw-diff-otitle2, #mw-diff-otitle3,
#mw-diff-ntitle1, #mw-diff-ntitle2, #mw-diff-ntitle3 {
  color: var(--fg-text-primary) !important;
}

/* Revision info */
.mw-revision {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
}


/* ================================================================
   OOUI — ADDITIONAL WINDOWS & PANELS
   ================================================================ */

.oo-ui-panelLayout {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
}

.oo-ui-windowManager,
.oo-ui-window {
  color: var(--fg-text-primary) !important;
}

.oo-ui-dialog .oo-ui-window-head {
  background-color: var(--fg-bg-header) !important;
  border-color: var(--fg-border) !important;
}

.oo-ui-dialog .oo-ui-window-body {
  background-color: var(--fg-bg-surface) !important;
}

.oo-ui-dialog .oo-ui-window-foot {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}

.oo-ui-fieldsetLayout .oo-ui-fieldsetLayout-header .oo-ui-labelElement-label {
  color: var(--fg-accent) !important;
}

.oo-ui-fieldLayout .oo-ui-fieldLayout-header .oo-ui-labelElement-label {
  color: var(--fg-text-primary) !important;
}

.oo-ui-tabSelectWidget {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}

.oo-ui-tabOptionWidget {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-secondary) !important;
}

.oo-ui-tabOptionWidget.oo-ui-optionWidget-selected {
  background-color: var(--fg-bg-elevated) !important;
  color: var(--fg-accent) !important;
}

.oo-ui-tagMultiselectWidget {
  background-color: var(--fg-bg-input) !important;
  border-color: var(--fg-border) !important;
}

.oo-ui-tagItemWidget {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-text-primary) !important;
  border-color: var(--fg-border) !important;
}


/* ================================================================
   CODEX (CDX) COMPONENTS — COMPREHENSIVE
   ================================================================ */

.cdx-card {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}

.cdx-dialog {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
}

.cdx-dialog__header {
  background-color: var(--fg-bg-header) !important;
  border-color: var(--fg-border) !important;
}

.cdx-dialog__body {
  background-color: var(--fg-bg-surface) !important;
}

.cdx-dialog__footer {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}

.cdx-message {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}

.cdx-field {
  color: var(--fg-text-primary) !important;
}

.cdx-label {
  color: var(--fg-text-primary) !important;
}

.cdx-table {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
}

.cdx-table__header {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-accent) !important;
}

.cdx-tabs {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}

.cdx-tabs__list__item {
  color: var(--fg-text-secondary) !important;
}

.cdx-tabs__list__item--selected {
  color: var(--fg-accent) !important;
  border-color: var(--fg-accent) !important;
}

.cdx-toggle-switch__switch {
  background-color: var(--fg-gunmetal) !important;
  border-color: var(--fg-border) !important;
}

.cdx-toggle-switch--on .cdx-toggle-switch__switch {
  background-color: var(--fg-accent) !important;
}

.cdx-checkbox__icon,
.cdx-radio__icon {
  background-color: var(--fg-bg-input) !important;
  border-color: var(--fg-border) !important;
}

.cdx-lookup,
.cdx-typeahead-search {
  background-color: var(--fg-bg-input) !important;
  color: var(--fg-text-primary) !important;
}

.cdx-search-result-title {
  color: var(--fg-text-link) !important;
}

.cdx-menu-item {
  color: var(--fg-text-primary) !important;
}

.cdx-menu-item:hover,
.cdx-menu-item--highlighted {
  background-color: var(--fg-accent-glow) !important;
}

.cdx-select-vue__handle,
.cdx-select__handle {
  background-color: var(--fg-bg-input) !important;
  border-color: var(--fg-border) !important;
  color: var(--fg-text-primary) !important;
}


/* ================================================================
   SEARCH RESULTS PAGE — FULL COVERAGE
   ================================================================ */

.searchresults,
.mw-search-results {
  color: var(--fg-text-primary) !important;
}

.mw-search-result {
  color: var(--fg-text-primary) !important;
}

.mw-search-result-data {
  color: var(--fg-text-secondary) !important;
}

#mw-search-top-table {
  background-color: transparent !important;
  color: var(--fg-text-primary) !important;
}

.mw-search-profile-tabs {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}

.search-types .current a {
  color: var(--fg-accent) !important;
}


/* ================================================================
   PREFERENCES & HTML FORMS
   ================================================================ */

.mw-htmlform-field,
.mw-htmlform-field-HTMLTextField,
.mw-htmlform-field-HTMLCheckField {
  color: var(--fg-text-primary) !important;
}

.mw-prefs-fieldset,
.mw-prefs-fieldset legend {
  color: var(--fg-text-primary) !important;
}

.htmlform-tip {
  color: var(--fg-text-secondary) !important;
}


/* ================================================================
   PRINT FOOTER & MISC ELEMENTS
   ================================================================ */

.printfooter {
  color: var(--fg-text-secondary) !important;
}

/* Jump links (accessibility) */
.mw-jump-link {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-accent) !important;
}

/* Visual clear — no background needed */
.visualClear {
  background-color: transparent !important;
}

/* Page title indicator */
.mw-page-title-main {
  color: var(--fg-text-heading) !important;
}


/* ================================================================
   RC FILTERS — ADDITIONAL PANELS
   ================================================================ */

.mw-rcfilters-ui-filterWrapperWidget {
  background-color: var(--fg-bg-surface) !important;
  border-color: var(--fg-border) !important;
}

.mw-rcfilters-ui-filterWrapperWidget-showNewChanges a {
  color: var(--fg-accent) !important;
}

.mw-rcfilters-ui-changesListWrapperWidget {
  background-color: transparent !important;
}

.mw-rcfilters-ui-formWrapperWidget {
  background-color: var(--fg-bg-surface) !important;
}

/* RC filters capsule widgets */
.mw-rcfilters-ui-capsuleItemWidget {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-text-primary) !important;
  border-color: var(--fg-border) !important;
}


/* ================================================================
   WATCHLIST
   ================================================================ */

.mw-changeslist-legend dt {
  color: var(--fg-text-heading) !important;
}

.mw-changeslist-legend dd {
  color: var(--fg-text-primary) !important;
}


/* ================================================================
   CARGO / SEMANTIC MEDIAWIKI
   ================================================================ */

.cargoTable,
.smw-table-row,
.smw-format-table {
  background-color: var(--fg-bg-surface) !important;
  color: var(--fg-text-primary) !important;
  border-color: var(--fg-border) !important;
}

.cargoTable th,
.smw-table-row th {
  background-color: var(--fg-gunmetal) !important;
  color: var(--fg-accent) !important;
}


/* ================================================================
   NUCLEAR OPTION — Catch remaining white backgrounds
   Targets any element inside #content that has inline or
   inherited white/near-white background from default MW styles
   ================================================================ */

#content div,
#content td,
#content th,
#content li,
#content span,
#content p,
#content fieldset,
#content legend {
  border-color: inherit;
}

/* Override Monobook's default link colors within content */
#content a:not(.new):not(.external):not(.mw-ui-button) {
  color: var(--fg-text-link) !important;
}
#content a:not(.new):not(.external):not(.mw-ui-button):visited {
  color: var(--fg-text-link-visited) !important;
}
#content a:not(.new):not(.external):not(.mw-ui-button):hover {
  color: var(--fg-text-link-hover) !important;
}


/* ================================================================
   TRANSITION SMOOTHING — targeted elements (not *)
   ================================================================ */

body,
.mw-body,
.vector-body,
.mw-page-container,
.mw-page-container-inner,
.vector-column-start,
.vector-main-menu,
.vector-main-menu-container,
.vector-header,
.vector-sticky-header,
.vector-header-container,
.vector-toc,
.sidebar-toc,
.vector-footer,
#footer,
#globalWrapper,
#column-content,
#column-one,
#content,
#bodyContent,
#sidebar,
.portlet,
.pBody,
#p-cactions,
#p-cactions ul li,
#p-personal,
.catlinks,
.infobox,
table.wikitable,
table.mw-datatable,
.navbox,
.messagebox,
blockquote,
pre,
code,
fieldset,
.mw-ui-button,
.cdx-button,
button,
input,
select,
textarea,
a,
.thumb,
.thumbinner,
.ambox,
.diff-context,
.diff-addedline,
.diff-deletedline,
#fg-theme-toggle,
.oo-ui-widget,
.oo-ui-buttonElement-button,
.oo-ui-inputWidget-input,
.oo-ui-popupWidget-popup,
.vector-dropdown-content,
.cdx-menu,
.cdx-text-input__input,
.vector-menu-content,
.vector-user-menu-more,
.vector-page-toolbar,
.toc,
#toc,
.searchButton {
  transition: background-color 0.15s ease,
              color 0.15s ease,
              border-color 0.15s ease,
              box-shadow 0.15s ease;
}

/* Exclude media from transition */
img, video, canvas, svg, .mw-gallery-traditional {
  transition: none !important;
}


/* ================================================================
   MATH / LATEX (ext.math) — DARK MODE FIX
   MediaWiki renders <math> as SVG images with class mw-invert.
   In dark mode, we invert them so black→white. Light mode keeps them as-is.
   Also style MathML fallback and any inline TeX.
   ================================================================ */

/* Dark mode (default): invert black SVG math images to white */
img.mwe-math-fallback-image-inline,
img.mwe-math-fallback-image-display {
  filter: invert(1) hue-rotate(180deg) !important;
}

/* MathML rendered inline (if visible) */
.mwe-math-element math,
.mwe-math-element .mwe-math-mathml-inline,
.mwe-math-element .mwe-math-mathml-display {
  color: var(--fg-text-primary) !important;
}

/* Light mode: undo inversion — math stays black on light bg */
html.fg-light-mode img.mwe-math-fallback-image-inline,
html.fg-light-mode img.mwe-math-fallback-image-display {
  filter: none !important;
}

html.fg-light-mode .mwe-math-element math,
html.fg-light-mode .mwe-math-element .mwe-math-mathml-inline,
html.fg-light-mode .mwe-math-element .mwe-math-mathml-display {
  color: var(--fg-text-primary) !important;
}

/* Generic fallback: any .mw-invert element in dark mode */
.mw-invert {
  filter: invert(1) hue-rotate(180deg) !important;
}
html.fg-light-mode .mw-invert {
  filter: none !important;
}


/* ================================================================
   PRINT STYLES — Strip theming for print
   ================================================================ */

@media print {
  :root {
    --fg-bg-primary: #fff;
    --fg-bg-secondary: #fff;
    --fg-bg-surface: #fff;
    --fg-bg-elevated: #fff;
    --fg-bg-input: #fff;
    --fg-text-primary: #000;
    --fg-text-secondary: #333;
    --fg-text-heading: #000;
    --fg-text-link: #0645AD;
    --fg-border: #ccc;
    --fg-accent: #000;
  }
  #fg-theme-toggle { display: none !important; }
  body { background-image: none !important; }
}


/* ================================================================
   PREFERS-REDUCED-MOTION
   ================================================================ */

@media (prefers-reduced-motion: reduce) {
  body,
  .mw-body,
  .vector-body,
  .mw-page-container,
  .vector-header,
  .vector-sticky-header,
  a,
  button,
  input,
  #fg-theme-toggle,
  .oo-ui-widget {
    transition-duration: 0.01ms !important;
  }
}

/* === BEGIN: thora-character-layout (managed by tools/setup_thora_character_layout.py) === */
/* Tho'ra character-page layout system.
   Used by Aurora Tho'ra, Jono Tho'ra, Jane Tho'ra, Amber Tho'ra and other
   character-archetype pages. Provides hero block (coordinated top-of-page
   media + identity card), section-image floats with phone-portrait
   collapse, responsive capability grid, canon-meta blocks, and pull-quote
   styling. All breakpoints centered at 720px (tablet/phone divide). */

/* === Hero block === */
.thora-hero {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5em;
    align-items: flex-start;
    margin: 0 0 1.5em 0;
    clear: both;
}
.thora-hero-media {
    flex: 2 1 360px;
    min-width: 280px;
    max-width: 540px;
}
.thora-hero-card {
    flex: 1 1 280px;
    min-width: 240px;
    max-width: 360px;
}
.thora-hero-card .infobox {
    margin: 0 !important;
    width: 100% !important;
    float: none !important;
}
/* Crossfade nested inside hero media slot fills its slot */
.thora-hero-media .thora-crossfade {
    width: 100%;
    display: block;
}
.thora-hero-media .thora-crossfade .thora-frame img {
    width: 100%;
    height: auto;
}

/* Phone portrait: identity card first, media second, lede paragraph follows.
   column-reverse so source-order media-then-card flips visually. */
@media (max-width: 720px) {
    .thora-hero {
        flex-direction: column-reverse;
        gap: 1em;
    }
    .thora-hero-media,
    .thora-hero-card {
        max-width: 100%;
        flex-basis: auto;
    }
}

/* === Section image floats === */
.thora-section-image {
    float: right;
    margin: 0 0 1em 1.5em;
    max-width: 280px;
    clear: right;
}
.thora-section-image-left {
    float: left;
    margin: 0 1.5em 1em 0;
    max-width: 280px;
    clear: left;
}
.thora-section-image img,
.thora-section-image-left img,
.thora-section-image .thora-crossfade .thora-frame img,
.thora-section-image-left .thora-crossfade .thora-frame img {
    max-width: 100%;
    height: auto;
}
.thora-section-image .caption,
.thora-section-image-left .caption {
    font-size: 0.85em;
    color: var(--fg-text-secondary);
    margin-top: 0.25em;
    line-height: 1.3;
}

/* Phone portrait: section images become full-width inline blocks below
   the prose they illustrate (source-order rendering) */
@media (max-width: 720px) {
    .thora-section-image,
    .thora-section-image-left {
        float: none;
        margin: 1em auto;
        max-width: 100%;
        display: block;
    }
}

/* === Capability grid === */
/* Wide screens: behaves as a wikitable (inherits .wikitable styles).
   Phone: collapses to vertical card stack per row. */
.thora-capability-grid {
    width: 100%;
}
.thora-capability-grid td,
.thora-capability-grid th {
    vertical-align: top;
    padding: 0.5em 0.75em;
}

@media (max-width: 720px) {
    .thora-capability-grid,
    .thora-capability-grid tbody,
    .thora-capability-grid tr,
    .thora-capability-grid td {
        display: block;
        width: 100% !important;
        box-sizing: border-box;
    }
    .thora-capability-grid thead { display: none; }
    .thora-capability-grid tr {
        border: 1px solid var(--fg-border);
        border-radius: 4px;
        margin-bottom: 0.5em;
        padding: 0.25em 0.5em;
        background-color: var(--fg-bg-surface);
    }
    .thora-capability-grid td {
        border: none !important;
        padding: 0.25em 0;
    }
    .thora-capability-grid td:first-child {
        font-weight: 600;
        color: var(--fg-text-heading);
        border-bottom: 1px solid var(--fg-border-subtle) !important;
        margin-bottom: 0.25em;
    }
}

/* === Canon-meta block === */
/* Visually distinguishes "reserved" / "open hooks" / "canon meta" content
   from established canon, so casual readers don't mistake unsettled
   questions for established lore. */
.thora-canon-meta {
    border: 1px dashed var(--fg-border-light);
    background-color: var(--fg-bg-elevated);
    padding: 0.75em 1.25em;
    margin: 1.5em 0;
    border-radius: 6px;
    position: relative;
}
.thora-canon-meta::before {
    content: "⚠ Canonical meta";
    display: block;
    font-size: 0.72em;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--fg-accent-muted);
    margin-bottom: 0.5em;
    font-weight: 700;
    font-family: 'Space Grotesk', 'Inter', sans-serif;
}
.thora-canon-meta h2,
.thora-canon-meta h3 {
    color: var(--fg-accent-muted) !important;
    border-bottom: 1px solid var(--fg-border-light) !important;
    margin-top: 0.25em !important;
}
.thora-canon-meta ul {
    margin-left: 0.5em;
}

/* === Pull-quote === */
/* Single-sentence anchor placed below a section heading to give the
   reader an at-a-glance essence-statement before the prose. */
.thora-pullquote {
    font-family: 'Space Grotesk', 'Inter', sans-serif;
    font-size: 1.1em;
    line-height: 1.5;
    color: var(--fg-text-heading);
    border-left: 3px solid var(--fg-accent);
    padding: 0.25em 0 0.25em 1em;
    margin: 0.5em 0 1em 0;
    font-style: italic;
    background-color: transparent;
}

/* === Hero float-left variant === */
/* Use when a page wants classical text-wrap rather than the flex hero.
   The infobox (right-floated by default) hugs the right; this floated
   media block hugs the left; lede prose flows in the channel between.
   On phone, collapses to full-width block above prose. */
.thora-hero-float-left {
    float: left;
    width: 380px;
    max-width: 45%;
    margin: 0 1.5em 1em 0;
    clear: left;
}
.thora-hero-float-left .thora-crossfade {
    width: 100%;
}
.thora-hero-float-left .thora-crossfade img,
.thora-hero-float-left img {
    width: 100%;
    height: auto;
    max-width: 100%;
}
@media (max-width: 720px) {
    .thora-hero-float-left {
        float: none;
        width: 100%;
        max-width: 520px;
        margin: 0 auto 1em auto;
    }
}

/* === Banner image (full content-width, no float) === */
/* For mid-page anchor sections where an image deserves to span the full
   reading column rather than float beside text. Used e.g. for the
   Speeder Production banner on Aurora's page. */
.thora-banner-image {
    display: block;
    width: 100%;
    margin: 1.5em 0;
    clear: both;
}
.thora-banner-image img,
.thora-banner-image a img {
    display: block;
    width: 100%;
    height: auto;
    max-width: 100%;
    border-radius: 4px;
}
.thora-banner-image .thumbcaption,
.thora-banner-image figcaption {
    margin-top: 0.5em;
    font-size: 0.9em;
    color: var(--fg-text-secondary);
    text-align: center;
    font-style: italic;
}
/* === END: thora-character-layout === */

/* === BEGIN: thora-crossfade (managed by tools/setup_thora_crossfade.py) === */
/* Tho'ra crossfade gallery system.
   Use: <div class="thora-crossfade thora-cycle-N-tempo">
          <span class="thora-frame">[[File:...|400px]]</span> ... </span>
        </div>
   The first frame anchors the container size; subsequent frames overlay it.

   Preload strategy: every frame starts its animation at t=0 (no
   animation-delay). Each slot uses its own keyframe whose visible window is
   shifted within the cycle. This forces the browser to lay out, paint, and
   decode all frames on the first paint cycle — which prevents the "first
   loop is blank/blink" issue caused by deferred decode of opacity-0 images.
   We additionally use translateZ(0)/backface-visibility/will-change to
   promote each frame to its own compositor layer so subsequent transitions
   are GPU-composited and don't trigger re-decode. */

.thora-crossfade {
    position: relative;
    display: inline-block;
    line-height: 0;
    vertical-align: top;
}
.thora-crossfade .thora-frame {
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0;
    /* Preload + GPU-compositor hints */
    will-change: opacity;
    transform: translateZ(0);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
    animation-fill-mode: both;
    animation-delay: 0s; /* shared start so all frames decode immediately */
}
.thora-crossfade .thora-frame:first-child {
    position: relative; /* anchor: this frame defines container dimensions */
}
.thora-crossfade .thora-frame img,
.thora-crossfade .thora-frame a {
    display: block;
}
/* Hint to MediaWiki/browser: decode these images eagerly. */
.thora-crossfade .thora-frame img {
    image-rendering: auto;
    -webkit-transform: translateZ(0);
    transform: translateZ(0);
}

/* === 2-frame medium (8s total, 4s/frame) === */
.thora-cycle-2-medium .thora-frame { animation-duration: 8s; }
.thora-cycle-2-medium .thora-frame:nth-child(1) { animation-name: thora-fade-2-1; }
.thora-cycle-2-medium .thora-frame:nth-child(2) { animation-name: thora-fade-2-2; }
@keyframes thora-fade-2-1 {
    0%, 45%   { opacity: 1; }
    55%, 95%  { opacity: 0; }
    100%      { opacity: 1; }
}
@keyframes thora-fade-2-2 {
    0%, 45%   { opacity: 0; }
    55%, 95%  { opacity: 1; }
    100%      { opacity: 0; }
}

/* === 3-frame medium (12s total, 4s/frame) === */
.thora-cycle-3-medium .thora-frame { animation-duration: 12s; }
.thora-cycle-3-medium .thora-frame:nth-child(1) { animation-name: thora-fade-3-1; }
.thora-cycle-3-medium .thora-frame:nth-child(2) { animation-name: thora-fade-3-2; }
.thora-cycle-3-medium .thora-frame:nth-child(3) { animation-name: thora-fade-3-3; }
@keyframes thora-fade-3-1 {
    0%, 30%   { opacity: 1; }
    36%, 96%  { opacity: 0; }
    100%      { opacity: 1; }
}
@keyframes thora-fade-3-2 {
    0%, 30%   { opacity: 0; }
    36%, 63%  { opacity: 1; }
    70%, 100% { opacity: 0; }
}
@keyframes thora-fade-3-3 {
    0%, 63%   { opacity: 0; }
    70%, 96%  { opacity: 1; }
    100%      { opacity: 0; }
}

/* === 5-frame brisk (12.5s total, 2.5s/frame) === suit-up urgency */
.thora-cycle-5-brisk .thora-frame { animation-duration: 12.5s; }
.thora-cycle-5-brisk .thora-frame:nth-child(1) { animation-name: thora-fade-5-1; }
.thora-cycle-5-brisk .thora-frame:nth-child(2) { animation-name: thora-fade-5-2; }
.thora-cycle-5-brisk .thora-frame:nth-child(3) { animation-name: thora-fade-5-3; }
.thora-cycle-5-brisk .thora-frame:nth-child(4) { animation-name: thora-fade-5-4; }
.thora-cycle-5-brisk .thora-frame:nth-child(5) { animation-name: thora-fade-5-5; }

/* === 5-frame slow (25s total, 5s/frame) === hangar contemplation */
.thora-cycle-5-slow .thora-frame { animation-duration: 25s; }
.thora-cycle-5-slow .thora-frame:nth-child(1) { animation-name: thora-fade-5-1; }
.thora-cycle-5-slow .thora-frame:nth-child(2) { animation-name: thora-fade-5-2; }
.thora-cycle-5-slow .thora-frame:nth-child(3) { animation-name: thora-fade-5-3; }
.thora-cycle-5-slow .thora-frame:nth-child(4) { animation-name: thora-fade-5-4; }
.thora-cycle-5-slow .thora-frame:nth-child(5) { animation-name: thora-fade-5-5; }

/* Shared 5-frame keyframes — each slot 20% of cycle, 2% fade overlap.
   All slots animate from t=0 so all frames are painted/decoded immediately. */
@keyframes thora-fade-5-1 {
    0%, 18%   { opacity: 1; }
    22%, 96%  { opacity: 0; }
    100%      { opacity: 1; }
}
@keyframes thora-fade-5-2 {
    0%, 18%   { opacity: 0; }
    22%, 38%  { opacity: 1; }
    42%, 100% { opacity: 0; }
}
@keyframes thora-fade-5-3 {
    0%, 38%   { opacity: 0; }
    42%, 58%  { opacity: 1; }
    62%, 100% { opacity: 0; }
}
@keyframes thora-fade-5-4 {
    0%, 58%   { opacity: 0; }
    62%, 78%  { opacity: 1; }
    82%, 100% { opacity: 0; }
}
@keyframes thora-fade-5-5 {
    0%, 78%   { opacity: 0; }
    82%, 98%  { opacity: 1; }
    100%      { opacity: 0; }
}

/* Accessibility: honor reduced-motion preference. Show first frame only. */
@media (prefers-reduced-motion: reduce) {
    .thora-crossfade .thora-frame {
        animation: none !important;
        opacity: 0;
    }
    .thora-crossfade .thora-frame:first-child {
        opacity: 1;
    }
}
/* === END: thora-crossfade === */