/* WarcraftLogs Epog — Dark Theme */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
    --bg:        #0e1117;
    --surface:   #161b22;
    --surface2:  #1c2230;
    --border:    #2d3748;
    --accent:    #c89b3c;
    --text:      #e2e8f0;
    --text-muted:#718096;
    --bar-spell: #805ad5;
    --green:     #68d391; /* Claude: HPS / healing accent */
    --red:       #fc8181; /* Claude: wipes / errors / deaths */
    --text-secondary: #a0aec0; /* Claude: secondary text accent (footer etc.) */
    /* Claude (v0.56.23): boss / NPC / trash name color — light coral/salmon
       that complements the gold accent without reading as "error" (which is
       what --red is reserved for). Used everywhere a hostile-NPC name renders
       (progression tables, hover tooltips, ranking sidebar, log-viewer fight
       title + NPC filter). */
    --boss:      #ff9f7f;
}

body {
    background: var(--bg);
    color: var(--text);
    font-family: 'Segoe UI', system-ui, sans-serif;
    font-size: 14px;
    min-height: 100vh;
}

/* ── Header ─────────────────────────────────────────────────── */
/* Claude: header has a fixed height so it is pixel-identical on every page */
header {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 100;
    height: 56px; /* Claude: static height — never grows or shrinks with content */
}
/* Claude: inner wrapper constrains header content to same max-width as <main>
   so buttons / h1 align with page content on all viewport sizes */
/* Claude (v0.35.5): final value 1300px after iterating 1100 → 1600 → 1800 → 1600
   → 1300. 1600+ felt too wide for our table/card density; 1300 is the settled
   middle ground — modest bump from the original 1100 so 27" monitors don't
   feel half-empty, but compact enough that ranking tables and compare cards
   stay scannable without horizontal eye-travel. Sidebar ads on big monitors
   are anchored to this content edge via calc(50vw ± 650px ± 24px). */
.header-inner {
    max-width: 1300px;
    margin: 0 auto;
    padding: 0 24px;
    height: 100%;
    display: flex;
    align-items: center;
    gap: 12px;
}
header h1 { font-size: 20px; font-weight: 700; color: var(--accent); letter-spacing: 0.5px; }
/* Claude (v0.55.3): push the nav cluster to the right on every page. Pages with a
   .player-search-wrap (which carries its own margin-left:auto) split the slack with the
   h1 — visually identical end-result. Pages without a search bar (player.html, guild.html)
   relied on the search-wrap's auto-margin for nav alignment and were rendering all nav
   buttons crammed to the left. h1 margin-right:auto fixes both cases. */
header h1 { margin-right: auto; }
header .subtitle { color: var(--text-muted); font-size: 12px; flex: 1; }

/* Claude: dedicated log meta bar below the main header — shows guild/raid/date/duration,
   merged badge, Logs dropdown, notes, and the Copy Link button. Constrained to the same
   max-width + padding as <main> so the left edge lines up with the meter table below. */
/* Claude (v0.35.0): kept in sync with main + .header-inner — see note there. */
#log-meta-bar {
    max-width: 1300px;
    margin: 0 auto;
    padding: 10px 16px;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    color: var(--text-muted);
    flex-wrap: wrap;
    border-bottom: 1px solid var(--border);
}
#log-meta-bar .subtitle { display: block; flex: 1; min-width: 0; }
#log-meta-bar .header-copy-btn { flex-shrink: 0; }
.header-admin-btn {
    color: rgba(212,175,55,0.6);
    text-decoration: none;
    font-size: 16px;
    padding: 3px 8px;
    border-radius: 5px;
    transition: color 0.15s;
    line-height: 1;
}
.header-admin-btn:hover { color: var(--accent); }
.header-admin-btn.active { color: var(--accent); }

/* Claude: rankings button — gold tinted, visible label */
.header-rankings-btn {
    color: var(--accent);
    text-decoration: none;
    font-size: 12px;
    font-weight: 700;
    white-space: nowrap;
    padding: 4px 10px;
    border: 1px solid rgba(212,175,55,0.4);
    border-radius: 5px;
    background: rgba(212,175,55,0.08);
    transition: all 0.12s;
    margin-right: 4px;
}
.header-rankings-btn:hover { background: rgba(212,175,55,0.18); border-color: var(--accent); }
/* Claude: active-state — nav button for the current page gets a filled accent look so the
   user always knows where they are. Auto-applied by utils.js on DOMContentLoaded. */
.header-rankings-btn.active {
    background: var(--accent);
    color: #0e1117;
    border-color: var(--accent);
    box-shadow: 0 1px 4px rgba(212,175,55,0.35);
}
.header-rankings-btn.active:hover { background: var(--accent); color: #0e1117; }

/* Claude (v0.50.0): Tools dropdown — collapses Talents / Armory / Softres into a single
   header button with a downwards arrow. Wrap is the click target's parent (relative pos).
   Menu is absolutely positioned below; .open class on the wrap reveals it. */
.header-tools-wrap { position: relative; display: inline-block; margin-right: 4px; }
.header-tools-wrap .header-tools-btn {
    /* Claude: type=button on a <button> sharing .header-rankings-btn — strip native button look */
    cursor: pointer;
    margin-right: 0;       /* wrap already provides the right margin */
    font-family: inherit;
}
.header-tools-arrow { margin-left: 4px; font-size: 9px; opacity: 0.85; display: inline-block; transition: transform 0.12s; }
.header-tools-wrap.open .header-tools-arrow { transform: rotate(180deg); }
.header-tools-menu {
    position: absolute;
    top: calc(100% + 4px);
    /* Claude (v0.56.19): align the dropdown's LEFT edge with the Tools button
       (was right:0 which anchored to the right edge instead). The wrap is
       position:relative around the button, so left:0 + width:max-content gives
       a menu that starts where the button starts. */
    left: 0;
    /* Claude (v0.56.18): width auto-fits to the widest item instead of the
       hard-coded 160px min-width. width:max-content sizes to the natural width
       of the largest <a> child (item text + padding); min-width nudges to a
       sensible floor so single-letter labels still get a usable click target. */
    width: max-content;
    min-width: 120px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 4px 14px rgba(0,0,0,0.4);
    padding: 4px;
    z-index: 200;
    display: none;
}
.header-tools-wrap.open .header-tools-menu { display: block; }
.header-tools-menu a {
    display: block;
    /* Claude (v0.56.19): items use the same accent (orange) as the header
       buttons themselves — was var(--text) which read as off-white. */
    color: var(--accent);
    text-decoration: none;
    font-size: 12px;
    font-weight: 600;
    padding: 7px 12px;
    border-radius: 4px;
    white-space: nowrap;
}
.header-tools-menu a:hover { background: rgba(212,175,55,0.18); color: var(--accent); }

/* Claude: 3.3.5 client badge — Kezan / Gurubashi. Same orange style as the header nav
   buttons so it sits naturally alongside them. Used in the log meta bar, speedrun widgets,
   and uploaded-logs listings. */
.server-pill {
    display: inline-block;
    color: var(--accent);
    font-size: 10px;
    font-weight: 700;
    /* Claude (v0.56.12): tighter padding for the new 2-char abbreviated text
       (Kezan → KZ, Gurubashi → GB). Was 1px 8px when the badge held the full
       name; now sits at the same visual weight as a small inline tag. */
    padding: 1px 5px;
    border: 1px solid rgba(212,175,55,0.4);
    border-radius: 5px;
    background: rgba(212,175,55,0.08);
    white-space: nowrap;
    letter-spacing: 0.4px;
    vertical-align: middle;
}
/* Claude: shown when a group's logs span multiple servers — should never happen in practice
   (upload enforces a single server per log, group matching is per-guild per-night), so this
   is a loud red warning rather than a neutral pill. */
.server-pill.multiple {
    color: #fc8181;
    border-color: rgba(252,129,129,0.5);
    background: rgba(252,129,129,0.1);
}
/* Claude: .header-back removed — unused dead selector */

/* Claude: header search input — gold border/placeholder to match header button family */
.header-search-input {
    background: rgba(212,175,55,0.05);
    border: 1px solid rgba(212,175,55,0.3);
    color: var(--text);
    padding: 5px 10px;
    border-radius: 5px;
    font-size: 13px;
    outline: none;
    width: 180px;
    transition: all 0.12s;
}
.header-search-input:focus {
    border-color: var(--accent);
    background: rgba(212,175,55,0.08);
}
.header-search-input::placeholder { color: rgba(212,175,55,0.45); }

/* Claude: copy-link button — same gold style as .header-rankings-btn */
.header-copy-btn {
    color: var(--accent);
    background: rgba(212,175,55,0.08);
    border: 1px solid rgba(212,175,55,0.4);
    font-size: 12px;
    font-weight: 700;
    padding: 4px 10px;
    border-radius: 5px;
    cursor: pointer;
    transition: all 0.12s;
    white-space: nowrap;
    margin-right: 4px;
}
.header-copy-btn:hover { background: rgba(212,175,55,0.18); border-color: var(--accent); }

/* Claude: version badge — small monospace button appended to header by changelog.js */
.version-badge {
    background: none;
    border: 1px solid rgba(212,175,55,0.35);
    color: rgba(212,175,55,0.7);
    font-size: 11px;
    padding: 3px 8px;
    border-radius: 4px;
    cursor: pointer;
    margin-left: 8px;
    font-family: monospace;
    transition: all 0.12s;
    white-space: nowrap;
}
.version-badge:hover { border-color: var(--accent); color: var(--accent); }

/* Claude (v0.41.0): footer-mounted version badge — initVersionBadge now appends to
   <footer> instead of the header. Make it look like an inline footer link rather than
   the small monospace pill it was. The .version-badge above still applies its base
   styling; .footer-mounted overrides margin and adds a separator dot. */
.version-badge.footer-mounted {
    margin-left: 0;
    background: none;
    border: none;
    padding: 0 4px;
    color: var(--text-muted);
    text-decoration: underline dotted transparent;
    transition: color 0.12s, text-decoration-color 0.12s;
}
.version-badge.footer-mounted:hover {
    color: var(--accent);
    text-decoration-color: var(--accent);
}

/* Claude (v0.41.1): the v0.41.0 dropdown approach (.auth-widget-pill / .auth-menu)
   was reverted because the caret + menu crowded the navbar. The widget is back to a
   simple avatar+name+logout layout (styled inline in js/auth.js); admin shortcut
   lives on the /profile page itself. */

.pet-toggle-btn {
    background: none;
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 12px;
    padding: 3px 10px;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.12s;
    white-space: nowrap;
    margin-left: auto;
    margin-right: 8px;
}
.pet-toggle-btn:hover  { color: var(--text); border-color: var(--text-muted); }
.pet-toggle-btn.active { color: var(--green); border-color: var(--green); background: #1a2e1a; }

/* Wipe fight entries in the fight dropdown */
option.fight-wipe { color: var(--red); }

/* Wipe label shown in the fight duration bar */
#fight-duration { color: var(--text-muted); }
#fight-duration.is-wipe { color: var(--red); }

/* ── Footer ──────────────────────────────────────────────────── */
footer {
    display: flex;
    align-items: center;
    justify-content: center;
    /* Claude (v0.75.1 mobile): added flex-wrap so footer doesn't overflow horizontally
       on phones. With 8 items at 11px + 12px gaps the natural width is ~570px,
       so anything narrower (every phone) was being clipped or causing the whole
       page to side-scroll. row-gap kept tight (6px) so wrapped lines hug each
       other; column-gap stays at 12px between sibling items. */
    flex-wrap: wrap;
    gap: 6px 12px;
    padding: 24px 16px 20px;
    color: var(--text-muted);
    font-size: 11px;
    border-top: 1px solid var(--border);
    margin-top: 32px;
}
footer strong { color: var(--text-secondary); }
footer a {
    color: var(--text-muted);
    text-decoration: none;
    transition: color 0.12s;
}
footer a:hover { color: var(--accent); }

/* ── Homepage intro copy ── */
/* Collapsed behind a <details> toggle so it doesn't dominate above-the-fold space. */
.home-intro-wrap {
    max-width: 900px;
    margin: 12px auto 16px;
}
.home-intro-wrap summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 12px;
    color: var(--text-muted);
    cursor: pointer;
    list-style: none;
    user-select: none;
    transition: all 0.12s;
}
.home-intro-wrap summary::-webkit-details-marker { display: none; }
.home-intro-wrap summary::before {
    content: '▸';
    font-size: 10px;
    transition: transform 0.15s;
}
.home-intro-wrap[open] summary::before { transform: rotate(90deg); }
.home-intro-wrap summary:hover,
.home-intro-wrap[open] summary { border-color: var(--accent); color: var(--text); }

.home-intro {
    margin: 10px 0 0;
    padding: 18px 22px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
}
.home-intro h2 {
    font-size: 16px;
    font-weight: 700;
    color: var(--accent);
    margin: 0 0 10px 0;
}
.home-intro p {
    font-size: 13px;
    line-height: 1.6;
    color: var(--text-muted);
    margin: 0 0 10px 0;
}
.home-intro p:last-child { margin-bottom: 0; }
.home-intro strong { color: var(--text); }

/* ── Legal / About pages (scoped so dense rules don't bleed in) ── */
.legal {
    max-width: 720px;
    margin: 32px auto;
    padding: 0 20px;
    line-height: 1.65;
    color: var(--text);
}
.legal h1 {
    margin: 0 0 10px;
    font-size: 24px;
    color: var(--accent);
}
.legal h2 {
    margin: 28px 0 10px;
    font-size: 15px;
    color: var(--text);
    border-bottom: 1px solid var(--border);
    padding-bottom: 6px;
}
.legal p, .legal li {
    margin-bottom: 10px;
    font-size: 13.5px;
    color: var(--text);
}
.legal ul { padding-left: 22px; margin-bottom: 14px; }
.legal em { color: var(--text-muted); font-size: 12px; font-style: italic; }
.legal a { color: var(--accent); text-decoration: none; }
.legal a:hover { text-decoration: underline; }

/* Cookie consent banner CSS removed — superseded by Google's CMP, which renders its own
   UI for EU/UK/CH visitors. Non-EU visitors don't see a banner by policy. */

/* ── Main layout ─────────────────────────────────────────────── */
/* Claude (v0.35.5): final max-width 1300px (iterated 1100 → 1600 → 1800 →
   1600 → 1300). The data dashboard pages — Rankings tables, Compare cards,
   Meta box-plots, Timeline lanes — read better at modestly compact widths
   than at fully-stretched ones. 1300px is the sweet spot: meaningfully
   wider than the original 1100 so 27" monitors don't feel half-empty, but
   compact enough that tables/cards stay scannable. Sidebar ads on big
   monitors hug the 1300px edge via calc(50vw ± 650px ± 24px). */
main {
    max-width: 1300px;
    margin: 0 auto;
    padding: 24px 16px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* Claude: .header-upload-btn removed — element uses .header-rankings-btn class instead */

/* ── AdSense placements (Claude v0.35.6) ────────────────────────────────────
   Placeholder containers are now FULLY TRANSPARENT — no background, no
   border, no min-height, no "Advertisement" label. Slot stays in DOM so
   AdSense can still inject the <ins class="adsbygoogle"> and fill it; when
   filled, the ad's own content shows. When unfilled, AdSense sets
   data-ad-status="unfilled" and applies display:none to its <ins>, so the
   wrapper collapses invisibly. Result: visitors only see real ads, never
   empty placeholder boxes during ad-load or fill failure. */
.ad-in-content {
    width: 100%;
    margin: 16px 0;
    overflow: hidden;
    text-align: center;
}

/* Sidebar rails — content-edge anchored via calc(50vw ± 800px ± 24px).
   Math: content is 1600px wide, centered. Half-width = 800px. Content edges
   live at 50vw ± 800px. The 24px adds breathing space between content and ad.
   Result: ad's inner edge sits 24px outside the content edge regardless of
   viewport size, instead of stuck to the viewport edge in the periphery.
   Claude (v0.35.3): 300×600 half-page → 160×600 wide skyscraper. The 300×600
   felt visually too heavy (42% of vertical viewport on 1440p) — the smaller
   skyscraper sits in the gutter without dominating. */
.ad-sidebar-left,
.ad-sidebar-right {
    position: fixed;
    top: 80px;               /* below 56px header + breathing room */
    width: 160px;            /* wide skyscraper — keeps explicit size so AdSense knows the slot dimensions */
    height: 600px;
    z-index: 5;              /* below modals (100+) and dropdowns (50+) */
    overflow: hidden;
    display: none;           /* hidden until viewport is wide enough; chrome removed in v0.35.6 so invisible until filled */
}
.ad-sidebar-left  { right: calc(50vw + 650px + 24px); } /* right edge = content's left edge − 24px */
.ad-sidebar-right { left:  calc(50vw + 650px + 24px); } /* left edge  = content's right edge + 24px */

/* Claude (v0.35.5): content shrunk from 1600 → 1300, so the calc anchor is
   now 650px (was 800). Threshold lowered slightly: 1300 + 2×(24 + 160 + 16) =
   1700px minimum. Bumped to 2000px so 1080p users (1920px) still don't see
   sidebars — their 310px gutter would technically fit a 160px ad with
   breathing space, but ads on top of an already-narrow viewport feels
   cramped. Only 1440p+ users (2560px) get sidebars, with ~446px outer
   breathing. */
@media (min-width: 2000px) {
    .ad-sidebar-left,
    .ad-sidebar-right { display: block; }
}

/* Claude (v0.35.6): "Advertisement" ::before pseudo-elements removed.
   They were always visible regardless of fill state, defeating the purpose
   of hiding the placeholder until an ad actually loads. Real AdSense ads
   already render with their own visible "Ad" / "Sponsored" labelling per
   Google's serving rules, so visitors aren't misled. */

/* ── Fight row ───────────────────────────────────────────────── */
#fight-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.filter-group { display: flex; gap: 4px; }

.filter-btn {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 5px 14px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 12px;
    font-weight: 600;
    transition: all 0.15s;
    white-space: nowrap;
}
.filter-btn:hover { color: var(--text); border-color: var(--accent); }
.filter-btn.active { background: #2a1f00; border-color: var(--accent); color: var(--accent); }

#fight-select {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 6px 10px;
    border-radius: 6px;
    flex: 1;
    min-width: 200px;
    font-size: 13px;
}
#fight-select:focus { outline: none; border-color: var(--accent); }

/* ── Tabs row ────────────────────────────────────────────────── */
#tabs-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.tabs { display: flex; gap: 6px; }
.tab-btn {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 6px 16px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    transition: all 0.15s;
}
.tab-btn:hover { color: var(--text); border-color: var(--accent); }
.tab-btn.active[data-tab="damage"]  { background: #7f1d1d; border-color: #e53e3e; color: #fff; }
.tab-btn.active[data-tab="healing"] { background: #1a4731; border-color: #38a169; color: #fff; }
.tab-btn.active[data-tab="taken"]   { background: #7b341e; border-color: #dd6b20; color: #fff; }
.tab-btn.active[data-tab="deaths"]  { background: #2d1515; border-color: var(--red); color: #fff; }
.tab-btn.active[data-tab="casts"]      { background: #1a2744; border-color: #63b3ed; color: #fff; }
.tab-btn.active[data-tab="interrupts"] { background: #2d1a44; border-color: #a78bfa; color: #fff; }
.tab-btn.active[data-tab="dispels"]    { background: #134e4a; border-color: #2dd4bf; color: #fff; }
.tab-btn.active[data-tab="buffs"]      { background: #1a2e3a; border-color: #4fd1c5; color: #fff; } /* Claude: buffs tab active state */
.tab-btn.active[data-tab="friendlyfire"] { background: #3b1a1a; border-color: #f56565; color: #fff; } /* Claude: friendly fire tab */
.tab-btn.active[data-tab="overhealing"] { background: #3a2a00; border-color: #ecc94b; color: #fff; } /* Claude: overhealing tab */
.tab-btn.active[data-tab="resources"]   { background: #1e3a5f; border-color: #60a5fa; color: #fff; } /* Claude (v0.37.0): resources tab — sub-tabs for Mana/Rage/Focus/Energy/Happiness/Runic/Extra Attacks */
/* Claude (v0.43.24): summary + timeline active rules — both got missed when each tab's
   active styling was cherry-picked above, so the buttons looked unselected even on the
   active tab. Summary uses the accent gold; Timeline uses a violet to match the cast
   timeline's purple aesthetic. */
.tab-btn.active[data-tab="summary"]     { background: #2a1f00; border-color: var(--accent); color: var(--accent); }
.tab-btn.active[data-tab="timeline"]    { background: #2d1a44; border-color: #a78bfa; color: #fff; }

/* Claude (v0.39.2): on the Resources tab, the parse-badge column is always empty
   (no percentile concept for resource gains) so we shift .meter-bar left to fill
   that 72px of dead space. Bar now starts at left:14px (just past row padding) and
   extends across both parse + rank columns; the rank "#N" text still renders on top
   because it has no z-index conflict with the bar (bar is opacity:0.2 + behind in
   DOM order). Without this rule the bar started at left:86px and the row read as
   "wasted empty space + then a small bar in the middle". */
#meter-panel.tab-resources .meter-bar { left: 14px; }

#fight-stats { color: var(--text-muted); font-size: 12px; margin-left: auto; }

/* ── Icons ───────────────────────────────────────────────────── */
.class-icon {
    width: 20px; height: 20px;
    border-radius: 3px;
    object-fit: cover;
    flex-shrink: 0;
    display: block;
}
.class-icon-placeholder {
    display: inline-block;
    width: 20px; height: 20px;
}
.spell-icon {
    width: 20px; height: 20px;
    border-radius: 3px;
    object-fit: cover;
    display: block;
    background: var(--surface2);
}

/* ── Meter ───────────────────────────────────────────────────── */
#meter-panel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
}
.meter-header {
    display: grid;
    grid-template-columns: 36px 36px 24px 1fr 90px 80px 60px;
    padding: 8px 14px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
    background: var(--surface2);
}
.meter-row {
    display: grid;
    grid-template-columns: 36px 36px 24px 1fr 90px 80px 60px;
    align-items: center;
    /* Claude (v0.56.9): tighter rows — matches the v0.56.6 homepage trim. Was
       7px / 14px / min-height:34px (≈48px row); now 4px / 14px / 28px (≈36px row). */
    padding: 4px 14px;
    position: relative;
    cursor: pointer;
    border-bottom: 1px solid rgba(255,255,255,0.03);
    transition: background 0.1s;
    overflow: hidden;
    min-height: 28px;
}
.meter-row:last-child { border-bottom: none; }
.meter-row:hover    { background: rgba(255,255,255,0.04); }
.meter-row.selected { background: rgba(255,255,255,0.07); }

.meter-parse { display:flex; align-items:center; justify-content:center; position:relative; z-index:1; width:100%; }

.meter-bar {
    position: absolute;
    left: 86px; top: 0; bottom: 0; /* Claude: offset past parse-badge + rank cols (14px padding + 36px + 36px) */
    opacity: 0.2;
    pointer-events: none;
    transition: width 0.3s ease;
}
.meter-rank  { color: var(--text-muted); font-size: 14px; }
.meter-name  { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 8px; display: flex; align-items: center; gap: 6px; }

/* WarcraftLogs-style parse percentile badge */
.parse-badge {
    display: inline-block;
    font-size: 13px;
    font-weight: 700;
    font-family: monospace;
    padding: 1px 5px;
    border-radius: 3px;
    border: 1px solid currentColor;
    opacity: 0.9;
    flex-shrink: 0;
    letter-spacing: 0.3px;
}
/* Claude: Tank shield emoji in meter rows — marks players detected as tank for the active fight.
   Shows before the player name in every tab (Damage Done / Taken / Healing / Casts / …).
   Uses the same 🛡 shield as the rankings page Tank button. */
.tank-icon {
    font-size: 16px;
    flex-shrink: 0;
    line-height: 1;
}
/* Claude (v0.56.6): <GM> tag rendered next to verified Guildmaster character names. */
.gm-tag {
    display: inline-block;
    font-size: 9px;
    font-weight: 700;
    color: #e5cc80;
    background: rgba(229,204,128,0.10);
    border: 1px solid rgba(229,204,128,0.5);
    border-radius: 3px;
    padding: 0 4px;
    margin-right: 4px;
    line-height: 1.4;
    vertical-align: middle;
    flex-shrink: 0;
    letter-spacing: 0.04em;
}
/* Claude (v0.56.6): verified guild icon — sits in the .tbl-guild / .saved-log-guild
   pill before the name. Single rule on .guild-icon, applied wherever the helper renders. */
.guild-icon {
    width: 12px; height: 12px;
    border-radius: 2px;
    margin-right: 4px;
    vertical-align: -2px;
    object-fit: cover;
    display: inline-block;
}
/* ── Top Parsers section (homepage) ──────────────────── */
.parsers-section {
    margin-bottom: 24px;
}
.parsers-section-header {
    font-size: 13px;
    font-weight: 700;
    color: var(--accent);
    margin-bottom: 10px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.parsers-widgets {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}
/* Claude (v0.54.7): on narrow screens the desktop's inline grid-template-columns
   (set in overview.js to balance widgets across two rows) would overflow horizontally.
   Revert to flex-wrap so widgets stack naturally on mobile. */
@media (max-width: 700px) {
    .parsers-widgets {
        display: flex !important;
        flex-wrap: wrap;
        grid-template-columns: none !important;
    }
}
.parse-widget {
    flex: 1;
    min-width: 155px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    font-size: 12px;
}
.pwgt-body {
    /* Claude (v0.56.6): 5 rows × 28px row height = 140px (was 155px = 5 × 31px). */
    max-height: 140px;
    overflow-y: auto;
    scroll-snap-type: y mandatory;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}
.parse-widget-title {
    background: var(--surface2);
    padding: 4px 6px 4px 10px;
    font-size: 11px;
    font-weight: 700;
    /* Claude (v0.56.23): boss-name title uses the boss color (--boss). The
       --overall variant below overrides for the gold ⚡ Overall pill. */
    color: var(--boss);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
}
.pwgt-title-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wgt-maximize-btn {
    flex-shrink: 0;
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 13px;
    padding: 1px 3px;
    border-radius: 3px;
    line-height: 1;
    opacity: 0.6;
    transition: opacity 0.15s, color 0.15s;
}
.wgt-maximize-btn:hover { opacity: 1; color: var(--accent); }
/* Claude: collapse/minimize button inside parse widget title bar — same style as maximize */
.wgt-collapse-btn {
    flex-shrink: 0;
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: 11px;
    padding: 1px 4px;
    border-radius: 3px;
    line-height: 1;
    opacity: 0.6;
    transition: opacity 0.15s, color 0.15s;
}
.wgt-collapse-btn:hover { opacity: 1; color: var(--accent); }
/* Hide body when a parse widget is collapsed */
.parse-widget.pwgt-collapsed .pwgt-body { display: none; }
/* Claude: each row IS the bar — rank+dps on left, icon+name on right, all overlaid */
.pwgt-row {
    position: relative;
    /* Claude (v0.56.6): trimmed 31px → 28px (~10%) for a more compact homepage look. */
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid rgba(0,0,0,0.25);
    overflow: hidden;
    background: var(--surface2);
    scroll-snap-align: start;
    cursor: pointer;
    flex-shrink: 0;
}
.pwgt-row:last-child { border-bottom: none; }
.pwgt-row:hover { filter: brightness(1.25); }
.pwgt-bar {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    opacity: 0.35;
    pointer-events: none;
    z-index: 0;
    border-radius: 0 2px 2px 0;
}
.pwgt-left, .pwgt-right {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 0 7px;
    line-height: 1;
}
.pwgt-rank { font-size: 12px; font-weight: 700; color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,0.9); }
.pwgt-dps  { font-size: 12px; font-weight: 700; font-family: monospace; color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,0.9); }
.pwgt-name { font-size: 11px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100px; color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,0.9); }
.pwgt-empty { padding: 10px; color: var(--text-muted); font-size: 11px; text-align: center; }

/* ── Player parse modal ──────────────────────────────────────────────────── */
/* Claude (v0.18.2): widened from 420px — role-split sub-sections + Peak column were
   cramming the parse tables. 580px gives boss names + spec icon + values breathing room
   on desktop, still wraps cleanly on phones via width:100% + max-width. */
#player-modal .modal-box { max-width: 580px; width: 100%; }
.player-modal-header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
}
.player-modal-name { font-size: 16px; font-weight: 700; color: var(--text); }
.player-modal-spec { font-size: 11px; color: var(--text-muted); }
.player-parse-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.player-parse-table th {
    text-align: left;
    font-size: 10px;
    font-weight: 700;
    color: var(--text-muted);
    letter-spacing: 0.5px;
    padding: 0 0 6px;
    border-bottom: 1px solid var(--border);
}
.player-parse-table th:not(:first-child) { text-align: right; }
.player-parse-table td {
    padding: 6px 0;
    border-bottom: 1px solid var(--border);
    color: var(--text);
}
.player-parse-table td:not(:first-child) { text-align: right; }
.player-parse-table tr:last-child td { border-bottom: none; }
.ppt-boss { font-weight: 600; }
.ppt-dps  { font-family: monospace; color: var(--accent); }
.ppt-badge {
    display: inline-block;
    min-width: 32px;
    text-align: center;
    font-weight: 700;
    font-size: 11px;
    padding: 1px 5px;
    border-radius: 4px;
    border: 1px solid currentColor;
}
.wgt-icon    { width: 22px; height: 22px; border-radius: 3px; display: block; flex-shrink: 0; }
.wgt-icon-ph { display: inline-block; width: 22px; height: 22px; flex-shrink: 0; }
/* Claude: Overall raid widget gets a gold accent header to stand out from per-boss widgets */
.parse-widget--overall { border-color: rgba(255, 215, 0, 0.25); }
.parse-widget-title--overall { background: rgba(255, 215, 0, 0.10); color: #ffd700; }
/* Claude: HPS section header uses green accent instead of gold */
.parsers-section-header--hps { color: var(--green); margin-top: 14px; }
/* Claude: larger rows in widget maximize modal — no scroll-snap, taller for readability */
.pwgt-row--lg { height: 36px; scroll-snap-align: none; }
.pwgt-name--lg { max-width: 200px; font-size: 12px; }
/* Widget maximize modal — wider box */
.widget-modal-box { max-width: 480px; width: 100%; }

.meter-value { text-align: right; font-family: monospace; font-size: 13px; color: var(--accent); }
.meter-ps    { text-align: right; font-family: monospace; font-size: 12px; color: var(--text-muted); }
.meter-pct   { text-align: right; font-family: monospace; font-size: 12px; color: var(--text-muted); }

.empty-state { padding: 40px; text-align: center; color: var(--text-muted); }

/* Claude (v0.43.4): global .hidden rule. Was previously only defined for
   #detail-panel / .modal-overlay / .player-search-dropdown — every other
   element with class="hidden" (notably the #detail-important-btn toggle in
   log.html, plus #progression-section / #raid-sections / #overview-section
   on the homepage during initial load) was actually visible. The Important
   toggle showed up on the Damage / Healing / Casts player detail panels
   even though openDetail tried to hide it via classList.add('hidden') —
   that classList call was a no-op without this rule. */
.hidden { display: none; }

/* ── Detail panel ────────────────────────────────────────────── */
#detail-panel { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
#detail-panel.hidden { display: none; }

.detail-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    background: var(--surface2);
    border-bottom: 1px solid var(--border);
}
#detail-title { font-weight: 700; font-size: 15px; display: flex; align-items: center; gap: 8px; }
#detail-close { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: 18px; padding: 0 4px; line-height: 1; }
#detail-close:hover { color: var(--text); }

.detail-col-headers {
    display: grid;
    grid-template-columns: 24px 1fr 130px 80px 60px;
    padding: 6px 14px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
}
.detail-row {
    display: grid;
    grid-template-columns: 24px 1fr 130px 80px 60px;
    align-items: center;
    padding: 6px 14px;
    position: relative;
    overflow: hidden;
    border-bottom: 1px solid rgba(255,255,255,0.03);
}
/* Claude: expanded miss-column layout for the damage tab */
.detail-col-headers.expanded,
.detail-row.expanded {
    grid-template-columns: 24px 1fr 50px 80px 70px 70px 70px 70px 72px 50px;
}
/* Claude: shrink header text in expanded mode so labels fit the narrow miss columns */
.detail-col-headers.expanded span {
    font-size: 9px;
    letter-spacing: 0.2px;
}
.detail-miss { font-size: 12px; color: var(--text-muted); text-align: right; }
.detail-row:last-child { border-bottom: none; }
.detail-bar   { position: absolute; left: 0; top: 0; bottom: 0; opacity: 0.15; pointer-events: none; }
.detail-spell { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 8px; }
.detail-hits  { font-size: 12px; color: var(--text-muted); }
.detail-total { text-align: right; font-family: monospace; font-size: 13px; color: var(--accent); }
.detail-pct   { text-align: right; font-family: monospace; font-size: 12px; color: var(--text-muted); }

/* Claude (v0.36.5): Buffs detail panel layout — adds an "Uptime timeline" column
   that shows actual time windows instead of just a fill-bar proportional to %.
   Claude (v0.36.7): widened columns + standardized gap. UPTIME % header was
   wrapping because the column was only 56px; bumped to 70px and reduced count
   column to 56px (1× / 99× fits in less). Added column-gap so the timeline
   track doesn't touch the % cell. */
.detail-row-buff,
.detail-col-headers.detail-col-headers-buff {
    grid-template-columns: 24px minmax(0, 1fr) 56px 70px minmax(160px, 2.5fr);
    column-gap: 12px;
}
.detail-row-buff .detail-spell { padding-right: 0; }
.detail-row-buff .detail-total,
.detail-row-buff .detail-pct,
.detail-col-headers.detail-col-headers-buff > span:nth-child(3),
.detail-col-headers.detail-col-headers-buff > span:nth-child(4) {
    text-align: right;
    white-space: nowrap;
}
.detail-col-headers.detail-col-headers-buff > span:nth-child(5) {
    text-align: left;
    white-space: nowrap;
}
.aura-tl-track {
    position: relative;
    height: 16px;
    background: rgba(255,255,255,0.04);
    border-radius: 3px;
    overflow: hidden;
    border: 1px solid rgba(255,255,255,0.05);
    cursor: crosshair;
}
.aura-tl-segment {
    position: absolute;
    top: 0;
    bottom: 0;
    border-radius: 1px;
    opacity: 0.85;
    pointer-events: none;
}
.aura-tl-empty {
    color: var(--text-muted);
    font-size: 10px;
    font-style: italic;
    padding: 2px 8px;
}

/* Claude (v0.36.8): time axis row above the aura rows + shared hover cursor
   that spans across all tracks so the user can see what aura was up at any
   given fight time at a glance. Axis row uses the same grid as detail-row-buff
   so the timeline column aligns with the rows below. */
.detail-row-buff.aura-tl-axis-row {
    padding: 4px 14px 6px;
    border-bottom: 1px solid var(--border);
    font-size: 10px;
    color: var(--text-muted);
    cursor: default;
}
.aura-tl-axis {
    position: relative;
    height: 14px;
}
.aura-tl-tick {
    position: absolute;
    top: 0;
    transform: translateX(-50%);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.aura-tl-tick::before {
    content: '';
    display: block;
    height: 4px;
    width: 1px;
    background: rgba(255,255,255,0.18);
    margin: 0 auto -2px;
}
.aura-tl-cursor {
    position: absolute;
    top: -2px;
    bottom: -2px;
    width: 1px;
    background: rgba(255,255,255,0.7);
    opacity: 0;
    pointer-events: none;
    z-index: 2;
}
.aura-tl-cursor.visible { opacity: 1; }
.aura-tl-time-label {
    display: none;
    position: absolute;
    top: 14px;
    transform: translateX(-50%);
    font-size: 10px;
    color: var(--text);
    background: var(--surface2);
    padding: 1px 6px;
    border-radius: 3px;
    border: 1px solid var(--border);
    pointer-events: none;
    z-index: 3;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.aura-tl-time-label.visible { display: block; }

/* Claude (v0.36.10): always-visible time readout that lives in the axis row.
   Shows the cursor's current fight time anchored at the top of the panel so
   users see the time regardless of which row their mouse is over. The
   per-row .aura-tl-time-label still shows a redundant label near the cursor
   for convenience, but THIS is the one that always works. */
.aura-tl-axis-time {
    position: absolute;
    top: -2px;
    transform: translateX(-50%);
    font-size: 10px;
    font-weight: 700;
    color: var(--accent);
    background: var(--surface);
    padding: 1px 6px;
    border-radius: 3px;
    border: 1px solid var(--accent);
    pointer-events: none;
    z-index: 4;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ── Spell hover tooltip ─────────────────────────────────────── */
#spell-tooltip {
    display: none;
    position: fixed;
    z-index: 1000;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 0 6px;
    min-width: 320px;
    max-width: 440px;
    max-height: 85vh;
    overflow-y: auto;
    box-shadow: 0 6px 24px rgba(0,0,0,0.6);
    pointer-events: none;
}
#spell-tooltip.visible { display: block; }

.tt-title {
    display: flex;
    align-items: center;
    gap: 7px;
    font-weight: 700;
    font-size: 13px;
    padding: 0 14px 8px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 4px;
}
.tt-header {
    display: grid;
    grid-template-columns: 24px 1fr 90px 50px 44px;
    padding: 3px 14px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.7px;
    color: var(--text-muted);
}
.tt-row {
    display: grid;
    grid-template-columns: 24px 1fr 90px 50px 44px;
    align-items: center;
    padding: 3px 14px;
    font-size: 12px;
    position: relative;
    overflow: hidden;
}
.tt-bar {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    opacity: 0.12;
    pointer-events: none;
}
.tt-spell { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 6px; }
.tt-hits  { font-size: 11px; color: var(--text-muted); }
.tt-val   { text-align: right; font-family: monospace; color: var(--accent); }
.tt-pct   { text-align: right; font-family: monospace; color: var(--text-muted); }

/* ── Deaths detail panel ─────────────────────────────────────── */

.detail-section-header {
    padding: 7px 14px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-muted);
    background: var(--surface2);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.detail-section-header:first-child { border-top: none; }

.death-block-header {
    padding: 6px 14px 4px;
    font-size: 13px;
    font-weight: 700;
    color: var(--red);
    border-bottom: 1px solid rgba(255,255,255,0.05);
}

.death-hit-row {
    display: grid;
    grid-template-columns: 24px 1fr 110px 56px 44px 64px;
    align-items: center;
    padding: 3px 14px;
    font-size: 12px;
    border-bottom: 1px solid rgba(255,255,255,0.02);
}
.death-hit-spell  { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 6px; }
.death-hit-source { color: var(--text-muted); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: 4px; }
.death-hit-ts     { font-family: monospace; font-size: 11px; color: var(--text-muted); text-align: right; padding-right: 4px; }
.death-hit-delta  { font-family: monospace; font-size: 10px; color: var(--text-muted); text-align: right; padding-right: 4px; }
.death-hit-amount { text-align: right; font-family: monospace; }

/* ── Saved Logs panel ────────────────────────────────────────── */
#overview-section { /* Claude: removed dead #saved-logs-section from combined selector */
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
}
#saved-logs-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 16px;
    background: var(--surface2);
    border-bottom: 1px solid var(--border);
    cursor: default;
}
#saved-logs-title {
    font-size: 13px;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: 0.3px;
}
/* Claude: #saved-logs-toggle, #saved-logs-list, .raid-category-* removed — dead selectors, never referenced in JS/HTML */
/* Claude: show exactly 3 full rows (measured 164px from live DOM), snap scroll per row */
#overview-list {
    max-height: 164px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
    scroll-snap-type: y mandatory;
}
.saved-log-row { scroll-snap-align: start; }
.raid-category-body { padding: 4px 0; }

.merged-badge {
    display: inline-block;
    color: #68d391;
    font-size: 11px;
    font-weight: 600;
    background: #1a2e1a;
    border: 1px solid #2d5a3a;
    border-radius: 3px;
    padding: 1px 6px;
    margin-left: 6px;
    vertical-align: middle;
}

.saved-log-row {
    display: grid;
    /* Claude: columns — guild | name (meta, 1fr) | server pill | info | view button */
    grid-template-columns: auto 1fr auto auto auto;
    align-items: center;
    gap: 10px;
    padding: 7px 16px;
    border-bottom: 1px solid rgba(255,255,255,0.03);
}
/* Claude: admin variant — extra columns for Raw dropdown, Relevance badge, Actions dropdown */
.saved-log-row.admin-row {
    /* Claude: guild column is 170px — fits the 20-char maxlength enforced on upload
       (index.html #pub-upload-guild) including pill padding + border. Any legal guild
       name renders without overflowing into the next column, and the fixed width keeps
       every row's columns aligned.
       Server column: 90px — fits 'Gurubashi' + padding. Sortable via admin sort bar.
       Relevance column: 56px — fits .rel-badge (min-width 36 + 16px padding + 2px border)
       plus a little breathing room before the Actions button. Was 30px and overflowed.
       Columns: id | raw | guild | server | meta | info | relevance | actions */
    grid-template-columns: auto auto 170px 90px 1fr 200px 56px 80px;
    gap: 0 6px; /* Claude: no row gap, tight 6px column gap (overrides parent 10px) */
    transition: background 0.12s;
    cursor: default;
}
.saved-log-row:last-child { border-bottom: none; }
.saved-log-row:hover { background: var(--surface2); }
.saved-log-row.hidden-row { opacity: 0.45; } /* Claude: admin hidden logs */

.saved-log-guild {
    width: fit-content;   /* Claude: pill wraps text only — not full column width */
    /* Claude: left-align inside the 170px grid column (was centered via margin:0 auto).
       Matches the left-aligned Guild sort button in the admin sort bar. */
    margin: 0;
    padding: 2px 9px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.3px;
    white-space: nowrap;
    text-align: center;
    background: #2a1f00;
    color: #f0c050;
    border: 1px solid #5a4520;
}
.saved-log-guild.pug {
    background: #1a1f2e;
    color: #8a95a8;
    border-color: #3a4558;
}

/* Claude: guild profile roster — class-colored player pills with appearance count */
.guild-roster-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.guild-roster-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 4px 3px 10px;
    border-radius: 12px;
    border: 1px solid;
    background: rgba(255, 255, 255, 0.02);
    font-size: 12px;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.12s, border-color 0.12s;
    white-space: nowrap;
}
.guild-roster-pill:hover {
    background: rgba(255, 255, 255, 0.06);
    filter: brightness(1.2);
}
.guild-roster-count {
    display: inline-block;
    min-width: 18px;
    padding: 1px 6px;
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.4);
    color: var(--text-muted);
    font-size: 10px;
    font-weight: 700;
    text-align: center;
}

/* Claude: rankings table guild link — transparent so it blends with the row's parse bar gradient */
/* Claude (v0.56.25): inline-flex + gap so the verified guild icon sits cleanly before the name */
.rk-guild {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 1px 8px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.3px;
    white-space: nowrap;
    background: transparent;
    color: rgba(240, 192, 80, 0.75);
    border: 1px solid rgba(240, 192, 80, 0.35);
    text-decoration: none;
    transition: color 0.12s, border-color 0.12s;
}
.rk-guild:hover {
    color: #f0c050;
    border-color: rgba(240, 192, 80, 0.7);
}

/* Claude (v0.33.2): restyled to match the "Log ↗" gold/orange pill. Was using the
   muted-grey palette + cyan marked-state which clashed with the rest of the site's
   dark + orange aesthetic. Now: transparent bg with semi-gold border by default,
   solid gold on hover, soft gold-tinted fill when marked. */
.rk-compare-btn {
    display: inline-block;
    padding: 2px 7px;
    border: 1px solid rgba(212, 175, 55, 0.35);
    border-radius: 4px;
    background: transparent;
    color: rgba(212, 175, 55, 0.8);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    line-height: 1;
    transition: all 0.12s;
}
.rk-compare-btn:hover {
    border-color: var(--accent);
    color: var(--accent);
}
.rk-compare-btn.marked {
    background: rgba(212, 175, 55, 0.15);
    border-color: var(--accent);
    color: var(--accent);
}
.rk-compare-btn.marked:hover { background: rgba(212, 175, 55, 0.25); }

.saved-log-meta {
    font-size: 12px;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.saved-log-meta strong { color: var(--text); font-weight: 600; }

.saved-log-info {
    font-size: 11px;
    color: var(--text-muted);
    white-space: nowrap;
}
.saved-log-info .boss-count { color: var(--accent); font-weight: 600; }

.saved-log-load {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 4px 12px;
    border-radius: 5px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: all 0.12s;
}
.saved-log-load:hover { border-color: var(--accent); color: var(--accent); }

/* Claude: .saved-log-delete removed — dead selector, never referenced */

/* ── Modal ────────────────────────────────────────────────────── */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.65);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    backdrop-filter: blur(2px);
}
.modal-overlay.hidden { display: none; }

.modal-box {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    width: 380px;
    box-shadow: 0 20px 60px rgba(0,0,0,0.5);
    animation: modal-in 0.18s ease;
}
@keyframes modal-in {
    from { transform: translateY(-16px); opacity: 0; }
    to   { transform: translateY(0);     opacity: 1; }
}
.modal-title {
    padding: 16px 20px 12px;
    font-size: 15px;
    font-weight: 700;
    color: var(--accent);
    border-bottom: 1px solid var(--border);
}
.modal-body {
    padding: 16px 20px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
/* Claude: removed unused .modal-label, .modal-input, .modal-pug-label, .modal-footer (no references in HTML/JS) */
.modal-btn {
    padding: 7px 20px;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    border: 1px solid transparent;
    transition: all 0.12s;
}
/* Claude: removed unused .modal-btn-primary (no references in HTML/JS) */
.modal-btn-secondary {
    background: var(--surface2);
    border-color: var(--border);
    color: var(--text-muted);
}
.modal-btn-secondary:hover { border-color: var(--text-muted); color: var(--text); }

/* ── Scrollbar ───────────────────────────────────────────────── */
::-webkit-scrollbar       { width: 6px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

/* ── Progression page rows ──────────────────────────────────────────────── */
/* Claude: shared layout for both "First Full Clear" and "Per-boss First Kills" tables.
   Grid columns: rank/boss · team · server · date. Rows are clickable; hover brightens. */
.prog-row {
    display: grid;
    /* Claude: rank/boss · team · server · date.
       Claude (v0.54.6): date column shrunk 170px → 95px now that fmtDate emits the compact
       "3 May · 23:18" format (was "17 Apr 2026 · 20:34:11"). The reclaimed 75px goes to the
       team (1fr) column so guild names stop truncating.
       Claude (v0.54.8): server-pill column changed from auto (sized to content) to fixed
       90px so it matches the Guild Progression rows' inline 90px pill column. With matching
       column widths AND server-pill centered (see rule below), all three progression
       sub-cards now have visually identical pill placement.
       Claude (v0.56.12): server column shrunk 90px → 46px now that the badge holds a
       2-char abbreviation ("KZ" / "GB"). The reclaimed 44px flows into the 1fr team column
       so longer guild names don't truncate. */
    grid-template-columns: 70px 1fr 46px 95px;
    gap: 10px;
    align-items: center;
    padding: 8px 14px;
    border-bottom: 1px solid rgba(255,255,255,0.03);
    cursor: pointer;
    font-size: 12px;
    transition: background 0.12s;
}
/* Claude (v0.54.8): center the server-pill within its 90px grid column on every progression
   row variant (.prog-row covers First Full Clear + Per-boss First Kills; .prog-guild-row,
   which also carries .prog-row, covers Guild Progression). justify-self is the per-grid-item
   alignment property; default is `start` (left), `center` puts the pill mid-column with
   equal padding on each side. */
.prog-row .server-pill {
    justify-self: center;
}
/* Claude (v0.56.13/20): Per-boss First Kills variant. v0.56.13 set the boss column
   to 140px to fit full names ("Sulfuron Harbinger", "Golemagg the Incinerator",
   "Majordomo Executus"). v0.56.20 truncates the boss name to its first word in
   progression.js so the column shrinks to 90px — fits longest single-word names
   ("Majordomo" / "Sulfuron" / "Golemagg") with icon + gap. The 50px reclaimed
   flows into the 1fr team column. */
.prog-row.prog-firstkill-row {
    grid-template-columns: 90px 1fr 46px 95px;
}
/* Claude: mobile — stack the two panel columns (progression.js uses inline
   grid-template-columns:1fr 1fr, so we target the parent via its child selector and
   override with !important since inline styles otherwise win). Each row wraps the date
   under the team name so the timestamp stays visible without overflow. */
@media (max-width: 700px) {
    #progression-body > div > div[style*="grid-template-columns:1fr 1fr"],
    .prog-home-block [style*="grid-template-columns:1fr 1fr"] {
        grid-template-columns: 1fr !important;
    }
    .prog-row {
        grid-template-columns: 44px 1fr auto !important;
        grid-template-rows: auto auto;
        padding: 10px 14px;
        row-gap: 2px;
    }
    .prog-date {
        grid-column: 2 / -1 !important;
        grid-row: 2 !important;
        text-align: left !important;
        font-size: 10px;
    }
}
.prog-row:last-child  { border-bottom: none; }
.prog-row:hover       { background: var(--surface2); }
.prog-rank            { font-size: 14px; font-weight: 700; text-align: center; }
/* Claude (v0.56.20/23): guild names use the orange accent treatment; boss names
   use the boss/NPC color (--boss, light coral) so the two are visually distinct
   in the same row. Matches the convention applied site-wide in v0.56.23. */
.prog-boss            { font-size: 12px; font-weight: 700; color: var(--boss);   overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prog-team            { color: var(--accent); font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prog-date            { color: var(--text-muted); font-size: 11px; text-align: right; }
/* Pre-release raids (no kills yet) render at reduced contrast */
.prog-raid-block.pre-release h3 { color: var(--text-muted); }

/* ── Mobile baseline rules (apply across all pages) ──────────────────────── */
@media (max-width: 700px) {
    /* Claude: iOS Safari zooms the viewport when the user focuses a form field whose
       computed font-size is below 16px. Bump every form control to 16px to stop the
       zoom-in — accessible alternative to blocking pinch-zoom via maximum-scale. */
    input, select, textarea,
    .header-search-input, .meta-select { font-size: 16px !important; }

    /* Claude: 44×44 is Apple's accessibility guideline for tap targets. Apply to the
       header nav + admin button. Per-page smaller buttons still exist; we enforce the
       floor on the critical nav and the admin widget action buttons. */
    .header-rankings-btn, .header-admin-btn, .filter-btn,
    .tab-btn, .tf-btn, .action-btn {
        min-height: 44px;
        min-width:  44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    /* Upload modal: full-screen on phones so form + submit stay reachable. */
    #upload-modal-overlay > div {
        max-width: 100vw !important;
        width: 100% !important;
        max-height: 100vh !important;
        margin: 0 !important;
        border-radius: 0 !important;
        overflow-y: auto;
    }
    /* Meta filter bar: drop the inline labels on narrow screens so the row actually fits. */
    #meta-filters label { display: none; }
    #meta-filters { gap: 6px !important; padding: 10px !important; }
}

/* ── Meta page filter selects ───────────────────────────────────────────── */
/* Claude: native <select> defaults to white in dark-mode browsers — theme to match surface2. */
.meta-select {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 5px 10px;
    border-radius: 5px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    outline: none;
    transition: border-color 0.12s;
}
.meta-select:hover  { border-color: var(--accent); }
.meta-select:focus  { border-color: var(--accent); }
.meta-select option { background: var(--surface); color: var(--text); }

/* ── Timeframe filter buttons (index.html) ────────────────────────────── */
.tf-btn {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 4px 12px;
    border-radius: 5px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.12s;
}
.tf-btn:hover  { border-color: var(--accent); color: var(--text); }
.tf-btn.active { background: #2a1f00; border-color: var(--accent); color: var(--accent); }

/* ── Player search dropdown ────────────────────────────────────────────── */
.player-search-dropdown {
    position: absolute;
    top: calc(100% + 4px);
    left: 0; right: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.4);
    z-index: 500;
    overflow: hidden;
}
.player-search-dropdown.hidden { display: none; }
.ps-result {
    padding: 7px 12px;
    font-size: 13px;
    cursor: pointer;
    color: var(--text);
    transition: background 0.1s;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.ps-result:hover { background: var(--surface2); color: var(--accent); }
/* Claude: section header in unified search dropdown — groups players / guilds / log */
.ps-header {
    padding: 6px 14px 4px;
    font-size: 10px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    background: rgba(255,255,255,0.02);
    border-top: 1px solid var(--border);
}
.ps-header:first-child { border-top: none; }
.ps-profile-btn {
    font-size: 11px;
    color: #e5cc80;
    background: #2a1f00;
    border: 1px solid var(--accent);
    border-radius: 4px;
    padding: 1px 8px;
    text-decoration: none;
    font-weight: 600;
    white-space: nowrap;
    transition: background 0.1s;
}
.ps-profile-btn:hover { background: #3a2a00; }

/* ── Rankings page ─────────────────────────────────────────────────────── */
.rankings-layout {
    display: flex;
    gap: 20px;
    align-items: flex-start;
}
.rankings-sidebar {
    width: 200px;
    flex-shrink: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
    position: sticky;
    top: 12px;
}
.rankings-sidebar-raid {
    padding: 8px 12px 4px;
    font-size: 11px;
    font-weight: 700;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    border-top: 1px solid var(--border);
}
.rankings-sidebar-raid:first-child { border-top: none; }
/* Claude (v0.56.23): default boss-link color is --boss; muted on rest, brighter
   on hover, accent on the active page so the user always knows where they are. */
.rankings-sidebar-boss {
    display: block;
    padding: 5px 16px;
    font-size: 13px;
    color: var(--boss);
    cursor: pointer;
    text-decoration: none;
    transition: background 0.1s;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rankings-sidebar-boss:hover  { background: var(--surface2); color: var(--text); }
.rankings-sidebar-boss.active { background: #2a1f00; color: var(--accent); font-weight: 600; }
.rankings-main { flex: 1; min-width: 0; }
.rankings-filters {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-bottom: 14px;
    flex-wrap: wrap;
}
.rk-metric-btn {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 5px 14px;
    border-radius: 5px;
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    transition: all 0.12s;
}
.rk-metric-btn:hover  { border-color: var(--accent); color: var(--text); }
.rk-metric-btn.active { background: #2a1f00; border-color: var(--accent); color: var(--accent); }
.rk-class-select {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 5px 10px;
    border-radius: 5px;
    font-size: 12px;
    outline: none;
    cursor: pointer;
}
.rk-class-select:focus { border-color: var(--accent); }
.rankings-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.rankings-table th {
    padding: 8px 10px;
    text-align: left;
    background: var(--surface2);
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    position: sticky;
    top: 56px; /* Claude: offset below fixed-height page header so they don't overlap */
    z-index: 10; /* Claude: above row backgrounds so sticky header doesn't get covered by bar gradients */
}
/* Claude (v0.56.9): tighter row padding (was 7px) — matches the homepage bar trim. */
.rankings-table td { padding: 4px 10px; border-top: 1px solid rgba(255,255,255,0.04); }
.rankings-table tr:hover td { background: var(--surface2); }
.rk-pagination {
    display: flex;
    gap: 8px;
    align-items: center;
    justify-content: center;
    margin-top: 16px;
    font-size: 13px;
    color: var(--text-muted);
}
.rk-page-btn {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    padding: 4px 12px;
    border-radius: 5px;
    font-size: 12px;
    cursor: pointer;
    transition: all 0.12s;
}
.rk-page-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.rk-page-btn:disabled { opacity: 0.35; cursor: default; }

/* Claude: mobile boss select — hidden by default, shown at ≤700px */
#rk-mobile-boss-select { display: none; }

/* Claude: header-only breakpoint at ≤1000px. Covers iPhone 14 Pro Max landscape (932px),
   iPad portrait (768-1024px), small laptops under the site's natural 1100px header width.
   Forces the nav onto a second row instead of cramming everything horizontally — also
   prevents the h1 from wrapping to 3 lines when buttons squeeze it. The narrower ≤700
   breakpoint below stays the primary "phone" rules block. */
@media (max-width: 1000px) {
    header { height: auto; }
    .header-inner {
        flex-wrap: wrap;
        padding: 8px 16px;
        row-gap: 6px;
    }
    /* Claude: h1 stays single-line (was wrapping into 3 rows when the flex row overflowed).
       flex: 0 0 auto + white-space: nowrap keeps "WarcraftLogs Epog" intact on row 1. */
    header h1 {
        flex: 0 0 auto;
        white-space: nowrap;
        font-size: 18px;
    }
    /* Give the search input room to breathe once the row wraps */
    .player-search-wrap { flex: 1 1 220px; }
    .header-search-input { width: 100%; }
    /* Claude: version badge sits at the end of header-inner and would otherwise overflow
       off-screen when the row wraps. Let it drop onto its own row cleanly. */
    .version-badge { margin-left: auto; }
}

/* ── Mobile responsive ───────────────────────────────────────────────────── */
@media (max-width: 700px) {
    /* Claude: mobile — let header grow if content wraps; inner wrapper uses smaller padding */
    header { height: auto; }
    .header-inner { padding: 10px 12px; gap: 6px; flex-wrap: wrap; }
    header h1 { font-size: 17px; }
    /* Hide non-essential header items on small screens */
    .header-copy-btn { display: none; }
    .version-badge   { display: none; }

    main { padding: 12px 8px; gap: 10px; }

    /* Fight row — stack filters above select */
    #fight-row { gap: 6px; }
    #fight-select { min-width: 0; }

    /* Tabs — allow wrapping */
    #tabs-row { gap: 6px; }
    .tabs { flex-wrap: wrap; gap: 4px; }
    .tab-btn { font-size: 11px; padding: 5px 9px; }
    .pet-toggle-btn { font-size: 11px; padding: 3px 7px; }

    /* Meter — drop Per Sec and % columns, keep parse badge + rank + icon + name + total */
    .meter-header,
    .meter-row {
        grid-template-columns: 34px 30px 22px 1fr 80px;
    }
    /* Hide Per Sec (6th) and % (7th) columns */
    .meter-header > span:nth-child(6),
    .meter-header > span:nth-child(7),
    .meter-row > .meter-ps,
    .meter-row > .meter-pct { display: none; }

    /* Detail panel */
    .detail-col-headers,
    .detail-row,
    .detail-col-headers.expanded,
    .detail-row.expanded {
        grid-template-columns: 24px 1fr 80px 60px;
    }
    /* Hide % column and all miss columns on mobile */
    .detail-col-headers > span:last-child,
    .detail-row > .detail-pct,
    .detail-miss { display: none; }

    /* Footer */
    footer { padding: 16px 8px; }

    /* Rankings — hide sidebar, show mobile dropdown */
    .rankings-sidebar { display: none; }
    #rk-mobile-boss-select {
        display: block;
        width: 100%;
        background: var(--surface2);
        border: 1px solid var(--border);
        color: var(--text);
        padding: 8px 10px;
        border-radius: 6px;
        font-size: 13px;
        margin-bottom: 12px;
    }
    #rk-mobile-boss-select option { background: var(--surface2); color: var(--text); }
    #rk-mobile-boss-select optgroup { background: var(--surface); color: var(--accent); }
    /* Claude: hide placeholder texts on mobile — dropdown replaces sidebar */
    .rk-placeholder { display: none; }
    #rk-title { display: none; }
    .rankings-layout { flex-direction: column; gap: 0; }

    /* Rankings table — smaller text, tighter padding */
    .rankings-table { font-size: 12px; }
    .rankings-table th, .rankings-table td { padding: 5px 6px; }

    /* Touch targets — minimum 36px height for interactive elements */
    .filter-btn, .rk-metric-btn, .tf-btn, .tab-btn, .rk-page-btn,
    .saved-log-load, .header-rankings-btn {
        min-height: 36px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
}

/* Claude: mobile boss select hidden by default — shown in 700px media query above */

/* ── Medium phones (≤600px) ─────────────────────────────────────────────── */
@media (max-width: 600px) {
    /* Rankings filters — compress + wrap timeframe to new row */
    .rankings-filters { gap: 6px; flex-wrap: wrap; }
    .rk-metric-btn { padding: 4px 10px; font-size: 11px; }
    .rk-class-select { font-size: 11px; padding: 4px 8px; min-height: 36px; }
    .tf-btn { padding: 3px 8px; font-size: 11px; }
    /* Claude: Timeframe label — remove left margin on mobile so wrapping looks clean */
    .tf-label { margin-left: 0 !important; }

    /* Rankings table — hide Date and Log link columns */
    .rankings-table th:nth-child(6),
    .rankings-table td:nth-child(6),
    .rankings-table th:nth-child(7),
    .rankings-table td:nth-child(7) { display: none; }

    /* Speedrun tables — smaller font + tighter padding */
    [data-speedrun-body] table { font-size: 11px; }
    [data-speedrun-body] th,
    [data-speedrun-body] td { padding: 6px 8px !important; }

    /* Parse widgets — max 2 columns */
    .parse-widget { min-width: 140px; }

    /* Guild page tables — horizontal scroll */
    [data-instance] > div { overflow-x: auto; -webkit-overflow-scrolling: touch; }

    /* Admin tables — horizontal scroll */
    .admin-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* ── Small phones (≤480px) ──────────────────────────────────────────────── */
@media (max-width: 480px) {
    /* Header — compress */
    .header-search-input { width: 100px; font-size: 12px; }
    .header-rankings-btn { padding: 3px 6px; font-size: 11px; margin-right: 0; }
    .header-admin-btn { font-size: 14px; padding: 2px 4px; }
    header h1 { font-size: 14px; }
    header .subtitle { display: none; }

    /* Rankings filters — stack vertically */
    .rankings-filters { flex-direction: row; flex-wrap: wrap; gap: 4px; }

    /* Rankings table — also hide Parse % column */
    .rankings-table th:nth-child(5),
    .rankings-table td:nth-child(5) { display: none; }

    /* Tabs — horizontal scroll strip instead of wrapping */
    .tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .tabs::-webkit-scrollbar { display: none; }
    .tab-btn { font-size: 10px; padding: 4px 6px; white-space: nowrap; }

    /* Meter — 4 columns: badge, icon, name, total */
    .meter-header, .meter-row {
        grid-template-columns: 30px 22px 1fr 70px;
        padding: 5px 8px;
    }
    /* Hide rank column */
    .meter-header > span:nth-child(2),
    .meter-row > .meter-rank { display: none; }

    /* Detail panel — 3 columns */
    .detail-col-headers, .detail-row,
    .detail-col-headers.expanded, .detail-row.expanded {
        grid-template-columns: 20px 1fr 60px;
        font-size: 11px;
        padding: 4px 8px;
    }
    .detail-col-headers > span:nth-child(3),
    .detail-row > .detail-hits { display: none; }

    /* Spell tooltip — constrain to viewport */
    #spell-tooltip {
        min-width: 0 !important;
        max-width: calc(100vw - 16px) !important;
        left: 8px !important;
        right: 8px !important;
    }

    /* Fight selector */
    #fight-select { min-width: 0; flex: 1; font-size: 12px; }
    .filter-btn { padding: 4px 8px; font-size: 11px; }

    /* Parse widgets — single column */
    .parse-widget { min-width: 100%; flex-basis: 100%; }

    /* Saved logs — stack into a 2-line card on phones so the 5-col grid (guild, name,
       server, info, view) doesn't cram everything horizontally. Row 1: guild + name +
       view button. Row 2: server pill + metadata (boss count + fight count + date). */
    .saved-log-row {
        grid-template-columns: auto 1fr auto !important;
        grid-template-rows: auto auto;
        gap: 4px 8px;
        padding: 8px 12px;
    }
    .saved-log-guild { font-size: 10px; padding: 1px 6px; }
    .saved-log-meta { font-size: 11px; grid-column: 2 / 3; grid-row: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .saved-log-load { grid-column: 3 / 4; grid-row: 1; }
    .saved-log-row > .server-pill {
        grid-column: 1 / 2; grid-row: 2;
        justify-self: start;
    }
    .saved-log-info { font-size: 10px; grid-column: 2 / -1; grid-row: 2; }

    /* Footer — stack vertically */
    footer { flex-direction: column; align-items: center; gap: 8px; text-align: center; }

    /* Guild page — hide Wipes + Duration columns */
    [data-instance] table th:nth-child(4),
    [data-instance] table td:nth-child(4),
    [data-instance] table th:nth-child(5),
    [data-instance] table td:nth-child(5) { display: none; }

    /* Admin login — tighter margin */
    .admin-login { margin: 40px auto; padding: 20px 16px; }
}

/* ── Player Profile Page ─────────────────────────────────────────────── */

/* Claude (v0.28.3): flex layout so the armory CTA sits top-right while the player
   info (name + guild) stays on the left. Wraps on narrow screens so mobile stays sane. */
.pp-header {
    padding: 20px 0 8px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 16px;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    flex-wrap: wrap;
}
.pp-header-info { flex: 1; min-width: 0; }
.pp-name {
    font-size: 22px;
    font-weight: 700;
    display: flex;
    align-items: center;
    gap: 4px;
}
.pp-guild {
    display: inline-block;
    margin-right: 10px;
    color: var(--text-muted);
    text-decoration: none;
    font-size: 13px;
    margin-top: 4px;
}
.pp-guild:hover { color: var(--accent); }

/* Claude (v0.28.3): prominent armory shortcut — mirrors the header-nav button styling
   but in an accent-bordered variant so it reads as "this is THIS player's gear" rather
   than just another nav link. Shield glyph + label + arrow on the right hint at the
   click destination. */
.pp-armory-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    background: #2a1f00;
    border: 1px solid var(--accent);
    border-radius: 8px;
    padding: 10px 18px;
    color: var(--accent);
    text-decoration: none;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.3;
    transition: all 0.12s;
    white-space: nowrap;
    flex-shrink: 0;
}
.pp-armory-btn:hover {
    background: var(--accent);
    color: #0e1117;
}
.pp-armory-btn .pp-armory-icon { font-size: 22px; }
.pp-armory-btn .pp-armory-sub  { font-size: 10px; font-weight: 400; opacity: 0.85; display:block; margin-top:1px; }

.pp-specs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 16px;
}
.pp-spec-pill {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    font-size: 12px;
    font-weight: 600;
    padding: 3px 10px;
    border: 1px solid;
    border-radius: 12px;
    background: var(--surface);
}

.pp-section {
    margin-bottom: 24px;
}
.pp-section-title {
    font-size: 13px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: 10px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--border);
}
.pp-raid-label {
    font-size: 11px;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: 0.5px;
    margin: 14px 0 6px;
    text-transform: uppercase;
}
/* Claude: collapsible raid section on the player profile — same visual as .pp-raid-label
   but wraps a <details>/<summary> so each raid can be minimised/maximised independently. */
.pp-raid-details {
    margin: 14px 0 6px;
}
.pp-raid-summary {
    font-size: 11px;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: 0.5px;
    text-transform: uppercase;
    cursor: pointer;
    user-select: none;
    padding: 4px 0;
    outline: none;
}
.pp-raid-summary:hover { color: #e5cc80; }
.pp-raid-details[open] .pp-raid-summary { margin-bottom: 4px; }
.pp-raid-body { padding-left: 4px; }
.pp-boss-history-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--text);
    margin: 10px 0 4px 4px;
}

.pp-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
    margin-bottom: 8px;
    table-layout: fixed;
}
.pp-table th {
    text-align: left;
    font-size: 10px;
    font-weight: 700;
    color: var(--text-muted);
    letter-spacing: 0.5px;
    padding: 4px 8px 6px;
    border-bottom: 1px solid var(--border);
    overflow: hidden;
    text-overflow: ellipsis;
}
.pp-table th:not(:first-child) { text-align: right; }
.pp-table td {
    padding: 5px 8px;
    border-top: 1px solid rgba(255,255,255,0.04);
    overflow: hidden;
    text-overflow: ellipsis;
}
.pp-table td:not(:first-child) { text-align: right; }
.pp-table.pp-table-compact td { padding: 3px 8px; }
.pp-table.pp-table-compact th { padding: 3px 8px 4px; }

/* Claude: column widths — Parse % and Peak % anchored at same position from right edge.
   Both tables: last 2 cols = Parse%(80) + Peak%(80) = 160px from right edge. */

/* Best Parses: Boss | Spec | DPS/HPS | Rank | Parse % | Peak % */
.pp-best-table th:nth-child(1) { width: auto; }     /* Boss — fills remaining */
.pp-best-table th:nth-child(2) { width: 100px; }    /* Spec */
.pp-best-table th:nth-child(3) { width: 110px; }    /* DPS / HPS */
.pp-best-table th:nth-child(4) { width: 90px; }     /* Rank */
.pp-best-table th:nth-child(5) { width: 80px; }     /* Parse % */
.pp-best-table th:nth-child(6) { width: 80px; }     /* Peak % */
/* Spec column left-aligned */
.pp-best-table th:nth-child(2),
.pp-best-table td:nth-child(2) { text-align: left; }

/* Recent Raids: Date | Raid | Spec | Overall DPS/HPS | Parse % | Peak % */
.pp-recent-table th:nth-child(1) { width: 55px; }   /* Date */
.pp-recent-table th:nth-child(2) { width: auto; }   /* Raid — fills remaining */
.pp-recent-table th:nth-child(3) { width: 100px; }  /* Spec */
.pp-recent-table th:nth-child(4) { width: 160px; }  /* Overall DPS/HPS + PB badge */
.pp-recent-table th:nth-child(5) { width: 80px; }   /* Parse % */
.pp-recent-table th:nth-child(6) { width: 80px; }   /* Peak % */
/* Raid + Spec columns left-aligned */
.pp-recent-table th:nth-child(2),
.pp-recent-table td:nth-child(2),
.pp-recent-table th:nth-child(3),
.pp-recent-table td:nth-child(3) { text-align: left; }

/* Parse History: Date | Spec | DPS | HPS | Parse % | Historic % | Duration | Log */
.pp-table-fixed th:nth-child(1) { width: 55px; }    /* Date */
.pp-table-fixed th:nth-child(2) { width: 100px; }   /* Spec */
.pp-table-fixed th:nth-child(3) { width: 70px; }    /* DPS */
.pp-table-fixed th:nth-child(4) { width: 70px; }    /* HPS */
.pp-table-fixed th:nth-child(5) { width: 70px; }    /* Parse % */
.pp-table-fixed th:nth-child(6) { width: 75px; }    /* Historic % */
.pp-table-fixed th:nth-child(7) { width: 70px; }    /* Duration */
.pp-table-fixed th:nth-child(8) { width: 45px; }    /* Log btn */
/* Spec column left-aligned */
.pp-table-fixed th:nth-child(2),
.pp-table-fixed td:nth-child(2) { text-align: left; }

/* Claude: scrollable container for parse history — shows ~5 rows then scrolls */
.pp-history-scroll {
    max-height: 185px;
    overflow-y: auto;
    margin-bottom: 8px;
    border: 1px solid var(--border);
    border-radius: 4px;
}
.pp-history-scroll .pp-table { margin-bottom: 0; }
.pp-history-scroll thead { position: sticky; top: 0; z-index: 1; background: var(--surface); }

.pp-row { cursor: pointer; transition: background 0.1s; }
.pp-row:hover td { background: var(--surface2); }

.pp-log-btn {
    font-size: 11px;
    color: var(--text-muted);
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 1px 8px;
    text-decoration: none;
    font-weight: 600;
    white-space: nowrap;
    transition: all 0.1s;
}
.pp-log-btn:hover { color: var(--accent); border-color: var(--accent); }

.pp-pb-badge {
    font-size: 10px;
    background: #2a1f00;
    border: 1px solid var(--accent);
    border-radius: 3px;
    padding: 1px 5px;
    color: #e5cc80;
    font-weight: 700;
    margin-left: 5px;
}

@media (max-width: 700px) {
    .pp-name { font-size: 18px; }
    .pp-table { font-size: 11px; }
    /* Hide Spec + Peak columns on mobile */
    .pp-table th:nth-child(2),
    .pp-table td:nth-child(2),
    .pp-table th:nth-child(6),
    .pp-table td:nth-child(6) { display: none; }
}

/* Claude: Talent calculator styles (talents.html) */
.talent-class-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 18px;
    max-width: 900px;
}
@media (min-width: 640px) { .talent-class-grid { grid-template-columns: repeat(5, 1fr); } }
@media (min-width: 900px) { .talent-class-grid { grid-template-columns: repeat(9, 1fr); } }
.talent-class-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 16px;
    border: 1px solid var(--border);
    background: var(--surface);
    border-radius: 6px;
    text-decoration: none;
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 500;
    transition: all 0.15s;
}
.talent-class-card:hover {
    border-color: rgba(212, 175, 55, 0.4);
    background: rgba(212, 175, 55, 0.05);
    color: var(--accent);
}
.talent-control-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    max-width: 1400px;
    margin-bottom: 18px;
    padding: 10px 18px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    flex-wrap: wrap;
    gap: 12px;
}
.talent-link-btn {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 13px;
    padding: 0;
    font-family: inherit;
    transition: opacity 0.15s;
}
.talent-link-btn:hover { opacity: 0.75; }
.talent-trees-wrap {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    justify-content: center;
}
.talent-tree-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid rgba(212, 175, 55, 0.3);
    border-radius: 6px;
    background: var(--surface);
}
.talent-tree-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    background: var(--surface2, #161b22);
    border-bottom: 1px solid var(--border);
}
.talent-tree-grid {
    position: relative;
}
.talent-tree-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
}
.talent-arrow-layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 1;
}
.talent-icon-el {
    user-select: none;
    -webkit-user-select: none;
    transition: transform 0.1s;
}
.talent-icon-el:hover {
    transform: scale(1.1);
}
.talent-img-dimmed {
    opacity: 0.4;
    filter: grayscale(100%);
}
.talent-glow-maxed     { box-shadow: inset 0 0 6px 2px rgba(245, 197, 24, 0.7); }
.talent-glow-has-points { box-shadow: inset 0 0 6px 2px rgba(30, 255, 30, 0.6); }
.talent-glow-can-add    { box-shadow: inset 0 0 5px 2px rgba(30, 255, 30, 0.4); }
.talent-rank-badge {
    position: absolute;
    bottom: -6px;
    right: -6px;
    min-width: 18px;
    font-size: 11px;
    font-weight: 700;
    padding: 1px 4px;
    border-radius: 4px;
    background: #111;
    text-align: center;
    z-index: 3;
}
.talent-tooltip {
    position: fixed;
    z-index: 9999;
    pointer-events: none;
    max-width: 280px;
    padding: 10px 12px;
    background: var(--surface, #1c2230);
    border: 1px solid rgba(212, 175, 55, 0.3);
    border-radius: 6px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
}

/* ── Timeline tab (v0.19.x) ───────────────────────────────────── */
/* Claude: timeline lives inside #meter-body which becomes the scroll container — both horizontal
   (for zoom-induced lane overflow) and vertical (for long player lists). The meter-header row
   is hidden because the timeline has its own axis ruler below the sticky controls. */
#meter-panel.tab-timeline .meter-header { display: none; }
#meter-panel.tab-timeline #meter-body   { padding: 0; overflow: auto; position: relative; }

.tl-view-btn,
.tl-zoom-btn {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    border-radius: 4px;
    padding: 4px 10px;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    transition: all 0.12s;
}
.tl-view-btn:hover,
.tl-zoom-btn:hover { border-color: var(--accent); color: var(--text); }
.tl-view-btn.active { background: var(--accent); color: #000; border-color: var(--accent); }
.tl-zoom-btn { padding: 4px 8px; min-width: 28px; text-align: center; }

/* Class-filter buttons — one per class present in the fight */
.tl-class-btn {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: 4px;
    padding: 3px 8px;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.12s;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.tl-class-btn:hover  { border-color: var(--accent); }
.tl-class-btn.active { background: var(--accent); color: #000; border-color: var(--accent); }
.tl-class-count {
    font-size: 10px;
    opacity: 0.7;
    font-weight: 500;
}
.tl-player-select {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text);
    border-radius: 4px;
    padding: 4px 8px;
    font-size: 11px;
    outline: none;
    max-width: 180px;
}
.tl-player-select:hover { border-color: var(--accent); }
/* Cursor hint: clicking the player left column toggles the single-player filter */
.tl-left:hover { background: var(--surface2); cursor: pointer; }

/* Time axis row — lane is the wider (scrollable) piece; left cell is sticky to stay visible. */
.tl-axis {
    display: flex;
    position: sticky;
    top: 40px; /* sits just under the view-toggle controls */
    background: var(--surface);
    z-index: 3;
    border-bottom: 1px solid var(--border);
    height: 24px;
    width: max-content;
    min-width: 100%;
}
.tl-axis-left {
    flex: 0 0 var(--tl-left-col-w, 130px);
    border-right: 1px solid var(--border);
    position: sticky;
    left: 0;
    background: var(--surface);
    z-index: 4; /* Claude: above axis ticks so they don't visually overlap during horizontal scroll */
}
.tl-axis-lane {
    flex: 0 0 var(--tl-lane-w, 100%);
    position: relative;
}
.tl-tick {
    position: absolute;
    top: 14px;
    width: 1px;
    height: 6px;
    background: var(--text-muted);
    opacity: 0.35;
}
.tl-tick.major {
    top: 10px;
    height: 10px;
    opacity: 0.7;
}
.tl-tick-label {
    position: absolute;
    top: -12px;
    left: 3px;
    font-size: 10px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Per-player row — width matches axis so horizontal scroll stays in sync */
.tl-row {
    display: flex;
    border-bottom: 1px solid rgba(255,255,255,0.04);
    min-height: 32px;
    position: relative;
    width: max-content;
    min-width: 100%;
}
.tl-row:hover { background: rgba(255,255,255,0.02); }

/* Boss row — always first, highlighted with a subtle red tint so it reads as distinct from
   player rows. The 👹 emoji + light-red name in the sticky left column do most of the work. */
.tl-row-boss {
    background: rgba(252, 129, 129, 0.05);
    border-bottom: 2px solid rgba(252, 129, 129, 0.3);
}
.tl-row-boss:hover { background: rgba(252, 129, 129, 0.08); }
.tl-row-boss .tl-left { background: var(--surface); }
.tl-left {
    flex: 0 0 var(--tl-left-col-w, 130px);
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 10px;
    border-right: 1px solid var(--border);
    background: var(--surface);
    position: sticky;
    left: 0;
    /* Claude: z-index 7 so cast icons (3, hover 6), channel bars (2), buff bars (2), grid (0),
       and death markers (4) are all visually covered by the sticky left column as the lane
       scrolls horizontally. Without this, icons at small lane-x bled through when scrolled. */
    z-index: 7;
}
.tl-left-text {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-width: 0;
}
.tl-name {
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tl-gcd-sum {
    font-size: 10px;
    font-weight: 600;
    color: #fc8181;
    opacity: 0.85;
    font-variant-numeric: tabular-nums;
    margin-top: 2px;
}
.tl-left-selected {
    background: rgba(246, 201, 14, 0.08);
    box-shadow: inset 3px 0 0 var(--accent);
}
.tl-left-selected .tl-name { color: var(--accent) !important; }
.tl-lane {
    flex: 0 0 var(--tl-lane-w, 100%);
    position: relative;
    overflow: hidden;
}

/* Gridlines — mirror the axis ticks to guide the eye vertically */
.tl-grid {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: rgba(255,255,255,0.04);
    pointer-events: none;
}
.tl-grid.major { background: rgba(255,255,255,0.07); }

/* Cast icons — image + timestamp label stacked vertically, both centered on their ts.
   Icon size + label size scale with --tl-row-scale so focused views (2-3 players) read bigger. */
.tl-cast {
    position: absolute;
    top: 4px;
    transform: translateX(-50%); /* centre container (any width) on the timestamp */
    z-index: 3;
    cursor: help;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.tl-cast img {
    width: var(--tl-icon-size, 18px);
    height: var(--tl-icon-size, 18px);
    border-radius: 3px;
    border: 1px solid rgba(0,0,0,0.5);
    display: block;
}
.tl-cast-ts {
    margin-top: 2px;
    /* Claude: cap font scaling at 1.25× so labels stay readable at scale=2 (icon 36px) — user
       reported 18px fonts felt "way too big" when filtering to one player. 9px → max 11.25px. */
    font-size: calc(9px * min(1.25, var(--tl-row-scale, 1)));
    line-height: 1;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    opacity: 0.8;
    pointer-events: none;
}
.tl-cast:hover { z-index: 6; }
.tl-cast:hover img {
    outline: 1px solid var(--accent);
    transform: scale(1.25);
    transition: transform 0.08s;
}
.tl-cast:hover .tl-cast-ts { color: var(--text); opacity: 1; }

/* GCD-loss marker — "-0.3s" between two cast icons, centered vertically on the icon row so
   it reads inline with the spell icons rather than on its own line below the timestamps. */
.tl-gcd-loss {
    position: absolute;
    top: calc(4px + var(--tl-icon-size, 18px) / 2);
    transform: translate(-50%, -50%);
    font-size: calc(9px * min(1.25, var(--tl-row-scale, 1)));
    line-height: 1;
    font-weight: 700;
    color: #fc8181;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    opacity: 0.85;
    pointer-events: none;
    z-index: 2;
}

/* Channel bars — drawn behind cast icons, coloured per player. Stay centered on the icon as
   the icon scales with --tl-icon-size. top = iconSize/2 places the 8px bar on the icon's vertical midline. */
.tl-channel {
    position: absolute;
    top: calc(var(--tl-icon-size, 18px) / 2);
    height: 8px;
    opacity: 0.45;
    border-radius: 2px;
    z-index: 2;
    cursor: help;
}
.tl-channel:hover { opacity: 0.8; }

/* Buff bars — 10px-tall horizontal strips stacked below the cast row. Background color comes
   from the spell school (Envenom green, Slice and Dice amber, fire/frost/etc.) via inline style.
   Small 10×10 spell icon sits at the bar's left edge for quick visual identification. */
.tl-buff {
    position: absolute;
    height: 10px;
    border-radius: 2px;
    z-index: 2;
    cursor: help;
    opacity: 0.88;
    overflow: hidden; /* clip the icon when bar is narrower than 10px */
}
.tl-buff img {
    position: absolute;
    left: 0;
    top: 0;
    width: 10px;
    height: 10px;
    border-radius: 2px 0 0 2px;
    border: none;
    display: block;
    pointer-events: none;
}
.tl-buff.debuff { background: #2dd4bf !important; } /* debuffs: teal (overrides inline bg) */
.tl-buff:hover  { opacity: 1; z-index: 5; box-shadow: 0 0 4px rgba(255,255,255,0.3); }

/* Death markers — red vertical line across the full row height */
.tl-death {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    margin-left: -1px;
    background: #e53e3e;
    box-shadow: 0 0 4px rgba(229, 62, 62, 0.6);
    z-index: 4;
    pointer-events: auto;
    cursor: help;
}

/* Rows wrapper — containing block for the sync marker. Spans lane width like the rows
   inside it, so the marker can be positioned at any lane-x and be bounded vertically
   only by the player rows (not by the sticky controls/axis above). */
.tl-rows {
    position: relative;
    width: max-content;
    min-width: 100%;
}

/* Sync marker — draggable vertical line spanning all player rows. The element is 14px wide
   (invisible flanking zones) so it's easy to grab, while the visible line is a thin 2px
   stripe drawn via ::before centered inside. Label is sticky-top within the scroll container
   so it stays visible while vertically scrolling. */
.tl-marker {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 14px;
    margin-left: -7px;   /* centre the click target on the timestamp */
    background: transparent;
    z-index: 6;
    cursor: ew-resize;
    pointer-events: auto;
}
.tl-marker::before {
    content: '';
    position: absolute;
    left: 6px;           /* centre the 2px line within the 14px click zone */
    top: 0;
    bottom: 0;
    width: 2px;
    background: #60a5fa;
    opacity: 0.65;
    transition: opacity 0.12s;
    pointer-events: none;
}
.tl-marker:hover::before { opacity: 1; box-shadow: 0 0 6px rgba(96, 165, 250, 0.5); }
/* Hotkeys popover — positioned via fixed + inline top/left (relative to viewport) just below
   the Hotkeys button. Lives on document.body so it isn't clipped by the scroll container. */
.tl-hotkeys-panel {
    position: fixed;
    z-index: 1000;
    background: var(--surface);
    border: 1px solid var(--accent);
    border-radius: 6px;
    padding: 14px 18px;
    min-width: 280px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.7);
    font-size: 12px;
    color: var(--text);
}
.tl-hotkeys-panel h4 {
    margin: 0 0 10px 0;
    font-size: 11px;
    font-weight: 700;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.tl-hotkeys-panel kbd {
    display: inline-block;
    min-width: 18px;
    padding: 1px 6px;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-bottom-width: 2px;
    border-radius: 3px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 10.5px;
    color: var(--text);
    text-align: center;
    line-height: 1.4;
}
.tl-hotkeys-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 18px;
    padding: 4px 0;
}
.tl-hotkeys-desc { color: var(--text-muted); }

.tl-marker-label {
    position: sticky;
    top: 8px;
    left: 10px;
    display: inline-block;
    background: rgba(17, 24, 39, 0.95);
    color: #60a5fa;
    padding: 3px 8px;
    border-radius: 3px;
    font-size: 11px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    pointer-events: none;
    border: 1px solid #60a5fa;
    margin-left: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

/* Claude: mobile tweaks for Timeline tab. Phones are ≤700px wide — the default 130px left
   column eats over a third of the viewport, and the controls row wraps into a wall of text.
   Shrink left column, compact controls, and hide purely-decorative elements. Matching JS
   reads _tlLeftColW() → 90 on mobile → the --tl-left-col-w CSS var = 90px. */
@media (max-width: 700px) {
    #meter-panel.tab-timeline .meter-header { font-size: 10px; }
    .tl-view-btn, .tl-zoom-btn, .tl-class-btn {
        padding: 4px 7px;
        font-size: 10px;
        letter-spacing: 0.03em;
    }
    .tl-class-count { display: none; } /* save horizontal space */
    .tl-player-search { width: 90px; font-size: 10px; padding: 2px 6px; }
    .tl-name { font-size: 11px; }
    .tl-gcd-sum { font-size: 9px; }
    .tl-axis-left, .tl-left { padding: 0 6px; }
    /* Expand tap target on touch devices — the marker's 14px click zone is borderline on
       small phones. 24px tap area with the visible 2px line still centered inside. */
    .tl-marker {
        width: 24px;
        margin-left: -12px;
    }
    .tl-marker::before { left: 11px; }
}

/* Claude (v0.31.1): combined sticky strip — site stats on the left, timeframe
   pills on the right. Pinned at top:56px to clear the page header (header height
   = 56px). Opaque var(--bg) prevents raid blocks from bleeding through during
   scroll; subtle box-shadow gives a slight lift so the user notices it stuck. */
.tf-sticky {
    position: sticky;
    top: 56px;
    z-index: 50;
    background: var(--bg);
    padding: 10px 0;
    margin: -10px 0 12px;
    box-shadow: 0 4px 8px -8px rgba(0,0,0,0.6);
}
.tf-sticky-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 8px 14px;
}
.tf-controls {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.tf-label {
    font-size: 12px;
    color: var(--text-muted);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
/* Claude (v0.75.2 mobile): hide the DEV BUILD badge on phones — the position:fixed
   badge at top:60px sits on top of the wrapped (≥100 px tall) mobile header instead
   of below it like on desktop. Dev developers know they're on dev.epoglogs.com
   without the visual reminder. env-banner.js tags the badge with this class. */
@media (max-width: 700px) {
    .dev-build-badge { display: none !important; }
}

@media (max-width: 700px) {
    .tf-sticky { top: 50px; } /* slightly tighter on small screens */
    /* Claude (v0.75.2 mobile): stack the stats banner above the timeframe pills
       so they don't end up side-by-side. With the default flex row, the stats
       banner has flex:1 and wraps its 4 stats vertically on the LEFT while the
       3 timeframe pills sit on the RIGHT — visually broken (TIMEFRAME inline
       with "25 guilds"). flex-direction:column drops them onto separate rows. */
    .tf-sticky-row { flex-direction: column; align-items: stretch; gap: 10px; }
    .tf-controls   { justify-content: center; }
    .site-stats-banner { justify-content: center; }
}

/* Claude (v0.31.0): site-wide stats banner — totals strip (logs/guilds/players/raids).
   Now lives inside .tf-sticky-row as the left-side content, so its own background +
   border are dropped (parent provides the chrome). */
/* Claude (v0.31.2): bumped base font 12 → 13px and the strong numbers 13 → 15.5px
   so the totals read as the meaningful content of the strip. Row height is still
   governed by the tf-btn buttons (12px + padding) so the widget chrome doesn't grow. */
.site-stats-banner {
    font-size: 13px;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    flex: 1;
    min-width: 0;
}
.site-stats-banner .ssb-stat {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    white-space: nowrap;
}
.site-stats-banner .ssb-stat strong {
    color: var(--text);
    font-weight: 700;
    font-size: 15.5px;
}
.site-stats-banner .ssb-sep {
    color: var(--text-muted);
    opacity: 0.45;
}

/* Claude (v0.66.0): homepage two-column layout — main content left, polls sidebar right.
   Stacks vertically on viewports <1100px so mobile gets polls below the main content. */
.home-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: 16px;
    align-items: start;
}
.home-grid-main {
    min-width: 0;
}
.home-grid-sidebar {
    position: sticky;
    top: 60px;
    max-height: calc(100vh - 80px);
    overflow-y: auto;
}
@media (max-width: 1100px) {
    .home-grid {
        grid-template-columns: 1fr;
    }
    .home-grid-sidebar {
        position: static;
        max-height: none;
    }
}

.polls-widget {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
    margin-bottom: 16px;
}
.polls-widget-header {
    padding: 10px 14px;
    border-bottom: 1px solid var(--border);
    background: var(--surface2);
    font-size: 13px;
    font-weight: 700;
    color: var(--accent);
}
.polls-widget-body {
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-height: 720px;
    overflow-y: auto;
}
/* Claude (v0.66.2): footer note at the bottom of each polls widget. */
.polls-widget-footer {
    padding: 8px 14px;
    border-top: 1px solid var(--border);
    background: var(--surface2);
    color: var(--text-muted);
    font-size: 11px;
    font-style: italic;
    text-align: center;
}
.poll-card {
    background: var(--surface2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 12px;
    font-size: 12px;
}
.poll-header {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-bottom: 8px;
}
.poll-question {
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
    line-height: 1.3;
}
.poll-meta {
    font-size: 10px;
    color: var(--text-muted);
}
.poll-multi-hint {
    display: inline-block;
    background: rgba(212, 175, 55, 0.15);
    color: var(--accent);
    font-weight: 700;
    padding: 1px 5px;
    border-radius: 3px;
    font-size: 9px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.poll-options {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.poll-option {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 5px;
    cursor: pointer;
    overflow: hidden;
    transition: background 0.12s, border-color 0.12s;
}
.poll-option:hover {
    border-color: var(--accent);
}
.poll-option-mine {
    border-color: var(--accent);
    background: rgba(212, 175, 55, 0.08);
}
.poll-option input[type="radio"],
.poll-option input[type="checkbox"] {
    margin: 0;
    accent-color: var(--accent);
    flex-shrink: 0;
    z-index: 1;
}
.poll-bar {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    background: rgba(212, 175, 55, 0.18);
    z-index: 0;
    transition: width 0.4s cubic-bezier(.4,0,.2,1);
}
.poll-option-mine .poll-bar {
    background: rgba(212, 175, 55, 0.32);
}
.poll-label-text {
    flex: 1;
    z-index: 1;
    color: var(--text);
}
.poll-pct {
    z-index: 1;
    font-size: 11px;
    font-weight: 700;
    color: var(--accent);
    font-family: monospace;
}
.poll-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--border);
}
.poll-total {
    font-size: 10px;
    color: var(--text-muted);
}
.poll-submit-btn {
    background: var(--accent);
    color: #0e1117;
    border: none;
    padding: 4px 12px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 700;
    cursor: pointer;
    transition: opacity 0.12s, filter 0.12s;
}
.poll-submit-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.poll-submit-btn:not(:disabled):hover {
    filter: brightness(1.1);
}

/* News popup */
.news-popup-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    animation: news-popup-fade 0.18s ease-out;
}
@keyframes news-popup-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}
.news-popup-box {
    background: var(--surface);
    border: 1px solid var(--accent);
    border-radius: 12px;
    width: 100%;
    max-width: 520px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
    overflow: hidden;
}
.news-popup-header {
    padding: 14px 18px;
    border-bottom: 1px solid var(--border);
    background: var(--surface2);
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.news-popup-title-wrap {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
}
.news-popup-title {
    font-size: 15px;
    font-weight: 700;
    color: var(--accent);
}
.news-popup-date {
    font-size: 11px;
    color: var(--text-muted);
}
.news-popup-close {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 18px;
    cursor: pointer;
    line-height: 1;
}
.news-popup-close:hover {
    color: var(--accent);
}
.news-popup-body {
    padding: 18px;
    color: var(--text);
    font-size: 13px;
    line-height: 1.6;
    max-height: 50vh;
    overflow-y: auto;
}
.news-popup-body p { margin: 0 0 10px; }
.news-popup-body p:last-child { margin-bottom: 0; }
.news-popup-body a { color: var(--accent); }
.news-popup-footer {
    padding: 12px 18px;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: flex-end;
}
.news-popup-ok {
    background: var(--accent);
    color: #0e1117;
    border: none;
    padding: 7px 24px;
    border-radius: 5px;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}
.news-popup-ok:hover {
    filter: brightness(1.1);
}

/* Claude (v0.67.1): "📋 Parse rules" button next to the boss title on the rankings page. */
.rk-rules-btn {
    margin-left: 12px;
    background: rgba(212, 175, 55, 0.08);
    border: 1px solid rgba(212, 175, 55, 0.4);
    color: var(--accent);
    font-size: 11px;
    font-weight: 600;
    padding: 3px 10px;
    border-radius: 5px;
    cursor: pointer;
    vertical-align: middle;
    transition: background 0.12s, border-color 0.12s;
}
.rk-rules-btn:hover {
    background: rgba(212, 175, 55, 0.18);
    border-color: var(--accent);
}

/* Claude (v0.67.4): Discord brand icon for footer link. CSS mask so the icon
   picks up currentColor (matches the link's text color and hover state). */
.discord-icon {
    display: inline-block;
    width: 13px;
    height: 13px;
    vertical-align: -2px;
    margin-right: 5px;
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z'/%3E%3C/svg%3E") center / contain no-repeat;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z'/%3E%3C/svg%3E") center / contain no-repeat;
}
