﻿html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

a, .btn-link {
    color: #006bb7;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

/* Global (un-isolated) styling for Blazor's unhandled-error bar. The framework toggles this element's
   inline display on/off via blazor.web.js; it must be hidden by default. The matching rule shipped only
   in MainLayout.razor.css, which is CSS-isolated (scoped to a [b-xxxxx] attribute) and therefore never
   matched the #blazor-error-ui rendered inside CodexLayout — leaving the bar permanently visible on every
   Codex screen. Defining it here (global stylesheet) covers BOTH layouts. */
#blazor-error-ui {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ---- WPB dashboard ---- */
.muted { color: #6c757d; font-size: 0.9rem; }
.label { display: block; font-size: 0.7rem; text-transform: uppercase; letter-spacing: .04em; color: #6c757d; }

.page-head { display: flex; align-items: baseline; gap: 1rem; }
.page-head h1 { margin: 0; }

.banner { padding: .6rem .8rem; border-radius: 6px; margin: .5rem 0; }
.banner.error { background: #fdecea; color: #b32121; border: 1px solid #f5c6cb; }

.badge { font-size: .72rem; padding: .15rem .5rem; border-radius: 999px; }
.badge-on { background: #e6f4ea; color: #1e7e34; }
.badge-off { background: #ececec; color: #777; }

.bot-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: .9rem; margin-top: 1rem; }
.bot-card { border: 1px solid #e3e3e3; border-left: 4px solid #ccc; border-radius: 8px; padding: .8rem; background: #fff; }
.bot-card.on { border-left-color: #1e7e34; }
.bot-card.off { opacity: .7; }
.bot-card-head { display: flex; justify-content: space-between; align-items: center; }
.bot-name { font-weight: 600; font-size: 1.05rem; }
.bot-meta { color: #555; font-size: .85rem; margin: .2rem 0 .5rem; }
.bot-activity { margin-bottom: .4rem; }
.bot-reason { background: #f6f8fa; border-radius: 6px; padding: .4rem .5rem; }
.bot-reason span:last-child { font-style: italic; }
.bot-updated { margin-top: .4rem; font-size: .72rem; }

.filters { display: flex; gap: .4rem; margin: .6rem 0 1rem; }
.chip { border: 1px solid #ccc; background: #fff; border-radius: 999px; padding: .25rem .8rem; cursor: pointer; font-size: .85rem; }
.chip.active { background: #1b6ec2; color: #fff; border-color: #1861ac; }

.decisions { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: .6rem; }
.decision { border: 1px solid #e3e3e3; border-left: 4px solid #ccc; border-radius: 8px; padding: .6rem .8rem; background: #fff; }
.decision.guild { border-left-color: #b8860b; }
.decision.individual { border-left-color: #1b6ec2; }
.decision-top { display: flex; align-items: center; gap: .6rem; }
.scope-tag { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; padding: .1rem .45rem; border-radius: 4px; }
.tag-guild { background: #fff3cd; color: #856404; }
.tag-indiv { background: #e7f1fb; color: #1861ac; }
.subject { font-weight: 600; }
.time { margin-left: auto; }
.decision-text { margin: .3rem 0; }
.decision-reason { font-size: .9rem; color: #444; }
.decision-reason .label { display: inline; margin-right: .3rem; }

.home-links { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 1rem; }
.home-card { display: flex; flex-direction: column; gap: .4rem; text-decoration: none; color: inherit;
    border: 1px solid #e3e3e3; border-radius: 8px; padding: 1rem; min-width: 260px; background: #fff; }
.home-card:hover { border-color: #1b6ec2; }
.home-card-title { font-weight: 600; font-size: 1.1rem; color: #1b6ec2; }

/* ====================================================================== */
/* STORMWIND CODEX design system (extracted from the Figma export).        */
/* Tokens: docs/codex-design-tokens.md. Used by the 5 drill-down screens.  */
/* ====================================================================== */
@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@500;600;700&family=EB+Garamond:ital,wght@0,400;0,500;0,600;1,400;1,500&display=swap');

:root {
    /* gilt ramp */
    --cx-gilt-bright: #f0c662; --cx-gilt: #e0a526; --cx-gilt-dim: #b9892a; --cx-gilt-deep: #b07d1f;
    /* parchment / cream text, descending */
    --cx-cream: #f7e9c2; --cx-cream-hi: #ffeec2; --cx-head: #ecd9a8; --cx-body: #cdb88c;
    --cx-muted: #a98c5a; --cx-dim: #8a6f3e; --cx-dimmer: #7e6536; --cx-faint: #5e4d2c;
    /* borders, descending */
    --cx-bd: #6b5320; --cx-bd-2: #5a4519; --cx-bd-3: #4a3a1a; --cx-bd-4: #3d2f17; --cx-bd-5: #2e2410;
    /* surfaces */
    --cx-card: linear-gradient(180deg,#221a11,#191209);
    --cx-page: radial-gradient(135% 120% at 50% -12%, #2b1e14 0%, #170f08 58%, #100a06 100%);
    --cx-hero: radial-gradient(120% 160% at 12% 0%, #312413 0%, #1d1409 62%);
    /* factions + status */
    --cx-horde: #cf6b4a; --cx-horde-hi: #e08a6a; --cx-alliance: #6f9fd8; --cx-alliance-hi: #7fa8e0;
    --cx-green: #79c267; --cx-green-hi: #7fcf6b; --cx-red: #dd8a6a;
    /* provenance */
    --cx-ai: #c7a4ec; --cx-rule: #8fb0d4;
}

.codex { min-height: 100vh; background: var(--cx-page); font-family: 'EB Garamond', serif; color: var(--cx-body); padding: 0 0 48px; }
.codex-shell { max-width: 1680px; margin: 0 auto; padding: 0 32px; }
.codex a { color: inherit; text-decoration: none; }

@keyframes wpbPulse { 0%,100% { box-shadow: 0 0 0 0 currentColor; } 50% { box-shadow: 0 0 9px 2px currentColor; } }
@keyframes giltGlow { 0%,100% { box-shadow: 0 0 0 1px rgba(224,165,38,.45), 0 0 24px rgba(224,165,38,.12); } 50% { box-shadow: 0 0 0 1px rgba(224,165,38,.7), 0 0 34px rgba(224,165,38,.24); } }

.cx-display { font-family: 'Cinzel', serif; }
.cx-cream { color: var(--cx-cream); }

/* top bar (full gilt) */
.cx-topbar { display: flex; align-items: center; gap: 26px; padding: 18px 4px 16px; border-bottom: 1px solid var(--cx-bd);
    box-shadow: 0 1px 0 rgba(224,165,38,.18), 0 2px 0 rgba(224,165,38,.06); }
.cx-logo { width: 30px; height: 30px; transform: rotate(45deg); background: linear-gradient(135deg,#f0d28f,#b07d1f);
    display: flex; align-items: center; justify-content: center; box-shadow: 0 0 16px rgba(224,165,38,.45); }
.cx-logo > i { width: 11px; height: 11px; transform: rotate(45deg); background: #160e08; display: block; }
.cx-wordmark { font: 700 18px 'Cinzel', serif; color: #f3e3b6; letter-spacing: .08em; }
.cx-vrule { width: 1px; height: 26px; background: linear-gradient(180deg,transparent,var(--cx-bd),transparent); flex: none; }

/* breadcrumb */
.cx-crumbs { display: flex; align-items: center; gap: 11px; flex: 1; min-width: 0; }
.cx-crumb { font: 500 13px 'Cinzel', serif; letter-spacing: .08em; color: var(--cx-dimmer); }
.cx-crumb.active { display: flex; align-items: center; gap: 8px; padding: 4px 12px; border: 1px solid #7a5e22; border-radius: 3px;
    background: rgba(224,165,38,.1); color: #f3e3b6; font-weight: 600; }
.cx-crumb.active > .d { width: 7px; height: 7px; transform: rotate(45deg); background: var(--cx-gilt); box-shadow: 0 0 7px rgba(224,165,38,.6); }
a.cx-crumb:hover { color: var(--cx-horde-hi); }
.cx-sep { color: var(--cx-bd); font-size: 13px; }

/* search */
.cx-search { display: flex; align-items: center; gap: 10px; padding: 8px 14px; border: 1px solid var(--cx-bd-2); border-radius: 3px;
    background: linear-gradient(180deg,#221a11,#191209); width: 300px; flex: none; color: var(--cx-dimmer); font: italic 400 14px 'EB Garamond', serif; }
.cx-search .k { margin-left: auto; font: 600 10px 'Cinzel', serif; letter-spacing: .1em; color: var(--cx-faint); border: 1px solid var(--cx-bd-3); border-radius: 2px; padding: 1px 5px; }

/* interactive global character search (BotSearch) */
.cx-search-box { position: relative; display: flex; align-items: center; gap: 10px; padding: 8px 14px;
    border: 1px solid var(--cx-bd-2); border-radius: 3px; background: linear-gradient(180deg,#221a11,#191209);
    width: 300px; flex: none; }
.cx-search-box:focus-within { border-color: #7a5e22; box-shadow: 0 0 0 1px rgba(224,165,38,.25); }
.cx-search-icon { color: var(--cx-gilt-dim); flex: none; }
.cx-search-input { flex: 1; min-width: 0; background: transparent; border: none; outline: none;
    color: var(--cx-body); font: 400 14px 'EB Garamond', serif; }
.cx-search-input::placeholder { color: var(--cx-dimmer); font-style: italic; }
.cx-search-box .k { font: 600 10px 'Cinzel', serif; letter-spacing: .1em; color: var(--cx-faint);
    border: 1px solid var(--cx-bd-3); border-radius: 2px; padding: 1px 5px; flex: none; }
.cx-search-results { position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 1100;
    background: linear-gradient(180deg,#221a11,#160f07); border: 1px solid var(--cx-bd-2); border-radius: 4px;
    box-shadow: 0 12px 30px rgba(0,0,0,.5); overflow: hidden; }
.cx-search-empty { padding: 12px 14px; font: italic 400 13px 'EB Garamond', serif; color: var(--cx-dimmer); }
.cx-search-row { display: flex; align-items: center; gap: 10px; padding: 9px 14px; text-decoration: none;
    border-bottom: 1px solid var(--cx-bd-5); }
.cx-search-row:last-child { border-bottom: none; }
.cx-search-row:hover, .cx-search-row.active { background: rgba(224,165,38,.08); }
.cx-search-name { font: 600 14px 'EB Garamond', serif; color: var(--cx-head); }
.cx-search-meta { font: 400 12px 'EB Garamond', serif; color: var(--cx-dimmer); }
.cx-search-dot { width: 7px; height: 7px; border-radius: 99px; margin-left: auto; flex: none; }

/* section heads */
.cx-section { display: flex; align-items: center; gap: 14px; margin: 30px 0 16px; }
.cx-section > .d { width: 9px; height: 9px; transform: rotate(45deg); background: var(--cx-gilt); box-shadow: 0 0 8px rgba(224,165,38,.5); flex: none; }
.cx-section > h2 { font: 600 14px 'Cinzel', serif; letter-spacing: .18em; color: var(--cx-head); white-space: nowrap; margin: 0; }
.cx-section > .rule { flex: 1; height: 1px; background: linear-gradient(90deg,var(--cx-gilt-dim),rgba(185,137,42,0)); }
.cx-section > .note { font: italic 400 13px 'EB Garamond', serif; color: var(--cx-dimmer); }

/* hero band (double-framed) */
.cx-hero { position: relative; margin-top: 24px; padding: 24px 30px; border: 1px solid var(--cx-bd); border-radius: 5px; background: var(--cx-hero);
    box-shadow: inset 0 0 0 1px rgba(224,165,38,.12), inset 0 1px 0 rgba(240,210,143,.18), 0 18px 40px -22px rgba(0,0,0,.7); }
.cx-hero::before { content: ''; position: absolute; inset: 6px; border: 1px solid rgba(185,137,42,.28); border-radius: 3px; pointer-events: none; }
.cx-hero-row { display: flex; align-items: center; gap: 30px; position: relative; flex-wrap: wrap; }
.cx-kicker { font: 600 11px 'Cinzel', serif; letter-spacing: .14em; color: var(--cx-dim); }
.cx-stat-big { font: 700 46px 'Cinzel', serif; color: var(--cx-cream-hi); line-height: 1; text-shadow: 0 0 20px rgba(224,165,38,.35); }

/* cards with corner ticks */
.cx-card { position: relative; background: var(--cx-card); border: 1px solid var(--cx-bd-3); border-radius: 4px; padding: 16px 17px; display: block; }
.cx-card.tick::before, .cx-card.tick::after { content: ''; position: absolute; width: 10px; height: 10px; opacity: .6; }
.cx-card.tick::before { top: 7px; left: 7px; border-top: 1px solid var(--cx-gilt-dim); border-left: 1px solid var(--cx-gilt-dim); }
.cx-card.tick::after { bottom: 7px; right: 7px; border-bottom: 1px solid var(--cx-gilt-dim); border-right: 1px solid var(--cx-gilt-dim); }
a.cx-card:hover { border-color: #7a5e22; }
.cx-card.flagship { border-color: #7a5e22; background: radial-gradient(130% 130% at 50% 0%, #34260f 0%, #1f1509 66%); animation: giltGlow 3.6s ease-in-out infinite; overflow: hidden; }
.cx-card-label { font: 600 11px 'Cinzel', serif; letter-spacing: .12em; color: var(--cx-dim); }
.cx-card-num { font: 700 44px 'Cinzel', serif; color: var(--cx-cream); line-height: 1; margin-top: 8px; text-shadow: 0 0 16px rgba(224,165,38,.18); }
.cx-card-sub { font: italic 400 13px 'EB Garamond', serif; color: var(--cx-muted); margin-top: 9px; }

.cx-grid-4 { display: grid; grid-template-columns: 1fr 1fr 1.35fr 1fr; gap: 16px; }
/* ★A grid of IDENTICAL cards needs identical columns.★ .cx-grid-4's third column is 1.35fr, which is
   right for the pages that put a wider panel there (Realm, Faction, Group) and wrong wherever the
   children are peers: the raid roster lays 8 equal subgroup cards into it, so groups 3 and 7 render
   35% wider than the other six, and opening one seat's picker re-widths that whole column and shoves
   its neighbours. Peers get this modifier. It is spelled as a compound selector so it also has to be
   listed in the responsive collapse below — specificity beats media queries, and a modifier that
   silently opted out of the 1340px breakpoint would be a worse bug than the one it fixes. */
.cx-grid-4.cx-eq { grid-template-columns: repeat(4, 1fr); }
.cx-grid-3 { display: grid; grid-template-columns: repeat(3,1fr); gap: 16px; }
.cx-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.cx-grid-main { display: grid; grid-template-columns: 1fr 544px; gap: 26px; align-items: start; margin-top: 30px; }
@media (max-width: 1340px) { .cx-grid-main { grid-template-columns: 1fr; } .cx-grid-4, .cx-grid-4.cx-eq, .cx-grid-3, .cx-grid-2 { grid-template-columns: 1fr 1fr; } }

/* constraint/policy chips (Bot directive) + filter chips (Cohort) */
.cx-chip { font: 500 11.5px 'EB Garamond', serif; color: var(--cx-body); background: rgba(224,165,38,.08);
    border: 1px solid var(--cx-bd-4); border-radius: 99px; padding: 3px 11px; white-space: nowrap; text-decoration: none; }
a.cx-chip:hover { border-color: #7a5e22; color: var(--cx-head); }
a.cx-chip.active { background: linear-gradient(180deg,#e6b94a,#b07d1f); color: #160e08; border-color: #b07d1f; font-weight: 600; }

/* God Controls (OverrideConsole) */
.cx-god-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
@media (max-width: 1100px) { .cx-god-grid { grid-template-columns: 1fr; } }
.cx-god-cell { border: 1px solid var(--cx-bd-5); border-radius: 4px; padding: 13px 14px; background: rgba(0,0,0,.12); }
.cx-input { background: #1a130a; border: 1px solid var(--cx-bd-3); border-radius: 3px; color: var(--cx-body);
    font: 400 13px 'EB Garamond', serif; padding: 5px 9px; outline: none; }
.cx-input:focus { border-color: #7a5e22; }
.cx-btn { font: 600 11px 'Cinzel', serif; letter-spacing: .06em; padding: 6px 12px; border-radius: 3px; cursor: pointer;
    border: 1px solid var(--cx-bd-3); background: #221a11; color: var(--cx-body); }
.cx-btn:hover { border-color: #7a5e22; color: var(--cx-head); }
/* ★A DISABLED BUTTON HAS TO LOOK DISABLED.★ The raid COMMANDS bar disables every control while a
   command is in flight (`disabled="@_busy"`) and for options that do not apply, but the base button
   had no :disabled rule at all -- so the whole bar stayed fully lit and clickable-looking while
   nothing it offered would respond. `:disabled` also kills the hover lift, or a dead button still
   brightens under the cursor and promises an action it will not perform. */
.cx-btn:disabled, .cx-btn[disabled] { opacity: .42; cursor: not-allowed; filter: saturate(.5); }
.cx-btn:disabled:hover, .cx-btn[disabled]:hover { border-color: var(--cx-bd-3); color: inherit; }
.cx-btn-ok { background: linear-gradient(180deg,#3a6b2f,#234a1b); color: #eaf6e4; border-color: #2f5a23; }
.cx-btn-warn { background: linear-gradient(180deg,#7a5e22,#5a4318); color: #f6ead0; border-color: #7a5e22; }
.cx-btn-danger { background: linear-gradient(180deg,#8a3220,#5e2014); color: #f6dcd4; border-color: #8a3220; }

/* cohort roster list */
.cx-roster { display: flex; flex-direction: column; gap: 6px; }
.cx-roster-row { display: flex; align-items: center; gap: 14px; padding: 11px 16px; text-decoration: none;
    background: var(--cx-card); border: 1px solid var(--cx-bd-3); border-radius: 4px; }
.cx-roster-row:hover { border-color: #7a5e22; background: rgba(224,165,38,.05); }
.cx-roster-dot { width: 8px; height: 8px; border-radius: 99px; flex: none; }
.cx-roster-name { font: 600 15px 'EB Garamond', serif; color: var(--cx-head); min-width: 150px; }
.cx-roster-meta { font: 400 13px 'EB Garamond', serif; color: var(--cx-muted); min-width: 200px; }
.cx-roster-zone { font: 400 13px 'EB Garamond', serif; color: var(--cx-dimmer); flex: 1; }
.cx-roster-faction { font: 600 12px 'Cinzel', serif; letter-spacing: .06em; margin-left: auto; }

/* fleet roster grid (Bots) — responsive card wall over the /api/bots snapshot */
.cx-fleet { display: grid; grid-template-columns: repeat(auto-fill, minmax(264px, 1fr)); gap: 14px; }
.cx-fleet-card { display: flex; flex-direction: column; gap: 6px; padding: 14px 15px; }
.cx-fleet-head { display: flex; align-items: center; gap: 10px; }
.cx-fleet-dot { width: 8px; height: 8px; border-radius: 99px; flex: none; }
.cx-fleet-dot.on { background: var(--cx-green-hi); color: var(--cx-green-hi); animation: wpbPulse 1.6s infinite; }
.cx-fleet-dot.off { background: var(--cx-dim); }
.cx-fleet-name { font: 600 16px 'EB Garamond', serif; color: var(--cx-head); }
.cx-fleet-lvl { margin-left: auto; font: 700 13px 'Cinzel', serif; color: var(--cx-gilt-bright); }
.cx-fleet-meta { font: 400 13px 'EB Garamond', serif; color: var(--cx-muted); }
.cx-fleet-act { font: 500 13.5px 'EB Garamond', serif; color: var(--cx-body); }
.cx-fleet-reason { font: italic 400 13px 'EB Garamond', serif; color: var(--cx-dimmer); }
.cx-fleet-foot { margin-top: 2px; font: 400 11.5px 'EB Garamond', serif; color: var(--cx-faint); }
.cx-fleet-state.on { color: var(--cx-green-hi); }
.cx-fleet-state.off { color: var(--cx-dim); }

/* Bot stat grid (STR/AGI/CRIT/…) */
.cx-statgrid { display: grid; grid-template-columns: repeat(3,1fr); gap: 14px 8px; padding-top: 12px; border-top: 1px solid var(--cx-bd-5); }

/* faction balance bar */
.cx-bar { display: flex; height: 10px; border-radius: 2px; overflow: hidden; border: 1px solid var(--cx-bd-4); margin-top: 9px; }
.cx-bar .horde { background: linear-gradient(90deg,#7a2417,#cf6b4a); }
.cx-bar .alliance { background: linear-gradient(90deg,#2f5489,#6f9fd8); }

/* level histogram */
.cx-histo { display: flex; align-items: flex-end; gap: 2px; height: 60px; }
.cx-histo > .bar { flex: 1; border-radius: 1px; min-height: 2px; }

/* zone density rows */
.cx-zone { display: flex; align-items: center; gap: 10px; margin: 7px 0; }
.cx-zone .track { flex: 1; height: 8px; border: 1px solid var(--cx-bd-4); border-radius: 2px; overflow: hidden; }
/* ★display:block, and without it NO BAR IN THIS APP HAS EVER FILLED.★ `.fill` is a <span>, so it
   defaults to display:inline — and width/height do not apply to a non-replaced inline box. Every
   caller's `style="width:N%"` and every `min-width:3px` guard was inert, and every .cx-zone bar on
   every page (roster HP, xp, mana, cast, cooldowns, skills, quests, rep, kit bags, faction, realm)
   painted an empty outline. The sibling .cx-bar never showed this because it is display:flex, so
   its children get blockified for free. Measured after the fix: a 72% bar fills 392.5 of 547.2px. */
.cx-zone .fill { display: block; height: 100%; background: linear-gradient(90deg,var(--cx-gilt-deep),var(--cx-gilt)); }
.cx-zone .name { width: 120px; font: 500 13px 'EB Garamond', serif; color: var(--cx-body); }
.cx-zone .n { width: 28px; text-align: right; font: 600 13px 'Cinzel', serif; color: var(--cx-cream); }

/* Wowhead tooltip overlay readability (#P4 separate ask): the widget's default tooltip renders faint/low-
   contrast over the dark Codex theme. Force an opaque dark backing + bright text + a gilt border + high z-index
   so item/spell/quest tooltips are legible. The widget injects #wowhead-tooltip (and .wowhead-tooltip). */
#wowhead-tooltip,
.wowhead-tooltip {
    background: #120c06 !important;
    opacity: 1 !important;
    border: 1px solid var(--cx-gilt-deep, #8a6d1f) !important;
    border-radius: 4px !important;
    box-shadow: 0 6px 24px rgba(0,0,0,.75) !important;
    color: #e8ddc4 !important;
    z-index: 99999 !important;
    padding: 6px 8px !important;
}
#wowhead-tooltip th, #wowhead-tooltip td, #wowhead-tooltip b, #wowhead-tooltip span,
.wowhead-tooltip th, .wowhead-tooltip td, .wowhead-tooltip b, .wowhead-tooltip span {
    text-shadow: none !important;
}

/* decision feed */
.cx-feed { display: flex; flex-direction: column; gap: 10px; }
.cx-feed-row { position: relative; background: var(--cx-card); border: 1px solid var(--cx-bd-3); border-radius: 4px; padding: 12px 14px; }
.cx-feed-top { display: flex; align-items: center; gap: 10px; }
.cx-prov { font: 600 10px 'Cinzel', serif; letter-spacing: .1em; padding: 2px 7px; border-radius: 3px; border: 1px solid; }
.cx-prov.ai { color: var(--cx-ai); border-color: rgba(176,139,224,.45); background: rgba(176,139,224,.09); }
.cx-prov.rule { color: var(--cx-rule); border-color: rgba(143,176,212,.4); background: rgba(143,176,212,.07); }
.cx-prov.verified { color: var(--cx-gilt-bright); border-color: rgba(224,165,38,.5); background: rgba(224,165,38,.1); }
.cx-tok { margin-left: auto; font: 600 12px 'Cinzel', serif; }
.cx-feed-subject { font: 600 14px 'EB Garamond', serif; color: var(--cx-head); }
a.cx-feed-subject-link { text-decoration: none; cursor: pointer; }
a.cx-feed-subject-link:hover { color: var(--cx-gilt-bright); text-decoration: underline; }
.cx-feed-decision { font: 500 14px 'EB Garamond', serif; color: var(--cx-body); margin: 5px 0 3px; }
.cx-feed-reason { font: italic 400 13px 'EB Garamond', serif; color: var(--cx-muted); }
.cx-feed-time { font: 400 12px 'EB Garamond', serif; color: var(--cx-faint); }

/* columnar decision feed (wide screens: Decisions/Faction/Group/Guild) — the design's
   ACTOR · ACTION · REASON · SOURCE · TOKENS · TIME table. Realm's narrow rail keeps the row cards above. */
.cx-feedtable-card { padding: 6px 0; }
.cx-feedtable { display: flex; flex-direction: column; }
.cx-feedtable-head, .cx-feedtable-row { display: grid; grid-template-columns: 200px 184px 1fr 84px 64px 68px; gap: 12px; align-items: center; padding: 0 14px; }
.cx-feedtable-head { height: 30px; font: 600 10px 'Cinzel', serif; letter-spacing: .12em; color: var(--cx-dim); border-bottom: 1px solid var(--cx-bd-4); }
.cx-feedtable-head .r, .cx-feedtable-row .r { text-align: right; }
.cx-feedtable-row { padding-top: 10px; padding-bottom: 10px; border-bottom: 1px solid var(--cx-bd-5); }
.cx-feedtable-row:last-child { border-bottom: none; }
.cx-feedtable-row.ai { background: rgba(224,165,38,.045); }
.cx-ft-actor { font: 600 13.5px 'EB Garamond', serif; color: var(--cx-head); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
a.cx-ft-actor { text-decoration: none; }
a.cx-ft-actor:hover { color: var(--cx-gilt-bright); }
.cx-ft-action { font: 500 13.5px 'EB Garamond', serif; color: var(--cx-body); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cx-ft-reason { font: italic 400 13px 'EB Garamond', serif; color: var(--cx-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cx-ft-tok { font: 600 12px 'Cinzel', serif; color: var(--cx-dimmer); }
.cx-ft-time { font: 400 12px 'EB Garamond', serif; color: var(--cx-faint); }

/* cohort lens chips (scope grammar) */
.cx-lenses { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.cx-lens { font: 600 11px 'Cinzel', serif; letter-spacing: .08em; padding: 5px 12px; border: 1px solid var(--cx-bd-3); border-radius: 3px;
    background: var(--cx-card); color: var(--cx-dim); cursor: pointer; }
.cx-lens.active { border-color: var(--cx-gilt); color: var(--cx-cream); background: rgba(224,165,38,.1); }
.cx-lens:hover { border-color: #7a5e22; }

.cx-empty { padding: 24px; text-align: center; font: italic 400 14px 'EB Garamond', serif; color: var(--cx-dimmer); border: 1px dashed var(--cx-bd-3); border-radius: 4px; }
.cx-banner-error { padding: 12px 16px; border: 1px solid #6e2f1d; border-radius: 4px; background: rgba(207,107,74,.1); color: var(--cx-horde-hi); margin: 12px 0; }

/* ====================================================================== */
/* DATA-REALITY & STATES system (design "Patterns" page). Readiness tiers, */
/* the reusable sparse-data states, and freshness pills. Used everywhere.  */
/* ====================================================================== */
@keyframes wpbShimmer { 0% { background-position: -180% 0; } 100% { background-position: 180% 0; } }

/* readiness-tier chip — every panel header wears one. T = R1 (live) / R2 (derived) / R3 (staged). */
.cx-tier { font: 700 9px 'Cinzel', serif; letter-spacing: .08em; border: 1px solid; border-radius: 3px; padding: 2px 8px; white-space: nowrap; flex: none; }
.cx-tier.r1 { color: #9fe08a; border-color: #2f5a2a; background: rgba(121,194,103,.1); }
.cx-tier.r2 { color: #f0c662; border-color: #7a5e22; background: rgba(224,165,38,.1); }
.cx-tier.r3 { color: #8fb0d4; border-color: #35506e; background: rgba(143,176,212,.1); }

/* loading skeleton (shimmer) */
.cx-skel { display: flex; flex-direction: column; gap: 11px; }
.cx-skel-row { display: flex; align-items: center; gap: 10px; }
.cx-skel-bar { height: 9px; border-radius: 2px; background: linear-gradient(90deg,#241b10,#3a2c17,#241b10); background-size: 200% 100%; animation: wpbShimmer 1.6s linear infinite; }
.cx-skel-d { width: 11px; height: 11px; transform: rotate(45deg); border-radius: 2px; flex: none; background: linear-gradient(90deg,#241b10,#3a2c17,#241b10); background-size: 200% 100%; animation: wpbShimmer 1.6s linear infinite; }

/* awaiting telemetry — an R3 panel whose feed hasn't started (dashed-blue hatch) */
.cx-awaiting { position: relative; min-height: 132px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; gap: 8px; padding: 20px 16px;
    border: 1px dashed #35506e; border-radius: 4px; background: repeating-linear-gradient(135deg, #161d28 0 9px, #131922 9px 18px); }
.cx-awaiting .ic { width: 26px; height: 26px; transform: rotate(45deg); border: 1px dashed #35506e; display: flex; align-items: center; justify-content: center; }
.cx-awaiting .ic > span { transform: rotate(-45deg); color: #6f86a8; font-size: 13px; }
.cx-awaiting .t { font: 600 14px 'EB Garamond', serif; color: #8fb0d4; }
.cx-awaiting .n { font: italic 400 12px 'EB Garamond', serif; color: #6f86a8; line-height: 1.4; max-width: 320px; }

/* content-level error (in-panel; the browser #blazor-error-ui stays hidden) */
.cx-error-panel { position: relative; border: 1px solid #6e2f1d; border-radius: 4px; background: radial-gradient(130% 150% at 50% 0%, #2c1410 0%, #1a0d09 70%); padding: 15px 18px; }
.cx-error-panel .row { display: flex; align-items: center; gap: 12px; }
.cx-error-panel .ic { width: 30px; height: 30px; transform: rotate(45deg); border: 1px solid #a8451f; background: rgba(207,74,50,.12); display: flex; align-items: center; justify-content: center; flex: none; }
.cx-error-panel .ic > span { transform: rotate(-45deg); color: var(--cx-horde-hi); font-size: 16px; }
.cx-error-panel .t { font: 600 14.5px 'EB Garamond', serif; color: #f0b89a; }
.cx-error-panel .n { font: italic 400 12.5px 'EB Garamond', serif; color: var(--cx-muted); margin-top: 2px; }
.cx-error-panel .retry { font: 600 10px 'Cinzel', serif; letter-spacing: .06em; color: var(--cx-horde-hi); border: 1px solid #6e2f1d; border-radius: 2px; padding: 5px 11px; flex: none; cursor: pointer; background: none; }
.cx-error-panel .retry:hover { background: rgba(207,107,74,.1); }

/* freshness pills — every value declares LIVE / LAST-KNOWN / PROJECTED */
.cx-fresh { display: inline-flex; align-items: center; gap: 7px; }
.cx-fresh .dot { width: 6px; height: 6px; border-radius: 99px; flex: none; }
.cx-fresh .lab { font: 600 9px 'Cinzel', serif; letter-spacing: .08em; }
.cx-fresh.live .dot { background: var(--cx-green-hi); color: var(--cx-green-hi); animation: wpbPulse 1.6s infinite; }
.cx-fresh.live .lab { color: #9fe08a; }
.cx-fresh.last .dot { background: var(--cx-muted); }
.cx-fresh.last .lab { color: var(--cx-muted); }
.cx-fresh.proj .dot { background: var(--cx-ai); }
.cx-fresh.proj .lab { color: var(--cx-ai); }

/* cohort lens tabs (label + live count + active glow) */
.cx-lenstabs { display: flex; gap: 8px; flex-wrap: wrap; }
.cx-lenstab { cursor: pointer; display: flex; align-items: center; gap: 9px; padding: 9px 15px; border: 1px solid var(--cx-bd-3); border-radius: 3px; background: var(--cx-card); }
.cx-lenstab:hover { filter: brightness(1.1); }
.cx-lenstab > .d { width: 8px; height: 8px; transform: rotate(45deg); flex: none; }
.cx-lenstab > .l { font: 600 12px 'Cinzel', serif; letter-spacing: .06em; color: var(--cx-muted); }
.cx-lenstab > .c { font: 700 12px 'EB Garamond', serif; color: var(--cx-dimmer); font-variant-numeric: tabular-nums; }
.cx-lenstab.active { border-color: #7a5e22; background: rgba(224,165,38,.12); box-shadow: 0 0 14px -4px rgba(224,165,38,.5); }
.cx-lenstab.active > .l { color: var(--cx-cream); }
.cx-lenstab.active > .c { color: var(--cx-gilt-bright); }

/* form primitives (Settings selector cards + labels + save row) */
.cx-flabel { font: 600 11px 'Cinzel', serif; letter-spacing: .1em; color: var(--cx-dim); }
.cx-optrow { display: flex; gap: 8px; margin-top: 9px; }
.cx-opt { flex: 1; cursor: pointer; padding: 11px 14px; border: 1px solid var(--cx-bd-3); border-radius: 3px; background: rgba(0,0,0,.18); text-align: center; }
.cx-opt:hover { filter: brightness(1.1); }
.cx-opt.active { border-color: #7a5e22; background: rgba(224,165,38,.12); }
.cx-opt .nm { font: 600 14px 'EB Garamond', serif; color: var(--cx-body); }
.cx-opt.active .nm { color: var(--cx-cream-hi); }
.cx-opt .sub { font: italic 400 11px 'EB Garamond', serif; color: var(--cx-dimmer); margin-top: 2px; }
.cx-saverow { display: flex; align-items: center; gap: 14px; margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--cx-bd-5); }
.cx-btn-save { cursor: pointer; display: flex; align-items: center; gap: 9px; padding: 11px 22px; border-radius: 3px; border: 1px solid #7a5e22;
    background: linear-gradient(180deg,#e6b94a,#b07d1f); color: #160e08; font: 700 13px 'Cinzel', serif; letter-spacing: .08em; box-shadow: 0 2px 10px -2px rgba(224,165,38,.5); }
.cx-btn-save:hover { filter: brightness(1.07); }
.cx-spin { width: 13px; height: 13px; border-radius: 99px; border: 2px solid rgba(22,14,8,.35); border-top-color: #160e08; animation: wpbSpin .7s linear infinite; flex: none; }
@keyframes wpbSpin { to { transform: rotate(360deg); } }
.cx-saved { display: flex; align-items: center; gap: 7px; font: 600 13px 'EB Garamond', serif; color: var(--cx-green-hi); }
.cx-savefail { display: flex; align-items: center; gap: 7px; font: 600 13px 'EB Garamond', serif; color: var(--cx-horde-hi); }

/* cohort roster table (CHARACTER · CLASS · ROLE · MEMBERSHIP · DOING NOW · ▸) */
.cx-rt { position: relative; background: linear-gradient(180deg,#211910,#171008); border: 1px solid var(--cx-bd-3); border-radius: 4px; overflow: hidden; }
.cx-rt-head, .cx-rt-row { display: grid; grid-template-columns: 1.25fr 1fr 104px 1.2fr 1.4fr 18px; gap: 14px; padding: 11px 20px; align-items: center; }
.cx-rt-head { border-bottom: 1px solid var(--cx-bd-4); background: rgba(224,165,38,.04); }
.cx-rt-head span { font: 600 10px 'Cinzel', serif; letter-spacing: .12em; color: var(--cx-dim); }
.cx-rt-row { border-bottom: 1px solid #241b10; text-decoration: none; }
.cx-rt-row:last-child { border-bottom: none; }
.cx-rt-row:hover { background: rgba(224,165,38,.04); }
.cx-role { font: 600 10px 'Cinzel', serif; letter-spacing: .04em; border: 1px solid; border-radius: 2px; padding: 2px 8px; white-space: nowrap; }
.cx-mtag { font: 600 9px 'Cinzel', serif; letter-spacing: .04em; border: 1px solid; border-radius: 2px; padding: 2px 7px; white-space: nowrap; }
.cx-lenscap { display: flex; align-items: center; gap: 12px; margin-top: 18px; padding: 12px 18px; border: 1px solid var(--cx-bd-3); border-radius: 3px; background: rgba(224,165,38,.04); }

/* gameplan chat (Discuss) */
@keyframes wpbBlink { 0%,100% { opacity: .25; } 50% { opacity: 1; } }
.cx-blink { width: 6px; height: 6px; border-radius: 99px; background: var(--cx-ai); animation: wpbBlink 1s infinite; flex: none; }
.cx-btn-send { cursor: pointer; padding: 9px 18px; border-radius: 3px; border: 1px solid #4a3a5a; background: linear-gradient(180deg,#b08be0,#7a55b0); color: #1a1024; font: 700 12px 'Cinzel', serif; letter-spacing: .06em; box-shadow: 0 2px 10px -2px rgba(176,139,224,.5); flex: none; }
.cx-btn-send:hover { filter: brightness(1.08); }
.cx-btn-send:disabled { opacity: .5; cursor: default; }
button.cx-chip { cursor: pointer; font-family: inherit; }
button.cx-chip:disabled { opacity: .5; cursor: default; }
button.cx-lens { cursor: pointer; font-family: 'Cinzel', serif; }
/* ── Talent grid ─────────────────────────────────────────────────────────────────────────────────
   The client's panel, in the site's palette: a 7x4 field of icon tiles with prerequisite arrows
   underneath them. Positions come from TalentGridGeometry, so nothing here does arithmetic. */
.cx-talentgrid { position: relative; margin-top: 12px; }

/* The client's own backdrop for the tree, extracted from interface.MPQ. The painted panel is 300x331
   and the grid is 300 wide by design — same panel — so only the height is stretched, which a painted
   sky absorbs invisibly. */
.cx-talentgrid.art { background-size: 100% 100%; background-repeat: no-repeat;
    border: 1px solid var(--cx-bd-4); border-radius: 4px; }
/* ★The art is lit for a black game window, not for this page, and icons have to stay readable on top
   of it.★ A scrim under the tiles keeps the backdrop legible as scenery without letting it compete
   with the talents; it sits below the arrows, which sit below the tiles. */
.cx-talentgrid.art::before { content: ''; position: absolute; inset: 0; border-radius: 3px;
    background: linear-gradient(180deg, rgba(12,8,4,.52), rgba(12,8,4,.68)); z-index: 0; }

.cx-talentgrid-arrows { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.cx-talentgrid-arrows line { stroke-width: 2; }
/* A met prerequisite reads gilt; an unmet one stays faint, so a reachable branch is obvious. */
.cx-talentgrid-arrows line.on { stroke: var(--cx-gilt); opacity: .95; }
.cx-talentgrid-arrows line.off { stroke: var(--cx-bd); opacity: .55; }

.cx-talentgrid-gate { position: absolute; left: 0; width: 26px; text-align: right; z-index: 2;
    font: 600 10px 'Cinzel', serif; letter-spacing: .04em; }
.cx-talentgrid-gate.open { color: var(--cx-gilt-dim); }
.cx-talentgrid-gate.shut { color: var(--cx-faint); }

.cx-talent { position: absolute; width: 44px; height: 44px; border-radius: 3px; z-index: 2;
    border: 1px solid var(--cx-bd-3); background: #0d0906; box-sizing: border-box; }
/* ★power.js decorates a Wowhead link by giving it left padding and a background-image icon, and
   data-wh-icon-size="none" does NOT prevent it.★ Measured on the live page: the anchor came back with
   padding-left 20.8px, so the tile's own art — width:100% of what was left — rendered at half width,
   squashed against the right edge with Wowhead's icon showing through the padding. The tile IS an icon
   already, so both are refused here rather than asked not to happen. */
.cx-talent a { display: block; width: 100%; height: 100%; line-height: 0;
    padding: 0 !important; background-image: none !important; }
.cx-talent img { width: 100%; height: 100%; display: block; border-radius: 2px; }
.cx-talent.editable { cursor: pointer; }
.cx-talent.editable:hover { box-shadow: 0 0 0 2px rgba(240,198,98,.55); }

/* Four states, matching what the client shows: taken to the cap, partially taken, affordable now,
   and locked. Only the last is desaturated — a locked talent should be legible but plainly out. */
.cx-talent.maxed { border-color: var(--cx-gilt-bright); box-shadow: 0 0 9px -1px rgba(240,198,98,.5); }
.cx-talent.partial { border-color: var(--cx-gilt-deep); }
.cx-talent.open { border-color: var(--cx-bd); }
.cx-talent.open img { filter: brightness(.82); }
.cx-talent.locked { border-color: var(--cx-bd-5); }
.cx-talent.locked img { filter: grayscale(1) brightness(.5); }

.cx-talent-rank { position: absolute; right: -3px; bottom: -5px; min-width: 13px; padding: 0 3px;
    border-radius: 2px; background: #120c06; border: 1px solid var(--cx-bd-3);
    font: 600 9px 'Cinzel', serif; text-align: center; color: var(--cx-dim); }
.cx-talent.maxed .cx-talent-rank { color: var(--cx-gilt-bright); border-color: var(--cx-gilt-deep); }
.cx-talent.partial .cx-talent-rank { color: var(--cx-gilt); border-color: var(--cx-bd-2); }

.cx-talent-noicon { display: flex; align-items: center; justify-content: center; width: 100%;
    height: 100%; font: 600 13px 'Cinzel', serif; color: var(--cx-dim); line-height: 1; }
