/* =========================================================================
   UARO WoE Dashboard — Design Tokens & Base Styles
   Unified with FluxCP bootstrap5 theme (cp/themes/bootstrap5/scss/).
   Brand accent = site blue. Ember amber kept as siege-event accent only.
   Surfaces, text, radii, validation colors mirror FluxCP --color-* tokens.
   All tokens namespaced --woe-* to avoid collision with Bootstrap --bs-*.
   See woe/docs/design-system.md for rationale.
   ========================================================================= */


/* -------------------------------------------------------------------------
   THEME-INDEPENDENT TOKENS
   ------------------------------------------------------------------------- */

:root {
  /* Sans matches FluxCP --bs-font-sans-serif (Rubik). Mono is WoE-specific. */
  --woe-font-sans: "Rubik", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --woe-font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Type scale — minor-third, 15px body */
  --woe-font-xs:   0.6875rem; /* 11px */
  --woe-font-sm:   0.8125rem; /* 13px */
  --woe-font-base: 0.9375rem; /* 15px */
  --woe-font-md:   1rem;      /* 16px */
  --woe-font-lg:   1.125rem;  /* 18px */
  --woe-font-xl:   1.375rem;  /* 22px */
  --woe-font-2xl:  1.75rem;   /* 28px */
  --woe-font-3xl:  2.25rem;   /* 36px */

  --woe-weight-regular:  400;
  --woe-weight-medium:   500;
  --woe-weight-semibold: 600;
  --woe-weight-bold:     700;

  --woe-line-tight:   1.15;
  --woe-line-snug:    1.3;
  --woe-line-normal:  1.5;
  --woe-line-relaxed: 1.65;

  --woe-tracking-tight:  -0.01em;
  --woe-tracking-normal: 0;
  --woe-tracking-wide:   0.06em;

  /* Spacing — 4/8 hybrid */
  --woe-space-0:  0;
  --woe-space-1:  0.25rem;   /* 4px  */
  --woe-space-2:  0.5rem;    /* 8px  */
  --woe-space-3:  0.75rem;   /* 12px */
  --woe-space-4:  1rem;      /* 16px */
  --woe-space-5:  1.25rem;   /* 20px */
  --woe-space-6:  1.5rem;    /* 24px */
  --woe-space-7:  2rem;      /* 32px */
  --woe-space-8:  2.5rem;    /* 40px */
  --woe-space-9:  3rem;      /* 48px */
  --woe-space-10: 4rem;      /* 64px */

  /* Radii — md/lg mirror FluxCP --s-radius (4px) and --m-radius (8px). */
  --woe-radius-sm:   2px;
  --woe-radius-md:   4px;
  --woe-radius-lg:   8px;
  --woe-radius-xl:   12px;
  --woe-radius-full: 9999px;

  /* Motion */
  --woe-duration-instant: 80ms;
  --woe-duration-fast:    120ms;
  --woe-duration-normal:  200ms;
  --woe-duration-slow:    320ms;

  --woe-ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --woe-ease-in:       cubic-bezier(0.4, 0, 1, 1);
  --woe-ease-out:      cubic-bezier(0, 0, 0.2, 1);
  --woe-ease-in-out:   cubic-bezier(0.4, 0, 0.2, 1);

  /* Focus */
  --woe-focus-ring-width:  2px;
  --woe-focus-ring-offset: 2px;

  /* Sticky offsets — navbar height */
  --woe-sticky-top: 56px;
}


/* -------------------------------------------------------------------------
   LIGHT THEME (opt-in)
   ------------------------------------------------------------------------- */

:root,
[data-bs-theme="light"] {
  /* Surfaces — mirror FluxCP --color-bg-main-* (light) */
  --woe-surface-base:     #FFFFFF;
  --woe-surface:          #F8F9FB;  /* = --color-bg-main-subtle */
  --woe-surface-elevated: #FFFFFF;
  --woe-surface-overlay:  #FFFFFF;
  --woe-surface-sunken:   #F1F3F6;

  /* Borders — default mirrors --color-border-default */
  --woe-border:         #E5E7EB;
  --woe-border-strong:  #D1D5DB;

  /* Text — mirrors --color-text-main-* */
  --woe-text-primary:   #1a1d20;
  --woe-text-secondary: #5a6470;
  --woe-text-muted:     #8e96a0;
  --woe-text-inverse:   #FFFFFF;

  /* Brand accent — site blue (FluxCP --color-action-primary / --color-text-main-link) */
  --woe-accent:         #2563EB;
  --woe-accent-hover:   #1D4ED8;
  --woe-accent-muted:   rgba(37, 99, 235, 0.10);

  /* Event accent — ember amber, WoE-only (siege moments, emperium break) */
  --woe-accent-event:        #C2410C;
  --woe-accent-event-hover:  #9A3412;
  --woe-accent-event-muted:  rgba(194, 65, 12, 0.10);

  /* Semantic — mirrors FluxCP validation tokens */
  --woe-success:        #16A34A;
  --woe-success-muted:  rgba(22, 163, 74, 0.10);
  --woe-danger:         #EF4444;
  --woe-danger-muted:   rgba(239, 68, 68, 0.10);
  --woe-warning:        #B45309;
  --woe-warning-muted:  rgba(180, 83, 9, 0.10);
  --woe-info:           #1D4ED8;
  --woe-info-muted:     rgba(29, 78, 216, 0.10);

  /* Stat-specific data-viz */
  --woe-stat-kills:            #16A34A;
  --woe-stat-deaths:           #EF4444;
  --woe-stat-damage-dealt:     #C2410C;  /* ember */
  --woe-stat-damage-received:  #7E22CE;
  --woe-stat-heal:             #0E7490;
  --woe-stat-emp-break:        #A16207;
  --woe-stat-castle-hold:      #475569;  /* slate — neutral, doesn't collide with brand blue */

  /* Guild categorical — slot 1 is brand blue (top guild wears the brand) */
  --woe-guild-1: #2563EB;
  --woe-guild-2: #C2410C;
  --woe-guild-3: #15803D;
  --woe-guild-4: #7E22CE;
  --woe-guild-5: #B45309;
  --woe-guild-6: #0E7490;
  --woe-guild-7: #BE185D;
  --woe-guild-8: #525252;

  --woe-row-hover:        rgba(14, 17, 22, 0.03);
  --woe-row-hover-strong: rgba(14, 17, 22, 0.06);

  --woe-shadow-sm:
    0 1px 2px rgba(14, 17, 22, 0.04),
    0 1px 1px rgba(14, 17, 22, 0.03);
  --woe-shadow-md:
    0 2px 4px rgba(14, 17, 22, 0.04),
    0 4px 12px rgba(14, 17, 22, 0.06);
  --woe-shadow-lg:
    0 8px 16px rgba(14, 17, 22, 0.06),
    0 16px 32px rgba(14, 17, 22, 0.08);

  --woe-focus-ring-color: var(--woe-accent);
  --woe-focus-ring-style:
    0 0 0 var(--woe-focus-ring-offset) var(--woe-surface-base),
    0 0 0 calc(var(--woe-focus-ring-offset) + var(--woe-focus-ring-width)) var(--woe-focus-ring-color);

  /* Bootstrap overrides so native components adopt the palette */
  --bs-body-bg:           var(--woe-surface-base);
  --bs-body-color:        var(--woe-text-primary);
  --bs-secondary-color:   var(--woe-text-secondary);
  --bs-tertiary-bg:       var(--woe-surface);
  --bs-border-color:      var(--woe-border);
  --bs-font-sans-serif:   var(--woe-font-sans);
  --bs-font-monospace:    var(--woe-font-mono);
  --bs-body-font-size:    var(--woe-font-base);
  --bs-body-line-height:  var(--woe-line-normal);
  --bs-primary:           var(--woe-accent);
  --bs-link-color:        var(--woe-accent);
  --bs-link-hover-color:  var(--woe-accent-hover);
}


/* -------------------------------------------------------------------------
   DARK THEME (default experience)
   ------------------------------------------------------------------------- */

[data-bs-theme="dark"] {
  /* Surfaces — mirror FluxCP --bs-body-bg / --color-bg-main-* (dark) */
  --woe-surface-base:     #1B1F22;  /* = --bs-body-bg dark */
  --woe-surface:          #212529;  /* = --color-bg-main-default */
  --woe-surface-elevated: #2A2F33;  /* one step brighter than panel */
  --woe-surface-overlay:  #343A40;  /* = --color-menu-main-bg-secondary */
  --woe-surface-sunken:   #121619;  /* = --color-bg-main-subtle / sidebar bg */

  /* Borders — bumped above FluxCP default so row dividers stay visible on #212529 */
  --woe-border:         #343A40;
  --woe-border-strong:  #464B52;

  /* Text — 3-tier hierarchy. Each tier ~30% lower contrast than the one above.
     Mirrors light theme: primary > secondary > muted (most muted). */
  --woe-text-primary:   #F1F3F5;
  --woe-text-secondary: #B0B5BD;
  --woe-text-muted:     #7A828D;
  --woe-text-inverse:   #1B1F22;

  /* Brand accent — site blue (FluxCP --color-text-main-link / --color-action-primary) */
  --woe-accent:         #5291FF;
  --woe-accent-hover:   #7DA9FF;
  --woe-accent-muted:   rgba(82, 145, 255, 0.14);

  /* Event accent — ember amber, WoE-only */
  --woe-accent-event:        #F0883E;
  --woe-accent-event-hover:  #F79E5F;
  --woe-accent-event-muted:  rgba(240, 136, 62, 0.14);

  /* Semantic — mirrors FluxCP validation tokens (dark) */
  --woe-success:        #22C55E;
  --woe-success-muted:  rgba(34, 197, 94, 0.14);
  --woe-danger:         #FF7E7E;
  --woe-danger-muted:   rgba(255, 126, 126, 0.14);
  --woe-warning:        #FBBF24;
  --woe-warning-muted:  rgba(251, 191, 36, 0.14);
  --woe-info:           #60A5FA;
  --woe-info-muted:     rgba(96, 165, 250, 0.14);

  /* Stat-specific data-viz */
  --woe-stat-kills:            #22C55E;
  --woe-stat-deaths:           #FF7E7E;
  --woe-stat-damage-dealt:     #F0883E;  /* ember */
  --woe-stat-damage-received:  #A855F7;
  --woe-stat-heal:             #22D3EE;
  --woe-stat-emp-break:        #FDE047;
  --woe-stat-castle-hold:      #94A3B8;  /* slate — neutral */

  /* Guild categorical — slot 1 is brand blue */
  --woe-guild-1: #5291FF;
  --woe-guild-2: #F0883E;
  --woe-guild-3: #4ADE80;
  --woe-guild-4: #A855F7;
  --woe-guild-5: #FBBF24;
  --woe-guild-6: #22D3EE;
  --woe-guild-7: #F472B6;
  --woe-guild-8: #A3A3A3;

  --woe-row-hover:        rgba(255, 255, 255, 0.03);
  --woe-row-hover-strong: rgba(255, 255, 255, 0.06);

  /* Dark mode suppresses shadows; borders and surface layering do the work */
  --woe-shadow-sm: none;
  --woe-shadow-md: none;
  --woe-shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.6);

  --woe-focus-ring-color: var(--woe-accent);
  --woe-focus-ring-style:
    0 0 0 var(--woe-focus-ring-offset) var(--woe-surface-base),
    0 0 0 calc(var(--woe-focus-ring-offset) + var(--woe-focus-ring-width)) var(--woe-focus-ring-color);

  --bs-body-bg:           var(--woe-surface-base);
  --bs-body-color:        var(--woe-text-primary);
  --bs-secondary-color:   var(--woe-text-secondary);
  --bs-tertiary-bg:       var(--woe-surface);
  --bs-border-color:      var(--woe-border);
  --bs-primary:           var(--woe-accent);
  --bs-link-color:        var(--woe-accent);
  --bs-link-hover-color:  var(--woe-accent-hover);
}


/* -------------------------------------------------------------------------
   BASE ELEMENT STYLES — apply the tokens globally
   ------------------------------------------------------------------------- */

html {
  color-scheme: dark light;
}

body {
  background: var(--woe-surface-base);
  color: var(--woe-text-primary);
  font-family: var(--woe-font-sans);
  font-size: var(--woe-font-base);
  line-height: var(--woe-line-normal);
  font-variant-numeric: tabular-nums;
  transition: background-color var(--woe-duration-normal) var(--woe-ease-standard),
              color var(--woe-duration-normal) var(--woe-ease-standard);
}

h1, h2, h3, h4, h5, h6 {
  font-weight: var(--woe-weight-semibold);
  line-height: var(--woe-line-snug);
  letter-spacing: var(--woe-tracking-normal);
  color: var(--woe-text-primary);
  margin-top: 0;
  margin-bottom: 0;
}

p { margin-top: 0; margin-bottom: 0; }

/* Numerics: mono family + tabular figures + slashed zero. The slashed zero
   makes "0" unmistakably distinct from "O" in dense leaderboards. */
code, kbd, samp, pre,
.woe-num {
  font-family: var(--woe-font-mono);
  font-variant-numeric: tabular-nums slashed-zero;
}

a {
  color: var(--woe-accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  transition: color var(--woe-duration-fast) var(--woe-ease-out);
}

a:hover {
  color: var(--woe-accent-hover);
}

:focus-visible {
  outline: var(--woe-focus-ring-width) solid var(--woe-focus-ring-color);
  outline-offset: var(--woe-focus-ring-offset);
  box-shadow: var(--woe-focus-ring-style);
  border-radius: var(--woe-radius-sm);
}

::selection {
  background: var(--woe-accent-muted);
  color: var(--woe-text-primary);
}


/* -------------------------------------------------------------------------
   NAVBAR
   ------------------------------------------------------------------------- */

.woe-navbar {
  background: var(--woe-surface-base);
  border-bottom: 1px solid var(--woe-border);
  padding-block: var(--woe-space-2);
  min-height: var(--woe-sticky-top);
  /* Repoint Bootstrap's navbar tokens to the WoE theme so the rules below
     don't need !important to win over .navbar's defaults. */
  --bs-navbar-color: var(--woe-text-secondary);
  --bs-navbar-hover-color: var(--woe-text-primary);
  --bs-navbar-active-color: var(--woe-text-primary);
  --bs-navbar-brand-color: var(--woe-text-primary);
  --bs-navbar-brand-hover-color: var(--woe-text-primary);
}

.woe-brand {
  font-weight: var(--woe-weight-semibold);
  letter-spacing: 0.02em;
}

.woe-nav-link {
  font-size: var(--woe-font-sm);
  font-weight: var(--woe-weight-medium);
  padding-inline: var(--woe-space-3);
  position: relative;
  transition: color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-nav-link.active::after,
.woe-nav-link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: var(--woe-space-3);
  right: var(--woe-space-3);
  bottom: calc(-1 * var(--woe-space-2) - 1px);
  height: 2px;
  background: var(--woe-accent);
  border-radius: var(--woe-radius-sm) var(--woe-radius-sm) 0 0;
}

.woe-server-time {
  color: var(--woe-text-muted);
  font-family: var(--woe-font-mono);
  font-size: var(--woe-font-xs);
  letter-spacing: 0.02em;
}

.woe-theme-toggle {
  background: transparent;
  border: 1px solid var(--woe-border);
  color: var(--woe-text-secondary);
  border-radius: var(--woe-radius-md);
  padding: 6px 8px;
  line-height: 1;
  transition: color var(--woe-duration-fast) var(--woe-ease-out),
              border-color var(--woe-duration-fast) var(--woe-ease-out),
              background-color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-theme-toggle:hover {
  color: var(--woe-text-primary);
  border-color: var(--woe-border-strong);
  background: var(--woe-row-hover);
}

.woe-theme-toggle .bi {
  font-size: 1rem;
}

.woe-theme-toggle__sun,
.woe-theme-toggle__moon {
  display: none;
}

[data-bs-theme="dark"] .woe-theme-toggle__sun { display: inline-block; }
[data-bs-theme="light"] .woe-theme-toggle__moon { display: inline-block; }


/* -------------------------------------------------------------------------
   MAIN / FOOTER
   ------------------------------------------------------------------------- */

.woe-main {
  padding-top: var(--woe-space-6);
  padding-bottom: var(--woe-space-9);
}

.woe-footer {
  border-top: 1px solid var(--woe-border);
  padding-block: var(--woe-space-4);
  margin-top: var(--woe-space-9);
  color: var(--woe-text-muted);
  font-size: var(--woe-font-xs);
}

.woe-footer a {
  color: var(--woe-text-secondary);
  text-decoration: none;
}

.woe-footer a:hover {
  color: var(--woe-text-primary);
}


/* -------------------------------------------------------------------------
   UTILITIES
   ------------------------------------------------------------------------- */

.woe-id {
  font-family: var(--woe-font-mono);
  font-size: 0.875em;
  color: var(--woe-text-muted);
  letter-spacing: 0;
}

.woe-accent {
  color: var(--woe-accent);
}


/* -------------------------------------------------------------------------
   BREADCRUMBS
   ------------------------------------------------------------------------- */

.woe-breadcrumbs .breadcrumb {
  --bs-breadcrumb-divider: "/";
  font-size: var(--woe-font-sm);
  margin-bottom: 0;
}

.woe-breadcrumbs .breadcrumb-item,
.woe-breadcrumbs .breadcrumb-item a {
  color: var(--woe-text-muted);
}

.woe-breadcrumbs .breadcrumb-item a:hover {
  color: var(--woe-accent);
}

.woe-breadcrumbs .breadcrumb-item.active {
  color: var(--woe-text-primary);
  font-weight: var(--woe-weight-medium);
}

.woe-breadcrumbs .breadcrumb-item + .breadcrumb-item::before {
  color: var(--woe-text-muted);
  padding-inline: var(--woe-space-2);
}


/* -------------------------------------------------------------------------
   STAT CARD
   ------------------------------------------------------------------------- */

.woe-stat-card {
  background: var(--woe-surface);
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-lg);
  padding: var(--woe-space-3) var(--woe-space-4);
  display: flex;
  flex-direction: column;
  gap: var(--woe-space-1);
  box-shadow: var(--woe-shadow-sm);
  transition: border-color var(--woe-duration-fast) var(--woe-ease-out),
              background-color var(--woe-duration-fast) var(--woe-ease-out);
  min-width: 0;
}

.woe-stat-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--woe-space-2);
  min-height: 1.25rem;
}

.woe-stat-card__label {
  color: var(--woe-text-muted);
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: var(--woe-space-1);
}

.woe-stat-card__icon {
  font-size: 1.05em;
  line-height: 1;
  vertical-align: -0.05em;
}

.woe-stat-card__delta {
  font-family: var(--woe-font-mono);
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-medium);
  padding: 1px 6px;
  border-radius: var(--woe-radius-full);
  display: inline-flex;
  align-items: center;
  gap: 2px;
  line-height: 1.3;
}

.woe-stat-card__delta--up {
  color: var(--woe-success);
  background: var(--woe-success-muted);
}

.woe-stat-card__delta--down {
  color: var(--woe-danger);
  background: var(--woe-danger-muted);
}

.woe-stat-card__delta--flat {
  color: var(--woe-text-muted);
  background: transparent;
}

/* Hero number — same recipe used in the player page's square cards, applied
   to every stat-card variant (wide on home/session/records, cols-3 on records).
   Scale + weight do the work; color stays neutral so contrast is consistent
   regardless of variant; tabular numerals keep columns aligned across rows. */
.woe-stat-card__value {
  font-family: var(--woe-font-mono);
  font-weight: 800;
  font-size: clamp(1.5rem, 1rem + 1.4vw, 2rem);
  line-height: var(--woe-line-tight);
  letter-spacing: -0.015em;
  color: var(--woe-text-primary);
  margin: 0;
  font-variant-numeric: tabular-nums slashed-zero;
  font-feature-settings: 'tnum' 1, 'lnum' 1, 'zero' 1;
  overflow-wrap: anywhere;
}

.woe-stat-card__foot {
  margin-top: var(--woe-space-1);
}

.woe-stat-card__caption {
  color: var(--woe-text-muted);
  font-size: var(--woe-font-sm);
}

/* Variant accents — color goes on a 3px left border + on the label glyph,
   never on the number. Pairs each card with a redundant non-color cue
   (icon + stripe), per WCAG 1.4.1. */
.woe-stat-card--positive {
  border-left: 3px solid var(--woe-success);
}
.woe-stat-card--negative {
  border-left: 3px solid var(--woe-danger);
}
.woe-stat-card--accent {
  border-left: 3px solid var(--woe-accent);
  background: var(--woe-accent-muted);
}

.woe-stat-card--positive .woe-stat-card__icon { color: var(--woe-success); }
.woe-stat-card--negative .woe-stat-card__icon { color: var(--woe-danger); }
.woe-stat-card--accent   .woe-stat-card__icon { color: var(--woe-accent); }


/* -------------------------------------------------------------------------
   STAT CARD GROUP — CSS grid, card-count-agnostic
   ------------------------------------------------------------------------- */

.woe-stat-group {
  display: grid;
  gap: var(--woe-space-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-block: var(--woe-space-4);
}

@media (min-width: 576px) {
  .woe-stat-group { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 768px) {
  .woe-stat-group { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 992px) {
  .woe-stat-group { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); }
}

/* --wide variant: locks to 4-up on lg+ so a 7-card group reads as 4+3 across
   two rows with extra room per card — large numbers (millions, billions) need
   the breathing space. */
.woe-stat-group--wide { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (min-width: 768px) {
  .woe-stat-group--wide { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 992px) {
  .woe-stat-group--wide { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* --cols-3: locks 3-up at md+ for a 3-card row that always fills evenly
   (used for the records highlight strip; pairs with --wide above it). */
.woe-stat-group--cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

@media (min-width: 768px) {
  .woe-stat-group--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 992px) {
  .woe-stat-group--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* -------------------------------------------------------------------------
   DATA TABLE
   ------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
   WoE table — single, consistent treatment across every page (player,
   leaderboard, sessions, session, guild, records). One simple recipe:
     - Subtle grey backdrop using --woe-surface-sunken
     - Soft border, rounded corners on the responsive wrapper
     - Quiet thead (one shade above the body for separation, no harsh fill)
     - Compact rows, subtle hover, tabular numerals
   The wrapper rule via :has() lets every existing `<div class="table-responsive">`
   automatically pick up the card treatment without HTML changes.
   ------------------------------------------------------------------------- */

.woe-table-wrap,
.table-responsive:has(> .woe-table) {
  position: relative;
  overflow-x: auto;
  background: var(--woe-surface-sunken);
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-md);
}

.woe-table {
  --bs-table-bg: transparent;
  --bs-table-hover-bg: var(--woe-row-hover);
  --bs-table-border-color: var(--woe-border);
  margin-bottom: 0;
  color: var(--woe-text-primary);
  font-size: var(--woe-font-sm);
  font-variant-numeric: tabular-nums;
  background: transparent;
}

.woe-table thead th {
  background: color-mix(in srgb, var(--woe-surface-sunken) 60%, var(--woe-surface));
  color: var(--woe-text-muted);
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  padding: var(--woe-space-3) var(--woe-space-3);
  border-top: 0;
  border-bottom: 1px solid var(--woe-border);
  white-space: nowrap;
  vertical-align: middle;
}

.woe-table tbody td {
  padding: var(--woe-space-2) var(--woe-space-3);
  border-color: var(--woe-border);
  vertical-align: middle;
  background: transparent;
}

.woe-table tbody tr:last-child td {
  border-bottom: 0;
}

.woe-table tbody tr:hover > td {
  background: var(--woe-row-hover);
}

.woe-sort {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--woe-space-1);
  transition: color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-sort:hover {
  color: var(--woe-text-primary);
}

.woe-sort--asc,
.woe-sort--desc {
  color: var(--woe-text-primary);
}

.woe-sort__icon {
  color: var(--woe-accent);
  font-size: 0.9em;
}

.woe-table__rank {
  width: 3.5rem;
  text-align: right;
}

.woe-rank {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  min-width: 1.75rem;
  padding: 0.125rem 0.5rem;
  border-radius: var(--woe-radius-full);
  text-align: center;
  color: var(--woe-text-muted);
  font-family: var(--woe-font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--woe-font-sm);
  font-weight: var(--woe-weight-semibold);
  line-height: 1;
}

.woe-rank__icon {
  font-size: 0.95rem;
  line-height: 1;
}

.woe-rank__num {
  line-height: 1;
}

/* Metallic medal palettes — gradient bg + ring + soft drop */
.woe-rank--gold {
  background: linear-gradient(135deg, #fde68a 0%, #f59e0b 60%, #b45309 100%);
  color: #422006;
  box-shadow:
    0 0 0 1px rgba(253, 224, 71, 0.55),
    0 1px 4px rgba(245, 158, 11, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.45);
}

.woe-rank--silver {
  background: linear-gradient(135deg, #f1f5f9 0%, #cbd5e1 60%, #64748b 100%);
  color: #1e293b;
  box-shadow:
    0 0 0 1px rgba(203, 213, 225, 0.55),
    0 1px 4px rgba(148, 163, 184, 0.40),
    inset 0 1px 0 rgba(255, 255, 255, 0.55);
}

.woe-rank--bronze {
  background: linear-gradient(135deg, #fed7aa 0%, #c2410c 60%, #7c2d12 100%);
  color: #431407;
  box-shadow:
    0 0 0 1px rgba(253, 186, 116, 0.55),
    0 1px 4px rgba(194, 65, 12, 0.40),
    inset 0 1px 0 rgba(255, 255, 255, 0.40);
}

/* Top-3 row highlight — left-edge metallic accent + subtle gradient sweep.
   Driven by :has() so we don't have to thread a per-row class through every callsite. */
.woe-table tbody tr:has(.woe-rank--gold) {
  background: linear-gradient(90deg,
    rgba(245, 158, 11, 0.14) 0%,
    rgba(245, 158, 11, 0.04) 40%,
    transparent 80%);
  box-shadow: inset 3px 0 0 0 #f59e0b;
}

.woe-table tbody tr:has(.woe-rank--silver) {
  background: linear-gradient(90deg,
    rgba(148, 163, 184, 0.14) 0%,
    rgba(148, 163, 184, 0.04) 40%,
    transparent 80%);
  box-shadow: inset 3px 0 0 0 #94a3b8;
}

.woe-table tbody tr:has(.woe-rank--bronze) {
  background: linear-gradient(90deg,
    rgba(194, 65, 12, 0.14) 0%,
    rgba(194, 65, 12, 0.04) 40%,
    transparent 80%);
  box-shadow: inset 3px 0 0 0 #c2410c;
}

/* Boost the metric cell on top-3 rows to match the medal tone. */
[data-bs-theme="dark"] .woe-table tbody tr:has(.woe-rank--gold) td.fw-semibold   { color: #fbbf24; }
[data-bs-theme="dark"] .woe-table tbody tr:has(.woe-rank--silver) td.fw-semibold { color: #e2e8f0; }
[data-bs-theme="dark"] .woe-table tbody tr:has(.woe-rank--bronze) td.fw-semibold { color: #fb923c; }

[data-bs-theme="light"] .woe-table tbody tr:has(.woe-rank--gold) td.fw-semibold   { color: #b45309; }
[data-bs-theme="light"] .woe-table tbody tr:has(.woe-rank--silver) td.fw-semibold { color: #475569; }
[data-bs-theme="light"] .woe-table tbody tr:has(.woe-rank--bronze) td.fw-semibold { color: #9a3412; }

/* Pinned-first-column on top-3 rows — keep the tinted bg behind the sticky cell
   so the highlight isn't truncated when the table scrolls horizontally. */
.woe-table--sticky-first tbody tr:has(.woe-rank--gold) .woe-table__pin {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--woe-surface) 86%, #f59e0b 14%),
    var(--woe-surface));
}
.woe-table--sticky-first tbody tr:has(.woe-rank--silver) .woe-table__pin {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--woe-surface) 86%, #94a3b8 14%),
    var(--woe-surface));
}
.woe-table--sticky-first tbody tr:has(.woe-rank--bronze) .woe-table__pin {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--woe-surface) 86%, #c2410c 14%),
    var(--woe-surface));
}

/* Pinned first column — visible while the table scrolls horizontally */
.woe-table--sticky-first .woe-table__pin {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--woe-surface);
}

.woe-table--sticky-first thead th.woe-table__pin {
  background: var(--woe-surface-elevated);
  z-index: 2;
}

.woe-table--sticky-first tbody tr:hover > td.woe-table__pin {
  background: color-mix(in srgb, var(--woe-surface), var(--woe-row-hover) 60%);
}


/* -------------------------------------------------------------------------
   EMPERIUM BREAK TIMELINE
   ------------------------------------------------------------------------- */

/* WoE event timeline — compact vertical spine with per-type beads.
   Density target: ~50px per row (was ~80px). Bead 2.25rem (was 3rem).
   Spine ::before draws one continuous track through the rail; per-type
   styles change the bead glyph + border accent so types are decoded by
   shape AND color (WCAG 1.4.1). */
.woe-emp-timeline {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--woe-space-2);
  position: relative;
}

.woe-emp-timeline::before {
  content: "";
  position: absolute;
  top: 1.125rem;
  bottom: 1.125rem;
  left: 1.125rem;
  width: 2px;
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--woe-stat-emp-break) 60%, transparent),
    color-mix(in srgb, var(--woe-stat-emp-break) 30%, transparent) 8%,
    color-mix(in srgb, var(--woe-stat-emp-break) 30%, transparent) 92%,
    color-mix(in srgb, var(--woe-stat-emp-break) 60%, transparent)
  );
  border-radius: 999px;
  z-index: 0;
}

.woe-emp-timeline__item {
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  gap: var(--woe-space-2);
  padding: var(--woe-space-2) var(--woe-space-3);
  background: var(--woe-surface);
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-md);
  position: relative;
  overflow: visible;
  z-index: 1;
  transition: border-color var(--woe-duration-fast) var(--woe-ease-out),
              box-shadow var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-emp-timeline__item:hover {
  border-color: color-mix(in srgb, var(--woe-stat-emp-break) 50%, var(--woe-border-strong));
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);
}

/* Bookend rows (start/end) read quieter — sunken backdrop, smaller type. */
.woe-emp-timeline__item--start,
.woe-emp-timeline__item--end {
  background: var(--woe-surface-sunken);
  font-size: var(--woe-font-sm);
}

.woe-emp-timeline__rail {
  width: 2.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 2;
}

.woe-emp-timeline__emp {
  position: relative;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--woe-radius-full);
  background: var(--woe-surface-sunken);
  border: 2px solid color-mix(in srgb, var(--woe-stat-emp-break) 40%, var(--woe-border-strong));
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  box-shadow:
    0 0 0 3px var(--woe-surface),
    0 0 8px color-mix(in srgb, var(--woe-stat-emp-break) 22%, transparent);
}

/* Per-type bead: distinct shape + accent so events can be parsed at a glance.
   Bookends use rounded squares; first-break is the same emperium PNG with a
   ring tinted to the milestone accent. */
.woe-emp-timeline__item--start .woe-emp-timeline__emp,
.woe-emp-timeline__item--end .woe-emp-timeline__emp {
  border-radius: var(--woe-radius-sm);
  background: var(--woe-surface);
  box-shadow: 0 0 0 3px var(--woe-surface-sunken);
}
.woe-emp-timeline__item--start .woe-emp-timeline__emp {
  border-color: var(--woe-success);
}
.woe-emp-timeline__item--end .woe-emp-timeline__emp {
  border-color: color-mix(in srgb, var(--woe-text-muted) 70%, var(--woe-border-strong));
}
.woe-emp-timeline__item--first-break .woe-emp-timeline__emp {
  border-color: var(--woe-accent);
  box-shadow:
    0 0 0 3px var(--woe-surface),
    0 0 12px color-mix(in srgb, var(--woe-accent) 35%, transparent);
}

.woe-emp-timeline__emp-img {
  display: block;
  width: 90%;
  height: 90%;
  object-fit: contain;
  image-rendering: pixelated;
  position: relative;
  z-index: 5;
}

.woe-emp-timeline__glyph {
  font-size: 0.95rem;
  line-height: 1;
  font-weight: var(--woe-weight-bold);
}
.woe-emp-timeline__item--start .woe-emp-timeline__glyph { color: var(--woe-success); }
.woe-emp-timeline__item--end   .woe-emp-timeline__glyph { color: var(--woe-text-muted); }

/* Single-line row: time + body inline, with hold-for chip pushed to the right. */
.woe-emp-timeline__row {
  display: flex;
  align-items: center;
  gap: var(--woe-space-3);
  min-width: 0;
  flex-wrap: wrap;
}

.woe-emp-timeline__when {
  display: inline-flex;
  align-items: baseline;
  gap: var(--woe-space-1);
  white-space: nowrap;
  flex-shrink: 0;
  min-width: 5rem;
}

.woe-emp-timeline__time {
  font-family: var(--woe-font-mono);
  font-variant-numeric: tabular-nums slashed-zero;
  font-size: var(--woe-font-sm);
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-text-primary);
  line-height: 1;
}

.woe-emp-timeline__offset {
  font-size: var(--woe-font-xs);
  color: var(--woe-text-muted);
  font-family: var(--woe-font-mono);
}

.woe-emp-timeline__body {
  display: flex;
  align-items: baseline;
  gap: var(--woe-space-2);
  flex-wrap: wrap;
  flex: 1;
  min-width: 0;
}

.woe-emp-timeline__title {
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-text-primary);
  letter-spacing: var(--woe-tracking-tight);
}

.woe-emp-timeline__note {
  color: var(--woe-text-muted);
  font-size: var(--woe-font-xs);
}

.woe-emp-timeline__pill {
  display: inline-block;
  padding: 1px 6px;
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-bold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: color-mix(in srgb, var(--woe-accent) 14%, transparent);
  color: var(--woe-accent);
  border-radius: var(--woe-radius-sm);
  line-height: 1.4;
}

.woe-emp-timeline__castle {
  display: inline-flex;
  align-items: baseline;
  gap: var(--woe-space-1);
  min-width: 0;
}

.woe-emp-timeline__castle-name {
  font-size: var(--woe-font-sm);
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-text-primary);
  letter-spacing: var(--woe-tracking-tight);
}

.woe-emp-timeline__castle-map {
  font-size: var(--woe-font-xs);
  color: var(--woe-text-muted);
}

.woe-emp-timeline__actor {
  font-size: var(--woe-font-sm);
  color: var(--woe-text-primary);
  line-height: var(--woe-line-snug);
  display: inline-flex;
  align-items: baseline;
  gap: var(--woe-space-1);
  flex-wrap: wrap;
}

.woe-emp-timeline__hold {
  margin-left: auto;
  font-size: var(--woe-font-xs);
  color: var(--woe-text-secondary);
  white-space: nowrap;
  cursor: help;
}

.woe-emp-timeline__hold strong {
  color: var(--woe-stat-emp-break);
  font-weight: var(--woe-weight-semibold);
}

.woe-emp-timeline__ttk,
.woe-emp-timeline__attackers {
  font-size: var(--woe-font-xs);
  color: var(--woe-text-secondary);
  white-space: nowrap;
  cursor: help;
}

.woe-emp-timeline__ttk strong {
  color: var(--woe-stat-emp-break);
  font-weight: var(--woe-weight-semibold);
}

.woe-emp-timeline__attackers strong {
  color: var(--woe-text-primary);
  font-weight: var(--woe-weight-semibold);
}

@media (max-width: 575.98px) {
  .woe-emp-timeline__row {
    align-items: flex-start;
  }
  .woe-emp-timeline__hold,
  .woe-emp-timeline__ttk,
  .woe-emp-timeline__attackers {
    margin-left: 0;
  }
}


/* -------------------------------------------------------------------------
   EMPTY STATE
   ------------------------------------------------------------------------- */

.woe-empty {
  border: 1px dashed var(--woe-border);
  border-radius: var(--woe-radius-lg);
  padding: var(--woe-space-7) var(--woe-space-4);
  text-align: center;
  max-width: 36rem;
  margin: 0 auto;
  color: var(--woe-text-secondary);
  background: var(--woe-surface);
}

.woe-empty__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--woe-radius-full);
  background: var(--woe-accent-muted);
  color: var(--woe-accent);
  font-size: 1.25rem;
  margin-bottom: var(--woe-space-3);
}

.woe-empty__title {
  font-size: var(--woe-font-lg);
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-text-primary);
  margin: 0 0 var(--woe-space-2);
}

.woe-empty__subtext {
  font-size: var(--woe-font-sm);
  color: var(--woe-text-muted);
  margin: 0 0 var(--woe-space-4);
  max-width: 36ch;
  margin-inline: auto;
}

.woe-empty--compact {
  padding: var(--woe-space-4);
}

.woe-empty--compact .woe-empty__title {
  font-size: var(--woe-font-md);
}


/* -------------------------------------------------------------------------
   PAGINATION
   ------------------------------------------------------------------------- */

.woe-pagination {
  margin-top: var(--woe-space-4);
}

.woe-pagination .pagination {
  --bs-pagination-bg: var(--woe-surface);
  --bs-pagination-border-color: var(--woe-border);
  --bs-pagination-color: var(--woe-text-secondary);
  --bs-pagination-hover-bg: var(--woe-row-hover);
  --bs-pagination-hover-color: var(--woe-text-primary);
  --bs-pagination-hover-border-color: var(--woe-border-strong);
  --bs-pagination-active-bg: var(--woe-accent);
  --bs-pagination-active-border-color: var(--woe-accent);
  --bs-pagination-active-color: var(--woe-text-inverse);
  --bs-pagination-disabled-bg: var(--woe-surface);
  --bs-pagination-disabled-border-color: var(--woe-border);
  --bs-pagination-disabled-color: var(--woe-text-muted);
}


/* -------------------------------------------------------------------------
   PLAYER / GUILD / CASTLE LINKS
   ------------------------------------------------------------------------- */

.woe-player {
  display: inline-flex;
  align-items: baseline;
  gap: var(--woe-space-1);
  min-width: 0;
  max-width: 100%;
}

/* When char info is present we stack name+badges over a class+level subline. */
.woe-player--rich {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  line-height: var(--woe-line-snug);
}

.woe-player__head {
  display: inline-flex;
  align-items: baseline;
  gap: var(--woe-space-1);
  min-width: 0;
  max-width: 100%;
  flex-wrap: wrap;
}

.woe-player__name {
  color: var(--woe-text-primary);
  font-weight: var(--woe-weight-medium);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.woe-player__name:hover {
  color: var(--woe-accent);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

.woe-player--muted .woe-player__name {
  color: var(--woe-text-muted);
}

.woe-player__sub {
  display: inline-flex;
  gap: var(--woe-space-2);
  font-size: var(--woe-font-xs);
  color: var(--woe-text-muted);
  white-space: nowrap;
}

.woe-player__class {
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  color: var(--woe-text-muted);
}

.woe-player__levels {
  color: var(--woe-text-secondary);
}

.woe-guild-badge {
  color: var(--woe-text-muted);
  font-size: var(--woe-font-xs);
  text-decoration: none;
  letter-spacing: 0;
  white-space: nowrap;
}

.woe-guild-badge:hover {
  color: var(--woe-accent);
}

.woe-guild {
  display: inline-flex;
  align-items: center;
  gap: var(--woe-space-2);
  min-width: 0;
}

.woe-guild__emblem {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: var(--woe-radius-sm);
  background: var(--woe-surface-sunken);
  border: 1px solid var(--woe-border);
  overflow: hidden;
  flex-shrink: 0;
}

.woe-guild__emblem img {
  width: 100%;
  height: 100%;
  display: block;
}

.woe-guild__emblem-fallback {
  font-size: 0.625rem;
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-text-muted);
  letter-spacing: 0.02em;
}

.woe-guild__name {
  color: var(--woe-text-primary);
  font-weight: var(--woe-weight-medium);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.woe-guild__name:hover {
  color: var(--woe-accent);
}

.woe-castle {
  display: inline-flex;
  align-items: baseline;
  gap: var(--woe-space-2);
  padding: 2px var(--woe-space-2);
  border: 1px solid var(--woe-border);
  border-left-width: 3px;
  border-radius: var(--woe-radius-sm);
  color: var(--woe-text-primary);
  text-decoration: none;
  font-size: var(--woe-font-sm);
  background: var(--woe-surface);
  white-space: nowrap;
  transition: border-color var(--woe-duration-fast) var(--woe-ease-out),
              background-color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-castle:hover {
  border-color: var(--woe-border-strong);
  color: var(--woe-text-primary);
}

.woe-castle--owned {
  border-left-color: var(--woe-castle-owner, var(--woe-accent-event));
}

.woe-castle--unowned {
  color: var(--woe-text-muted);
  border-left-color: var(--woe-border);
}

.woe-castle--contested {
  border-style: dashed;
}

.woe-castle__name {
  font-weight: var(--woe-weight-medium);
}

.woe-castle__map {
  color: var(--woe-text-muted);
}

/* Castle Breakdown table cell — castle name + map id, plus an inline guild
   chip with emblem in the "Last Owner Proxy" column. */
.woe-castle-cell {
  display: flex;
  align-items: baseline;
  gap: var(--woe-space-2);
  flex-wrap: wrap;
}

.woe-castle-cell__name {
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-text-primary);
}

.woe-castle-cell__map {
  font-size: var(--woe-font-xs);
  color: var(--woe-text-muted);
}

.woe-castle-cell__guild {
  display: inline-flex;
  align-items: center;
  gap: var(--woe-space-2);
  text-decoration: none;
  color: var(--woe-text-primary);
  font-weight: var(--woe-weight-semibold);
  transition: color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-castle-cell__guild:hover {
  color: var(--woe-accent-event);
}

.woe-castle-cell__emblem {
  width: 22px;
  height: 22px;
  object-fit: contain;
  flex-shrink: 0;
  image-rendering: pixelated;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.3));
}


/* -------------------------------------------------------------------------
   ITEM — icon + name with placeholder fallback
   ------------------------------------------------------------------------- */

.woe-item {
  display: inline-flex;
  align-items: center;
  gap: var(--woe-space-2);
  min-width: 0;
  vertical-align: middle;
}

.woe-item__icon {
  position: relative;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--woe-surface-sunken);
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-sm);
  overflow: hidden;
}

.woe-item__icon--icon {
  width: 28px;
  height: 28px;
}

.woe-item__icon--image {
  width: 60px;
  height: 80px;
}

.woe-item__icon img {
  max-width: 100%;
  max-height: 100%;
  display: block;
  image-rendering: -webkit-optimize-contrast;
  image-rendering: crisp-edges;
}

.woe-item__placeholder {
  display: none;
  width: 60%;
  height: 60%;
  color: var(--woe-text-muted);
  fill: currentColor;
  opacity: 0.6;
}

.woe-item__icon--missing img {
  display: none;
}

.woe-item__icon--missing .woe-item__placeholder {
  display: block;
}

.woe-item__body {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.woe-item__name {
  color: var(--woe-text-primary);
  font-weight: var(--woe-weight-medium);
  font-size: var(--woe-font-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.woe-item__slots {
  color: var(--woe-accent);
  font-family: var(--woe-font-mono);
  font-size: 0.85em;
  font-weight: var(--woe-weight-semibold);
}

.woe-item__amount {
  color: var(--woe-text-secondary);
  font-family: var(--woe-font-mono);
  font-size: 0.9em;
}

.woe-item--icon {
  gap: 0;
}

.woe-item--mini .woe-item__icon--icon {
  width: 20px;
  height: 20px;
}

.woe-item--mini .woe-item__name {
  font-size: var(--woe-font-xs);
}

.woe-item--missing {
  color: var(--woe-text-muted);
  font-family: var(--woe-font-mono);
}


/* -------------------------------------------------------------------------
   FILTER BAR / SEGMENTED SELECTOR
   ------------------------------------------------------------------------- */

.woe-subtle-card {
  background: var(--woe-surface);
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-lg);
  box-shadow: var(--woe-shadow-sm);
}

.woe-filter .card-body {
  padding: var(--woe-space-3) var(--woe-space-4);
}

.woe-filter__label {
  display: block;
  color: var(--woe-text-muted);
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  margin-bottom: var(--woe-space-1);
}

.woe-filter .form-control,
.woe-filter .form-select {
  background: var(--woe-surface-base);
  border-color: var(--woe-border);
  color: var(--woe-text-primary);
  font-size: var(--woe-font-sm);
}

.woe-filter .form-control:focus,
.woe-filter .form-select:focus {
  background: var(--woe-surface-base);
  border-color: var(--woe-accent);
  box-shadow: none;
}

.woe-filter .btn-group .btn {
  --bs-btn-bg: var(--woe-surface-base);
  --bs-btn-color: var(--woe-text-secondary);
  --bs-btn-border-color: var(--woe-border);
  --bs-btn-hover-bg: var(--woe-row-hover);
  --bs-btn-hover-color: var(--woe-text-primary);
  --bs-btn-hover-border-color: var(--woe-border-strong);
  --bs-btn-active-bg: var(--woe-accent);
  --bs-btn-active-color: var(--woe-text-inverse);
  --bs-btn-active-border-color: var(--woe-accent);
  font-size: var(--woe-font-sm);
  font-weight: var(--woe-weight-medium);
  text-decoration: none;
}


/* -------------------------------------------------------------------------
   SECTION / HEADING HELPERS — used by pages
   ------------------------------------------------------------------------- */

.woe-section {
  margin-top: var(--woe-space-7);
}

.woe-section__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--woe-space-3);
  margin-bottom: var(--woe-space-3);
  flex-wrap: wrap;
}

.woe-section__title,
.woe-section-title {
  font-size: var(--woe-font-lg);   /* 18px — clear hierarchy step above body 15px */
  font-weight: var(--woe-weight-semibold);
  line-height: var(--woe-line-snug);
  letter-spacing: 0;
  color: var(--woe-text-primary);
  margin: 0;
}

.woe-section__meta {
  font-size: var(--woe-font-sm);   /* 13px — same as Bootstrap .small for parity */
  line-height: var(--woe-line-normal);
  color: var(--woe-text-secondary);
}

.woe-page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--woe-space-4);
  flex-wrap: wrap;
  margin-bottom: var(--woe-space-3);
}

.woe-page-title {
  font-size: var(--woe-font-2xl);
  font-weight: var(--woe-weight-semibold);
  line-height: var(--woe-line-tight);
  letter-spacing: var(--woe-tracking-tight);
  color: var(--woe-text-primary);
  margin: 0;
}

.woe-page-subtitle {
  color: var(--woe-text-secondary);
  font-size: var(--woe-font-sm);
  line-height: var(--woe-line-normal);
  margin: var(--woe-space-1) 0 0;
}

.woe-page-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--woe-space-1) var(--woe-space-3);
  margin-top: var(--woe-space-2);
}

.woe-page-meta > span {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}

.woe-page-meta > span + span {
  position: relative;
  padding-left: calc(var(--woe-space-3) + var(--woe-space-1));
}

.woe-page-meta > span + span::before {
  content: "·";
  position: absolute;
  left: 0;
  color: var(--woe-text-muted);
}

/* Emoji utility — used wherever a single emoji glyph stands in for a small
   icon. Keeps emoji at proper typographic size (sometimes browsers render
   them oversized) and prevents font-fallback wobble. The natural space
   character in markup provides spacing — no extra margin needed, otherwise
   emoji feels detached from the label. */
.woe-emoji {
  display: inline;
  font-style: normal;
  font-size: 1em;
  line-height: 1;
  vertical-align: -0.05em;
}


/* -------------------------------------------------------------------------
   INDEX PAGE — session status, meta bar, castle roster
   ------------------------------------------------------------------------- */

.woe-session-status {
  display: inline-flex;
  align-items: center;
  gap: var(--woe-space-2);
  padding: var(--woe-space-1) var(--woe-space-3);
  border-radius: var(--woe-radius-full);
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  border: 1px solid var(--woe-border);
  color: var(--woe-text-secondary);
  white-space: nowrap;
}

.woe-session-status__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--woe-radius-full);
  background: var(--woe-text-muted);
}

.woe-session-status--live {
  color: var(--woe-success);
  border-color: var(--woe-success-muted);
  background: var(--woe-success-muted);
}

.woe-session-status--live .woe-session-status__dot {
  background: var(--woe-success);
  box-shadow: 0 0 0 3px var(--woe-success-muted);
  animation: woePulse 2s var(--woe-ease-in-out) infinite;
}

@keyframes woePulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

.woe-session-status--done {
  color: var(--woe-text-secondary);
  border-color: var(--woe-border);
}

.woe-castle-roster {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--woe-space-1);
}

/* Four-column grid: 4px tint stripe → 28px emblem → flexible main column
   (guild name + castle list) → count. justify-items:start keeps every cell's
   content left-aligned; the count column hugs its own auto width on the
   right. The .woe-castle-roster__row:not(:has(.woe-castle-roster__emblem))
   selector below collapses the emblem column gracefully if the markup
   ever ships without an emblem. */
.woe-castle-roster__row {
  display: grid;
  grid-template-columns: 4px 28px 1fr auto;
  align-items: center;
  justify-items: start;
  gap: var(--woe-space-3);
  padding: var(--woe-space-2) var(--woe-space-3);
  background: var(--woe-surface);
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-md);
  color: var(--woe-text-primary);
  text-decoration: none;
  transition: border-color var(--woe-duration-fast) var(--woe-ease-out),
              background-color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-castle-roster__row:not(:has(.woe-castle-roster__emblem)) {
  grid-template-columns: 4px 1fr auto;
}

.woe-castle-roster__row:hover {
  border-color: var(--woe-border-strong);
  background: var(--woe-row-hover);
  color: var(--woe-text-primary);
}

.woe-castle-roster__tint {
  width: 4px;
  height: 1.5rem;
  background: var(--woe-castle-owner, var(--woe-accent-event));
  border-radius: var(--woe-radius-sm);
}

.woe-castle-roster__emblem {
  width: 28px;
  height: 28px;
  object-fit: contain;
  flex-shrink: 0;
  image-rendering: pixelated;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));
}

.woe-castle-roster__main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  width: 100%;
  text-align: left;
}

.woe-castle-roster__name {
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.woe-castle-roster__castles {
  font-size: var(--woe-font-xs);
  color: var(--woe-text-muted);
  letter-spacing: 0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.woe-castle-roster__count {
  font-family: var(--woe-font-mono);
  color: var(--woe-accent);
  font-weight: var(--woe-weight-semibold);
  font-size: var(--woe-font-md);
  flex-shrink: 0;
  justify-self: end;
}


/* -------------------------------------------------------------------------
   PLAYER PROFILE — Latest WoE / Total side-by-side sections
   ------------------------------------------------------------------------- */

.woe-profile-section {
  background: var(--woe-surface);
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-lg);
  padding: var(--woe-space-5);
  display: flex;
  flex-direction: column;
  gap: var(--woe-space-4);
}

.woe-profile-section__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--woe-space-4);
  flex-wrap: wrap;
}

.woe-profile-section__head-main {
  display: flex;
  flex-direction: column;
  gap: var(--woe-space-1);
  min-width: 0;
}

.woe-scope-toggle {
  flex-shrink: 0;
}

.woe-scope-toggle .bi {
  margin-right: var(--woe-space-1);
}

.woe-profile-section__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--woe-space-2);
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  color: var(--woe-accent);
}

.woe-profile-section__title {
  font-size: var(--woe-font-xl);
  font-weight: var(--woe-weight-semibold);
  margin: 0;
  line-height: var(--woe-line-snug);
}

.woe-profile-section__title a {
  color: var(--woe-text-primary);
}

.woe-profile-section__title a:hover {
  color: var(--woe-accent);
}

.woe-profile-section__sub {
  font-size: var(--woe-font-sm);
}

.woe-profile-section .woe-stat-group:not(.woe-stat-group--square):not(.woe-stat-group--wide):not(.woe-stat-group--cols-3) {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.woe-profile-section__subhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--woe-space-3);
  padding-top: var(--woe-space-3);
  margin-bottom: var(--woe-space-3);
  border-top: 1px dashed var(--woe-border);
}

.woe-profile-section__subhead .bi {
  margin-right: var(--woe-space-1);
  color: var(--woe-text-secondary);
}

@media (max-width: 575px) {
  .woe-profile-section {
    padding: var(--woe-space-4);
  }
}

/* Consumables — by-category expandable list.
   Each category is a <details> "row" whose summary mimics a table row via
   CSS grid; opening it reveals an items table inside. */

.woe-category {
  display: inline-flex;
  align-items: baseline;
  gap: var(--woe-space-2);
  min-width: 0;
}

/* Emoji sits inline with the category name — no separate flex slot, no gap.
   The 0.35em margin gives the icon natural breathing room without making
   it feel detached. */
.woe-category__icon {
  display: inline;
  font-size: 1.1em;
  line-height: 1;
  margin-right: 0.35em;
  vertical-align: -0.05em;
}

.woe-category__name {
  font-weight: var(--woe-weight-semibold);
}

.woe-category__count {
  white-space: nowrap;
}

.woe-category-bar {
  position: relative;
  display: inline-block;
  width: 100%;
  padding: 0.125rem 0.5rem;
  border-radius: var(--woe-radius-sm);
  background: linear-gradient(
    90deg,
    var(--woe-accent-muted) 0,
    var(--woe-accent-muted) var(--woe-bar-pct, 0%),
    transparent var(--woe-bar-pct, 0%),
    transparent 100%
  );
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.woe-category-bar__value {
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-text-primary);
}

/* List + per-category row layout */

.woe-category-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-md);
  overflow: hidden;
  background: var(--woe-surface);
}

.woe-category-list__head,
.woe-category-row__summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(5rem, auto) minmax(8rem, 14rem);
  align-items: center;
  gap: var(--woe-space-3);
  padding: var(--woe-space-2) var(--woe-space-3);
}

.woe-category-list__head {
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  color: var(--woe-text-muted);
  background: var(--woe-surface-sunken);
  border-bottom: 1px solid var(--woe-border);
}

.woe-category-row {
  border-bottom: 1px solid var(--woe-border);
}

.woe-category-row:last-child {
  border-bottom: none;
}

.woe-category-row__summary {
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: background-color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-category-row__summary::-webkit-details-marker { display: none; }
.woe-category-row__summary::marker { content: ''; }

.woe-category-row__summary:hover {
  background: var(--woe-row-hover);
}

.woe-category-row[open] > .woe-category-row__summary {
  background: var(--woe-row-hover);
  border-bottom: 1px solid var(--woe-border);
}

.woe-category-row__summary:focus-visible {
  outline: 2px solid var(--woe-accent);
  outline-offset: -2px;
}

.woe-category-row__chevron {
  display: inline-block;
  color: var(--woe-text-muted);
  font-size: 0.85rem;
  line-height: 1;
  margin-right: var(--woe-space-1);
  transition: transform var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-category-row[open] .woe-category-row__chevron {
  transform: rotate(90deg);
  color: var(--woe-accent);
}

.woe-category-row__amount {
  white-space: nowrap;
}

.woe-category-row__pct {
  min-width: 0;
}

.woe-category-row__body {
  padding: var(--woe-space-3) var(--woe-space-4) var(--woe-space-4);
  background: var(--woe-surface-sunken);
}

.woe-category-items {
  background: transparent;
}

.woe-category-items th {
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  color: var(--woe-text-muted);
}

@media (max-width: 575px) {
  .woe-category-list__head,
  .woe-category-row__summary {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .woe-category-list__head > :nth-child(3),
  .woe-category-row__pct {
    grid-column: 1 / -1;
  }
}

/* Sessions list — live row is gated (no link until results publish). */
.woe-row--live td {
  background: color-mix(in srgb, var(--woe-warning) 6%, transparent);
}

.woe-row--live td:first-child {
  box-shadow: inset 3px 0 0 0 var(--woe-warning);
}


/* -------------------------------------------------------------------------
   PLAYER PROFILE — bold hero with class portrait + guild emblem
   ------------------------------------------------------------------------- */

.woe-player-hero {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--woe-space-5);
  padding: var(--woe-space-5);
  margin-bottom: var(--woe-space-4);
  background:
    radial-gradient(circle at top right, color-mix(in srgb, var(--woe-accent) 8%, transparent), transparent 60%),
    var(--woe-surface);
  border: 1px solid var(--woe-border);
  border-left: 3px solid var(--woe-accent);
  border-radius: var(--woe-radius-lg);
  position: relative;
  overflow: hidden;
}

.woe-player-hero::before {
  content: "";
  position: absolute;
  inset: -50% -10% auto auto;
  width: 280px;
  height: 280px;
  background: radial-gradient(circle, color-mix(in srgb, var(--woe-accent) 18%, transparent), transparent 60%);
  pointer-events: none;
  filter: blur(40px);
}

/* Class portrait — square tile with class glyph + guild emblem inset */
.woe-player-hero__portrait {
  position: relative;
  width: 7rem;
  height: 7rem;
  border-radius: var(--woe-radius-lg);
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--woe-accent) 30%, var(--woe-surface-sunken)),
    var(--woe-surface-sunken));
  border: 1px solid var(--woe-border-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 8px 24px rgba(0, 0, 0, 0.25);
}

.woe-player-hero__portrait[data-class-tier="transcendent"] {
  background: linear-gradient(135deg,
    color-mix(in srgb, #f59e0b 32%, var(--woe-surface-sunken)),
    var(--woe-surface-sunken));
  border-color: color-mix(in srgb, #f59e0b 40%, var(--woe-border));
}

.woe-player-hero__portrait[data-class-tier="second"] {
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--woe-accent) 32%, var(--woe-surface-sunken)),
    var(--woe-surface-sunken));
}

.woe-player-hero__portrait[data-class-tier="first"] {
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--woe-text-secondary) 24%, var(--woe-surface-sunken)),
    var(--woe-surface-sunken));
}

.woe-player-hero__portrait[data-class-tier="novice"] {
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--woe-success) 24%, var(--woe-surface-sunken)),
    var(--woe-surface-sunken));
}

.woe-player-hero__glyph {
  font-size: 3.5rem;
  line-height: 1;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.4));
  position: absolute;
  z-index: 1;
}

/* Class-glyph watermark behind the rendered sprite — large, faded, blurred
   so it reads as decorative backdrop instead of competing with the character. */
.woe-player-hero__glyph--watermark {
  font-size: 5rem;
  opacity: 0.18;
  filter: blur(1px) drop-shadow(0 4px 8px rgba(0, 0, 0, 0.3));
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* RO sprite art is foot-anchored inside a mostly-transparent 100×110 canvas,
   so the glyph emoji bleeds through the empty regions. The glyph is purely
   a fallback for sprite-load failures — hide it whenever a sprite is present
   and reveal it again only if onerror flips on --no-sprite. */
.woe-player-hero__portrait--has-sprite .woe-player-hero__glyph {
  display: none;
}
.woe-player-hero__portrait--has-sprite.woe-player-hero__portrait--no-sprite .woe-player-hero__glyph {
  display: block;
}

.woe-player-hero__sprite {
  position: relative;
  z-index: 2;
  max-width: 88%;
  max-height: 88%;
  object-fit: contain;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.55));
  image-rendering: pixelated;
  image-rendering: -moz-crisp-edges;
  image-rendering: crisp-edges;
}

.woe-player-hero__portrait--no-sprite .woe-player-hero__sprite {
  display: none;
}

.woe-player-hero__emblem {
  position: absolute;
  bottom: -0.5rem;
  right: -0.5rem;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--woe-radius-md);
  background: var(--woe-surface);
  border: 2px solid var(--woe-surface-base);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
  object-fit: contain;
  padding: 2px;
}

/* Body — class eyebrow, big name, level pills, guild block */
.woe-player-hero__body {
  display: flex;
  flex-direction: column;
  gap: var(--woe-space-1);
  min-width: 0;
}

.woe-player-hero__eyebrow {
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  color: var(--woe-accent);
  line-height: 1;
}

.woe-player-hero__name {
  font-size: clamp(1.5rem, 1rem + 1.5vw, 2.25rem);
  font-weight: var(--woe-weight-bold);
  line-height: 1.1;
  letter-spacing: var(--woe-tracking-tight);
  color: var(--woe-text-primary);
  margin: 0;
}

.woe-player-hero__meta {
  display: flex;
  align-items: center;
  gap: var(--woe-space-3);
  margin-top: var(--woe-space-1);
  flex-wrap: wrap;
}

.woe-player-hero__level {
  display: inline-flex;
  align-items: baseline;
  gap: var(--woe-space-1);
}

.woe-player-hero__level-num {
  font-family: var(--woe-font-mono);
  font-size: var(--woe-font-lg);
  font-weight: var(--woe-weight-bold);
  color: var(--woe-text-primary);
  font-variant-numeric: tabular-nums slashed-zero;
}

.woe-player-hero__level-label {
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  color: var(--woe-text-muted);
}

.woe-player-hero__level-sep {
  width: 1px;
  height: 1rem;
  background: var(--woe-border);
}

.woe-player-hero__id {
  color: var(--woe-text-muted);
  font-size: var(--woe-font-sm);
}

/* Top line: Nickname  |  [emblem] Guild */
.woe-player-hero__topline {
  display: flex;
  align-items: center;
  gap: var(--woe-space-3);
  flex-wrap: wrap;
}

.woe-player-hero__topline-sep {
  color: var(--woe-border-strong);
  font-weight: var(--woe-weight-bold);
  font-size: 1.5rem;
  line-height: 1;
  user-select: none;
}

.woe-player-hero__guild {
  display: inline-flex;
  align-items: center;
  gap: var(--woe-space-2);
  text-decoration: none;
  color: var(--woe-text-primary);
  transition: transform var(--woe-duration-fast) var(--woe-ease-out),
              color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-player-hero__guild-emblem-inline {
  width: 28px;
  height: 28px;
  object-fit: contain;
  flex-shrink: 0;
  image-rendering: pixelated;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));
}

/* Sub line: <Job> 99 Lvl. #charId */
.woe-player-hero__subline {
  display: flex;
  align-items: baseline;
  gap: var(--woe-space-2);
  flex-wrap: wrap;
  margin-top: var(--woe-space-1);
}

.woe-player-hero__job {
  font-size: var(--woe-font-base);
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-accent);
  letter-spacing: var(--woe-tracking-wide);
}

.woe-player-hero__guild-text {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.woe-player-hero__guild:hover {
  background: color-mix(in srgb, var(--woe-accent-event) 8%, var(--woe-surface-sunken));
  color: var(--woe-accent-event);
  transform: translateX(2px);
}

.woe-player-hero__guild-eyebrow {
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  color: var(--woe-text-muted);
  line-height: 1;
}

.woe-player-hero__guild-name {
  font-size: var(--woe-font-base);
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-text-primary);
}

.woe-player-hero__back {
  align-self: flex-start;
  white-space: nowrap;
  position: relative;
  z-index: 1;
}

@media (max-width: 767.98px) {
  .woe-player-hero {
    grid-template-columns: auto 1fr;
    grid-template-rows: auto auto;
    gap: var(--woe-space-3) var(--woe-space-4);
    padding: var(--woe-space-4);
  }
  .woe-player-hero__portrait {
    width: 5rem;
    height: 5rem;
  }
  .woe-player-hero__glyph {
    font-size: 2.5rem;
  }
  .woe-player-hero__back {
    grid-column: 1 / -1;
    align-self: stretch;
    text-align: center;
  }
}


/* -------------------------------------------------------------------------
   STAT CARDS — square variant for player profile
   ------------------------------------------------------------------------- */

.woe-stat-group--square {
  display: grid;
  gap: var(--woe-space-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 576px) {
  .woe-stat-group--square { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 768px) {
  .woe-stat-group--square { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 992px) {
  .woe-stat-group--square { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

.woe-stat-group--square .woe-stat-card {
  aspect-ratio: 1 / 1;
  padding: var(--woe-space-3);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border-radius: var(--woe-radius-md);
  border: 1px solid var(--woe-border);
  background: var(--woe-surface);
  position: relative;
  overflow: hidden;
  transition: transform var(--woe-duration-fast) var(--woe-ease-out),
              border-color var(--woe-duration-fast) var(--woe-ease-out),
              box-shadow var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-stat-group--square .woe-stat-card:hover {
  transform: translateY(-2px);
  border-color: var(--woe-border-strong);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
}

.woe-stat-group--square .woe-stat-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: nowrap;
  margin: 0;
  min-height: auto;
  gap: var(--woe-space-1);
}

/* Hero number — scale + weight + tight tracking, neutral white. Research-grounded
   recipe: scale carries 60% of impact, weight 25%, accent (variant stripe + icon
   color, NOT number color) carries 15%. Tabular numerals + slashed zero keep
   columns visually aligned across multiple cards. */
.woe-stat-group--square .woe-stat-card__value {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  margin: 0;
  font-family: var(--woe-font-mono);
  font-size: clamp(2.125rem, 1.4rem + 3vw, 3.25rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  text-align: center;
  color: var(--woe-text-primary);
  line-height: 1;
  font-variant-numeric: tabular-nums slashed-zero;
  font-feature-settings: 'tnum' 1, 'lnum' 1, 'zero' 1;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.35);
}

/* Square label: tighter, bolder uppercase eyebrow above the number. */
.woe-stat-group--square .woe-stat-card__label {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Glyph icon next to the label — slightly larger so it reads as a category
   token, not a punctuation mark. */
.woe-stat-group--square .woe-stat-card__icon {
  font-size: 1.05em;
  margin-right: 2px;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.35));
}

.woe-stat-group--square .woe-stat-card__caption,
.woe-stat-group--square .woe-stat-card__foot {
  font-size: var(--woe-font-xs);
  color: var(--woe-text-muted);
  text-align: center;
  line-height: 1.2;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Variant accents — thicker left stripe (4px per Material/dashboard guidance);
   color stays on stripe + label icon, NEVER on the hero number, so contrast
   against the dark surface remains AA-compliant regardless of variant. */
.woe-stat-group--square .woe-stat-card--positive { box-shadow: inset 4px 0 0 0 var(--woe-success); }
.woe-stat-group--square .woe-stat-card--negative { box-shadow: inset 4px 0 0 0 var(--woe-danger); }
.woe-stat-group--square .woe-stat-card--accent   { box-shadow: inset 4px 0 0 0 var(--woe-accent-event); }

/* Hover: subtle accent-tinted backdrop + brightened stripe + lift. ~10% accent
   tint reads as "alive" without becoming a colored card. */
.woe-stat-group--square .woe-stat-card--positive:hover {
  background: color-mix(in srgb, var(--woe-success) 8%, var(--woe-surface));
  box-shadow: inset 4px 0 0 0 var(--woe-success), 0 8px 24px rgba(0,0,0,0.28);
}
.woe-stat-group--square .woe-stat-card--negative:hover {
  background: color-mix(in srgb, var(--woe-danger) 8%, var(--woe-surface));
  box-shadow: inset 4px 0 0 0 var(--woe-danger), 0 8px 24px rgba(0,0,0,0.28);
}
.woe-stat-group--square .woe-stat-card--accent:hover {
  background: color-mix(in srgb, var(--woe-accent-event) 8%, var(--woe-surface));
  box-shadow: inset 4px 0 0 0 var(--woe-accent-event), 0 8px 24px rgba(0,0,0,0.28);
}

/* Tint the variant icon so it picks up the accent color the stripe is using —
   gives the eye a second visual cue paired with the stripe (icon + color +
   stripe redundancy = colorblind-safe per WCAG 1.4.1). */
.woe-stat-group--square .woe-stat-card--positive .woe-stat-card__icon { color: var(--woe-success); }
.woe-stat-group--square .woe-stat-card--negative .woe-stat-card__icon { color: var(--woe-danger); }
.woe-stat-group--square .woe-stat-card--accent   .woe-stat-card__icon { color: var(--woe-accent-event); }

@media (prefers-reduced-motion: reduce) {
  .woe-stat-group--square .woe-stat-card { transition: none; }
  .woe-stat-group--square .woe-stat-card:hover { transform: none; }
}


/* -------------------------------------------------------------------------
   STATE GATE — full-page hero card for pre-WoE / during-WoE states
   ------------------------------------------------------------------------- */

.woe-gate {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--woe-space-3);
  text-align: center;
  padding: var(--woe-space-9) var(--woe-space-5);
  margin-block: var(--woe-space-5);
  background: var(--woe-surface);
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-lg);
  position: relative;
  overflow: hidden;
}

.woe-gate::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--woe-text-muted);
}

.woe-gate--event::before  { background: var(--woe-stat-emp-break); }
.woe-gate--warning::before { background: var(--woe-warning); }

.woe-gate__icon {
  font-size: 4rem;
  line-height: 1;
  margin-bottom: var(--woe-space-2);
  filter: drop-shadow(0 4px 12px color-mix(in srgb, var(--woe-text-primary) 15%, transparent));
}

.woe-gate--event .woe-gate__icon {
  animation: woe-gate-pulse 2.4s ease-in-out infinite;
}

@keyframes woe-gate-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.06); }
}

.woe-gate__eyebrow {
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: var(--woe-tracking-wide);
  text-transform: uppercase;
  color: var(--woe-text-muted);
}

.woe-gate--event .woe-gate__eyebrow { color: var(--woe-stat-emp-break); }
.woe-gate--warning .woe-gate__eyebrow { color: var(--woe-warning); }

.woe-gate__title {
  font-size: var(--woe-font-2xl);
  font-weight: var(--woe-weight-semibold);
  line-height: var(--woe-line-tight);
  letter-spacing: var(--woe-tracking-tight);
  color: var(--woe-text-primary);
  margin: 0;
  max-width: 30ch;
}

.woe-gate__lead {
  font-size: var(--woe-font-base);
  line-height: var(--woe-line-normal);
  color: var(--woe-text-secondary);
  max-width: 56ch;
  margin: 0;
}

.woe-gate__meta {
  font-size: var(--woe-font-sm);
  color: var(--woe-text-muted);
  margin: 0;
  font-variant-numeric: tabular-nums slashed-zero;
}

.woe-gate__cta {
  margin-top: var(--woe-space-3);
}

@media (max-width: 575px) {
  .woe-gate { padding: var(--woe-space-7) var(--woe-space-4); }
  .woe-gate__icon { font-size: 3rem; }
}

@media (prefers-reduced-motion: reduce) {
  .woe-gate--event .woe-gate__icon { animation: none; }
}


/* -------------------------------------------------------------------------
   REDUCED MOTION
   ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  :root,
  [data-bs-theme="dark"],
  [data-bs-theme="light"] {
    --woe-duration-instant: 0.01ms;
    --woe-duration-fast:    0.01ms;
    --woe-duration-normal:  0.01ms;
    --woe-duration-slow:    0.01ms;
  }

  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}


/* -------------------------------------------------------------------------
   LEADERBOARD — filters (segmented control + session select) + podium
   ------------------------------------------------------------------------- */

.woe-leaderboard-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--woe-space-3) var(--woe-space-5);
  padding: var(--woe-space-3) var(--woe-space-4);
  background: var(--woe-surface-sunken);
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-md);
}

.woe-leaderboard-filters__group {
  display: flex;
  flex-direction: column;
  gap: var(--woe-space-1);
  min-width: 0;
}

.woe-leaderboard-filters__group--session {
  flex: 1;
  min-width: 14rem;
}

/* Segmented control — replaces Bootstrap btn-group for entity/metric pickers.
   aria-pressed on each button surfaces the active state to AT. */
.woe-segmented {
  display: inline-flex;
  flex-wrap: wrap;
  background: var(--woe-surface);
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-md);
  padding: 2px;
  gap: 2px;
}

.woe-segmented__btn {
  display: inline-flex;
  align-items: center;
  gap: var(--woe-space-1);
  padding: 0.4rem 0.85rem;
  font-size: var(--woe-font-sm);
  font-weight: var(--woe-weight-semibold);
  color: var(--woe-text-muted);
  text-decoration: none;
  background: transparent;
  border: 0;
  border-radius: calc(var(--woe-radius-md) - 2px);
  white-space: nowrap;
  transition: background-color var(--woe-duration-fast) var(--woe-ease-out),
              color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-segmented__btn:hover {
  background: var(--woe-row-hover);
  color: var(--woe-text-primary);
}

.woe-segmented__btn.is-active,
.woe-segmented__btn[aria-pressed="true"] {
  background: var(--woe-accent);
  color: #fff;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.woe-segmented__btn:focus-visible {
  outline: 2px solid var(--woe-accent);
  outline-offset: 2px;
}

.woe-session-select {
  width: 100%;
  background: var(--woe-surface);
  border-color: var(--woe-border);
  color: var(--woe-text-primary);
}

/* Podium — DOM order is [2nd, 1st, 3rd] so the medal stand reads correctly
   while keeping rank indication explicit in markup for screen readers. */
.woe-podium {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--woe-space-5);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: end;
  gap: var(--woe-space-3);
}

.woe-podium__slot {
  min-width: 0;
}

.woe-podium__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--woe-space-1);
  padding: var(--woe-space-4) var(--woe-space-3);
  background: var(--woe-surface);
  border: 1px solid var(--woe-border);
  border-top: 4px solid var(--woe-border-strong);
  border-radius: var(--woe-radius-md);
  text-decoration: none;
  color: var(--woe-text-primary);
  text-align: center;
  transition: transform var(--woe-duration-fast) var(--woe-ease-out),
              border-color var(--woe-duration-fast) var(--woe-ease-out),
              box-shadow var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-podium__card:hover {
  transform: translateY(-2px);
  color: var(--woe-text-primary);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.20);
}

/* Per-rank stripe colors — same medal palette already used in .woe-rank--*.
   Number stays neutral; color goes on the stripe and medal glyph (research
   recipe). */
.woe-podium__slot--1 .woe-podium__card {
  min-height: 11.5rem;
  border-top-color: #f59e0b;
  box-shadow: 0 0 0 1px rgba(245, 158, 11, 0.35), 0 4px 16px rgba(245, 158, 11, 0.18);
}
.woe-podium__slot--2 .woe-podium__card {
  min-height: 10rem;
  border-top-color: #94a3b8;
}
.woe-podium__slot--3 .woe-podium__card {
  min-height: 9rem;
  border-top-color: #d97706;
}

.woe-podium__rank {
  display: inline-flex;
  align-items: center;
  gap: var(--woe-space-1);
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-bold);
  color: var(--woe-text-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.woe-podium__medal {
  font-size: 1.6rem;
  line-height: 1;
}

.woe-podium__rank-num {
  font-family: var(--woe-font-mono);
}

.woe-podium__name {
  font-size: var(--woe-font-md);
  font-weight: var(--woe-weight-bold);
  color: var(--woe-text-primary);
  letter-spacing: var(--woe-tracking-tight);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.woe-podium__primary {
  font-family: var(--woe-font-mono);
  font-size: clamp(1.75rem, 1.2rem + 1.6vw, 2.5rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--woe-text-primary);
  font-variant-numeric: tabular-nums slashed-zero;
  margin-top: var(--woe-space-1);
}

.woe-podium__primary-label {
  font-size: var(--woe-font-xs);
  font-weight: var(--woe-weight-semibold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--woe-text-muted);
}

.woe-podium__secondary {
  font-size: var(--woe-font-xs);
  color: var(--woe-text-muted);
  font-family: var(--woe-font-mono);
  display: flex;
  gap: var(--woe-space-1);
  flex-wrap: wrap;
  justify-content: center;
}

@media (max-width: 575.98px) {
  .woe-podium {
    grid-template-columns: 1fr;
  }
  .woe-podium__slot--1 .woe-podium__card,
  .woe-podium__slot--2 .woe-podium__card,
  .woe-podium__slot--3 .woe-podium__card {
    min-height: auto;
  }
  /* On mobile, restore strict rank order (1, 2, 3) top-to-bottom. */
  .woe-podium__slot--2 { order: 2; }
  .woe-podium__slot--1 { order: 1; }
  .woe-podium__slot--3 { order: 3; }

  .woe-leaderboard-filters {
    flex-direction: column;
    align-items: stretch;
  }
  .woe-segmented {
    width: 100%;
  }
  .woe-segmented__btn {
    flex: 1 1 0;
    justify-content: center;
  }
}


/* -------------------------------------------------------------------------
   PODIUM additions: secondary guild line + info-tip popover
   ------------------------------------------------------------------------- */

.woe-podium__guild {
  font-size: var(--woe-font-xs);
  color: var(--woe-text-muted);
  letter-spacing: 0.02em;
  margin-top: -2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

/* Info tip — small ⓘ button next to a heading. Hovering OR focusing OR
   clicking ("is-open") reveals an explanatory popover anchored below the
   button. Pure CSS-driven for hover/focus; tiny inline JS toggles
   `.is-open` on click for touch devices that don't fire :hover. */
.woe-info-tip {
  position: relative;
  display: inline-flex;
  vertical-align: baseline;
  margin-left: var(--woe-space-1);
}

.woe-info-tip__btn {
  appearance: none;
  width: 1.25rem;
  height: 1.25rem;
  padding: 0;
  border: 1px solid var(--woe-border);
  border-radius: var(--woe-radius-full);
  background: var(--woe-surface-sunken);
  color: var(--woe-text-muted);
  font-size: 0.85rem;
  font-weight: var(--woe-weight-bold);
  line-height: 1;
  cursor: help;
  transition: color var(--woe-duration-fast) var(--woe-ease-out),
              border-color var(--woe-duration-fast) var(--woe-ease-out),
              background-color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-info-tip__btn:hover,
.woe-info-tip__btn:focus-visible,
.woe-info-tip__btn.is-open {
  color: var(--woe-accent);
  border-color: var(--woe-accent);
  background: color-mix(in srgb, var(--woe-accent) 12%, var(--woe-surface));
  outline: none;
}

.woe-info-tip__body {
  position: absolute;
  top: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%) translateY(-4px);
  width: max-content;
  max-width: min(28rem, calc(100vw - 2rem));
  padding: var(--woe-space-3) var(--woe-space-4);
  background: var(--woe-surface-overlay);
  color: var(--woe-text-primary);
  border: 1px solid var(--woe-border-strong);
  border-radius: var(--woe-radius-md);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.32);
  font-size: var(--woe-font-sm);
  font-weight: var(--woe-weight-regular);
  line-height: 1.55;
  letter-spacing: 0;
  text-transform: none;
  z-index: 50;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--woe-duration-fast) var(--woe-ease-out),
              transform var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-info-tip:hover .woe-info-tip__body,
.woe-info-tip:focus-within .woe-info-tip__body,
.woe-info-tip__btn.is-open + .woe-info-tip__body {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}

.woe-info-tip__body::before {
  content: "";
  position: absolute;
  top: -7px;
  left: 50%;
  width: 12px;
  height: 12px;
  background: var(--woe-surface-overlay);
  border-top: 1px solid var(--woe-border-strong);
  border-left: 1px solid var(--woe-border-strong);
  transform: translateX(-50%) rotate(45deg);
}

.woe-info-tip__formula {
  margin: var(--woe-space-2) 0;
  padding: var(--woe-space-1) var(--woe-space-2);
  background: var(--woe-surface-sunken);
  border-radius: var(--woe-radius-sm);
  font-family: var(--woe-font-mono);
  font-size: var(--woe-font-xs);
  color: var(--woe-accent);
  text-align: center;
}

@media (max-width: 575.98px) {
  /* Anchor popover to viewport edge on small screens to avoid clipping. */
  .woe-info-tip__body {
    left: auto;
    right: -1rem;
    transform: translateY(-4px);
  }
  .woe-info-tip:hover .woe-info-tip__body,
  .woe-info-tip:focus-within .woe-info-tip__body,
  .woe-info-tip__btn.is-open + .woe-info-tip__body {
    transform: translateY(0);
  }
  .woe-info-tip__body::before {
    left: auto;
    right: 1.25rem;
  }
}


/* -------------------------------------------------------------------------
   TABLE SEARCH — inline search field above paginated tables (e.g. session
   participant list with 1000+ rows).
   ------------------------------------------------------------------------- */

.woe-table-search {
  display: flex;
  align-items: center;
  gap: var(--woe-space-2);
  flex-wrap: wrap;
}

.woe-table-search__field {
  position: relative;
  flex: 1;
  min-width: 14rem;
  max-width: 28rem;
}

.woe-table-search__icon {
  position: absolute;
  left: 0.65rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.9rem;
  pointer-events: none;
  color: var(--woe-text-muted);
}

.woe-table-search__input {
  padding-left: 2rem;
  padding-right: 2rem;
  background: var(--woe-surface);
  border-color: var(--woe-border);
  color: var(--woe-text-primary);
}

.woe-table-search__input:focus {
  border-color: var(--woe-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--woe-accent) 20%, transparent);
}

.woe-table-search__clear {
  position: absolute;
  right: 0.5rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1.4rem;
  height: 1.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--woe-radius-full);
  font-size: 1.1rem;
  line-height: 1;
  color: var(--woe-text-muted);
  background: transparent;
  text-decoration: none;
  transition: background-color var(--woe-duration-fast) var(--woe-ease-out),
              color var(--woe-duration-fast) var(--woe-ease-out);
}

.woe-table-search__clear:hover {
  background: var(--woe-row-hover);
  color: var(--woe-text-primary);
}

/* Leaderboard filter — search input fits alongside the segmented controls */
.woe-leaderboard-filters__group--search {
  flex: 1;
  min-width: 14rem;
  max-width: 22rem;
}

/* Highlighted band for search results above the main ranking */
.woe-search-results {
  padding: var(--woe-space-3) var(--woe-space-4);
  background: color-mix(in srgb, var(--woe-accent) 6%, var(--woe-surface-sunken));
  border: 1px solid color-mix(in srgb, var(--woe-accent) 25%, var(--woe-border));
  border-radius: var(--woe-radius-md);
}

.woe-search-results .woe-section__head {
  margin-top: 0;
}

.woe-search-results__query {
  color: var(--woe-text-primary);
  font-weight: 600;
}

.woe-search-results__empty {
  padding: var(--woe-space-3) var(--woe-space-1) var(--woe-space-1);
  color: var(--woe-text-muted);
}


/* Leaderboard row emblem (table rows) — sits inline next to the player or
   guild name. Squared with subtle border so transparent emblems keep their
   visual weight against varying backgrounds. */
.woe-row-emblem {
  flex: 0 0 auto;
  border-radius: 3px;
  background: var(--woe-surface-sunken);
  object-fit: contain;
  image-rendering: pixelated;
}

/* ===================================================================== *
 * Kill log (kills.php) — quiet chrome, monospace time, right-arrow column
 * collapses to almost nothing on mobile. PC-only feed; the cause column,
 * badges and mobile dots were removed in the post-audit cleanup.
 * ===================================================================== */
.woe-kill-table__time {
  width: 1%;
  white-space: nowrap;
}

.woe-kill-table__time time {
  font-variant-numeric: tabular-nums;
}

.woe-kill-table__arrow {
  width: 24px;
  text-align: center;
  padding-left: 0;
  padding-right: 0;
  font-size: 1.1em;
  user-select: none;
}

.woe-kill-table__map {
  width: 1%;
  white-space: nowrap;
  font-size: var(--woe-font-xs);
}

.woe-kill-table__map code {
  background: transparent;
  color: inherit;
  padding: 0;
}

/* Compact pill inside a stat card value — used for the streak ×N badge. */
.woe-stat-card__pill {
  display: inline-block;
  margin-left: 6px;
  padding: 0 8px;
  border-radius: var(--woe-radius-sm);
  background: color-mix(in srgb, var(--woe-stat-kills) 16%, transparent);
  color: var(--woe-stat-kills);
  font-size: 0.7em;
  font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: middle;
}

/* Cursor pager — three-up; disabled state keeps focus order without
 * flashing as a real link. */
.woe-cursor-pager .btn.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}


