/* Plain stylesheet for the server-rendered player UI. No build step needed. */
:root {
    --bg: #17130f;
    --panel: #221c16;
    --panel-2: #2b231b;
    --line: #3d3226;
    --text: #e9e0d2;
    --muted: #a1937f;
    --accent: #d6a85a;
    --danger: #c0563f;
    --ok: #7ea66a;
    --hp: #b9443a;
    --sp: #4f7fbf;
    --st: #c79a3c;
    --xp: #8e6fc0;
    --rarity-common: #e9e0d2;
    --rarity-uncommon: #8fd17a;
    --rarity-rare: #6fa8f0;
    --rarity-epic: #c08cf2;
    --rarity-legendary: #f59a4e;
}

* { box-sizing: border-box; }

/* Scrollbars in the game's colours instead of the bright system default (mostly visible on Windows desktops).
   Firefox and current Chrome/Edge use scrollbar-width/-color; Safari and older Chromium fall back to ::-webkit-scrollbar. */
:root { --scroll-thumb: #75603f; --scroll-thumb-hover: #a8834c; --scroll-track: rgba(14, 11, 8, 0.6); }
html { scrollbar-color: var(--scroll-thumb) var(--bg); }
* { scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) var(--scroll-track); }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: var(--scroll-track); }
::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 999px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); background-clip: padding-box; }
::-webkit-scrollbar-corner { background: transparent; }
body { margin: 0; background: var(--bg); color: var(--text); font: 15px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif; }
/* Site background: the dragon pattern stays fixed behind the page, darkened so text on it stays readable. */
body::before { content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none; background: linear-gradient(rgba(23, 19, 15, 0.35), rgba(23, 19, 15, 0.55)), url("../images/brand/background.webp") center / cover no-repeat; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 1.6rem; margin: 0.6rem 0 0.2rem; }
h2 { font-size: 1.15rem; margin: 1.4rem 0 0.6rem; color: var(--accent); }
h3 { margin: 0 0 0.3rem; }
p { margin: 0.3rem 0; }

.page { max-width: 960px; margin: 0 auto; padding: 0 16px 48px; }
.muted { color: var(--muted); }
.small { font-size: 0.85rem; }
.warn { color: var(--accent); }
.email-status-ok { color: var(--ok); font-weight: 700; }

.topbar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; padding: 0.8rem 0; border-bottom: 1px solid var(--line); }
.brand { display: inline-flex; align-items: center; gap: 0.45rem; font-weight: 700; font-size: 1.15rem; letter-spacing: 0.05em; text-transform: uppercase; }
.brand:hover { text-decoration: none; }
.brand-emblem { width: 32px; height: 32px; flex: none; }
.nav { display: flex; flex-wrap: wrap; gap: 0.1rem; flex: 1; font-size: 0.875rem; }
.nav a, .nav .locked { padding: 0.3rem 0.65rem; border-radius: 6px; color: var(--text); }
.nav > a, .nav > .locked, .nav-town > a { display: inline-flex; align-items: center; gap: 0.25rem; padding-inline: 0.4rem; white-space: nowrap; }
.nav > span.locked::before { content: "\1F512\FE0E"; font-size: 0.85em; }
.nav-icon { width: 1.25rem; height: 1.25rem; flex: none; color: var(--accent); }
.nav a.active, .nav a:hover { background: var(--panel-2); text-decoration: none; }
/* Dropdowns in the top bar: "Town" (jumps straight to each town service) and "More"
   (language, sound, account …). Click opens them; on desktop "Town" also opens on hover. */
.nav-dropdown { position: relative; display: flex; align-items: center; }
.nav-dropdown-toggle { display: inline-flex; align-items: center; gap: 0.3rem; background: none; border: 0; color: var(--text); cursor: pointer; padding: 0.3rem 0.35rem; border-radius: 6px; font: inherit; line-height: 1.5; }
.nav-dropdown-toggle:hover, .nav-dropdown.open .nav-dropdown-toggle { background: var(--panel-2); }
.nav-dropdown-arrow { display: inline-block; transition: transform 0.15s; }
.nav-dropdown.open .nav-dropdown-arrow { transform: rotate(180deg); }
.nav-town-toggle .nav-dropdown-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.nav-dropdown-list { display: none; position: absolute; top: 100%; left: 0; z-index: 60; min-width: 230px; padding: 0.35rem; gap: 2px; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45); }
.nav-dropdown.open .nav-dropdown-list { display: grid; }
.nav .nav-town-list a, .nav .nav-town-list .locked { display: flex; align-items: center; gap: 0.5rem; white-space: nowrap; }
.nav-more { margin-left: auto; }
.nav-more-toggle { color: var(--muted); }
.nav-more-list { left: auto; right: 0; min-width: 190px; }
.nav-more-list > .btn-link, .nav-more-list > .inline-form > .btn-link { display: block; width: 100%; padding: 0.35rem 0.6rem; border-radius: 6px; text-align: left; color: var(--text); }
.nav-more-list > .inline-form:not(.lang-switch) { display: block; }
.nav-more-list > .btn-link:hover, .nav-more-list > .inline-form > .btn-link:hover:not(:disabled) { background: var(--panel-2); text-decoration: none; }
.nav-more-list > .btn-link.active { font-weight: bold; }
.nav-more-list > .lang-switch { flex-wrap: nowrap; padding-bottom: 0.25rem; margin-bottom: 0.2rem; border-bottom: 1px solid var(--line); }
.nav-more-list > .lang-switch .btn-link { width: auto; color: var(--muted); }
.nav-more-list > .lang-switch .btn-link.active { color: var(--text); }
html:not(.js) .nav-more-toggle { display: none; }
html:not(.js) .nav-more-list { position: static; display: flex; flex-wrap: wrap; min-width: 0; padding: 0; background: none; border: 0; box-shadow: none; }
.town-icon { width: 1.5rem; height: 1.5rem; flex: none; color: var(--accent); }
.town-heading-icon { width: 2.4rem; height: 2.4rem; vertical-align: middle; margin-right: 0.5rem; }
.town-tile-icon { float: right; width: 3.2rem; height: 3.2rem; margin: 0 0 0.3rem 0.6rem; }
.town-tile.locked .town-icon { filter: grayscale(1); }
.badge { display: inline-block; min-width: 1.3em; padding: 0 0.35em; margin-left: 0.2em; border-radius: 99px; background: var(--accent); color: #1b140c; font-size: 0.75rem; text-align: center; }
.progress-board-badge { display: inline-flex; align-items: center; padding: 0.15rem 0.55rem; border-radius: 99px; background: var(--ok); color: #10160d; font-size: 0.8rem; font-weight: 700; white-space: nowrap; }
.progress-board-badge:hover { text-decoration: none; filter: brightness(1.1); }
.progress-board h2 { margin-top: 0; }
.progress-board-row { display: grid; grid-template-columns: minmax(8rem, 0.9fr) 2fr auto; gap: 0.5rem 0.8rem; align-items: center; padding: 0.45rem 0; border-top: 1px solid var(--line); color: var(--text); }
.progress-board-row:first-of-type { border-top: 0; }
.progress-board-row:hover { text-decoration: none; background: var(--panel-2); }
.progress-board-name { font-weight: 600; }
.progress-board-detail { color: var(--muted); font-size: 0.88rem; }
.progress-board-status { text-align: right; white-space: nowrap; }
@media (max-width: 600px) {
    .progress-board-row { grid-template-columns: 1fr auto; }
    .progress-board-detail { grid-column: 1 / -1; }
}
.topbar-menu { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.6rem; flex: 1; }
.btn.menu-toggle { display: none; align-items: center; gap: 0.45rem; margin-left: auto; }
.menu-toggle-icon, .menu-toggle-icon::before, .menu-toggle-icon::after { display: block; width: 1.1rem; height: 2px; border-radius: 1px; background: currentColor; transition: transform 0.15s ease; }
.menu-toggle-icon { position: relative; }
.menu-toggle-icon::before, .menu-toggle-icon::after { content: ""; position: absolute; left: 0; }
.menu-toggle-icon::before { top: -6px; }
.menu-toggle-icon::after { top: 6px; }
.menu-open .menu-toggle-icon { background: transparent; }
.menu-open .menu-toggle-icon::before { transform: translateY(6px) rotate(45deg); }
.menu-open .menu-toggle-icon::after { transform: translateY(-6px) rotate(-45deg); }
/* Mobile: compact header with logo + menu button, links collapse behind it.
   The open menu is an icon grid (4 per row), town services fold out below it and the
   rest (language, sound, account …) is one small row of links at the bottom.
   Without JavaScript the full bar stays visible. */
@media (max-width: 800px) {
    .topbar { flex-wrap: nowrap; padding: 0.6rem 0; position: relative; }
    .js .btn.menu-toggle { display: inline-flex; }
    .js .topbar-menu { display: none; }
    .js .menu-open { flex-wrap: wrap; }
    .js .menu-open .topbar-menu { display: flex; flex-direction: column; align-items: stretch; flex-basis: 100%; gap: 0.5rem; padding-top: 0.6rem; }
    .js .menu-open .nav { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.3rem; }
    .js .menu-open .nav > a, .js .menu-open .nav > .locked, .js .menu-open .nav-town > a, .js .menu-open .nav-town > .locked {
        position: relative; flex-direction: column; justify-content: center; gap: 0.15rem; min-width: 0; padding: 0.5rem 0.2rem 0.4rem;
        background: var(--panel-2); font-size: 0.8rem; line-height: 1.2; text-align: center; overflow-wrap: anywhere;
    }
    .js .menu-open .nav-icon { width: 1.6rem; height: 1.6rem; }
    .js .menu-open .nav > a.active, .js .menu-open .nav-town > a.active { box-shadow: inset 0 0 0 1px var(--accent); }
    .js .menu-open .nav .badge { position: absolute; top: 0.2rem; right: 0.2rem; margin: 0; }
    .js .menu-open .nav .locked::before { position: absolute; top: 0.2rem; left: 0.3rem; font-size: 0.7rem; }
    .js .menu-open .nav-town { display: contents; }
    .js .menu-open .nav-town-toggle { order: 1; grid-column: 1 / -1; justify-content: space-between; padding: 0.4rem 0.7rem; background: var(--panel-2); color: var(--muted); font-size: 0.88rem; }
    .js .menu-open .nav-town-toggle .nav-dropdown-label { position: static; width: auto; height: auto; overflow: visible; clip-path: none; }
    .js .menu-open .nav-town-list { order: 2; position: static; grid-column: 1 / -1; grid-template-columns: repeat(3, minmax(0, 1fr)); min-width: 0; padding: 0; background: none; border: 0; box-shadow: none; gap: 0.3rem; }
    .js .menu-open .nav .nav-town-list a, .js .menu-open .nav .nav-town-list .locked {
        position: relative; flex-direction: column; justify-content: center; gap: 0.15rem; min-width: 0; padding: 0.4rem 0.2rem;
        background: var(--panel-2); font-size: 0.75rem; line-height: 1.2; text-align: center; white-space: normal; overflow-wrap: anywhere; hyphens: auto;
    }
    .js .menu-open .nav-more { display: block; margin: 0; padding-top: 0.4rem; border-top: 1px solid var(--line); }
    .js .menu-open .nav-more-toggle { display: none; }
    .js .menu-open .nav-more-list { position: static; display: flex; flex-wrap: wrap; align-items: center; gap: 0.1rem 0.2rem; min-width: 0; padding: 0; background: none; border: 0; box-shadow: none; }
    .js .menu-open .nav-more-list > .btn-link, .js .menu-open .nav-more-list > .inline-form > .btn-link { width: auto; padding: 0.35rem 0.45rem; color: var(--muted); font-size: 0.88rem; }
    .js .menu-open .nav-more-list > .lang-switch { margin: 0 0.3rem 0 0; padding: 0 0.4rem 0 0; border-bottom: 0; border-right: 1px solid var(--line); }
}
/* Desktop: the game menu is a fixed column on the left (like Shakes & Fidget), the game
   screen sits to its right. Town services and "More" unfold inside the column instead of
   floating; town services start open on town pages. Phones keep the burger menu above. */
@media (min-width: 801px) {
    .page.has-sidebar { max-width: 1180px; display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 0 1.5rem; align-items: start; }
    .has-sidebar .topbar { position: sticky; top: 0; flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 0.7rem; max-height: 100vh; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; padding: 1rem 0; border-bottom: 0; scrollbar-color: transparent transparent; }
    /* The sidebar only scrolls when the menu is taller than the window; its scrollbar stays invisible until the mouse is on it. */
    .has-sidebar .topbar:hover, .has-sidebar .topbar:focus-within { scrollbar-color: var(--scroll-thumb) transparent; }
    .has-sidebar .topbar::-webkit-scrollbar-track { background: transparent; }
    .has-sidebar .topbar::-webkit-scrollbar-thumb { background: transparent; }
    .has-sidebar .topbar:hover::-webkit-scrollbar-thumb { background: var(--scroll-thumb); background-clip: padding-box; }
    .has-sidebar .brand { padding: 0 0.3rem; }
    .has-sidebar .progress-board-badge { align-self: flex-start; }
    .has-sidebar .topbar-menu { flex: none; flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 0.7rem; }
    .has-sidebar .nav { flex: none; flex-direction: column; flex-wrap: nowrap; gap: 4px; font-size: 0.92rem; }
    .has-sidebar .nav > a, .has-sidebar .nav > .locked, .has-sidebar .nav-town > a {
        display: flex; gap: 0.55rem; padding: 0.45rem 0.6rem; border: 1px solid var(--line); border-radius: 6px;
        background: linear-gradient(180deg, var(--panel-2), var(--panel)); font-weight: 600;
    }
    .has-sidebar .nav > a:hover, .has-sidebar .nav-town > a:hover { border-color: var(--muted); background: var(--panel-2); }
    .has-sidebar .nav > a.active, .has-sidebar .nav-town > a.active { border-color: var(--accent); background: var(--panel-2); box-shadow: inset 3px 0 0 var(--accent); }
    .has-sidebar .nav .badge { margin-left: auto; }
    .has-sidebar .nav-town { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px; }
    .has-sidebar .nav-town-toggle { align-self: stretch; padding: 0 0.55rem; border: 1px solid var(--line); background: var(--panel); color: var(--muted); }
    .has-sidebar .nav-town-list { grid-column: 1 / -1; position: static; min-width: 0; padding: 0 0 0.2rem 0.7rem; background: none; border: 0; box-shadow: none; }
    .has-sidebar .nav .nav-town-list a, .has-sidebar .nav .nav-town-list .locked { padding: 0.25rem 0.5rem; font-size: 0.86rem; white-space: normal; }
    .has-sidebar .nav-town-list .town-icon { width: 1.25rem; height: 1.25rem; }
    .has-sidebar .nav-more { display: block; margin: 0; padding-top: 0.5rem; border-top: 1px solid var(--line); }
    .has-sidebar .nav-more-toggle { width: 100%; justify-content: space-between; }
    .has-sidebar .nav-more-list { position: static; min-width: 0; padding: 0.2rem 0 0; background: none; border: 0; box-shadow: none; }
}
@media (prefers-reduced-motion: reduce) { .menu-toggle-icon::before, .menu-toggle-icon::after, .nav-dropdown-arrow { transition: none; } }

.status { display: grid; grid-template-columns: 1fr 2fr 1fr; gap: 1rem; align-items: center; padding: 0.8rem 0; border-bottom: 1px solid var(--line); }
.status .who { display: flex; flex-direction: column; }
.status .right { text-align: right; }
.bars { display: grid; grid-template-columns: 1fr 1fr; gap: 0.3rem 1rem; }
.stat { display: flex; flex-direction: column; font-size: 0.8rem; }
.stat.wide { max-width: 420px; margin: 0.3rem 0; }
.meter { display: block; height: 7px; border-radius: 4px; background: #0e0b08; overflow: hidden; }
.meter b { display: block; height: 100%; }
.meter.hp b { background: var(--hp); }
.meter.sp b { background: var(--sp); }
.meter.st b { background: var(--st); }
.meter.xp b { background: var(--xp); }
.cooldown { color: var(--accent); font-size: 0.85rem; }
.ready { color: var(--ok); font-size: 0.85rem; }

.flash { margin: 0.8rem 0; padding: 0.6rem 0.8rem; border-radius: 6px; border: 1px solid var(--line); }
.flash-ok { border-color: var(--ok); background: #1f2a1a; }
.flash-err { border-color: var(--danger); background: #2e1a15; }
.flash-info { border-color: var(--accent); background: #2a2216; }

.card { display: block; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 0.8rem 1rem; margin: 0.6rem 0; color: var(--text); }
.card.dead { opacity: 0.45; }
.battle-defeated { padding: 0.4rem 1rem; }
.battle-defeated summary { cursor: pointer; color: var(--muted); }
.battle-defeated p { margin: 0.3rem 0 0; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 0.6rem; }
.grid .card { margin: 0; }
.player-stats { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); margin: 0.6rem 0; }
.player-presence { display: flex; align-items: center; gap: 0.4rem; }
.presence-dot { width: 0.55rem; height: 0.55rem; border-radius: 50%; background: var(--muted); flex: none; }
.presence-dot.is-online { background: var(--ok); box-shadow: 0 0 0 2px rgba(126, 166, 106, 0.25); }
.tile { border-left: 4px solid var(--accent); }
.tile:hover { background: var(--panel-2); text-decoration: none; }
.tile strong { display: block; font-size: 1.05rem; }
.tile p { color: var(--muted); font-size: 0.9rem; }
.tutorial { border-color: var(--accent); }
/* Story tutorial: what the current quest is about glows, what it has not opened yet is greyed out. */
.tutorial-focus { outline: 2px solid var(--accent); outline-offset: 2px; animation: tutorial-pulse 1.6s ease-in-out infinite; }
.nav .locked, .tile.locked, .row > .locked { opacity: 0.45; cursor: not-allowed; }
.nav .locked::before, .tile.locked strong::before, .row > .locked::before { content: "\1F512\FE0E  "; }
@keyframes tutorial-pulse { 50% { outline-color: transparent; } }
@media (prefers-reduced-motion: reduce) { .tutorial-focus { animation: none; } }
.log ol, ol.log { margin: 0; padding-left: 1.4rem; font-size: 0.88rem; }
.log summary { cursor: pointer; color: var(--accent); }
.log li.log-loot { color: #b98cff; font-weight: 600; }
.log li.log-lumiis { color: #6fd3ff; font-weight: 600; }
.boss-sigil-stat span { color: #b98cff; }

/* Manual fight: player on the left, combat log in the middle, enemies on the right. */
.battle-layout { display: grid; grid-template-columns: minmax(170px, 210px) minmax(0, 1fr) minmax(230px, 300px); gap: 0.8rem; align-items: start; }
.battle-layout > * { min-width: 0; }
.battle-layout h2 { margin-top: 0.2rem; }
.battle-unit { position: relative; overflow: visible; }
.battle-log-column .log { max-height: 460px; overflow-y: auto; }
.damage-float {
    position: absolute;
    left: 50%;
    top: 22%;
    z-index: 5;
    font-size: 1.55rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0.02em;
    white-space: nowrap;
    pointer-events: none;
    text-shadow: 0 2px 6px rgba(0, 0, 0, 0.85), 0 0 12px rgba(0, 0, 0, 0.5);
    animation: damage-rise 1.5s ease-out both;
    animation-delay: var(--delay, 0s);
}
.damage-dealt { color: #f5c542; }
.damage-taken { color: #e25845; }
.damage-crit { font-size: 1.35em; color: #ffd75e; text-shadow: 0 2px 6px rgba(0, 0, 0, 0.85), 0 0 12px rgba(255, 196, 66, 0.8); }
/* Piercing hits ignore defence: the number gets a cold steel-blue edge. */
.damage-pierce { text-shadow: 0 2px 6px rgba(0, 0, 0, 0.85), 0 0 10px rgba(120, 210, 255, 0.85); }
.damage-crit.damage-pierce { text-shadow: 0 2px 6px rgba(0, 0, 0, 0.85), 0 0 12px rgba(255, 196, 66, 0.8), 0 0 4px rgba(120, 210, 255, 0.9); }
@keyframes damage-rise {
    0% { opacity: 0; transform: translate(-50%, 12px) scale(0.7); }
    18% { opacity: 1; transform: translate(-50%, 0) scale(1.05); }
    65% { opacity: 1; transform: translate(-50%, -22px) scale(1); }
    100% { opacity: 0; transform: translate(-50%, -44px) scale(1.12); }
}
@media (prefers-reduced-motion: reduce) {
    .damage-float { animation: none; opacity: 1; transform: translateX(-50%); }
}
/* Poison and burn: bubbles or flames rise over the hit card, the card glows, the number is coloured. */
.damage-poison { color: #8ee05a; }
.damage-burn { color: #ff8a3d; }
.status-fx {
    position: absolute;
    inset: 0;
    z-index: 4;
    overflow: hidden;
    border-radius: inherit;
    pointer-events: none;
}
.status-fx i {
    position: absolute;
    bottom: -14px;
    left: 50%;
    opacity: 0;
    animation: status-rise 1.5s ease-out both;
    animation-delay: calc(var(--delay, 0s) + var(--offset, 0s));
}
.status-fx i:nth-child(1) { left: 12%; --offset: 0s; --drift: 6px; }
.status-fx i:nth-child(2) { left: 32%; --offset: 0.18s; --drift: -8px; }
.status-fx i:nth-child(3) { left: 52%; --offset: 0.06s; --drift: 4px; }
.status-fx i:nth-child(4) { left: 70%; --offset: 0.26s; --drift: -5px; }
.status-fx i:nth-child(5) { left: 88%; --offset: 0.12s; --drift: 7px; }
.status-fx-poison i {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #e6ffcc 0 18%, #7bd44a 45%, #2f7d1f 100%);
    box-shadow: 0 0 6px rgba(120, 220, 70, 0.75);
}
.status-fx-poison i:nth-child(even) { width: 7px; height: 7px; }
.status-fx-burn i {
    width: 12px;
    height: 18px;
    border-radius: 50% 50% 45% 45% / 65% 65% 35% 35%;
    background: radial-gradient(ellipse at 50% 75%, #fff2a8 0 20%, #ffb53d 45%, #e2401c 85%);
    box-shadow: 0 0 8px rgba(255, 120, 40, 0.8);
    animation-name: status-flame;
}
.status-fx-burn i:nth-child(even) { width: 9px; height: 13px; }
@keyframes status-rise {
    0% { opacity: 0; transform: translate(0, 0) scale(0.5); }
    15% { opacity: 0.95; }
    70% { opacity: 0.85; transform: translate(var(--drift, 0px), -62px) scale(1); }
    100% { opacity: 0; transform: translate(calc(var(--drift, 0px) * 2), -96px) scale(1.25); }
}
@keyframes status-flame {
    0% { opacity: 0; transform: translate(0, 0) scale(0.6, 0.5); }
    15% { opacity: 1; transform: translate(0, -10px) scale(1, 1.1); }
    35% { transform: translate(var(--drift, 0px), -30px) scale(0.85, 1.2); }
    55% { opacity: 0.9; transform: translate(0, -48px) scale(1.05, 0.95); }
    100% { opacity: 0; transform: translate(var(--drift, 0px), -80px) scale(0.4, 0.6); }
}
.status-hit-poison { animation: status-glow-poison 1.6s ease-out both; }
.status-hit-burn { animation: status-glow-burn 1.6s steps(8, end) both; }
.status-hit-poison.status-hit-burn { animation: status-glow-poison 1.6s ease-out both, status-glow-burn 1.6s steps(8, end) 0.4s both; }
@keyframes status-glow-poison {
    0%, 100% { box-shadow: none; }
    25%, 60% { box-shadow: inset 0 0 0 2px #6cc23f, 0 0 16px rgba(108, 194, 63, 0.55); }
}
@keyframes status-glow-burn {
    0%, 100% { box-shadow: none; }
    20%, 50% { box-shadow: inset 0 0 0 2px #ff7a2f, 0 0 18px rgba(255, 110, 40, 0.6); }
    35%, 65% { box-shadow: inset 0 0 0 2px #ffb347, 0 0 10px rgba(255, 170, 60, 0.45); }
}
/* The replay fighters are small emoji boxes: let bubbles and flames rise above them. */
.series-replay-fighter .status-fx { overflow: visible; inset: -6px; }
.series-replay-fighter .damage-float { font-size: 1rem; top: 45%; left: 135%; }
/* Critical hit: a short golden starburst with a ring on the card. Piercing hit: a bright streak through it. */
.hit-fx {
    position: absolute;
    inset: 0;
    z-index: 4;
    overflow: hidden;
    border-radius: inherit;
    pointer-events: none;
}
.hit-fx i { position: absolute; display: block; }
.hit-fx-crit { animation: hit-crit-ring 0.6s ease-out both; animation-delay: var(--delay, 0s); }
.hit-fx-crit i {
    left: 50%;
    top: 28%;
    width: 96px;
    height: 96px;
    margin: -48px 0 0 -48px;
    border-radius: 50%;
    background: repeating-conic-gradient(rgba(255, 220, 110, 0.9) 0 7deg, transparent 7deg 30deg);
    -webkit-mask: radial-gradient(circle, #000 0 18%, rgba(0, 0, 0, 0.6) 40%, transparent 70%);
    mask: radial-gradient(circle, #000 0 18%, rgba(0, 0, 0, 0.6) 40%, transparent 70%);
    opacity: 0;
    animation: hit-crit-burst 0.55s ease-out both;
    animation-delay: var(--delay, 0s);
}
.hit-fx-pierce i {
    left: -10%;
    top: 46%;
    width: 120%;
    height: 3px;
    border-radius: 3px;
    background: linear-gradient(90deg, transparent, rgba(160, 225, 255, 0.95) 45%, #fff 60%, transparent);
    box-shadow: 0 0 8px rgba(120, 210, 255, 0.8);
    opacity: 0;
    transform-origin: center;
    animation: hit-pierce-streak 0.45s ease-out both;
    animation-delay: calc(var(--delay, 0s) + 0.05s);
}
@keyframes hit-crit-burst {
    0% { opacity: 0; transform: scale(0.3) rotate(0deg); }
    25% { opacity: 1; }
    100% { opacity: 0; transform: scale(1.35) rotate(25deg); }
}
@keyframes hit-crit-ring {
    0%, 100% { box-shadow: none; }
    25% { box-shadow: inset 0 0 0 2px #ffd75e, 0 0 14px rgba(255, 200, 70, 0.55); }
}
@keyframes hit-pierce-streak {
    0% { opacity: 0; transform: rotate(-16deg) translateX(-70%) scaleX(0.4); }
    30% { opacity: 1; }
    100% { opacity: 0; transform: rotate(-16deg) translateX(70%) scaleX(1); }
}
.series-replay-fighter .hit-fx { overflow: visible; }
.series-replay-fighter .hit-fx-crit i { width: 64px; height: 64px; margin: -32px 0 0 -32px; top: 50%; }
@media (prefers-reduced-motion: reduce) {
    .hit-fx { display: none; }
}
.duel-replay-fighter { border-radius: 8px; }
.log-poison { color: #a6e57d; }
/* Group fight log: the damage of a hit as a small bold badge after the line. */
.log-damage { display: inline-block; margin-left: 0.3rem; padding: 0 0.3rem; border-radius: 999px; font-weight: 800; }
.log-damage-dealt { color: #f5c542; background: rgba(245, 197, 66, 0.14); }
.log-damage-taken { color: #e25845; background: rgba(226, 88, 69, 0.14); }
.group-fight-damage { display: block; margin-top: 0.2rem; }
.log-burn { color: #ffab70; }
.status-chips { display: inline-flex; flex-wrap: wrap; gap: 0.3rem; margin-left: 0.25rem; vertical-align: middle; }
.status-chip {
    display: inline-block;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    font-size: 0.75rem;
    line-height: 1.5;
    white-space: nowrap;
}
.status-chip-poison { background: rgba(108, 194, 63, 0.16); border: 1px solid rgba(108, 194, 63, 0.6); color: #a6e57d; }
.status-chip-burn { background: rgba(255, 122, 47, 0.16); border: 1px solid rgba(255, 122, 47, 0.6); color: #ffab70; }
@media (prefers-reduced-motion: reduce) {
    .status-fx { display: none; }
    .status-hit-poison, .status-hit-burn, .status-hit-poison.status-hit-burn { animation: none; }
    .status-hit-poison { box-shadow: inset 0 0 0 2px #6cc23f; }
    .status-hit-burn { box-shadow: inset 0 0 0 2px #ff7a2f; }
}
@media (max-width: 800px) {
    .battle-layout { grid-template-columns: 1fr; }
    .battle-player { order: 1; }
    .battle-enemies { order: 2; }
    .battle-log-column { order: 3; }
    .battle-log-column .log { max-height: none; }
}
/* Finished manual fight: one last look at both sides, then continue. */
.battle-result-banner { border-width: 2px; }
.battle-result-victory { border-color: var(--ok); }
.battle-result-defeat { border-color: var(--danger); }
.battle-result-victory h1 { color: var(--ok); }
.battle-result-defeat h1 { color: var(--danger); }
.battle-result-actions { margin-top: 1rem; }
.bonus { color: var(--ok); }
.compare { margin-top: 0.2em; }
.delta-up { color: var(--ok); }
.delta-down { color: var(--danger); }
.missing { color: var(--danger); font-weight: 600; }
.inventory-filter { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: flex-end; margin: 0.5rem 0 0.75rem; }
.inventory-filter label { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.78rem; color: var(--muted); }
.inventory-filter select { min-width: 9rem; }
.series-filter { display: flex; flex-wrap: wrap; gap: 0.35rem 0.6rem; align-items: center; margin: 0.35rem 0; max-width: min(28rem, 100%); }
.series-filter label { display: inline-flex; gap: 0.25rem; align-items: center; }
ul.plain { padding-left: 1.2rem; }

.row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.4rem 0; }
.inline-form { display: inline-flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; margin: 0; }
.stack { display: flex; flex-direction: column; gap: 0.6rem; max-width: 320px; }
.stack label { display: flex; flex-direction: column; gap: 0.2rem; }

.btn { display: inline-block; padding: 0.4rem 0.8rem; border-radius: 6px; border: 1px solid var(--line); background: var(--panel-2); color: var(--text); font: inherit; cursor: pointer; }
.btn:hover:not(:disabled) { border-color: var(--accent); text-decoration: none; }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #1b140c; font-weight: 600; }
.btn-danger { border-color: var(--danger); color: #f0b4a6; }
.btn-link { background: none; border: none; color: var(--muted); padding: 0.3rem; }
.lang-switch .btn-link.active { color: var(--text, inherit); font-weight: bold; cursor: default; }

input, select { padding: 0.35rem 0.5rem; border-radius: 6px; border: 1px solid var(--line); background: #120f0c; color: var(--text); font: inherit; }
input.qty { width: 4.5rem; }

.table { width: 100%; border-collapse: collapse; margin: 0.4rem 0; }
.table th, .table td { padding: 0.45rem 0.5rem; border-bottom: 1px solid var(--line); text-align: left; vertical-align: middle; }
/* .row is a flex box; on a table cell that would drop it out of the table layout, so the
   cell's border and height no longer line up with its row. Keep the cell, space the buttons. */
.table td.row { display: table-cell; }
.table td.row > * { margin: 0.2rem 0.4rem 0.2rem 0; }
/* Bonus workshop reroll: soul anchor select on top, button underneath, never wider than the cell. */
.bonus-reroll { max-width: 100%; }
.bonus-reroll .inline-form { display: flex; flex-direction: column; align-items: flex-start; }
.bonus-reroll select { width: 100%; max-width: 22rem; min-width: 0; text-overflow: ellipsis; }
.table th { color: var(--muted); font-weight: 600; font-size: 0.85rem; }
.table tr.locked td { color: var(--muted); }
.table tr.own td { background: #2a2216; color: var(--accent); font-weight: 600; }
.pager { display: flex; gap: 1rem; align-items: center; justify-content: center; margin-top: 0.6rem; }

@media (max-width: 640px) {
    .status { grid-template-columns: 1fr; }
    .status .right { text-align: left; }
    .table { display: block; overflow-x: auto; }
}

.tabs { display: flex; flex-wrap: wrap; gap: 0.25rem; margin: 0.8rem 0; border-bottom: 1px solid var(--line); padding-bottom: 0.4rem; }
.tabs a { padding: 0.3rem 0.65rem; border-radius: 6px; color: var(--text); }
.tabs a.active, .tabs a:hover { background: var(--panel-2); text-decoration: none; }
.tile span { display: block; }
.tile .tile-inline span, .tile .tile-inline strong { display: inline; font-size: inherit; }
.tile .countdown { display: inline; }

/* Elite packs: small badge on region paths, map tiles and enemy names. */
.elite-badge { display: inline-block; padding: 0 0.35rem; border: 1px solid var(--accent); border-radius: 4px; color: var(--accent); font-size: 0.75rem; font-weight: 600; letter-spacing: 0.02em; }
.tile .tile-inline .elite-badge { display: inline-block; font-size: 0.75rem; }

/* Main story: quest log section and NPC dialog boxes. */
.card.story { border-left: 3px solid var(--xp); }
.story-quest + .story-quest { border-top: 1px solid var(--line); margin-top: 0.6rem; padding-top: 0.6rem; }
.story input[name="answer"] { background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 4px; padding: 0.3rem 0.5rem; }

/* Account page. */
.account-head { justify-content: space-between; align-items: center; }
.account-locale { display: flex; flex-direction: column; gap: 0.3rem; border: 1px solid var(--line); border-radius: 6px; padding: 0.5rem 0.7rem; margin: 0; }
.account-locale legend { color: var(--muted); padding: 0 0.3rem; }
.account-danger { border-color: var(--danger); }
.account-danger summary { cursor: pointer; color: #f0b4a6; }
.stack input[type="email"], .stack input[type="password"] { width: 100%; }

/* Attribute tooltips on the character page: hover on desktop, tap (focus) on mobile. */
.stat-tip { position: relative; display: inline-flex; align-items: center; gap: 0.3em; cursor: help; outline: none; }
.stat-tip-icon { display: inline-block; width: 1.1em; height: 1.1em; border: 1px solid var(--muted); border-radius: 50%; color: var(--muted); font-size: 0.7rem; line-height: 1.05em; text-align: center; }
.stat-tip-box { display: none; position: absolute; left: 0; top: calc(100% + 4px); z-index: 80; width: max-content; max-width: min(280px, 80vw); padding: 0.5rem 0.7rem; background: var(--panel-2); border: 1px solid var(--accent); border-radius: 6px; color: var(--text); font-size: 0.85rem; font-weight: normal; line-height: 1.4; flex-direction: column; gap: 0.15rem; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); }
.stat-tip-box strong { color: var(--accent); }
.stat-tip:hover .stat-tip-box, .stat-tip:focus .stat-tip-box, .stat-tip:focus-within .stat-tip-box { display: flex; }
.stat-tip:focus-visible .stat-tip-icon { border-color: var(--accent); color: var(--accent); }
.stat-drop { position: relative; }
.stat-drop > summary { display: inline-flex; align-items: center; gap: 0.3em; cursor: pointer; list-style: none; }
.stat-drop > summary::-webkit-details-marker { display: none; }
.stat-drop[open] > summary .stat-tip-icon { border-color: var(--accent); color: var(--accent); }
.stat-drop-box { margin-top: 0.35rem; padding: 0.5rem 0.7rem; background: var(--panel-2); border: 1px solid var(--accent); border-radius: 6px; font-size: 0.85rem; line-height: 1.4; max-width: min(340px, 85vw); }
.stat-drop-box strong { color: var(--accent); }
.stat-drop-box ul { margin: 0.25rem 0 0; padding-left: 1.1rem; }
.collapsible > summary { cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.collapsible > summary::-webkit-details-marker { display: none; }
.collapsible > summary h2, .collapsible > summary h3 { margin: 0; }
.collapse-toggle { font-size: 0.75rem; padding: 0.1rem 0.5rem; border: 1px solid var(--muted); border-radius: 999px; color: var(--muted); white-space: nowrap; }
.collapsible > summary:hover .collapse-toggle, .collapsible > summary:focus-visible .collapse-toggle { border-color: var(--accent); color: var(--accent); }
.collapsible:not([open]) .collapse-toggle .when-open, .collapsible[open] .collapse-toggle .when-closed { display: none; }

/* Item rarity colours (ItemRarityCatalog). The tier name is also in the title and for screen readers. */
.item-name { font-weight: 500; }
.rarity-common { color: var(--rarity-common); }
.rarity-uncommon { color: var(--rarity-uncommon); }
.rarity-rare { color: var(--rarity-rare); }
.rarity-epic { color: var(--rarity-epic); }
.rarity-legendary { color: var(--rarity-legendary); }
.flash-rare { background: #241c2c; border-color: var(--rarity-epic); }
.flash-rare.rarity-border-legendary { background: #2c2016; border-color: var(--rarity-legendary); }
.loot-list { display: inline; margin: 0; padding: 0; list-style: none; }
.loot-list li { display: inline; }
.loot-list li + li::before { content: ", "; color: var(--muted); }
.loot-rows { margin: 0.3rem 0 0; padding: 0; list-style: none; display: grid; gap: 0.45rem; }
.loot-row-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem 0.6rem; }
.loot-row-head .btn { padding: 0.2rem 0.7rem; }
.loot-values summary { cursor: pointer; color: var(--muted); width: max-content; }
.loot-values[open] { padding: 0.4rem 0.6rem; margin-top: 0.25rem; background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; }
.loot-values .item-tooltip {
    display: block; position: static; width: auto; max-width: none; padding: 0; margin: 0.3rem 0 0;
    background: none; border: 0; box-shadow: none; pointer-events: auto; font-size: 0.85rem;
}
.loot-values .item-tooltip .tt-head { display: none; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.item-icon { display: inline-block; width: 1.35em; height: 1.35em; margin-right: 0.3em; vertical-align: -0.2em; fill: currentColor; }
.ally-unit { border-left: 3px solid var(--ok); }
.ally-unit.defeated { opacity: 0.55; }

/* 10-pack series replay (resources/js/series-replay.js): plays back already decided fights. */
.series-replay { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; padding: 1rem; background: rgba(0, 0, 0, 0.7); }
.series-replay-box { max-height: calc(100vh - 2rem); overflow-y: auto; width: min(440px, 100%); padding: 1rem 1.1rem; background: var(--panel); border: 1px solid var(--accent); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6); display: flex; flex-direction: column; gap: 0.6rem; }
.series-replay-head { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; }
.series-replay-counter { font-variant-numeric: tabular-nums; color: var(--accent); font-weight: 600; }
.series-replay-dots { display: flex; gap: 0.3rem; margin: 0; padding: 0; list-style: none; }
.series-replay-dot { flex: 1; height: 0.45rem; border-radius: 999px; background: var(--panel-2); border: 1px solid var(--muted); }
.series-replay-dot.current { border-color: var(--accent); animation: series-pulse 0.9s ease-in-out infinite alternate; }
.series-replay-dot.won { background: #3f8f4f; border-color: #3f8f4f; }
.series-replay-dot.lost { background: #a33a3a; border-color: #a33a3a; }
.series-replay-arena { display: flex; align-items: center; justify-content: center; gap: 1.2rem; height: 4.5rem; font-size: 2.3rem; overflow: hidden; }
.series-replay-clash { font-size: 1.6rem; opacity: 0.35; }
.series-replay-arena.fighting .series-replay-player { animation: series-lunge-right 0.7s ease-in-out infinite; }
.series-replay-arena.fighting .series-replay-enemy { animation: series-lunge-left 0.7s ease-in-out infinite 0.35s; }
.series-replay-arena.fighting .series-replay-clash { animation: series-flash 0.35s ease-in-out infinite alternate; }
.series-replay-arena.won .series-replay-enemy { transform: rotate(80deg) translateY(0.4rem); opacity: 0.35; transition: transform 0.4s, opacity 0.4s; }
.series-replay-arena.lost .series-replay-player { transform: rotate(-80deg) translateY(0.4rem); opacity: 0.35; transition: transform 0.4s, opacity 0.4s; }
.series-replay-enemy-name { text-align: center; font-weight: 600; }
.series-replay-health { display: flex; align-items: center; gap: 0.5rem; }
.series-replay-bar { flex: 1; height: 0.6rem; background: var(--panel-2); border-radius: 999px; overflow: hidden; }
.series-replay-bar span { display: block; height: 100%; background: #3f8f4f; transition: width 1.2s ease-out; }
.series-replay-bar span.low { background: #a33a3a; }
.series-replay-result { min-height: 2.6em; text-align: center; font-size: 0.9rem; }
.series-replay-stop { text-align: center; font-weight: 600; }
.series-replay-actions { justify-content: center; }
.series-replay-still .series-replay-arena * { animation: none !important; transition: none !important; }
.series-replay-live, .series-replay-summary { display: flex; flex-direction: column; gap: 0.6rem; }
.series-replay-totals { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem 1rem; font-weight: 600; }
.series-replay-loot { margin: 0; text-align: center; font-size: 0.9rem; }
.series-replay-gear .series-gear { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.9rem; }
.series-replay-list { margin: 0; padding: 0 0.2rem; list-style: none; max-height: min(45vh, 20rem); overflow-y: auto; display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.9rem; }
.series-replay-list li { display: flex; flex-direction: column; }
.series-replay-list li.warn strong { color: inherit; }
@keyframes series-lunge-right { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(0.9rem); } }
@keyframes series-lunge-left { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-0.9rem); } }
@keyframes series-flash { from { opacity: 0.25; transform: scale(0.9); } to { opacity: 1; transform: scale(1.2); } }
@keyframes series-pulse { from { background: var(--panel-2); } to { background: var(--accent); } }

/* Patch notes */
.topbar-menu > .btn-link.active { color: var(--text); font-weight: bold; }
.patch-note h2 { margin: 0 0 0.2rem; font-size: 1.1rem; }
.patch-note-meta { margin: 0 0 0.6rem; font-size: 0.85rem; }
.patch-note-changes { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
.patch-note-changes li { display: flex; gap: 0.5rem; align-items: baseline; }
.patch-type { flex: 0 0 auto; min-width: 5.5em; padding: 0 0.4em; border: 1px solid currentColor; border-radius: 4px; font-size: 0.72rem; text-align: center; text-transform: uppercase; }
.patch-type-new { color: var(--ok); }
.patch-type-change { color: var(--accent); }
.patch-type-fix { color: var(--sp); }

/* Item hover cards: only on devices with a real mouse, mobile keeps the inline details. */
.item-tooltip { display: none; }
@media (hover: hover) and (pointer: fine) {
    .has-tooltip { position: relative; cursor: help; text-decoration: underline dotted rgba(161, 147, 127, 0.5); text-underline-offset: 3px; }
    .has-tooltip:hover > .item-tooltip, .has-tooltip:focus-visible > .item-tooltip { display: block; }
    .item-tooltip {
        position: absolute; left: 0; top: calc(100% + 6px); z-index: 80;
        width: max-content; max-width: 320px; padding: 0.55rem 0.7rem;
        background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px;
        box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
        color: var(--text); font-size: 0.85rem; font-weight: 400; line-height: 1.4;
        text-align: left; white-space: normal; pointer-events: none;
    }
    .item-tooltip.is-placed { position: fixed; }
}
.item-tooltip .tt-head { display: block; font-weight: 600; font-size: 0.95rem; }
.item-tooltip .tt-rarity { font-weight: 400; font-size: 0.8rem; opacity: 0.8; }
.item-tooltip .tt-line { display: block; }
.item-tooltip .tt-section { display: block; margin-top: 0.35rem; padding-top: 0.35rem; border-top: 1px solid var(--line); }
.item-tooltip .tt-blocked { color: var(--danger); }

/* Inventory window: figure with equipment slots and the 5x9 bag grid (play.partials.equipment-table / bag-table).
   The layout follows the classic MMO inventory; frames, cells and icons are our own. */
html:not(.js) .js-only { display: none !important; }
/* Cell size lives on :root so the figure also fits outside the inventory page (character page). */
:root { --cell: 46px; --cell-gap: 2px; }
@media (max-width: 760px) {
    :root { --cell: min(56px, calc((100vw - 32px - 28px) / 5)); }
}
.inv-layout {
    display: grid; grid-template-columns: max-content minmax(0, 1fr);
    grid-template-areas: "equip detail" "bag detail" "tools tools";
    gap: 12px 20px; align-items: start; margin-top: 0.6rem;
}
.inv-contents { display: contents; }
.inv-equip-area { grid-area: equip; }
.inv-bag-window { grid-area: bag; }
.inv-detail { grid-area: detail; }
.inv-tools { grid-area: tools; }
.inv-window {
    width: max-content; padding: 6px 8px 8px;
    background: linear-gradient(180deg, #2c2219 0%, #1c1611 100%);
    border: 2px solid #6b5230; border-radius: 4px;
    box-shadow: inset 0 0 0 1px #120c07, inset 0 0 0 2px rgba(226, 179, 71, 0.18), 0 6px 18px rgba(0, 0, 0, 0.45);
}
.inv-window-head {
    display: flex; justify-content: space-between; align-items: baseline; gap: 0.6rem;
    margin: -2px -4px 6px; padding: 2px 8px;
    background: linear-gradient(180deg, #4a3722, #2e2216); border-bottom: 1px solid #6b5230; border-radius: 2px;
    color: #f2d48a; font-weight: 700; font-size: 0.85rem; letter-spacing: 0.06em; text-transform: uppercase;
}
.inv-window-head .small { text-transform: none; letter-spacing: 0; font-weight: 400; }
.inv-bag, .inv-doll {
    position: relative; display: grid; gap: var(--cell-gap);
    grid-template-columns: repeat(5, var(--cell));
}
.inv-bag { grid-template-rows: repeat(var(--inv-rows, 9), var(--cell)); }
.inv-bag + .inv-bag { margin-top: 6px; }
html.js .inv-bag:not(.is-active) { display: none; }
.inv-bag-actions { display: flex; justify-content: flex-end; margin-bottom: 4px; }
.inv-page-tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--cell-gap); margin-bottom: 4px; }
.inv-page-tab {
    padding: 2px 0; font: inherit; font-weight: 700; font-size: 0.85rem; letter-spacing: 0.08em; cursor: pointer;
    color: #a1937f; background: linear-gradient(180deg, #2e2216, #1a140e); border: 1px solid #4a3a28; border-radius: 3px 3px 0 0;
}
.inv-page-tab:hover { color: #f2d48a; }
.inv-page-tab.is-active { color: #f2d48a; background: linear-gradient(180deg, #5a4329, #2e2216); border-color: #6b5230; }
.inv-doll { grid-template-rows: repeat(5, var(--cell)); }
.inv-cell, .inv-slot.is-empty {
    background: #120e0b; border: 1px solid #36291d;
    box-shadow: inset 1px 1px 0 #000, inset -1px -1px 0 #4a3a28;
}
.inv-bag.is-moving .inv-cell { cursor: crosshair; background: #1d1a10; }
.inv-cell.is-drop-target { background: #3a3215; border-color: var(--accent); }
.inv-drop-preview { display: none; z-index: 2; pointer-events: none; border: 2px solid var(--accent); background: rgba(226, 179, 71, 0.18); border-radius: 2px; }
.inv-drop-preview.is-drop-target { display: block; }
.inv-doll-figure {
    position: absolute; top: 0; bottom: 0; left: calc(var(--cell) + var(--cell-gap)); width: calc(3 * var(--cell) + 2 * var(--cell-gap)); height: 100%;
    fill: rgba(214, 168, 90, 0.06); stroke: rgba(214, 168, 90, 0.22); stroke-width: 0.8; pointer-events: none;
}
.inv-slot.is-empty { display: flex; align-items: center; justify-content: center; padding: 6px; }
.inv-slot.is-empty .inv-tile-icon { opacity: 0.16; filter: grayscale(1); }
.inv-slot.is-drop-target { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); }
.inv-tile {
    position: relative; z-index: 1; display: flex; align-items: center; justify-content: center;
    min-width: 0; min-height: 0; padding: 2px; margin: 0;
    background: radial-gradient(circle at 50% 40%, rgba(255, 240, 200, 0.07), rgba(0, 0, 0, 0) 70%), #17120d;
    border: 1px solid #4a3a28; border-radius: 2px; font: inherit; cursor: pointer;
}
.inv-tile.has-tooltip { text-decoration: none; cursor: pointer; }
/* Every tile is its own stacking layer, so the hovered one moves up or the next tiles cover its card.
   Phones keep :hover on the last tapped tile, so there the lift would cover the detail sheet. */
@media (hover: hover) { .inv-tile:hover { z-index: 80; } }
.inv-tile:focus-visible { z-index: 80; }
.inv-tile:not(.rarity-common) { border-color: currentColor; box-shadow: inset 0 0 8px color-mix(in srgb, currentColor 40%, transparent); }
.inv-tile:hover, .inv-tile:focus-visible { border-color: var(--accent); outline: none; background-color: #2a2016; }
.inv-tile.is-selected { box-shadow: 0 0 0 2px var(--accent), inset 0 0 10px rgba(226, 179, 71, 0.45); }
.inv-tile.is-blocked { background: radial-gradient(circle at 50% 40%, rgba(255, 120, 100, 0.12), rgba(0, 0, 0, 0) 70%), #4a1714; }
.inv-tile.is-dimmed { opacity: 0.18; }
.inv-tile.is-dragging { opacity: 0.35; }
.inv-tile { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
/* Sell mode: picks glow red with a check, items without vendor value fade out. */
.inv-layout.is-sell-mode .inv-tile, .inv-layout.is-sell-mode tr[data-sell-id] { cursor: copy; }
.inv-tile.is-picked { border-color: #e0604a; box-shadow: 0 0 0 2px #e0604a, inset 0 0 12px rgba(224, 96, 74, 0.55); }
.inv-tile.is-picked::after {
    content: "✓"; position: absolute; right: 2px; top: 1px; font-size: 12px; font-weight: 700; line-height: 1; color: #ffb3a5;
    text-shadow: 1px 0 0 #000, -1px 0 0 #000, 0 1px 0 #000, 0 -1px 0 #000; pointer-events: none;
}
.inv-tile.is-unsellable, tr.is-unsellable { opacity: 0.25; cursor: not-allowed; }
tr.is-picked > td { background: rgba(224, 96, 74, 0.16); }
.inv-detail.is-selling .inv-detail-empty { display: none; }
.inv-sell-summary { margin: 0.4rem 0; color: #f2d48a; font-weight: 600; }
.inv-sell-presets { margin-bottom: 0.3rem; }
.inv-tile-icon { display: block; width: 100%; height: 100%; }
.inv-tile-qty, .inv-tile-plus {
    position: absolute; font-size: 11px; font-weight: 700; line-height: 1; color: #fff; pointer-events: none;
    text-shadow: 1px 0 0 #000, -1px 0 0 #000, 0 1px 0 #000, 0 -1px 0 #000;
}
.inv-tile-qty { right: 2px; bottom: 2px; }
.inv-tile-plus { left: 2px; top: 2px; color: #f2d48a; }
.inv-tile-sockets { position: absolute; left: 3px; bottom: 3px; display: flex; gap: 2px; pointer-events: none; }
.socket-pip { width: 6px; height: 6px; border-radius: 50%; box-sizing: border-box; box-shadow: 0 0 0 1px #000; }
.socket-pip.is-empty { border: 1px solid #c9b07a; background: rgba(0, 0, 0, 0.55); }
.socket-pip.is-stone { background: radial-gradient(circle at 35% 30%, #e6fbff, #47c6e8 55%, #1a6f8c); }
.socket-pip.is-shard { background: linear-gradient(135deg, #8a8580 45%, #c0392b 45%, #c0392b 55%, #5b5650 55%); }
.inv-loose { display: flex; flex-wrap: wrap; gap: var(--cell-gap); margin-top: 4px; }
.inv-loose .inv-tile { width: var(--cell); height: var(--cell); }
.inv-bag-foot { display: flex; align-items: center; justify-content: flex-end; gap: 0.3rem; margin-top: 6px; padding: 2px 6px; background: #120e0b; border: 1px solid #36291d; color: #f2d48a; font-weight: 600; font-size: 0.85rem; }
.inv-hint { max-width: calc(5 * var(--cell) + 8px); margin-top: 6px; }
.inv-hint-touch { display: none; }
@media (hover: none) {
    .inv-hint-mouse { display: none; }
    .inv-hint-touch { display: block; }
}
.inv-detail { position: sticky; top: 12px; min-height: 8rem; padding: 0.8rem 0.9rem; background: var(--panel); border: 1px solid var(--line); border-radius: 6px; }
.inv-detail.has-selection .inv-detail-empty { display: none; }
.inv-detail-close { display: none; }
.inv-detail-head { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.3rem; font-size: 1.05rem; font-weight: 600; }
.inv-detail-icon { flex: 0 0 auto; width: 44px; height: 44px; padding: 3px; background: #120e0b; border: 1px solid #4a3a28; }
.inv-detail .item-tooltip {
    display: block; position: static; width: auto; max-width: none; padding: 0; margin: 0;
    background: none; border: 0; box-shadow: none; pointer-events: auto; font-size: 0.88rem;
}
.inv-detail .item-tooltip .tt-head { display: none; }
.inv-detail .item-tooltip .tt-section:first-of-type, .inv-detail .item-tooltip > .tt-line:first-child { margin-top: 0; }
.inv-detail-actions { margin-top: 0.7rem; }
.inv-view-toggle { display: flex; gap: 0.3rem; }
.inv-equipment-list { margin-top: 0.6rem; }
/* Character page: figure next to the value list, both inside the card. */
.inv-equipment-readonly { display: flex; flex-wrap: wrap; gap: 0.8rem 1.2rem; align-items: flex-start; }
.inv-equipment-readonly .inv-equipment-list { flex: 1 1 16rem; margin-top: 0; }
@media (max-width: 760px) {
    .inv-layout {
        grid-template-columns: minmax(0, 1fr); grid-template-areas: "equip" "bag" "tools";
        justify-items: center;
    }
    .inv-tools { justify-self: stretch; }
    .inv-detail {
        position: fixed; left: 0; right: 0; bottom: 0; top: auto; z-index: 90; max-height: 62vh; overflow-y: auto;
        border-radius: 12px 12px 0 0; border-color: var(--accent); box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.6);
        transform: translateY(105%); visibility: hidden; transition: transform 0.18s ease, visibility 0s linear 0.18s;
    }
    .inv-detail.is-open { transform: none; visibility: visible; transition: transform 0.18s ease; }
    /* On phones the sell panel stays docked at the bottom, small enough to keep the bag in view. */
    .inv-detail.is-selling { transform: none; visibility: visible; max-height: 42vh; padding-bottom: 0.6rem; }
    .inv-layout.is-sell-mode { padding-bottom: 42vh; }
    .inv-detail-close { display: block; position: absolute; right: 0.6rem; top: 0.6rem; padding: 0.1rem 0.6rem; font-size: 1.2rem; }
    .inv-detail-empty { display: none; }
}

/* Smith: the bag grid on the left, the chosen piece with chance and cost on the right. */
.smith-layout {
    display: grid; grid-template-columns: max-content minmax(0, 1fr);
    gap: 12px 20px; align-items: start; margin-top: 0.6rem;
}
.smith-grid { display: grid; gap: 8px; align-content: start; }
/* Equipped pieces wrap at the bag's five columns, otherwise the row outgrows a phone screen. */
.smith-grid .inv-loose { max-width: calc(5 * var(--cell) + 4 * var(--cell-gap)); }
/* The inventory places its detail by grid area; here it simply takes the second column. */
.inv-detail.smith-detail { grid-area: auto; }
span.inv-tile { cursor: default; }
.smith-step { margin: 0.2rem 0 0.4rem; }
.smith-cost { margin-top: 0.4rem; }
.smith-recipe-tiers { margin: 0.2rem 0 0.6rem; padding-left: 1.1rem; }
@media (max-width: 760px) {
    .smith-layout { grid-template-columns: minmax(0, 1fr); justify-items: center; }
    /* The detail stays in the page flow below the bag instead of the inventory's bottom sheet.
       z-index must be reset too: as a grid item it would still be lifted above the footer chat. */
    .inv-detail.smith-detail {
        position: static; z-index: auto; justify-self: stretch; max-height: none; overflow: visible;
        transform: none; visibility: visible; border-radius: 6px; border-color: var(--line); box-shadow: none;
    }
    .smith-detail .inv-detail-empty { display: block; }
    .smith-detail.has-selection .inv-detail-empty { display: none; }
}

/* Group fights: live playback, tactic editor and the small reaction row. */
[x-cloak] { display: none !important; }
.group-fight-banner {
    display: block; margin: 0.4rem 0 0.6rem; padding: 0.5rem 0.8rem;
    background: #2a2216; border: 1px solid var(--accent); border-radius: 6px;
    color: #f2d48a; font-weight: 600; text-decoration: none;
}
.group-fight-banner:hover { filter: brightness(1.1); }
.group-fight-controls { justify-content: space-between; align-items: center; }
.group-fight-moment { border-color: var(--accent); background: #1b140d; }
.group-fight-moment-announcement { font-size: 1.1rem; color: #f2d48a; margin: 0.4rem 0 0.6rem; }
.group-fight-cards { align-items: stretch; }
.group-fight-card {
    display: flex; flex-direction: column; align-items: flex-start; gap: 0.25rem;
    flex: 1 1 180px; text-align: left; padding: 0.6rem 0.8rem; white-space: normal;
}
.group-fight-card:disabled { opacity: 0.75; }
.group-fight-round { list-style: none; margin: 0 0 0.7rem; }
.group-fight-round h3 { margin: 0 0 0.25rem; color: #f2d48a; }
.group-fight-round ul.plain { margin: 0; }
/* Tactic rules sit side by side on desktop; the form keeps its other fields narrow. */
.tactic-form { max-width: none; }
.tactic-form > :not(.tactic-rules) { max-width: 320px; }
.tactic-rules { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0.6rem; }
@media (max-width: 640px) { .tactic-rules { grid-template-columns: 1fr; } }
.tactic-rule-tag { display: inline-block; padding: 0 0.35rem; margin-right: 0.3rem; border: 1px solid var(--line, currentColor); border-radius: 0.6rem; font-size: 0.8em; white-space: nowrap; }
.tactic-sim-log ul { margin: 0.2rem 0 0.5rem; padding-left: 1rem; }
.tactic-rule {
    display: grid; gap: 0.4rem; padding: 0.6rem;
    background: #120e0b; border: 1px solid #36291d; border-radius: 6px;
}
.tactic-rule label { display: flex; flex-direction: column; gap: 0.15rem; }
.tactic-rule select { width: 100%; }
.tactic-rule input[type="number"] { width: 100%; }
.tactic-rule-head { justify-content: space-between; align-items: center; }
.tactic-rule-head .btn-link { padding: 0 0.3rem; }
.reaction-button { font-size: 1.35rem; line-height: 1; padding: 0.35rem 0.6rem; }
.group-fight-reaction-items { display: flex; flex-wrap: wrap; gap: 0.4rem 1rem; margin-top: 0.5rem; }
.group-fight-reaction-items li { display: inline-flex; align-items: center; gap: 0.25rem; }
/* Pages outside the game: login, registration, password reset, error pages. */
.guest-menu { justify-content: flex-end; }
.guest-main { padding-top: 1.2rem; }
.brand-banner { margin: 0 auto 0.4rem; text-align: center; }
.brand-banner img { display: block; width: 100%; height: auto; border: 1px solid var(--line); border-radius: 10px; box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5); }
.brand-banner-tagline { margin: 0.5rem 0 0; color: var(--accent); font-family: Georgia, "Times New Roman", serif; font-size: 1.15rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; }
.auth-card { max-width: 440px; margin: 1rem auto; padding: 1.2rem 1.4rem; }
.auth-card-wide { max-width: 760px; }
.auth-card h1 { margin-top: 0; }
.auth-form { display: flex; flex-direction: column; gap: 0.8rem; margin-top: 0.8rem; }
.auth-form label { display: flex; flex-direction: column; gap: 0.25rem; }
.auth-form label.auth-check { flex-direction: row; align-items: center; gap: 0.4rem; }
.auth-form input[type="email"], .auth-form input[type="password"], .auth-form input[type="text"] { width: 100%; }
.auth-form input:disabled { opacity: 0.7; }
.auth-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem; }
.auth-actions { margin-top: 0.4rem; }
.field-error { color: var(--danger); font-size: 0.85rem; }
.race-grid { margin-top: 0.3rem; }
.race-grid .lumiis-race-card { cursor: pointer; }
.race-grid .lumiis-race-card.selected { border-color: var(--accent); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--accent); }
.error-card { margin-top: 2rem; }
/* Public legal pages (imprint, privacy, terms, withdrawal) rendered from Markdown. */
.legal-document { max-width: 760px; margin: 1rem auto; padding: 1.2rem 1.4rem; }
.legal-document h1 { margin-top: 0; }
.legal-document-body { line-height: 1.65; }
.legal-document-body h2 { margin: 1.6rem 0 0.4rem; color: var(--accent); font-size: 1.15rem; }
.legal-document-body h3 { margin: 1.1rem 0 0.3rem; font-size: 1rem; }
.legal-document-body p { margin: 0.5rem 0; }
.legal-document-body ul, .legal-document-body ol { margin: 0.5rem 0; padding-left: 1.25rem; }
.legal-document-body li { margin: 0.2rem 0; }
.legal-document-body blockquote {
    margin: 0.8rem 0; padding: 0.45rem 0.8rem;
    border-left: 3px solid var(--accent); background: #120e0b; color: #d8c7a8;
}
.legal-document-body code { padding: 0 0.25rem; background: #120e0b; border-radius: 3px; }
.legal-document-body a { color: var(--accent); }
@media (max-width: 600px) { .legal-document { margin: 0.6rem 0; padding: 1rem; } }
/* Public site footer (legal links) on pages outside the game. */
.public-site-footer { margin-top: 2rem; }
.public-site-footer-inner {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1rem 1.5rem;
    align-items: start; padding: 1rem 1.2rem;
}
.public-footer-links { display: flex; flex-wrap: wrap; gap: 0.4rem 0.9rem; }
.public-footer-copy, .public-footer-meta { margin: 0.3rem 0 0; color: var(--muted); font-size: 0.85rem; }
.public-footer-meta { grid-column: 1 / -1; }
@media (max-width: 600px) { .public-site-footer-inner { grid-template-columns: 1fr; } }
@media (max-width: 600px) {
    .auth-grid { grid-template-columns: 1fr; }
    .guest-topbar .topbar-menu { justify-content: flex-start; }
    .brand-banner-tagline { font-size: 0.9rem; letter-spacing: 0.08em; }
}

/* Skill values: next-stage line on the character page, hover card around battle skill buttons. */
.skill-upgrade { margin-top: 0.2rem; }
.skill-change { overflow-wrap: anywhere; }
.skill-rank-inline { display: none; }
/* Skills the equipped weapon locks (bow vs. melee): greyed, with the reason in red. */
.skill-table tr.skill-locked .skill-name, .btn.skill-locked { opacity: 0.55; }
.btn.skill-locked { cursor: not-allowed; }
.skill-lock-reason { color: var(--danger); margin-top: 0.2rem; }
option.option-locked { color: var(--muted); }
.skill-table td.skill-rank, .skill-table td.skill-action { white-space: nowrap; }
.skill-values-touch { margin-top: 0.3rem; }
.skill-values-touch summary { cursor: pointer; color: var(--accent); }
.skill-values-list { display: grid; grid-template-columns: auto 1fr; gap: 0.1rem 0.8rem; margin: 0.3rem 0; }
.skill-values-list dt { color: var(--muted); }
.skill-values-list dd { margin: 0; }
@media (hover: hover) and (pointer: fine) and (min-width: 641px) { .skill-values-touch { display: none; } }
/* Phones: every skill becomes a small card. Name and rank on top, the description and
   the next-stage changes (one per line) below, the learn button across the bottom. */
@media (max-width: 640px) {
    .table.skill-table, .skill-table tbody { display: block; }
    .skill-table thead { display: none; }
    .skill-table tr { display: block; padding: 0.6rem 0; border-bottom: 1px solid var(--line); }
    .skill-table td { display: block; padding: 0; border: 0; }
    .skill-table td.skill-rank { display: none; }
    .skill-table .skill-name { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; font-weight: 600; }
    .skill-table .skill-rank-inline { display: inline; flex: none; color: var(--accent); font-size: 0.85rem; font-weight: 400; }
    .skill-table .skill-upgrade { display: grid; gap: 0.1rem; margin-top: 0.35rem; padding: 0.35rem 0.5rem; border-radius: 6px; background: var(--panel-2); }
    .skill-table .skill-sep { display: none; }
    .skill-table td.skill-action .inline-form, .skill-table td.skill-action form { display: flex; margin-top: 0.45rem; }
    .skill-table td.skill-action .btn { flex: 1; }
}
.has-tooltip.skill-button { text-decoration: none; cursor: default; }

/* Wide tables on phones: each row becomes a small card. The title cell spans the row,
   the other cells line up with their column name in front (data-label), the buttons go
   to the bottom. Columns marked hide-narrow are dropped instead. */
.show-narrow { display: none; }
@media (max-width: 640px) {
    .hide-narrow { display: none; }
    .show-narrow { display: inline; }
    .table.table-cards, .table-cards tbody { display: block; overflow: visible; }
    .table-cards thead { display: none; }
    .table-cards tr { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 1rem; padding: 0.55rem 0; border-bottom: 1px solid var(--line); }
    .table-cards td { display: block; padding: 0; border: 0; }
    .table-cards td.hide-narrow { display: none; }
    .table-cards td.cell-title { flex-basis: 100%; }
    .table-cards td[data-label]::before { content: attr(data-label) ": "; color: var(--muted); font-size: 0.85rem; }
    .table-cards td.cell-actions { display: flex; flex-wrap: wrap; gap: 0.35rem; flex-basis: 100%; margin-top: 0.3rem; }
    .table-cards td.cell-actions:empty { display: none; }
    .table-cards td.cell-actions > * { margin: 0; }
}
.group-fight-round li.group-fight-combo {
    margin: 0.2rem 0; padding: 0.25rem 0.5rem; border-left: 3px solid #f2b84a;
    background: #2a2216; color: #ffe5a3; font-weight: 600;
}

/* Footer chat: a slim bar at the end of the game column that folds out into the public
   chat (players + smith announcements). It is sticky, not fixed: it shares the column
   width with the content and at the end of the page sits below it, never over it.
   Hover cards (item, skill, stat tooltips) use z-index 80 so they stay above it. */
.chat-footer { position: sticky; bottom: 0; z-index: 50; margin-top: 1.5rem; background: var(--panel); border: 1px solid var(--line); border-bottom: 0; border-radius: 10px 10px 0 0; box-shadow: 0 -6px 18px rgba(0, 0, 0, 0.4); }
.page:has(.chat-footer) { padding-bottom: 0; }
.chat-footer-bar { display: flex; align-items: center; gap: 0.5rem; width: 100%; min-height: 2.6rem; padding: 0.4rem 0.8rem; background: none; border: 0; color: var(--text); font: inherit; cursor: pointer; text-align: left; }
.chat-footer-bar:hover { background: var(--panel-2); border-radius: 10px 10px 0 0; }
.chat-footer-title { font-weight: 600; }
.chat-footer-last { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.chat-footer-toggle { margin-left: auto; white-space: nowrap; }
.chat-footer-panel { border-top: 1px solid var(--line); padding: 0.4rem 0.8rem 0.7rem; }
.chat-lines { height: 160px; overflow-y: auto; margin: 0 0 0.5rem; padding: 0; list-style: none; overscroll-behavior: contain; }
.chat-page-lines { max-height: 420px; overflow-y: auto; list-style: none; padding: 0; }
.chat-line { padding: 0.15rem 0; overflow-wrap: anywhere; }
.chat-time { font-size: 0.75rem; margin-right: 0.35rem; font-variant-numeric: tabular-nums; }
.chat-sender { margin-right: 0.25rem; }
.chat-line-smith { color: var(--accent); }
.chat-line-smith .chat-body { font-style: italic; }
.chat-line-group { color: #9fd6a8; }
.chat-line-group .chat-body { font-style: italic; }
.chat-link { margin-left: 0.35rem; font-weight: 600; }
.chat-tabs { display: flex; gap: 0.35rem; margin-bottom: 0.35rem; }
.chat-tab { display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.2rem 0.7rem; border: 1px solid var(--line); border-radius: 99px; background: none; color: var(--muted, inherit); font: inherit; font-size: 0.85rem; cursor: pointer; }
.chat-tab.is-active { background: var(--panel-2); color: var(--text); border-color: var(--accent); }
.chat-tab-dot { width: 0.45rem; height: 0.45rem; border-radius: 50%; background: var(--accent); }
.chat-lines-tab-world [data-chat-tab="groups"], .chat-lines-tab-groups [data-chat-tab="world"] { display: none; }
.chat-footer-form { display: flex; gap: 0.5rem; }
.chat-footer-form input { flex: 1; min-width: 0; }
.chat-footer-error { color: var(--danger); margin: 0.3rem 0 0; }
@media (max-width: 640px) {
    .chat-footer { margin-inline: -16px; border-radius: 0; border-inline: 0; }
    .chat-lines { height: 28vh; }
    .chat-footer-last { display: none; }
}

/* Inbox: private messages and system notifications, apart from the public chat. */
.inbox-badge { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.15rem 0.55rem; border-radius: 99px; background: var(--accent); color: #1b140c; font-size: 0.8rem; font-weight: 700; white-space: nowrap; }
.badge[hidden], .inbox-badge[hidden] { display: none; }
.inbox-badge:hover { text-decoration: none; filter: brightness(1.1); }
.inbox-badge .nav-icon { width: 1.1em; height: 1.1em; }
.inbox-columns { display: grid; grid-template-columns: minmax(220px, 1fr) 2fr; gap: 1rem; align-items: start; }
.inbox-columns > * { min-width: 0; }
.inbox-list { list-style: none; padding: 0; margin: 0 0 0.8rem; }
.inbox-entry { padding: 0.45rem 0.5rem; border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.inbox-entry:last-child { border-bottom: 0; }
.inbox-entry.active { background: var(--panel-2); border-radius: 6px; }
.inbox-unread { border-left: 3px solid var(--accent); }
.inbox-conversation { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem; color: var(--text); }
.inbox-conversation:hover { text-decoration: none; }
.inbox-conversation time { margin-left: auto; }
.inbox-preview { flex-basis: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.inbox-meta { display: flex; gap: 0.5rem; align-items: center; margin-bottom: 0.15rem; }
.inbox-text { display: block; }
.inbox-tag { padding: 0 0.4rem; border-radius: 4px; background: var(--panel-2); color: var(--text); }
.inbox-tag-shop { color: var(--accent); }
.inbox-tag-fight { color: var(--ok); }
.inbox-new { color: var(--accent); font-weight: 700; }
.inbox-conversations .inline-form, .inbox-thread .inline-form { display: flex; flex-wrap: wrap; gap: 0.4rem; width: 100%; }
.inbox-conversations .inline-form input { flex: 1 1 100%; min-width: 0; }
.inbox-thread .inline-form input { flex: 1; min-width: 0; }
.inbox-messages { list-style: none; padding: 0; margin: 0 0 0.8rem; max-height: 460px; overflow-y: auto; display: flex; flex-direction: column; gap: 0.4rem; }
.inbox-message { max-width: 85%; padding: 0.35rem 0.6rem; border-radius: 8px; background: var(--panel-2); overflow-wrap: anywhere; }
.inbox-message-out { align-self: flex-end; background: color-mix(in srgb, var(--accent) 18%, var(--panel-2)); }
.inbox-message.inbox-unread { border-left: 3px solid var(--accent); }
@media (max-width: 720px) {
    .inbox-columns { grid-template-columns: minmax(0, 1fr); }
    .inbox-message { max-width: 100%; }
    .inbox-columns.has-thread .inbox-thread { order: -1; }
}

/* PvP duel replay */
.duel-replay-head { display: grid; grid-template-columns: 1fr auto 1fr; gap: 1rem; align-items: center; margin-bottom: 1rem; }
.duel-replay-fighter { display: flex; flex-direction: column; gap: 0.25rem; }
.duel-replay-fighter:last-child { text-align: right; align-items: flex-end; }
.duel-replay-round { font-weight: 700; white-space: nowrap; }
.duel-replay-bar { width: 100%; height: 0.8rem; border-radius: 999px; background: var(--panel-2); overflow: hidden; }
.duel-replay-bar > span { display: block; height: 100%; background: var(--ok); transition: width 220ms ease; }
.duel-replay-bar > span.low { background: var(--danger); }
.duel-replay-log { list-style: none; padding: 0; margin: 0 0 0.8rem; max-height: 420px; overflow-y: auto; display: flex; flex-direction: column; gap: 0.25rem; }
.duel-replay-event { padding: 0.15rem 0.4rem; border-left: 3px solid var(--line); }
.duel-replay-challenger { border-left-color: var(--accent); }
.duel-replay-defender { border-left-color: var(--ok); }
.duel-replay-status { color: var(--muted); font-style: italic; }
.duel-replay-result { font-weight: 700; margin-top: 0.5rem; }
@media (prefers-reduced-motion: reduce) {
    .duel-replay-bar > span { transition: none; }
}
@media (max-width: 720px) {
    .duel-replay-head { grid-template-columns: 1fr; text-align: left; }
    .duel-replay-fighter:last-child { text-align: left; align-items: flex-start; }
    .duel-replay-round { order: -1; }
}

/* Hire lists (mercenaries, shadows): one line per offer, info left and button right; wraps in narrow cards. */
.hire-list { display: flex; flex-direction: column; margin: 0.5rem 0 0.2rem; border-top: 1px solid var(--line); }
.hire-option { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.4rem 0.8rem; padding: 0.5rem 0; border-bottom: 1px solid var(--line); }
.hire-info { display: flex; flex-direction: column; gap: 0.1rem; flex: 1 1 8rem; min-width: 0; }
.hire-info strong { overflow-wrap: break-word; }

/* Fame ranks next to character names */
.rank-tag { font-size: 0.8em; font-weight: 700; letter-spacing: 0.02em; white-space: nowrap; }
.rank-friendly { color: #7ea66a; }
.rank-good { color: #4a90d9; }
.rank-noble { color: #b07ad0; }
.rank-chivalrous { color: #e2b347; }
.rank-champion { color: #c63b33; }
/* Bug report form under "More". */
.bug-report-form { max-width: 560px; }
.bug-report-form input[type="text"], .bug-report-form textarea, .bug-report-form select { width: 100%; }
.bug-report-form textarea { padding: 0.35rem 0.5rem; border-radius: 6px; border: 1px solid var(--line); background: #120f0c; color: var(--text); font: inherit; resize: vertical; }
.bug-report-form input[type="file"] { width: 100%; }
.bug-status { color: var(--accent); }
.bug-status-done { color: var(--muted); }

/* Community Discord link: pill in the top bar (game + guest pages), card on the start page, line on the patch notes. */
.discord-icon { width: 1.15em; height: 1.15em; flex: none; }
.discord-badge { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.2rem 0.65rem; border-radius: 99px; background: #5865f2; color: #fff; font-size: 0.82rem; font-weight: 700; white-space: nowrap; }
.discord-badge:hover, .discord-btn:hover { text-decoration: none; filter: brightness(1.12); }
.btn.discord-btn { display: inline-flex; align-items: center; gap: 0.45rem; background: #5865f2; border-color: #5865f2; color: #fff; font-weight: 700; }
.discord-card { max-width: 440px; margin: 1rem auto; padding: 1rem 1.4rem; text-align: center; }
.discord-card h2 { margin: 0 0 0.3rem; }
.discord-card p { margin: 0 0 0.8rem; }
.discord-line { margin: 0 0 1rem; }
/* Page footer with the Discord link and the forum threads about lumiis. */
.community-footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.4rem 0.8rem; margin: 2rem 0 1rem; padding: 0.8rem 0 0; border-top: 1px solid var(--line); }
.community-footer-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem; }
.community-link { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.25rem 0.7rem 0.25rem 0.35rem; border: 1px solid var(--line); border-radius: 99px; background: var(--panel); color: var(--text); font-size: 0.85rem; white-space: nowrap; }
.community-link:hover { text-decoration: none; border-color: var(--accent); color: var(--accent); }
.community-link-icon { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; flex: none; border-radius: 4px; object-fit: contain; }
.community-link-icon-discord { background: #5865f2; color: #fff; }
.community-link-icon-discord .discord-icon { width: 14px; height: 14px; }
.community-link-wide { padding: 0.15rem 0.45rem; }
.community-link-banner { display: block; height: 22px; width: auto; border-radius: 3px; }
.community-link-monogram { background: var(--panel-2); color: var(--accent); font-size: 0.55rem; font-weight: 800; letter-spacing: -0.02em; }
@media (max-width: 420px) {
    .discord-badge { padding: 0.25rem 0.45rem; }
    .discord-badge-label { display: none; }
}

/* Achievement titles: the shown title next to a name and the titles page. */
.title-tag { color: var(--accent); font-style: italic; font-weight: 600; white-space: nowrap; }
.title-tag::before { content: "«"; }
.title-tag::after { content: "»"; }
.character-name .title-tag { font-size: 0.85em; }
.titles-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); gap: 0.6rem; margin-top: 0.6rem; }
.title-entry { border: 1px solid var(--line); border-radius: 8px; padding: 0.55rem 0.7rem; display: flex; flex-direction: column; gap: 0.3rem; }
.title-entry h3 { margin: 0; font-size: 1rem; }
.title-entry p { margin: 0; }
.title-entry.is-locked { opacity: 0.72; }
.title-entry.is-active { border-color: var(--accent); }

/* Group finder: pressure estimate as a traffic light. */
.group-pressure { border-left: 4px solid var(--muted); padding: 0.35rem 0.6rem; margin: 0.5rem 0; background: var(--panel-2); border-radius: 4px; }
.group-pressure p { margin: 0.1rem 0; }
.group-pressure-head { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.group-pressure-light { width: 0.75rem; height: 0.75rem; border-radius: 50%; background: var(--muted); flex: none; }
.group-pressure-good { border-left-color: var(--ok); }
.group-pressure-good .group-pressure-light { background: var(--ok); }
.group-pressure-tight { border-left-color: var(--st); }
.group-pressure-tight .group-pressure-light { background: var(--st); }
.group-pressure-weak { border-left-color: var(--danger); }
.group-pressure-weak .group-pressure-light { background: var(--danger); }
.group-pressure-hints { margin: 0.2rem 0 0; padding-left: 1.1rem; }
.group-pressure-badge { display: inline-flex; align-items: center; gap: 0.3rem; white-space: nowrap; }
.group-pressure-badge::before { content: ""; width: 0.6rem; height: 0.6rem; border-radius: 50%; background: var(--muted); }
.group-pressure-badge.group-pressure-good::before { background: var(--ok); }
.group-pressure-badge.group-pressure-tight::before { background: var(--st); }
.group-pressure-badge.group-pressure-weak::before { background: var(--danger); }
.group-target { border-top: 1px solid var(--line); padding: 0.5rem 0; }
.group-target:first-of-type { border-top: 0; }
/* Item search (/spiel/gegenstaende): search bar, category row and one card per item. */
.item-search-form { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.item-search-form input[type="search"] { flex: 1 1 14rem; min-width: 0; }
.item-search-categories { display: flex; flex-wrap: wrap; gap: 0.2rem 0.4rem; margin-top: 0.6rem; }
.item-search-categories .active { color: var(--accent); text-decoration: underline; }
.item-search-explain { margin-top: 0.5rem; }
.item-codex-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr)); gap: 0.6rem; }
.item-codex-entry { background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 0.6rem 0.8rem; display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.item-codex-entry:target { border-color: var(--accent); }
.item-codex-head { display: flex; gap: 0.6rem; align-items: flex-start; }
.item-codex-head h3 { margin: 0; font-size: 1rem; }
.item-codex-head p { margin: 0; }
.item-codex-icon { flex: 0 0 auto; width: 40px; height: 40px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); }
.item-codex-stats { margin: 0; color: var(--text); }
.item-codex-facts { margin: 0; font-size: 0.88rem; }
.item-codex-facts dt { color: var(--accent); font-weight: 600; margin-top: 0.3rem; }
.item-codex-facts dd { margin: 0; overflow-wrap: anywhere; }
.item-codex-source { display: block; }
/* Welcome window on the first visit (play.partials.welcome-dialog), again under "More → About the game". */
.welcome-dialog { position: relative; z-index: 900; overflow: hidden; width: min(36rem, calc(100% - 2rem)); max-height: calc(100dvh - 2rem); margin: 1rem auto; padding: 0; border: 1px solid var(--accent); border-radius: 12px; background: var(--panel); color: var(--text); box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6); }
.welcome-dialog:not([open]) { display: none; }
.welcome-dialog.is-modal { position: fixed; inset: 0; margin: auto; }
.welcome-dialog::backdrop { background: rgba(5, 4, 3, 0.75); }
.welcome-dialog-body { position: relative; max-height: calc(100dvh - 2rem); overflow-y: auto; padding: 1.4rem 1.4rem 1.1rem; box-sizing: border-box; }
.welcome-dialog h2 { margin: 0.2rem 2rem 0.5rem 0; font-size: 1.35rem; }
.welcome-dialog h3 { margin: 1rem 0 0.35rem; font-size: 1rem; color: var(--accent); }
.welcome-dialog p, .welcome-dialog ul { margin: 0 0 0.5rem; }
.welcome-dialog ul { padding-left: 1.2rem; }
.welcome-emblem { display: block; width: 56px; height: 56px; }
.welcome-lead { font-size: 1.02rem; }
.welcome-steps li { margin-bottom: 0.3rem; }
.welcome-steps strong { color: var(--accent); }
.welcome-start { margin-top: 0.9rem !important; padding: 0.6rem 0.75rem; border-left: 3px solid var(--accent); background: var(--panel-2); border-radius: 6px; }
.welcome-actions { display: flex; justify-content: flex-end; margin-top: 0.9rem; }
.welcome-actions .btn { min-width: 9rem; }
.welcome-close { position: absolute; top: 0.6rem; right: 0.7rem; width: 2rem; height: 2rem; padding: 0; border: 1px solid var(--line); border-radius: 50%; background: var(--panel-2); color: var(--text); font-size: 1.2rem; line-height: 1; cursor: pointer; }
.welcome-close:hover, .welcome-close:focus-visible { border-color: var(--accent); color: var(--accent); }
.welcome-hint { margin-top: 0.6rem !important; text-align: right; }
@media (max-width: 640px) {
    .welcome-dialog-body { padding: 1.1rem 1rem 0.9rem; }
    .welcome-actions .btn { width: 100%; }
    .welcome-hint { text-align: left; }
}
/* Guide page (/spiel/leitfaden): advice card, fit badges, region tiles with monster lists. */
.guide-advice { border-left: 4px solid var(--accent); }
.guide-advice h2 { margin: 0.2rem 0 0.4rem; color: var(--text); }
.guide-verdict-level { border-left-color: var(--ok); }
.guide-verdict-farm { border-left-color: var(--st); }
.guide-verdict-tutorial { border-left-color: var(--xp); }
.guide-verdict-badge { display: inline-block; padding: 0 0.45rem; border-radius: 4px; background: var(--accent); color: #1b140c; font-size: 0.85rem; vertical-align: middle; }
.guide-verdict-level .guide-verdict-badge { background: var(--ok); }
.guide-verdict-tutorial .guide-verdict-badge { background: var(--xp); color: var(--text); }
.guide-reasons, .guide-tips { margin: 0.3rem 0; padding-left: 1.2rem; }
.guide-spot { margin: 0.5rem 0; padding: 0.45rem 0.6rem; background: var(--panel-2); border-radius: 6px; }
.guide-fit { display: inline-block; margin-left: 0.3rem; padding: 0 0.4rem; border: 1px solid var(--line); border-radius: 4px; font-size: 0.75rem; font-weight: 600; color: var(--muted); vertical-align: middle; }
.tile .guide-fit { display: inline-block; margin: 0.2rem 0; }
.guide-fit-good, .guide-gear-good { border-color: var(--ok); color: var(--ok); }
.guide-fit-risky, .guide-gear-fair { border-color: var(--accent); color: var(--accent); }
.guide-fit-too-hard, .guide-gear-weak { border-color: var(--danger); color: var(--danger); }
.guide-map { margin-bottom: 1rem; }
.guide-map h3 { margin-top: 1rem; }
.guide-area.locked { opacity: 0.7; }
.guide-monsters { margin-top: 0.35rem; }
.guide-monsters summary { cursor: pointer; color: var(--accent); }
.guide-monsters ul.plain { margin: 0.3rem 0; }
.tile .guide-monsters span { display: inline; }
.tile .guide-monsters .elite-badge { display: inline-block; margin-left: 0.25rem; }
.guide-glossary summary { cursor: pointer; }
.guide-glossary p { margin-top: 0.4rem; color: var(--muted); }
/* Manual group round: countdown, action buttons, picked target, who is ready. */
.group-fight-round-choice { border-color: rgba(245, 197, 66, 0.55); }
.group-fight-playback { border-color: rgba(120, 170, 255, 0.45); }
.group-fight-intro h2 { color: #f5c542; animation: group-intro-pulse 1.2s ease-in-out infinite; }
@keyframes group-intro-pulse { 50% { opacity: 0.55; } }
@media (prefers-reduced-motion: reduce) { .group-fight-intro h2 { animation: none; } }
.group-fight-timer { display: flex; align-items: center; gap: 0.5rem; margin: 0.4rem 0 0.6rem; }
.group-fight-timer .meter { flex: 1; }
.group-fight-timer .meter b { background: #f5c542; transition: width 0.5s linear; }
.group-fight-actions { flex-wrap: wrap; gap: 0.4rem; }
.group-fight-actions .btn { display: inline-flex; flex-direction: column; align-items: flex-start; }
.group-fight-ready { gap: 0.4rem 1rem; margin-top: 0.5rem; padding-left: 0; list-style: none; }
.group-fight-ready li { display: inline-flex; align-items: center; gap: 0.25rem; white-space: nowrap; }
.enemy-unit.is-target { outline: 2px solid #f5c542; outline-offset: 2px; }
.enemy-unit[role="button"] { cursor: pointer; }
.group-fight-chat-lines { max-height: 12rem; overflow-y: auto; margin: 0 0 0.5rem; }
.group-fight-chat-lines li { padding: 0.15rem 0; }
.group-fight-chat form { display: flex; gap: 0.4rem; }
.group-fight-chat input { flex: 1; min-width: 0; }

/* Group dungeon: room track above the fight, current room highlighted. */
.dungeon-track { padding: 0.6rem 0.75rem; overflow-x: auto; }
.dungeon-track ol { display: flex; list-style: none; margin: 0; padding: 0; gap: 0; min-width: max-content; }
.dungeon-track-room { position: relative; display: flex; flex-direction: column; align-items: center; gap: 0.25rem; width: 5.5rem; text-align: center; opacity: 0.55; }
/* The line runs from the edge of the previous circle to the edge of this one, never through them. */
.dungeon-track-room + .dungeon-track-room::before { content: ''; position: absolute; top: calc(0.95rem - 1px); left: calc(-50% + 1.15rem); right: calc(50% + 1.15rem); height: 2px; background: rgba(255, 255, 255, 0.18); }
.dungeon-track-room.is-done + .dungeon-track-room::before,
.dungeon-track-room.is-done + .dungeon-track-room.is-current::before { background: #7fb069; }
.dungeon-track-node { position: relative; z-index: 1; display: inline-flex; align-items: center; justify-content: center; width: 1.9rem; height: 1.9rem; border-radius: 50%; border: 2px solid rgba(255, 255, 255, 0.3); background: #1d1a17; font-weight: 700; }
.dungeon-track-room.is-done { opacity: 0.85; }
.dungeon-track-room.is-done .dungeon-track-node { border-color: #7fb069; color: #7fb069; }
.dungeon-track-room.is-current { opacity: 1; }
.dungeon-track-room.is-current .dungeon-track-node { border-color: #f5c542; color: #f5c542; box-shadow: 0 0 0 4px rgba(245, 197, 66, 0.2); }
.dungeon-track-room.is-boss .dungeon-track-node { border-color: #c94f4f; color: #e07070; }
.dungeon-track-room.is-boss.is-current .dungeon-track-node { border-color: #f5c542; }
.dungeon-track-name { line-height: 1.2; }
.group-fight-room-divider { margin: 0.6rem 0 0.2rem; padding: 0.2rem 0.5rem; border-left: 3px solid #f5c542; background: rgba(245, 197, 66, 0.08); font-weight: 700; }
.tactic-order { margin: 0.3rem 0 0; padding-left: 1.4rem; }
.tactic-order li { gap: 0.3rem; align-items: center; }
.tactic-order li span { flex: 1; }
