/*
 * Redesign layer — loaded AFTER base.css and sprite-system.css.
 *
 * A RealmEye-style wiki presentation: left sidebar navigation, slim top bar, and a clean
 * left-aligned content column (white page, near-black text, blue links, cool hairlines,
 * striped listings). Theme architecture from wiki.gg: semantic CSS variables on :root,
 * overridden by [data-theme="dark"] (which keeps the wiki's original black/steel-blue
 * identity). base.css remains the structural base; this file re-skins and re-lays-out
 * the surfaces on top of it.
 *
 * Deliberate rules:
 *  - Item/affix cards keep the dark in-game tooltip look in BOTH themes and float right
 *    as an infobox (RealmEye/Terraria convention). The card's server-rendered inline
 *    colors (#FFFFFF values, #A9A9A9 labels, tier colors) only read on a dark panel.
 *  - Body copy is a readable sans; the Nope 8 pixel font stays on the sidebar brand and
 *    inside the tooltip cards for game flavor.
 */

/* ---------- tokens ------------------------------------------------------------------ */

:root {
    /* Native widgets (select popups, scrollbars) must follow the site theme, not the OS. */
    color-scheme: light;
    /* light (default) — RealmEye-inspired but nudged cooler; no value is a direct copy */
    --bg-page: #f2f3f5;
    --bg-chrome: #f6f7f9;          /* sidebar + top bar (RealmEye navbar) */
    --bg-panel: #ffffff;           /* the content panel ("the box") */
    --panel-border: #d9dde2;       /* swap for an accent (#a7d7f9, a green, …) to tint the panel */
    --bg-stripe: #f7f9fb;          /* striped rows */
    --bg-inset: #f4f6f8;
    --bg-hover: #eef2f6;
    --text: #2f3237;
    --text-muted: #6d747c;
    --text-faint: #8f96a0;
    --text-heading: #2b2e33;
    --link: #2d7dc4;
    --link-hover: #1f5a94;
    --border: #d9dde2;
    --border-chrome: #e4e7ec;
    --input-bg: #ffffff;
    --input-border: #c6ccd4;
    --input-text: #2f3237;
    --input-placeholder: #8f96a0;
    --scrollbar-thumb: #c3c9d1;
    --scrollbar-track: #eef0f4;
    --shadow-panel: 0 1px 2px rgba(0, 0, 0, 0.05);
    --accent-green: #2e7d32;       /* readable-on-white version of the brand green */
    --emphasis-bg: rgba(45, 125, 196, 0.10);   /* key-term chip background */

    /* Item-page semantic colors (light values; dark theme restores the game's brights). */
    --c-heal: #15803d;
    --c-barrier: #0369a1;
    --c-mana: #965285;
    --c-hpcost: #b2334d;
    --c-reroll: #a16207;
    --c-effect: #0f766e;
    --c-divine: #a97b00;
    --c-unreleased: #8a6d3b;
    --c-event-reward: #0d9488;
    --c-event-item: #c2410c;
    --c-quest: #6d28d9;
    --c-emote: #be185d;
    --c-title: #8e44ad;
    --c-ability-cost: #2563eb;
    --c-crafting: #8a5a28;
    --c-free-reroll: #0f766e;
    --c-warning: #dc2626;
    --c-reanimates: #a16207;
    --c-stat-green: #2e7d32;
    --c-stat-red: #c62828;
    /* Game-authored colors (description markup, titles, SubDesc, status effects) were
       designed for a dark background; the light theme mixes them toward black. */
    --desc-mix: 62%;

    /* the always-dark tooltip card */
    --card-bg: #101418;
    --card-text: #ffffff;

    /* Game-style sprite outline: four 1px hard drop-shadows trace the sprite's alpha
       silhouette (the browser equivalent of the client's outline shader), plus a soft
       dark glow. drop-shadow follows the rendered pixels, so it works on our
       atlas-cropped background sprites. */
    --sprite-outline-color: rgba(0, 0, 0, 0.85);
    --sprite-outline:
        drop-shadow(1px 0 0 var(--sprite-outline-color))
        drop-shadow(-1px 0 0 var(--sprite-outline-color))
        drop-shadow(0 1px 0 var(--sprite-outline-color))
        drop-shadow(0 -1px 0 var(--sprite-outline-color))
        drop-shadow(0 0 2px rgba(0, 0, 0, 1));

    /* Smooth (non-pixel) art like the footer logo: glow only, no hard stamps.
       The sprite outline's four 1px stamps assume chunky pixel-art features. Smooth art scaled
       to fit has thin strokes and ~15% soft edge (a nearest-neighbour sprite has 0%), so those
       stamps both thicken every stroke and compound on the partial pixels — it reads much
       darker even when the total ink per unit of art matches. A soft glow lifts the art off
       the background without outlining it. Turn this one alpha up or down to taste. */
    --smooth-outline: drop-shadow(0 0 2px rgba(0, 0, 0, 0.6));

    --font-body: "Helvetica Neue", Helvetica, Arial, sans-serif;
    --font-display: "Nope 8", sans-serif;

    --sidebar-width: 240px;
    --content-max: 1280px;
    --header-h: 56px;
}

[data-theme="dark"] {
    color-scheme: dark;
    --bg-page: #0b0b0d;
    --bg-chrome: #131316;
    --bg-panel: #121215;
    --panel-border: #26262c;
    --bg-stripe: #121216;
    --bg-inset: #101014;
    --bg-hover: rgba(255, 255, 255, 0.06);
    --text: #ededed;
    --text-muted: #9aa4ad;
    --text-faint: #6c757d;
    --text-heading: #f6fbff;
    --link: #77bff4;
    --link-hover: #a9d7f2;
    --border: #33363f;
    --border-chrome: #26262c;
    --input-bg: #0c0c0e;
    --input-border: #3b404c;
    --input-text: #dddddd;
    --input-placeholder: #808570;
    --scrollbar-thumb: #444444;
    --scrollbar-track: #111111;
    --shadow-panel: none;
    --accent-green: #78e08f;       /* the original brand green works on dark */
    --emphasis-bg: rgba(164, 194, 221, 0.14);

    --c-heal: #14cc2c;
    --c-barrier: #4bbaf2;
    --c-mana: #b678a5;
    --c-hpcost: #e0607e;
    --c-reroll: #ffff77;
    --c-effect: #94eadf;
    --c-divine: #ffd700;
    --c-unreleased: #d0a85c;
    --c-event-reward: #40e0d0;
    --c-event-item: #ff6347;
    --c-quest: #9370db;
    --c-emote: #ff69b4;
    --c-title: #dda0dd;
    --c-ability-cost: #a9d7f2;
    --c-crafting: #b0814f;
    --c-free-reroll: #4fb095;
    --c-warning: #ff1e14;
    --c-reanimates: #e9b11b;
    --c-stat-green: #00ff00;
    --c-stat-red: #ff1d14;
    --desc-mix: 100%;
}

/* ---------- accent presets ----------------------------------------------------------
   data-accent on <html> sets one strong base color; every tinted surface derives from it
   via color-mix, so an accent recolors the whole chrome: page wash, panel border + top
   strip, sidebar/topbar tint, inner-box borders, hovers, and stripes. */

[data-accent="azure"] { --accent: #3d8fd1; }
[data-accent="forest"] { --accent: #75c526; }
[data-accent="royal"] { --accent: #9a3fd5; }
[data-accent="crimson"] { --accent: #d14b4b; }
[data-accent="steel"] { --accent: #6b8cb0; }

/* Light accents color the surfaces, not the page: the content panel and the nav chrome
   carry the tint while the page behind stays neutral gray. */
/* All surfaces step off ONE base (accent + pure white) so every tint is the same hue —
   mixed gray bases made the palette read glassy/uneven. Hierarchy: chrome strongest,
   page mid, panel lightest (content stays the most readable surface). */
[data-accent] {
    --bg-panel: color-mix(in srgb, var(--accent) 8%, #ffffff);
    --bg-stripe: color-mix(in srgb, var(--accent) 13%, #ffffff);
    --bg-inset: color-mix(in srgb, var(--accent) 15%, #ffffff);
    --bg-page: color-mix(in srgb, var(--accent) 20%, #ffffff);
    --bg-hover: color-mix(in srgb, var(--accent) 22%, #ffffff);
    --bg-chrome: color-mix(in srgb, var(--accent) 28%, #ffffff);
    --border-chrome: color-mix(in srgb, var(--accent) 45%, #ffffff);
    --border: color-mix(in srgb, var(--accent) 40%, #ffffff);
    --panel-border: color-mix(in srgb, var(--accent) 65%, #ffffff);
    --accent-line: color-mix(in srgb, var(--accent) 65%, #ffffff);
    --scrollbar-track: color-mix(in srgb, var(--accent) 12%, #ffffff);
    --scrollbar-thumb: color-mix(in srgb, var(--accent) 45%, #ffffff);
}

[data-theme="dark"][data-accent] {
    --bg-page: color-mix(in srgb, var(--accent) 9%, #0a0a0c);
    --bg-chrome: color-mix(in srgb, var(--accent) 10%, #131316);
    --bg-panel: color-mix(in srgb, var(--accent) 6%, #121215);
    --border-chrome: color-mix(in srgb, var(--accent) 24%, #26262c);
    --border: color-mix(in srgb, var(--accent) 26%, #33363f);
    --panel-border: color-mix(in srgb, var(--accent) 45%, #26262c);
    --accent-line: color-mix(in srgb, var(--accent) 45%, #33363f);
    --bg-hover: color-mix(in srgb, var(--accent) 14%, #1a1a20);
    --bg-inset: color-mix(in srgb, var(--accent) 8%, #101014);
    --bg-stripe: color-mix(in srgb, var(--accent) 6%, #121216);
}


/* ---------- base -------------------------------------------------------------------- */

body {
    background-color: var(--bg-page);
    color: var(--text);
    font-family: var(--font-body);
    font-size: 14px;            /* RealmEye's exact body size */
    line-height: 1.45;
    display: block;             /* undo the centered flex column */
}

/* base.css sets user-select:none globally; wiki text must be selectable/copyable.
   Chrome (nav, buttons, tab controls) stays non-selectable. */
main.tooltip-container, main.tooltip-container * {
    -webkit-user-select: text;
    user-select: text;
}
main.tooltip-container .sprite-icon,
main.tooltip-container button,
main.tooltip-container .affix-options-container,
main.tooltip-container .drop-source-filters,
/* Click-to-toggle headers (essence groups, crafting groups, drop bags): repeatedly
   opening/closing them would otherwise text-select the title, since content text is
   selectable by default. */
main.tooltip-container .patch-header, main.tooltip-container .patch-header *,
main.tooltip-container summary.bag-header, main.tooltip-container summary.bag-header *,
main.tooltip-container .attacks-header, main.tooltip-container .attacks-header *,
main.tooltip-container .gem-header, main.tooltip-container .gem-header * {
    -webkit-user-select: none;
    user-select: none;
}

a { color: inherit; text-decoration: none; }
a.link, p a, li a, .item-description a {
    color: var(--link);
    text-decoration: none;
}
a.link:hover, p a:hover, li a:hover { color: var(--link-hover); }

/* RealmEye headings: plain, bold, sans (scaled to their density). */
h1, h2, h3, h4 {
    font-family: var(--font-body);
    font-weight: 700;
    color: var(--text-heading);
    text-align: left;
}
h1 { font-size: 26px; margin: 16px 0 10px; padding-bottom: 8px; border-bottom: 1px solid var(--accent-line, var(--border)); }
h2 { font-size: 20px; margin: 20px 0 8px; }
h3 { font-size: 16px; margin: 16px 0 6px; }

/* Headings that carry a sprite icon: base.css reset them to normal weight (and h1s to
   3rem) for the game-UI look — they match the plain headings' weight and scale instead. */
.heading-with-icon, .h1-with-icon, .h2-with-icon, .h3-with-icon,
.h4-with-icon, .h5-with-icon, .h6-with-icon {
    font-weight: 700;
}
h1.h1-with-icon { font-size: 26px; padding-top: 0; padding-bottom: 8px; margin: 16px 0 10px; }
h2.h1-with-icon, h2.h2-with-icon { font-size: 20px; margin: 20px 0 8px; }
h3.heading-with-icon, h3.h3-with-icon { font-size: 16px; }

/* base.css sizes prose and generic labels at 1.5rem; RealmEye is 14px. */
p, .body-text, li { font-size: 14px; line-height: 1.55; }
.menu-header { font-size: 14px; font-family: var(--font-body); }

/* ---- type-scale normalization -------------------------------------------------------
   base.css sizes dozens of components at 1.25–2rem for the old game-UI look; the wiki
   scale is 14px body, 15-16px component headers. Everything below is a flat re-scale —
   audit source: every base.css selector with font-size > 15px. */
h4 { font-size: 15px; }
.list-item { color: var(--text); }
.list-item, .menu-desc, .menu-tier, .beta-warning-top,
.item-description, .item-stats, .item-classes, .item-unique, .affix-stats,
.patch-summary, .patch-notes-list li, .attainment-name, .class-name-2,
.class-table.two-col .class-name-2, .class-table.three-col .class-name-2,
.class-table.five-col .class-name-2, .affix-description, .animation-item h4,
.bag-toggle, .guaranteed-indicator, .link-header, .item-additional-sprite-name,
.crafting-affix-label, .dictionary-def {
    font-size: 14px;
}
.crafting-header, .dictionary-term, .affix-name, .affix-header-label,
.affix-nav-entry .menu-header, .enemy-name, .dungeon-name, .dungeon-entry .dungeon-name,
.patch-toggle, .package-info h2, .item-additional-sprites-title, .items-header,
.item-title, .se-title {
    font-size: 16px;
}
.essence-table-header, .class-table-header, .class-col-title h2,
.class-table.five-col .class-col-title h2, .class-table.three-col .class-col-title h2 {
    font-size: 14px;
}
.affix-subtext, .small-affix-name { font-size: 13px; }
code { font-size: 13px; }
/* Icon-with-heading variants follow the new heading scale. */
.h1-with-icon { font-size: 26px; }
.h2-with-icon { font-size: 20px; }

/* One divider style. The content pages mix four (hr, 4px .pixel-hr bars, 2px .pixel-hr-2,
   gradient .custom-hr) — all normalize to the RealmEye hairline. */
hr, .pixel-hr, .pixel-hr-2, .custom-hr {
    height: 0;
    border: 0;
    border-top: 1px solid var(--border);
    background: none;
    margin: 20px 0;
}

/* Emphasis spans (341 uses in the content pages) were pale steel-blue on the old dark
   site — on a light page they read as links and have poor contrast. Wiki convention:
   emphasis is bold body text; color belongs to links alone. */
.highlight, .text-highlight, .text-green {
    color: var(--text);
    font-weight: 700;
}

/* Links to pages that don't exist yet, and deliberately disabled nav entries:
   plain muted text, no pointer, no hover. */
.dead-link { color: var(--text); }
.disabled-link, .disabled-link .menu-header {
    color: var(--text-faint) !important;
    cursor: default !important;
}
.disabled-link:hover { background: transparent !important; }
.disabled-link .sprite-icon { opacity: 0.55; }

/* gridItem cells hard-locked rows at 40px; tall content (vertical menus) overflowed the
   cell and later elements drew straight through it. Rows size to content instead. */
.gridItem {
    height: auto;
    grid-template-rows: auto;
    grid-auto-rows: auto;
}

/* Home category tiles are links — uniformly link-blue. */
.contentGrid a.category-container .menu-header { color: var(--link); }
.contentGrid a.category-container:hover .menu-header { color: var(--link-hover); }

/* ---------- app skeleton ------------------------------------------------------------ */

.application-wrapper { min-height: 100vh; }

/* Sidebar (base.css makes it position:fixed but never anchors it) */
.menu-container {
    background: var(--bg-chrome);
    border-right: 1px solid var(--border-chrome);
    width: var(--sidebar-width);
    padding: 0 0 24px;
    margin: 0;
    left: 0;
    top: 0;
    overflow-x: hidden;
    transition: width 0.25s ease;
}

/* ---- collapsed rail (toggled by the Navigation header; icons only) ---------------- */
html.nav-collapsed { --sidebar-width: 56px; }
.page-wrapper { transition: padding-left 0.25s ease; }
.menu-container .category-container { white-space: nowrap; flex-wrap: nowrap; }
.menu-container .menu-header, .wiki-brand-name {
    transition: opacity 0.18s ease;
}
html.nav-collapsed .menu-container .menu-header,
html.nav-collapsed .wiki-brand-name,
html.nav-collapsed .menu-container .menu-subcategory {
    opacity: 0;
}
/* The section list collapses to icons like every other nav group instead of vanishing: its
   rows are .category-container inside .menu-container, so the rule above already fades their
   labels and leaves the icons — no extra rules needed.
   Its heading deliberately keeps its space and only fades, exactly like the SPOTLIGHT /
   EQUIPMENT labels. Zeroing the height to close the gap looks tidier in a screenshot but
   shifts every row beneath it as the rail slides, which is the same jump the nowrap rule
   above exists to prevent. A static gap beats moving rows. */
/* Collapsed rail: the icon stays LEFT-ANCHORED and only its padding animates to the
   centered offset ((56 - 36) / 2 = 10px), in step with the rail width — switching to
   justify-content:center mid-animation makes the icon see-saw. The name gives up its
   width along with its opacity so it can't push the icon around. */
html.nav-collapsed .wiki-brand { padding: 0 0 0 10px; gap: 0; }
html.nav-collapsed .wiki-brand-name { max-width: 0; }
/* The expanded sidebar's right padding and scrollbar gutter would skew rail centering. */
html.nav-collapsed .menu-container.menu-right-pad { padding-right: 0; }
html.nav-collapsed .menu-container { scrollbar-width: none; }
html.nav-collapsed .menu-container::-webkit-scrollbar { display: none; }
/* Keep the Navigation toggle row's icon visible as the collapse handle. */
.menu-container summary.category-container { cursor: pointer; }

.wiki-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    height: var(--header-h);
    box-sizing: border-box;
    transition: padding 0.25s ease, gap 0.25s ease;
    padding: 0 16px;
    border-bottom: 1px solid var(--border-chrome);
    text-decoration: none;
    margin-bottom: 8px;
    white-space: nowrap;    /* the name must clip, not stack, while the rail slides */
    overflow: hidden;
    /* Pinned: the sidebar scrolls beneath it, so the home link never leaves the corner. */
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--bg-chrome);
    flex-shrink: 0;
}
.wiki-brand-name {
    font-family: var(--font-display);
    font-size: 22px;
    line-height: 1;               /* hug the pixel-font glyphs so flex centering is optical */
    color: var(--text-heading);
    display: inline-block;
    max-width: 220px;             /* animates to 0 when the rail collapses */
    overflow: hidden;
    transition: opacity 0.25s ease, max-width 0.25s ease;
}
/* Brand icon stays full-size (the sidebar's compact 22px icon rule would shrink it). */
.wiki-brand .sprite-icon,
.menu-container .wiki-brand .sprite-icon.sprite-icon-32 { width: 36px; height: 36px; }

/* Sidebar entries: compact rows, sans labels, small icons. */
.menu-container .category-container {
    padding: 5px 14px;
    margin: 0;
    gap: 8px;
    border-radius: 0;
}
/* No hover card in the nav: a filled rect behind the row is the old card look, and rows
   already signal via text colour (same reasoning as .contentReplace tiles below). The
   SPOTLIGHT/EQUIPMENT/OTHER group labels are plain divs with no page behind them and stay
   inert either way. */
.menu-container a.category-container:hover,
.menu-container summary.category-container:hover { background: transparent; }
.menu-container div.category-container:hover { background: transparent; cursor: auto; }
.menu-container .menu-header {
    font-family: var(--font-body);
    font-size: 14px;
    color: var(--text);
    margin: 0;
}
/* Nav hyperlinks read as links: blue, no underline (hover darkens the text — the row itself
   stays flat). The Navigation toggle is a summary, not a link, so it needs the hover colour
   spelled out or it would have no feedback left at all once the row highlight is gone. */
.menu-container a.category-container .menu-header { color: var(--link); }
.menu-container a.category-container:hover .menu-header,
.menu-container summary.category-container:hover .menu-header { color: var(--link-hover); }
.menu-container .sprite-icon-32,
.menu-container .sprite-icon.sprite-icon-32 { width: 22px; height: 22px; }

/* Section labels ("Equipment", …) */
.menu-container .menu-subcategory,
.menu-header.subcategory {
    font-family: var(--font-body);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-faint);
    padding: 12px 0 2px;
}

/* "Navigation" / section-list headers — identical to the .menu-subcategory labels
   (RESOURCES / EQUIPMENT / OTHER) so every sidebar group reads as one system. */
.menu-container summary.category-container { padding-top: 8px; }
.menu-header.nav {
    font-family: var(--font-body);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-faint);
    /* Group labels sit outside .category-container, so they miss its nowrap. Mid-slide the
       rail is narrow and the label fade (0.18s) is shorter than the width transition (0.25s),
       so a wrapping label is visible while it stacks and shoves the nav around. Clip like the
       brand name does instead. */
    white-space: nowrap;
    overflow: hidden;
}
.menu-container summary .sprite-icon-32 { width: 16px; height: 16px; }
.anchor-link-container.has-anchors {
    border-bottom: none;   /* it's the sidebar's last group now — no dangling divider */
    padding-bottom: 8px;
    margin-bottom: 4px;
}
/* Flows straight after the Navigation block like any other sidebar group —
   base.css spaced them apart (75px collapsible margin + 15px top margin). */
.anchor-link-container { margin-top: 0; }
.main-menu-collapsible { margin-bottom: 4px; }
/* The "On This Page" label is a bare div (no .category-container row padding) —
   align it with the padded rows below it. */
.anchor-link-container .menu-header.nav { padding: 10px 14px 2px; }
.anchor-link-container .menu-header { font-size: 13px; }
.anchor-link-container .menu-header.nav { font-size: 11px; }   /* the group label, not the rows */
.anchor-link-container a .menu-header { color: var(--link); }
.anchor-link-container .sprite-icon-32 { width: 18px; height: 18px; }
/* The section header ("Weapons") is a link to the category overview page. */
a.menu-header.nav { display: block; }
a.menu-header.nav:hover { color: var(--link-hover); }
/* Current page in the section list: emphasized, not link-colored. */
/* The current section is marked by its text alone — no filled row, matching the flat hover
   treatment above. The colour flip out of link-blue plus the weight carries it. */
.anchor-link-container .category-container.active .menu-header {
    color: var(--text);
    font-weight: 700;
}

/* Content pane: a full-viewport flex column so the footer pins to the bottom
   even on short pages. */
.page-wrapper {
    width: calc(100% - var(--sidebar-width));
    padding: 0 0 0 var(--sidebar-width);
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    box-sizing: border-box;
    justify-content: flex-start;
    align-items: stretch;
}

/* ---------- top bar ----------------------------------------------------------------- */

.menu-wrapper.topbar {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    height: var(--header-h);    /* matches the sidebar brand row so the borders align */
    padding: 0 24px;
    box-sizing: border-box;     /* width:100% + padding must not overflow (cut off the toggle) */
    background: var(--bg-chrome);
    border-bottom: 1px solid var(--border-chrome);
    position: sticky;
    top: 0;
    z-index: 20;
}
.topbar-nav { display: flex; align-items: center; gap: 4px; }
.topbar-nav .sprite-icon-32 { width: 26px; height: 26px; }
.topbar-title {
    font-family: var(--font-body);
    font-size: 16px;
    font-weight: 700;
    color: var(--text-heading);
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.topbar .search-container { margin-left: auto; width: 240px; position: relative; }
.leftMenuButton { display: none; }

/* ---------- content column ---------------------------------------------------------- */

/* The main container: a white content panel on the gray page, centered
   (wiki.gg's boxed-content look with RealmEye's insides). */
main.tooltip-container.areas, .tooltip-container.areas {
    display: block;
    width: auto;
    max-width: var(--content-max);
    margin: 16px auto 24px;
    padding: 8px 32px 40px;
    background: var(--bg-panel);
    border: 1px solid var(--panel-border);
    border-radius: 6px;
    box-shadow: var(--shadow-panel);
    color: var(--text);
    text-align: left;
}
/* Pages that author .center-text (the home page welcome, a couple of intros) keep it. */
.tooltip-container.areas .center-text { text-align: center; }

/* Home page banner: centered above the welcome text. */
.tooltip-container.areas .header-image-container { justify-content: center; padding: 10px 0 0; }
.tooltip-container.areas .header-image { width: 216px; height: auto; }

.breadcrumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 12px; font-size: 13px; }
.breadcrumbs a { color: var(--link); }
.breadcrumbs a:hover { color: var(--link-hover); }
.breadcrumb-sep { color: var(--text-muted); }
.breadcrumb-current { color: var(--text-muted); }

.footer {
    margin-top: auto;                          /* pins to the viewport bottom on short pages */
    padding: 18px 32px 22px;
    border-top: 1px solid var(--border-chrome);
}
/* Aligned to the same column as the content panel so it reads as part of the page,
   not a stray strip. Space-between keeps the brand left and the stores right; both
   halves stay whole when the row wraps on narrow screens. */
.footer-inner {
    width: 100%;                 /* base.css makes .footer a flex row — without this the
                                    inner box shrink-wraps and space-between does nothing */
    max-width: var(--content-max);
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px 24px;
}
.footer-brand-row { display: flex; align-items: center; gap: 12px; }
/* Outline/glow to match the game sprites, in the smooth-art strength (see --smooth-outline).
   No padding needed in the PNG: drop-shadow traces the rendered alpha and paints outside the
   element's box, so art running to the very edge is still outlined in full. */
.footer-logo { max-width: 72px; image-rendering: auto; filter: var(--smooth-outline); }   /* smooth art, not pixel art */
.footer-copyright { font-size: 12px; color: var(--text-muted); line-height: 1.6; white-space: nowrap; }
.footer-links { display: flex; align-items: center; gap: 12px; }
.footer-links-label { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.footer-links a { display: inline-flex; opacity: 0.8; transition: opacity 0.15s ease; }
.footer-links a:hover { opacity: 1; }

/* Narrow: centre the stack instead of pushing the halves to opposite edges. */
@media (max-width: 720px) {
    .footer-inner { justify-content: center; text-align: center; }
    .footer-copyright { white-space: normal; }
}

/* Discord widget at the sidebar's end — a custom card on the wiki's theme variables
   (Discord's official iframe can't be restyled and needs ~350px). The outer div is a
   spacing zone: margin-top:auto pins it to the bottom when the nav is shorter than the
   viewport; otherwise it follows the last group with the padding as the gap. */
.discord-widget { margin-top: auto; padding: 16px 12px 0; transition: opacity 0.18s ease; }
.discord-widget-card {
    background: var(--bg-hover);
    border: 1px solid var(--border-chrome);
    border-radius: 8px;
    padding: 10px 12px 12px;
    /* Fixed width (sidebar 240 − 2×12 spacing): during the rail collapse animation the
       sidebar's width tweens, and a fluid card would squish/rewrap every frame — fixed,
       it just clips at the shrinking edge while the fade below hides it (same trick as
       .wiki-brand-name). The mobile drawer overrides this back to fluid. */
    width: 216px;
    box-sizing: border-box;
}
.discord-widget-header { display: flex; align-items: center; gap: 8px; }
.discord-widget-title { min-width: 0; }
.discord-widget-name {
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.discord-widget-count { font-size: 11.5px; color: var(--text-faint); }
/* Green presence dot, only once the live count is in. */
.discord-widget-count.has-count::before {
    content: "";
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #3ba55d;
    margin-right: 5px;
    vertical-align: baseline;
}
.discord-widget-avatars { display: flex; padding-left: 6px; overflow: hidden; }
.discord-widget-avatars:empty { display: none; }
.discord-widget-avatars img {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 2px solid var(--bg-hover);   /* overlap ring matches the card background */
    margin: 10px 0 2px -6px;
    background: var(--bg-chrome);
}
.discord-widget-join {
    display: block;
    margin-top: 10px;
    padding: 7px 10px;
    text-align: center;
    background: #5865f2;                 /* Discord blurple, fine on both themes */
    color: #ffffff;
    font-size: 13px;
    font-weight: 600;
    border-radius: 6px;
    text-decoration: none;
    transition: background 0.15s ease;
}
.discord-widget-join:hover { background: #4752c4; color: #ffffff; }
/* No room for it on the collapsed icon rail: fade out (display:none would pop a frame
   before the width animation starts; opacity rides along with it). */
html.nav-collapsed .discord-widget { opacity: 0; pointer-events: none; }

/* The content panel keeps a constant width regardless of sidebar state (sized against the
   expanded 240px sidebar) — so collapsing the rail slides the column without re-wrapping
   its text mid-animation. */
main.tooltip-container.areas {
    width: clamp(300px, calc(100vw - 288px), var(--content-max));
    box-sizing: border-box;
}

/* ---------- search ------------------------------------------------------------------ */

.search-input, .filter-select {
    background: var(--input-bg);
    border: 1px solid var(--input-border);
    border-radius: 4px;
    color: var(--input-text);
    font-family: var(--font-body);
    font-size: 14px;
    padding: 6px 10px;
    width: 100%;
    /* width:100% must include the padding/border, or the input spills ~22px past its
       container and visually collides with the topbar buttons next to it. */
    box-sizing: border-box;
}
.search-input::placeholder { color: var(--input-placeholder); }
.filter-select option { background: var(--input-bg); color: var(--input-text); }
.search-input:focus { border-color: var(--link); outline: none; }
.search-results {
    background: var(--bg-panel);
    border: 1px solid var(--input-border);
    border-top: none;
    color: var(--text);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
a.search-result-item {
    display: block;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border-chrome);
    text-decoration: none;
}
.search-result-item:hover, .search-result-item.active { background: var(--bg-hover); }
.search-no-results { padding: 10px 12px; color: var(--text-faint); font-size: 13px; }
.search-result-title { color: var(--text); font-weight: 500; margin-bottom: 2px; font-size: 14px; }
.search-result-type { color: var(--text-faint); font-size: 11px; text-transform: capitalize; }

/* ---------- grids / listings -------------------------------------------------------- */

/* Item/category grids: a clean bordered box of link rows (RealmEye table feel). */
.contentReplace {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
    gap: 0;
    border: none;              /* flat rows, no card box (site-wide no-cards rule) */
    border-radius: 0;
    background: transparent;
    padding: 0;
    margin: 8px 0 18px;
}
/* The equipment tier sections' colored left-border strips are part of the old card look. */
.item-section-content, .content.item-section-content {
    border: none !important;
    background: transparent !important;
    padding: 0 !important;
}
.contentReplace .category-container {
    border: none !important;
    border-left: none !important;
    background: transparent !important;
    padding: 4px 8px;
    margin: 0;
    gap: 8px;
    border-radius: 3px;
}
/* No hover card on content tiles — links signal via text color (rules below). */
.contentReplace .category-container:hover { background: transparent !important; }
.contentReplace .menu-header, .contentReplace .link-header {
    font-family: var(--font-body);
    font-size: 14px;
    margin: 0;
    color: var(--text);
}
.contentReplace a.category-container .menu-header,
.contentReplace a.category-container .link-header { color: var(--link); }
.contentReplace a.category-container:hover .menu-header,
.contentReplace a.category-container:hover .link-header { color: var(--link-hover); }

/* Equipment tier sections: hairline box with a thin tier-colored left edge
   (replaces the thick full borders). */
.item-section-content {
    border-width: 1px !important;
    border-color: var(--border) !important;
    border-left-width: 3px !important;
    background: var(--bg-panel);
}
.item-section-content.item-section-tiered { border-left-color: #a4c2dd !important; }
.item-section-content.item-section-special { border-left-color: #8adb5c !important; }
.item-section-content.item-section-unique { border-left-color: #1e90ff !important; }
.item-section-content.item-section-relic { border-left-color: #9a3fd5 !important; }
.item-section-content.item-section-event { border-left-color: #68b1b8 !important; }
.item-section-content.item-section-trinket { border-left-color: #c2a1c2 !important; }

/* Section headings with icons: inline, modest */
.heading-with-icon, .h2-with-icon { display: flex; align-items: center; gap: 8px; }
.heading-icon, .h2-icon { width: 24px; height: 24px; }

/* generic striped/inset tables (essences, classes, patch notes) */
.middleman > .category-container:nth-child(2n-1) { background-color: var(--bg-stripe); }

/* The "dark card" table cells (essence/relic/class/affix/generic tables) were near-black
   game-UI chips. They render box-less, like the dungeons list: just the sprite with its
   label — blue when it's a link, plain when not. The nth-child selectors match base.css's
   per-column shade variants, which otherwise out-rank a single class override. */
.essence-container, .relic-container, .class-container, .affix-container, .generic-container,
.class-table.two-col .class-container, .class-table.three-col .class-container,
.class-table.five-col .class-container,
.essence-row > .essence-col:nth-child(2) .essence-container,
.essence-row > .essence-col:nth-child(3) .essence-container,
.relic-row > .relic-col:nth-child(2) .relic-container,
.relic-row > .relic-col:nth-child(3) .relic-container,
.generic-row > .generic-col:nth-child(2) .generic-container,
.generic-row > .generic-col:nth-child(3) .generic-container {
    background: transparent;
    border: none;
    color: var(--text);
}

/* The generic pairing tables (e.g. Event | Dungeon Drop): icon-over-label tiles spread
   across the full content width (base.css packed the columns with max-content). */
.generic-table, .generic-table.two-col { grid-template-columns: 1fr 1fr; }
.generic-table.three-col { grid-template-columns: 1fr 1fr 1fr; }
.generic-col-title { text-align: center; }
.generic-container {
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 6px;
    padding: 8px 4px;
    text-align: center;
}
.generic-container .sprite-icon-32 { width: 48px; height: 48px; }
div.generic-container, div.generic-container:hover { cursor: auto; }
/* Anchor tiles are links (the nth-child forms out-rank the column color variants). */
a.generic-container,
.generic-row > .generic-col:nth-child(1) a.generic-container,
.generic-row > .generic-col:nth-child(2) a.generic-container,
.generic-row > .generic-col:nth-child(3) a.generic-container {
    color: var(--link);
}
a.generic-container:hover,
.generic-row > .generic-col:nth-child(1) a.generic-container:hover,
.generic-row > .generic-col:nth-child(2) a.generic-container:hover,
.generic-row > .generic-col:nth-child(3) a.generic-container:hover {
    color: var(--link-hover);
}
/* Class tables: base.css paints values white (#fff) and headers #ccc for the dark SPA —
   invisible on the light theme. Values follow the theme; the tinted per-stat winner chips
   (.hp-gem etc.) keep white text on their colored backgrounds. */
.class-name-2,
.class-table.two-col .class-name-2, .class-table.three-col .class-name-2,
.class-table.five-col .class-name-2,
.class-table.three-col .description-container .class-name-2 { color: var(--text); }
.class-table-header { color: var(--text-muted); }
.class-container[class*="-gem"] .class-name-2,
.class-table .class-container[class*="-gem"] .class-name-2 { color: #fff; }
a.class-col .class-name-2,
.class-table.two-col a.class-col .class-name-2,
.class-table.three-col a.class-col .class-name-2,
.class-table.five-col a.class-col .class-name-2 { color: var(--link); }
a.class-col:hover .class-name-2,
.class-table.two-col a.class-col:hover .class-name-2,
.class-table.three-col a.class-col:hover .class-name-2,
.class-table.five-col a.class-col:hover .class-name-2 { color: var(--link-hover); }

/* Dictionary: terms read as headings, definitions as body text (base.css had #ccc). */
.dictionary-term { color: var(--text-heading); font-weight: 700; }
.dictionary-def { color: var(--text); }

.essence-name { color: var(--text); font-family: var(--font-body); font-size: 14px; }
.essence-table-header, .essence-col-title h2, .class-col-title h2,
.relic-col-title h2, .generic-col-title h2,
.class-table.five-col .class-col-title h2, .class-table.three-col .class-col-title h2 {
    color: var(--text-muted);
    font-family: var(--font-body);
}
.bag-content { border-top: 1px solid var(--border); }

/* Hover highlight only on the big interactive rows: collapsible headers and enemy cards.
   Content tiles and cells never get a hover card — links signal with color + pointer. */
.patch-header:hover, .attacks-header:hover,
.bag-header:hover, .gem-header:hover, .change-entry:hover, .enemy-card:hover {
    background: var(--bg-hover);
}
/* base.css puts cursor:pointer + a near-black background on every cell hover;
   kill both — non-link text keeps the I-beam, links re-add the pointer below. */
.class-container:hover, .affix-container:hover, .essence-container:hover,
.relic-container:hover, .generic-container:hover,
.class-table.two-col .class-container:hover, .class-table.three-col .class-container:hover,
.class-table.five-col .class-container:hover,
.essence-row > .essence-col:nth-child(2) div.essence-container:hover,
.essence-row > .essence-col:nth-child(3) div.essence-container:hover,
.relic-row > .relic-col:nth-child(2) div.relic-container:hover,
.relic-row > .relic-col:nth-child(3) div.relic-container:hover {
    cursor: auto;      /* text shows the I-beam again — it's selectable, just not clickable */
    background: transparent;
}
a .class-container:hover, a .essence-container:hover,
a .relic-container:hover, a .generic-container:hover,
a.class-container:hover, a.essence-container:hover,
a.relic-container:hover, a.generic-container:hover,
.essence-row > .essence-col:nth-child(2) a.essence-container:hover,
.essence-row > .essence-col:nth-child(3) a.essence-container:hover,
.relic-row > .relic-col:nth-child(2) a.relic-container:hover,
.relic-row > .relic-col:nth-child(3) a.relic-container:hover,
.class-table.two-col a .class-container:hover,
.class-table.three-col a .class-container:hover,
.class-table.five-col a .class-container:hover {
    cursor: pointer;
    background: transparent;
}
/* Box-less tiles hover by label color, not by background rectangle. */
.generic-container:hover,
.generic-row > .generic-col:nth-child(2) .generic-container:hover,
.generic-row > .generic-col:nth-child(3) .generic-container:hover {
    background: transparent;
}

/* ---- Affix tables (guides/affixes/*) ------------------------------------------------- */
/* Slot nav on the affixes index: compact list rows (icon left, label right) in the same
   bordered panel as the hub menus, instead of the SPA's spread-out icon-over-label tiles. */
.affix-nav-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
    gap: 0;
    border: none;
    background: transparent;
    padding: 0;
    margin: 8px 0 18px;
}
.affix-nav-entry {
    flex-direction: row;
    align-items: center;
    text-align: left;
    gap: 8px;
    max-width: none;
    padding: 5px 8px;    /* same row height as the standard category rows */
}
.affix-nav-entry .sprite-icon,
.affix-nav-entry .sprite-icon.slot-icon-48 { width: 32px; height: 32px; }
.affix-nav-entry .menu-header { text-align: left; font-size: 14px; }
a.affix-nav-entry .menu-header { color: var(--link); }
a.affix-nav-entry:hover .menu-header { color: var(--link-hover); }
/* Tier tables stack as one full-width list (base.css packed them side by side, but the
   rows of different tiers don't correspond, so twin columns just split the reading order). */
.affix-grid,
.menu-container:not(.menu-hide) ~ * .affix-grid,
.application-wrapper:not(.page-menu-hide) .affix-grid { grid-template-columns: 1fr; gap: 0.5rem; }
.affix-table { grid-template-columns: max-content 1fr; gap: 0; }
/* Row dividers instead of floating gaps, RealmEye-table style. */
.affix-col { padding: 10px 12px 10px 0; }
.affix-row + .affix-row .affix-col { border-top: 1px solid var(--border); }
/* Media-object left cell: icon | text block. Name and meta share one left edge,
   and the name's first line optically centers against the 32px icon. */
.affix-container.affix-left-row { flex-direction: row; align-items: flex-start; }
.affix-meta { margin-left: 0; }
.affix-text-block { padding-top: 5px; }
.affix-description { padding-top: 5px; }   /* same offset as the text block → shared first line */
.affix-header-label { color: var(--text-muted); }
.affix-name { color: var(--text); }
.affix-description { color: var(--text); }
.affix-subtext, .affix-key { color: var(--text-muted); }
.affix-value { color: var(--text); }
.affix-stat-label { color: var(--text-muted); }
.affix-stat-value { color: var(--text); }
.affix-stat-value.neg { color: #c0392b; }
.affix-stat-value.pos { color: #1e9e50; }
[data-theme="dark"] .affix-stat-value.neg { color: #e74c3c; }
[data-theme="dark"] .affix-stat-value.pos { color: #2ecc71; }
.affix-container, .affix-container:hover { cursor: auto; }
a.affix-subicon { color: var(--link); }
a.affix-subicon .small-affix-name { color: var(--link); }
a.affix-subicon:hover, a.affix-subicon:hover .small-affix-name { color: var(--link-hover); }
a.affix-subicon:hover { background: var(--bg-hover); }
div.affix-subicon:hover { background: transparent; }
/* Tier colors re-declared after the .affix-name reset so they win the cascade;
   pale hues that vanish on white get darker light-theme variants. */
/* ---- HATED (tier 10) affixes -------------------------------------------------------- */
/*
 * The client's obsidian shine, ported from HatedRimEffect.IconShineColor():
 *     phase     = tick % 4000 / 4000
 *     centre    = phase * 2.4 - 3 * 0.16
 *     intensity = exp(-(0.5 - centre)^2 / 0.16^2)
 *     colour    = lerp(#1a0b2e, #ff46f0, intensity)
 * A 4s lap that rests at near-black violet and passes through a hot magenta glint peaking at
 * ~41%. The stops below sample that gaussian; CSS's linear interpolation between them is
 * close enough at this size. The whole glyph glints at once rather than the band sweeping
 * across it — the client does the same, because at ~10px a sweep is a one-frame flicker.
 */
@keyframes hated-affix-glint {
    0%, 25%   { background-color: #1a0b2e; }
    30%       { background-color: #2a0f3c; }
    35%       { background-color: #842688; }
    41%       { background-color: #ff46f0; }
    45%       { background-color: #b533b1; }
    50%       { background-color: #3d144b; }
    58%, 100% { background-color: #1a0b2e; }
}
@keyframes hated-affix-glint-text {
    0%, 25%   { color: #1a0b2e; }
    30%       { color: #2a0f3c; }
    35%       { color: #842688; }
    41%       { color: #ff46f0; }
    45%       { color: #b533b1; }
    50%       { color: #3d144b; }
    58%, 100% { color: #1a0b2e; }
}

/*
 * The sprite is a WHITE MASK by design (the client tints it with a multiplicative vertex
 * colour, and a black glyph would multiply to black). So rather than painting the atlas cell
 * as a background, it becomes a mask and the animated colour shows through it.
 *
 * The tint lives on a pseudo-element, not the icon itself, because the rendering order is
 * filter -> clip -> mask: masking the icon directly would build .sprite-icon's outline around
 * the full box and then clip it away, leaving the glyph bare. With the fill one level down,
 * the icon's filter sees an already-masked glyph and traces its actual silhouette.
 */
.sprite-icon[data-sprite-id="hated_affix"] {
    background-image: none;
    position: relative;
}
.sprite-icon[data-sprite-id="hated_affix"]::before {
    content: "";
    position: absolute;
    inset: 0;
    /* The rest colour is set outright, not left to the animation: with the animation absent —
       reduced motion, a background tab, an old browser — an unset background-color is
       transparent and the glyph would simply not be there. */
    background-color: #1a0b2e;
    mask-image: var(--sprite-image);
    mask-size: var(--sprite-bg-size-x) var(--sprite-bg-size-y);
    mask-position: var(--sprite-bg-pos-x) var(--sprite-bg-pos-y);
    mask-repeat: no-repeat;
    -webkit-mask-image: var(--sprite-image);
    -webkit-mask-size: var(--sprite-bg-size-x) var(--sprite-bg-size-y);
    -webkit-mask-position: var(--sprite-bg-pos-x) var(--sprite-bg-pos-y);
    -webkit-mask-repeat: no-repeat;
    animation: hated-affix-glint 4s linear infinite;
}
/* The affix NAME wears the same palette on the same clock, so icon and label glint together
   exactly as they do in the tooltip. The palette is the game's own and is deliberately
   identical in both themes — the dark rest state IS the HATED identity, per the client's own
   note. Two class names because the affix list and the item-page picker key off different
   maps: AffixTierIcon gives "hated_affix_text", AffixTierColorClass gives "hated-affix". */
.hated_affix_text,
.hated-affix { color: #1a0b2e; animation: hated-affix-glint-text 4s linear infinite; }

/* An infinite pulse is exactly what reduced-motion asks us to drop; both settle on the rest
   colour, which is the identity anyway. */
@media (prefers-reduced-motion: reduce) {
    .sprite-icon[data-sprite-id="hated_affix"]::before,
    .hated_affix_text,
    .hated-affix { animation: none; }
}

/* Both spellings on every rule, because two maps feed two different places and they must not
   drift: AffixTierIcon gives "{icon}_text" to the affix list page, AffixTierColorClass gives
   "{colour}-affix" to the item picker's selected name and its damage/accuracy figures. Only
   pink ever had the hyphenated form, so tiers 1-4 and 6 were rendering as plain body text
   there while the same affix showed correctly coloured on the list page. */
.pink_affix_text,   .pink-affix   { color: #ec3789; }
.blue_affix_text,   .blue-affix   { color: #48a7c9; }
.orange_affix_text, .orange-affix { color: #bf5e1c; }
.red_affix_text,    .red-affix    { color: #be4f47; }
.green_affix_text,  .green-affix  { color: #2f9e4f; }
.event_affix_text,  .event-affix  { color: #2e8f77; }
.unique_affix_text, .unique-affix { color: #775346; }
[data-theme="dark"] .event_affix_text,
[data-theme="dark"] .event-affix { color: #a4ddce; }
[data-theme="dark"] .green_affix_text,
[data-theme="dark"] .green-affix { color: #57c970; }

/* ---- Drops guide bag sections (details/summary, server-rendered) --------------------- */
/* Flat like the crafting groups: heading row over a hairline, no card box. */
details.bag-section { background: transparent; border: none; border-radius: 0; margin-bottom: 4px; }
details.bag-section:hover { border-color: transparent; }
summary.bag-header { list-style: none; border-bottom: 1px solid var(--border); padding: 10px 4px; }
summary.bag-header::-webkit-details-marker { display: none; }
details.bag-section[open] .expand-indicator { transform: rotate(180deg); }
details.bag-section .bag-content { display: block; border-top: none; padding: 0 4px 10px; }
.bag-name { color: var(--text); }
a.bag-name { color: var(--link); }
a.bag-name:hover { color: var(--link-hover); }
.item-entry { background: transparent; }
.item-entry:hover { background: transparent; }
.item-name { color: var(--text); }
a.item-entry .item-name { color: var(--link); }
a.item-entry:hover .item-name { color: var(--link-hover); }
.item-tier, .item-count, .expand-indicator { color: var(--text-muted); }
.tile-ip { color: var(--text-muted); font-size: 12px; font-weight: 400; }

/* Package detail pages */
.package-page-art { max-width: min(420px, 100%); border-radius: 4px; margin: 4px 0 10px; image-rendering: auto; }
.package-retired-badge {
    font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
    color: #b3541e; border: 1px solid currentColor; border-radius: 3px;
    padding: 1px 6px; vertical-align: middle;
}
a.package-title-link { text-decoration: none; }
a.package-title-link .package-title:hover { text-decoration: underline; }
/* "T5 · weapon" kind line under loot entries (same info the drops guide shows). */
.tile-kind { display: block; font-size: 12px; color: var(--text-muted); font-weight: 400; }
a .menu-header .tile-kind { color: var(--text-muted); }
.chest-silver-info {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 12px; color: var(--text-muted);
}

/* ---- Attainments (guides/attainments) ------------------------------------------------ */
.attainment-entry {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    padding: 15px;                          /* no dot indicators server-side */
}
.attainment-entry:hover { background: var(--bg-hover); border-color: var(--border); }
.attainment-name { color: var(--text); font-size: 16px; }
.attainment-description { color: var(--text-muted); }
.attainment-progress { color: var(--text-muted); background: var(--bg-stripe); }
.status-text { color: var(--text); }
.other-reward { color: var(--text-muted); }
/* Reward hues readable on white; dark theme keeps the original bright palette. */
.score-reward { color: #9a8b1e; }
.gold-reward { color: #a8790a; }
/* Only real links go blue; span rewards (no page, e.g. reward chests) read as plain text. */
.item-reward { color: var(--text); }
a.item-reward { color: var(--link); }
a.item-reward:hover { color: var(--link-hover); }
.vault-reward { color: #7a5bc7; }
.class-reward { color: #d4442a; }
.essence-reward { color: #1f9e3d; }
[data-theme="dark"] .score-reward { color: #e8e881; }
[data-theme="dark"] .gold-reward { color: #FFD700; }
[data-theme="dark"] .item-reward { color: var(--text); }
[data-theme="dark"] a.item-reward { color: #87CEEB; }
[data-theme="dark"] .vault-reward { color: #9370DB; }
[data-theme="dark"] .class-reward { color: #FF6347; }
[data-theme="dark"] .essence-reward { color: #32CD32; }
/* Responsive card grid: base.css pinned 350px columns + 350px cards, which overlapped
   once .contentReplace's own grid rules got involved. Cards fill their column instead. */
.attainments-grid {
    grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
    gap: 15px;
    justify-content: stretch;
}
.attainment-entry { width: auto; }
.attainment-details { max-width: none; }
/* All stage/class cards render expanded (the SPA cycled them as a card stack). */
.attainment-stage-stack, .attainment-class-stack { cursor: default; }
.attainment-stage-card.active, .attainment-class-card.active {
    border-top: 1px solid var(--border);
    padding-top: 8px;
    margin-top: 8px;
}
.attainment-stage-stack > .attainment-stage-card.active:first-child,
.attainment-class-stack > .attainment-class-card.active:first-child {
    border-top: none;
    padding-top: 0;
    margin-top: 0;
}
/* Transparent button chrome so the sprite outline hugs the icon, not a gray box. */
.attainment-filter-btn { border: none; padding: 0; background-color: transparent; }
/* Header totals: the SPA's bright yellows disappear into the white theme. */
.text-score { color: #8a7d1a; }
.text-gold { color: #a8790a; }
[data-theme="dark"] .text-score { color: #e8e881; }
[data-theme="dark"] .text-gold { color: #dbc325; }

/* ---- Crafting recipe tables (guides/crafting) ----------------------------------------
   Same flat table language as the affix tables: Trade | NPC arrow | Receive columns,
   hairline row dividers (dashed when a recipe chains from the previous row). */
.crafting-table { display: grid; grid-template-columns: 1fr max-content 1fr; }
.crafting-table.essence-cols { grid-template-columns: 1fr max-content; }
.crafting-table.essence-source-cols { grid-template-columns: 1fr 1fr max-content; }
.crafting-table.crafting-recipe-cols { grid-template-columns: 1fr 1fr max-content; }
.crafting-table.two-col-even { grid-template-columns: 1fr 1fr; }
.essence-section-title { display: flex; align-items: center; gap: 8px; }
.essence-cost-icon { width: 20px; height: 20px; }
.crafting-row { display: contents; }
.crafting-cell {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 6px;
    padding: 10px 12px 10px 0;
    min-width: 0;
}
.crafting-row.crafting-head .crafting-cell { padding: 4px 12px 6px 0; }
.crafting-header-label { color: var(--text-muted); font-size: 14px; }
.crafting-row + .crafting-row .crafting-cell { border-top: 1px solid var(--border); }
.crafting-row.chain-continued .crafting-cell { border-top-style: dashed; }
.crafting-entry { display: flex; align-items: center; gap: 8px; min-width: 0; }
.crafting-entry .crafting-icon { width: 28px; height: 28px; flex-shrink: 0; }
.crafting-name { font-size: 14px; color: var(--text); overflow-wrap: break-word; }
a.crafting-entry .crafting-name { color: var(--link); }
a.crafting-entry:hover .crafting-name { color: var(--link-hover); }
.crafting-affix-label, .crafting-limited { font-size: 12px; color: var(--text-muted); margin-left: 36px; overflow-wrap: break-word; }
.crafting-limited { color: #b3541e; }
[data-theme="dark"] .crafting-limited { color: #e5a15d; }

/* ---- Status effects multiplier matrix --------------------------------------------------
   One grid per effect: a tier header row (I–V) plus a row per series. Values sit in shared
   columns so tiers line up down the whole page. No boxes — Player/Enemy is carried by the
   row label's color, which is all the distinction it ever needed. */
.mult-matrix {
    display: grid;
    grid-template-columns: 44px repeat(var(--levels), 46px);
    gap: 1px 10px;
    align-items: baseline;
    font-family: var(--font-body);
    font-size: 13px;
}
.mult-corner { content: ""; }
.mult-tier {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    text-align: right;
}
.mult-series { padding-right: 2px; font-size: 12px; font-weight: 700; white-space: nowrap; }
.mult-player { color: #1e9e50; }
.mult-enemy { color: #b4632c; }
[data-theme="dark"] .mult-player { color: #81c784; }
[data-theme="dark"] .mult-enemy { color: #d2b48c; }
.mult-value { color: var(--text); text-align: right; font-variant-numeric: tabular-nums; }

/* The table's 0.5rem grid gap is too tight where the numbers meet the prose. Pad the
   description column instead of widening the gap, which would also push Effect apart. */
.class-table.three-col .description-container,
.class-table.three-col .class-row > .class-col-title:nth-child(3) { padding-left: 26px; }
.no-data { color: var(--text-muted); }

/* menus rendered by HtmlContentService (menu-list) — left-aligned with the prose column
   (base.css centered them with the old game-UI layout). */
.content.menu-platform-oriented,
.menu-platform-oriented {
    justify-content: flex-start !important;
    align-items: flex-start;
}
.menu-list .menu-header { font-family: var(--font-body); font-size: 14px; }
.menu-list a.menu-list-header { color: var(--text-heading); font-weight: 700; }

/* Every clickable label in the content area is link-blue. Disabled entries keep their
   muted style via the !important rules above. */
main a .menu-header, main a .link-header {
    color: var(--link);
}
main a:hover .menu-header, main a:hover .link-header {
    color: var(--link-hover);
}

/* ---------- item pages: RealmEye-style stats page ----------------------------------- */

.item-heading { display: flex; align-items: center; gap: 12px; }
.item-heading-icon { flex-shrink: 0; }

.item-flavor {
    font-style: italic;
    color: var(--text-muted);
    margin: 4px 0 12px;
}
/* Game-authored colors: darkened toward black on light, as-authored on dark. */
.desc-c { color: var(--c); color: color-mix(in srgb, var(--c) var(--desc-mix), black); }

/* The stats table (RealmEye label/value style: striped, hairline rows). */
/* 4px to match .affix-selector and the affix dropdown it sits under — bordered surfaces on
   this site are rounded, and the tables were the only ones left square.
   border-collapse must be separate: browsers ignore border-radius on a collapsed table's
   border. With spacing 0 the cells' own border-top still draws each row separator, so the
   only fix-up needed is suppressing it on the first row (it would otherwise double against
   the table's own border). */
.item-table {
    border-collapse: separate;
    border-spacing: 0;
    margin: 10px 0 16px;
    min-width: 380px;
    max-width: 560px;
    width: fit-content;
    border: 1px solid var(--border);
    border-radius: 4px;
}
.item-table tbody tr:first-child > * { border-top: 0; }
.item-table th, .item-table td {
    border-top: 1px solid var(--border);
    padding: 6px 12px;
    text-align: left;
    font-size: 14px;
    vertical-align: middle;
}
.item-table th {
    color: var(--text-muted);
    font-weight: 600;
    width: 130px;
    white-space: nowrap;
}
.item-table tbody tr:nth-child(even) { background: var(--bg-stripe); }
/* Striped row backgrounds are painted by the cells, which don't inherit the table's radius —
   without this the stripes square off the corners the border just rounded. overflow:hidden
   would be the usual trick, but it isn't reliable on display:table. */
.item-table tbody tr:first-child > *:first-child { border-top-left-radius: 4px; }
.item-table tbody tr:first-child > *:last-child { border-top-right-radius: 4px; }
.item-table tbody tr:last-child > *:first-child { border-bottom-left-radius: 4px; }
.item-table tbody tr:last-child > *:last-child { border-bottom-right-radius: 4px; }
.item-table .sprite-icon { display: inline-block; vertical-align: middle; margin-right: 6px; }
.item-table tr.accuracy-row:has(td:empty) { display: none; }
.portal-source-list { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center; }

.prop-line, .effect-line { padding: 1px 0; }
.effect-line { display: flex; align-items: center; gap: 6px; }
.effect-line .effect-icon { margin-right: 0; }

.used-by-link { display: inline-flex; align-items: center; gap: 5px; margin-right: 14px; color: var(--link); }
.used-by-link:hover { color: var(--link-hover); }
.cost-cell { display: inline-flex; align-items: center; gap: 5px; }

.c-heal { color: var(--c-heal); }
.c-barrier { color: var(--c-barrier); }
.c-mana { color: var(--c-mana); }
.c-hpcost { color: var(--c-hpcost); }
.c-reroll { color: var(--c-reroll); }
.stat-green { color: var(--c-stat-green); }
.stat-red { color: var(--c-stat-red); }

/* Tag lines under the table (One Time Use, Divine Object, …). */
.item-tags { margin: 10px 0 16px; }
.item-tag { padding: 1px 0; font-size: 14px; }
.tag-plain { color: var(--text); }
.tag-effect { color: var(--c-effect); }
.tag-divine { color: var(--c-divine); }
.tag-unreleased { color: var(--c-unreleased); font-weight: 700; }
.tag-event-reward { color: var(--c-event-reward); }
.tag-event-item { color: var(--c-event-item); }
.tag-quest { color: var(--c-quest); }
.tag-emote { color: var(--c-emote); }
.tag-title { color: var(--c-title); }
.tag-ability-cost { color: var(--c-ability-cost); }
.tag-crafting { color: var(--c-crafting); }
.tag-free-reroll { color: var(--c-free-reroll); }
.tag-warning { color: var(--c-warning); }
.tag-reanimates { color: var(--c-reanimates); }

/* Affix control: an inline dropdown above the stats table. */
.affix-control {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 12px 0 4px;
    position: relative;
}
.affix-control-label { color: var(--text-muted); font-weight: 600; }
.affix-title-container { display: flex; align-items: center; gap: 6px; order: 2; }
.affix-title-container .sprite-icon-25 { width: 20px; height: 20px; }
/* Selected-affix name sits on the same line as its icon, at body scale (base.css had 24px). */
.affix-title-container .affix-item-label { font-size: 14px; line-height: 20px; }
.affix-options-container {
    position: relative;
    width: auto;
    height: auto;
    top: auto;
    right: auto;
    overflow: visible;
    background: transparent;
    border: none;
    /* Above page content: sprite outlines (filter) create stacking contexts that would
       otherwise paint later icons over the open dropdown. */
    z-index: 60;
}
.affix-selector {
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--input-border);
    border-radius: 4px;
    background: var(--input-bg);
    cursor: pointer;
}
.affix-selector:hover { background: var(--bg-hover); }
.affix-selector .sprite-icon { width: 22px; height: 22px; }
.affix-options-grid {
    display: none;
    position: absolute;
    top: 38px;
    left: 0;
    z-index: 50;
    width: 340px;
    max-height: 320px;
    overflow-y: auto;
    grid-template-columns: 1fr 1fr;
    gap: 2px 8px;
    padding: 8px;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 4px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.affix-options-container.border-fade-in { border: none; }
.affix-options-container.border-fade-in .affix-options-grid { display: grid; }
.affix-div { width: auto; color: var(--text); cursor: pointer; padding: 2px 4px; border-radius: 3px; }
.affix-div:hover { background-color: var(--bg-hover); }
.affix-option { font-size: 13px; }

/* Additional sprites + animation previews. No frame around the group: the sprites carry their
   own outline, so a box just adds a second rectangle around them (the animation previews below
   already sit unframed). */
.item-additional-sprites { margin: 6px 0 16px; width: fit-content; max-width: 100%; overflow-x: auto; }
/* Two fixed rows, flowing across: each column is a normal sprite over its shiny counterpart. */
.item-additional-sprites-grid {
    display: grid;
    grid-template-rows: auto auto;
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    gap: 6px 14px;
    justify-content: start;
}
.item-additional-sprite-entry { display: flex; flex-direction: column; align-items: center; gap: 4px; font-size: 12px; }
.item-additional-sprite-affixes { color: var(--text-faint); font-size: 11px; }

.animation-previews { display: flex; flex-wrap: wrap; gap: 16px; margin: 6px 0 16px; }
.animation-preview { display: flex; flex-direction: column; align-items: center; gap: 4px; font-size: 12px; }
.animation-preview [class*="_animation_"], .animation-preview .sprite-icon-64 {
    width: 64px;
    height: 64px;
    margin: 4px;    /* room for the outline/glow */
}
.animation-label { color: var(--text-muted); }
.corner-border { border-color: var(--border); }

/* ---------- enemy pages ------------------------------------------------------------- */

.wiki-table, .attacks-table {
    border-collapse: separate;        /* see .item-table: collapse defeats border-radius */
    border-spacing: 0;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg-panel);      /* base.css paints these translucent black */
    margin: 8px 0 16px;
    font-size: 14px;
    width: 100%;
}
.wiki-table th, .attacks-table th {
    background: var(--bg-inset);
    color: var(--text-muted);
    font-weight: 600;
    text-align: left;
    padding: 6px 10px;
    border-bottom: 1px solid var(--border);
}
.wiki-table td, .attacks-table td {
    background: transparent;
    color: var(--text);
    padding: 6px 10px;
    border-top: 1px solid var(--border);
    /* base.css still puts a hardcoded #444 border-bottom on these cells from the old
       dark-only design. border-collapse used to merge it with the row below's border-top;
       under border-collapse: separate both would draw, giving every row a doubled dark line. */
    border-bottom: 0;
    vertical-align: middle;
}
.wiki-table tbody tr, .attacks-table tbody tr { background: transparent; }
.wiki-table tbody tr:nth-child(even), .attacks-table tbody tr:nth-child(even) { background: var(--bg-stripe); }
/* The header's border-bottom already separates it from the body, so the first body row must
   not add its border-top on top of that (or against the table border when there's no thead). */
.wiki-table tbody tr:first-child > td, .attacks-table tbody tr:first-child > td { border-top: 0; }
/* Corner cells carry the radius so the header fill and row stripes clip to it. */
.wiki-table thead tr:first-child > *:first-child,
.attacks-table thead tr:first-child > *:first-child { border-top-left-radius: 4px; }
.wiki-table thead tr:first-child > *:last-child,
.attacks-table thead tr:first-child > *:last-child { border-top-right-radius: 4px; }
.wiki-table tbody tr:last-child > *:first-child,
.attacks-table tbody tr:last-child > *:first-child { border-bottom-left-radius: 4px; }
.wiki-table tbody tr:last-child > *:last-child,
.attacks-table tbody tr:last-child > *:last-child { border-bottom-right-radius: 4px; }
.table-wrapper { overflow-x: auto; background: transparent; border-radius: 0; }
.table-wrapper .attacks-table, .table-wrapper .wiki-table { margin: 0 0 16px; }
.projectile-info { display: inline-flex; align-items: center; gap: 6px; }

.drop-badge {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-radius: 3px;
    padding: 1px 5px;
    margin-left: 8px;
    vertical-align: 1px;
}
.drop-contribution { background: var(--c-barrier); color: #fff; }
.drop-soulbound { background: var(--c-quest); color: #fff; }

/* crafting recipe tables */
.relic-container a, a.relic-container { color: var(--link); }
a.relic-container:hover .crafting-header { color: var(--link-hover); }
a.relic-container .crafting-header { color: var(--link); }
div.relic-container .crafting-header { color: var(--text); }
.crafting-header { font-size: 14px; font-family: var(--font-body); }
.crafting-limited { color: var(--c-warning); font-size: 12px; margin-top: 4px; }
.patch-header { cursor: pointer; }
.patch-summary { color: var(--text-muted); }
.patch-notes-list li { color: var(--text); }
.patch-header, .patch-version, .patch-info h2 { color: var(--text-heading); }
.patch-info h2, .patch-version { font-weight: 700; }
.content-collapsible .patch-info h2, .content-collapsible .patch-version { font-size: 16px; }
.content-collapsible .patch-section { border-left: 2px solid var(--border); padding-left: 12px; margin-bottom: 0; }
/* Collapsible sections (crafting groups, patch notes) are fully flat — no card box at
   all, just a heading row over a hairline divider with the content beneath. */
.patch-section {
    background: transparent;
    border: none;
    border-radius: 0;
    margin-bottom: 4px;
}
.patch-header, .patch-header.active {
    background: transparent;
    border-bottom: 1px solid var(--border);
    padding: 10px 4px;
}
.patch-content { padding: 0 4px; }

#regular-essence-container, #event-essence-container {
    margin: 6px 0 0 10px;
    padding-left: 16px;
    border-left: 2px solid var(--border);
}

/* package cards */
.packages-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; margin: 12px 0 20px; }
.package-card { border: 1px solid var(--border); border-radius: 6px; background: var(--bg-panel); overflow: hidden; }
.package-art { width: 100%; height: auto; display: block; image-rendering: auto; }
.package-info { padding: 10px 14px 14px; }
.package-title { margin: 4px 0 6px; font-size: 16px; border: none; }
.package-cost { display: flex; align-items: center; gap: 6px; color: var(--text-muted); font-size: 13px; margin-bottom: 8px; }
.package-contents { display: flex; flex-direction: column; gap: 2px; }
.package-contents .category-container { padding: 2px 0; }
.package-contents .menu-header { font-size: 13px; }
.package-contents a.category-container .menu-header { color: var(--link); }

/* chest blessings/curses + box contents */
.effect-chip { display: inline-block; margin: 1px 3px 1px 0; }
.text-muted { color: var(--text-muted); }
.box-contents-table { width: auto; min-width: 380px; max-width: 560px; }
.box-content-item { display: inline-flex; align-items: center; gap: 8px; color: var(--link); }
a.box-content-item:hover { color: var(--link-hover); }
span.box-content-item { color: var(--text); }

/* /enemies list */
.enemies-filters { display: flex; gap: 10px; margin: 12px 0; flex-wrap: wrap; }
.enemies-filters .search-input { max-width: 260px; }
.enemies-filters .filter-select { width: auto; }
.enemies-count { color: var(--text-muted); }
.enemies-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 2px 12px;
    margin: 10px 0 20px;
}
/* Flat rows, no card box (site-wide no-cards rule) — the radius only shapes the
   hover highlight, and transform:none kills base.css's hover lift. */
a.enemy-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 10px;
    border: none;
    border-radius: 4px;
    background: transparent;
    color: var(--text);
    transform: none;
    /* 545 rows: skip layout/paint for offscreen rows (big memory + scroll win on
       mobile). The intrinsic-size hint keeps the scrollbar from jumping. */
    content-visibility: auto;
    contain-intrinsic-size: auto 64px;
}
a.enemy-card:hover { background: var(--bg-hover); transform: none; }
.enemy-card-sprite { flex-shrink: 0; }
.enemy-card .enemy-name { color: var(--link); font-size: 14px; font-weight: 600; margin-bottom: 2px; }
.enemy-card:hover .enemy-name { color: var(--link-hover); }
.enemy-card .enemy-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
    font-size: 12px;
    color: var(--text-muted);
}
.difficulty-beginner { color: #57c970; }
.difficulty-intermediate { color: #48a7c9; }
.difficulty-experienced { color: #bf9b1c; }
.difficulty-advanced { color: #bf5e1c; }
.difficulty-expert { color: #be4f47; }
.difficulty-endgame { color: #9a3fd5; }

/* Drop sources flow below the table. */
.full-width { width: auto; }
.no-drop-source {
    font-family: var(--font-body);
    font-size: 20px;
    font-weight: 700;
    color: var(--text-heading);
    text-align: left;
    padding-top: 1rem;
    border-bottom: none;
}
.drop-source-grid.contentReplace { grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }
.drop-source-enemy-name { font-family: var(--font-body); font-size: 14px; }
.drop-source-filters { justify-content: flex-start; }

/* ---- Dungeon minimaps ----------------------------------------------------------------- */
.minimap-wrapper { display: flex; flex-direction: column; align-items: center; gap: 8px; margin: 12px 0 20px; }
.minimap-image {
    max-width: min(480px, 100%);
    height: auto;
    image-rendering: pixelated;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg-panel);
}
.minimap-nav { display: flex; align-items: center; gap: 10px; }
.minimap-nav-btn {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text);
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
    padding: 4px 10px;
}
.minimap-nav-btn:hover { background: var(--bg-hover); }
.minimap-counter { color: var(--text-muted); font-size: 13px; }

/* Sprites whose id has no art anywhere (SPA included) render nothing, not a blank box. */
[data-sprite-missing] { display: none !important; }

/* ---------- sprite outlines --------------------------------------------------------- */

/* Every game sprite gets the client's outline/dark-glow treatment: static icons and the
   keyframe-animated frames alike. The filter covers the element's whole rendered subtree,
   so textile overlay layers are outlined together with their host icon. */
.sprite-icon,
[class*="_animation_"] {
    filter: var(--sprite-outline);
}
/* Nested sprite content (e.g. the textile layer inside an icon) must not double-outline. */
.sprite-icon .sprite-icon, .sprite-icon .textile-layer { filter: none; }
/* Framed animation previews paint a real border — the shadow would trace that rectangle,
   not the sprite, so they opt out. */
.corner-border, .sprite-icon.corner-border { filter: none; }

/* ---------- scrollbars -------------------------------------------------------------- */

::-webkit-scrollbar-track { background: var(--scrollbar-track); }
::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

/* ---------- theme toggle ------------------------------------------------------------ */

.theme-toggle {
    width: 32px;
    height: 32px;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--bg-panel);
    color: var(--text);
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.15s ease;
}
.theme-toggle:hover { background: var(--bg-hover); }

/* ---------- accent picker ----------------------------------------------------------- */

.accent-picker { position: relative; flex-shrink: 0; }
.accent-picker-popover {
    display: none;
    position: absolute;
    top: 38px;
    right: 0;
    z-index: 60;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    white-space: nowrap;
}
.accent-picker.open .accent-picker-popover { display: flex; gap: 6px; }
.accent-swatch {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 2px solid transparent;
    cursor: pointer;
    padding: 0;
}
.accent-swatch:hover { transform: scale(1.12); }
.accent-swatch.active { border-color: var(--text); }

/* ====================================================================================
   Page-switch flicker mitigation + mobile layout
   ==================================================================================== */

/* Sidebar touch behavior: vertical panning scrolls the nav itself and never chains
   into (or gets captured by) the page behind it. */
.menu-container {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-y;
}

/* Hamburger + drawer backdrop exist only at the mobile breakpoint. */
.mobile-nav-toggle { display: none; font-size: 18px; }
.nav-backdrop { display: none; }

@media (max-width: 768px) {
    .application-wrapper { width: 100%; }

    /* ---- off-canvas nav drawer ---------------------------------------------------- */
    .menu-container,
    html.nav-collapsed .menu-container {
        width: min(320px, 85vw);
        /* 100vh sits behind iOS Safari's bottom URL bar, hiding the last nav rows.
           dvh tracks the *visible* viewport (older browsers ignore it and keep the
           base.css 100vh); the safe-area pad clears the home-indicator strip. */
        height: 100dvh;
        padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
        /* translate3d keeps the drawer on its own compositor layer — plain translateX
           lets iOS drop to a main-thread (janky/instant) slide under load. */
        transform: translate3d(-105%, 0, 0);
        visibility: hidden;
        transition: transform 0.25s ease, visibility 0.25s ease;
    }
    html.mobile-nav-open .menu-container,
    html.mobile-nav-open.nav-collapsed .menu-container {
        transform: translate3d(0, 0, 0);
        visibility: visible;
        box-shadow: 0 0 40px rgba(0, 0, 0, 0.45);
    }

    /* The desktop icon-rail collapse makes no sense inside a drawer — keep full labels
       even when the user left desktop mode with the rail collapsed. */
    html.nav-collapsed .menu-container .menu-header,
    html.nav-collapsed .wiki-brand-name,
    html.nav-collapsed .menu-container .menu-subcategory { opacity: 1; }
    html.nav-collapsed .wiki-brand-name { max-width: 220px; }
    /* (The section list needs no override here — nothing hides or shrinks it any more.) */
    html.nav-collapsed .wiki-brand { padding: 0 16px; gap: 10px; }
    html.nav-collapsed .menu-container { scrollbar-width: auto; }

    .nav-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.5);
        z-index: 1000;               /* under the drawer (1001), over everything else */
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.25s ease;
    }
    html.mobile-nav-open .nav-backdrop { opacity: 1; pointer-events: auto; }
    html.mobile-nav-open { overflow: hidden; }   /* page scroll locks while the drawer is open */

    /* Drawer slides via transform (width never animates), so the Discord card can be
       fluid again and fill the wider drawer. */
    .discord-widget-card { width: auto; }

    /* ---- page column -------------------------------------------------------------- */
    .page-wrapper {
        width: 100%;
        padding-left: 0;
        /* Flex item: without this it refuses to shrink below its content's min-content
           width (fixed-width tile grids), dragging the topbar past the viewport edge. */
        min-width: 0;
    }

    /* Home/category tile grids: fixed 200px tiles set that min-content width — go fluid. */
    .gridItem { width: auto; max-width: 100%; min-width: 0; }

    .mobile-nav-toggle { display: inline-flex; align-items: center; justify-content: center; }
    .menu-wrapper.topbar { padding: 0 10px; gap: 8px; }
    .topbar .search-container { flex: 1 1 auto; min-width: 0; width: auto; margin-left: 0; }

    /* Content panel goes fluid — desktop pins it against the 240px sidebar
       (width: clamp(300px, 100vw - 288px, …)), which overflows a phone screen. */
    main.tooltip-container.areas, .tooltip-container.areas {
        width: auto;
        max-width: none;
        margin: 8px 8px 16px;
        padding: 8px 14px 28px;
    }

    /* Wide content scrolls in place instead of being clipped at the page edge.
       min-width: 0 matters: min-width BEATS max-width in CSS, so any table with a
       desktop min-width (.item-table is 380px) would ignore the 100% cap and poke
       out of the panel on narrow phones. */
    .tooltip-container.areas table {
        display: block;
        min-width: 0;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .tooltip-container.areas img { max-width: 100%; height: auto; }
    .tooltip-container.areas pre { max-width: 100%; overflow-x: auto; }

    .footer { padding: 12px 16px; }
}


/* Home page logo. Resize with --logo-width; it never exceeds the content column.
   image-rendering stays pixelated because the art is 5-colour pixel art. */
.site-logo {
    --logo-width: 30%;
    display: block;
    margin: 8px auto 4px;
    width: min(var(--logo-width), 100%);
    height: auto;
    image-rendering: pixelated;
}

/* ---- Unreleased grouping --------------------------------------------------------------
   Content the game data ships but hasn't released yet is still listed (the drop tables do
   reference it), but always in a trailing group behind this divider so it never reads as
   something a player can go get today. */
.grid-group-label {
    grid-column: 1 / -1;                    /* full-width inside any .contentReplace grid */
    margin: 16px 0 2px;
    padding-top: 10px;
    border-top: 1px solid var(--border-chrome);
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}
/* A group that starts the grid needs no rule above it. */
.grid-group-label:first-child { margin-top: 0; padding-top: 0; border-top: none; }

tr.table-group-label td {
    padding-top: 16px;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* ---- Nav-icon preview switch -----------------------------------------------------------
   Set by Middleware/NavIcons.cs (?icons=off). Hides the *navigation* icons only — sidebar,
   hub menu lists, and the home/items category grids. Item, skin and enemy icons inside page
   content are data, not chrome, so they stay.

   The collapsed rail is deliberately exempt: it is icon-only by design, so hiding icons there
   would leave an empty strip rather than a fair comparison. */
html.nav-icons-off:not(.nav-collapsed) #mainMenu .category-container > .sprite-icon,
html.nav-icons-off .menu-list .category-container > .sprite-icon,
html.nav-icons-off .contentGrid .category-container > .sprite-icon {
    display: none;
}

/* ---- Home page sections ----------------------------------------------------------------
   The landing page groups every destination by subject (Models/HomeSections.cs). Each group
   is a quiet heading over a dense grid — the heading rule does the separating, so the tiles
   themselves stay flat and card-free like the rest of the site. */
.home-section { margin: 0 0 26px; }
.home-section-title {
    margin: 0 0 6px;
    padding: 0 0 6px;
    border-bottom: 1px solid var(--border-chrome);
    font-family: var(--font-body);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--text-heading);
}
/* The heading's own link keeps the heading color; it is a section label first and a link
   second, so the site-wide blue would over-advertise it. */
.home-section-title a.link { color: inherit; }
.home-section-title a.link:hover { color: var(--link-hover); }

/* Denser than the default tile grid — these are labels, not cards, and the groups read
   better as tight blocks. Equal 1fr tracks plus justify-items:start is what keeps the icons
   in true columns: base.css centers each tile in its track, and since a tile shrink-wraps to
   its label, centering lands "Axes" and "Challenge" at different left edges — which reads as
   tiles scattered at random. */
.home-section .contentGrid {
    grid-template-columns: repeat(auto-fill, minmax(185px, 1fr));
    justify-items: start;
    gap: 10px;
}
