/* ===== Design Tokens ===== */
:root {
    /* Backgrounds */
    --color-bg:            #0f0f14;
    --color-bg-raised:     #1a1a24;
    --color-bg-surface:    #22222e;
    --color-bg-hover:      #2a2a38;

    /* Borders */
    --color-border:        #2e2e3e;
    --color-border-strong: #3e3e52;

    /* Text */
    --color-text:          #e4e4ec;
    --color-text-muted:    #8888a0;
    --color-text-heading:  #f0f0f8;
    --color-text-link:     #7cacf8;
    --color-text-link-hover: #a0c4ff;

    /* Brand */
    --color-primary:       #5b7fff;
    --color-primary-hover: #7a9aff;
    --color-primary-text:  #ffffff;
    --color-accent:        #9b6dff;
    --color-accent-hover:  #b08aff;

    /* Semantic */
    --color-danger:        #ef4444;
    --color-danger-bg:     rgba(239, 68, 68, 0.12);
    --color-success:       #22c55e;
    --color-success-bg:    rgba(34, 197, 94, 0.12);
    --color-info:          #38bdf8;
    --color-info-bg:       rgba(56, 189, 248, 0.12);
    --color-secondary:     #64748b;
    --color-secondary-bg:  rgba(100, 116, 139, 0.15);

    /* Chart palette — 9 base colours spread evenly across the hue wheel */
    --chart-1: #5b7fff;   /* blue      240° */
    --chart-2: #f97316;   /* orange     30° */
    --chart-3: #22c55e;   /* green     140° */
    --chart-4: #ec4899;   /* pink      320° */
    --chart-5: #06b6d4;   /* cyan      190° */
    --chart-6: #facc15;   /* yellow     50° */
    --chart-7: #ef4444;   /* red         0° */
    --chart-8: #a78bfa;   /* violet    270° */
    --chart-9: #14b8a6;   /* teal      170° */

    /* Spacing (4px base) */
    --space-1:  0.25rem;
    --space-2:  0.5rem;
    --space-3:  0.75rem;
    --space-4:  1rem;
    --space-5:  1.25rem;
    --space-6:  1.5rem;
    --space-8:  2rem;
    --space-10: 2.5rem;
    --space-12: 3rem;

    /* Typography */
    --font-sans: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --font-mono: 'JetBrains Mono', 'Cascadia Code', 'Fira Code', monospace;

    --text-xs:   0.8rem;
    --text-sm:   0.925rem;
    --text-base: 1.0625rem;
    --text-lg:   1.1875rem;
    --text-xl:   1.3125rem;
    --text-2xl:  1.5625rem;
    --text-3xl:  1.9375rem;

    --leading-tight:   1.25;
    --leading-normal:  1.5;

    /* Shape */
    --radius-sm:   0.25rem;
    --radius-md:   0.5rem;
    --radius-lg:   0.75rem;
    --radius-full: 9999px;

    --shadow-sm:  0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2);
    --shadow-md:  0 4px 6px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.2);
    --shadow-lg:  0 10px 25px rgba(0, 0, 0, 0.4);

    --transition-fast: 150ms ease;
    --transition-base: 200ms ease;
}

/* ===== Reset ===== */
*, *::before, *::after {
    box-sizing: border-box;
}

html {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    margin: 0;
    padding: 0;
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    color: var(--color-text);
    background-color: var(--color-bg);
}

/* ===== Typography ===== */
h1, h2, h3, h4, h5, h6 {
    color: var(--color-text-heading);
    line-height: var(--leading-tight);
    margin: 0 0 var(--space-2) 0;
}

h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
h4 { font-size: var(--text-lg); margin-top: var(--space-8); margin-bottom: var(--space-4); }
h5 { font-size: var(--text-base); }

h1:focus { outline: none; }

p {
    margin: 0 0 var(--space-4) 0;
}

small {
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

a {
    color: var(--color-text-link);
    text-decoration: none;
    transition: color var(--transition-fast);
}

a:hover {
    color: var(--color-text-link-hover);
    text-decoration: underline;
}

code {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    color: var(--color-accent);
    background: var(--color-bg-surface);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
}

pre {
    font-family: var(--font-mono);
    background: var(--color-bg-surface);
    padding: var(--space-4);
    border-radius: var(--radius-md);
    overflow-x: auto;
}

strong {
    color: var(--color-text-heading);
}

/* ===== Forms ===== */
label {
    display: block;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--color-text);
    margin-bottom: var(--space-2);
}

input, textarea, select {
    font-family: var(--font-sans);
    font-size: var(--text-base);
    color: var(--color-text);
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-3);
    width: 100%;
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

input:focus, textarea:focus, select:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 2px rgba(91, 127, 255, 0.25);
}

textarea {
    resize: vertical;
}

/* ===== Layout ===== */
.container {
    width: 100%;
    max-width: 1200px;
    margin-inline: auto;
    padding-inline: var(--space-4);
}

/* Breakpoints: sm 640px, md 768px, lg 1024px, xl 1280px */

.card-grid {
    display: grid;
    gap: var(--space-6);
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .card-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
    .card-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
}

/* ===== Utilities ===== */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ===== Scrollbar ===== */
::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: var(--color-bg);
}

::-webkit-scrollbar-thumb {
    background: var(--color-border-strong);
    border-radius: var(--radius-full);
}

::-webkit-scrollbar-thumb:hover {
    background: var(--color-text-muted);
}

/* ===== Blazor Error UI ===== */
.blazor-error-boundary {
    background: var(--color-danger-bg);
    border: 1px solid var(--color-danger);
    padding: var(--space-4);
    border-radius: var(--radius-md);
    color: var(--color-danger);
}

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

#blazor-error-ui {
    background: var(--color-danger-bg);
    border-top: 2px solid var(--color-danger);
    color: var(--color-text);
    bottom: 0;
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: var(--space-3) var(--space-5);
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: var(--space-3);
    top: var(--space-2);
}

#blazor-error-ui .reload {
    color: var(--color-text-link);
}

/* ===== Validation ===== */
.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--color-success);
}

.invalid {
    outline: 1px solid var(--color-danger);
}

.validation-message {
    color: var(--color-danger);
    font-size: var(--text-sm);
}

/* ===== Gamemode Badges ===== */
.kb-badge--gamemode {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.75rem;
    font-weight: 500;
    padding: 0.2rem 0.5rem;
    border-radius: var(--radius-sm);
}

.gamemode-badge-icon {
    display: inline-block;
    vertical-align: middle;
}

.gamemode-main    { background: var(--color-secondary-bg); color: var(--color-text-muted); }
.gamemode-iron    { background: rgba(148, 148, 148, 0.15); color: #c0c0c0; }
.gamemode-hcim    { background: rgba(239, 68, 68, 0.15); color: #f87171; }
.gamemode-uim     { background: rgba(234, 179, 8, 0.15); color: #facc15; }
.gamemode-gim     { background: rgba(56, 189, 248, 0.15); color: #7dd3fc; }
.gamemode-hcgim   { background: rgba(239, 68, 68, 0.10); color: #fca5a5; border: 1px solid rgba(239, 68, 68, 0.25); }
.gamemode-dmm      { background: rgba(168, 85, 247, 0.15); color: #c084fc; }
.gamemode-seasonal { background: rgba(168, 85, 247, 0.15); color: #c084fc; }

/* ===== Member Card ===== */
.member-card {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-4);
    background: var(--color-bg-raised);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    transition: border-color 0.15s, background 0.15s;
    text-decoration: none;
    color: inherit;
}

.member-card:hover {
    border-color: var(--color-primary);
    background: var(--color-bg-surface);
}

.member-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    flex-shrink: 0;
    object-fit: cover;
}

.member-info {
    flex: 1;
    min-width: 0;
}

.member-name {
    font-size: 1rem;
    font-weight: 600;
    color: var(--color-text-heading);
    margin: 0 0 0.25rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.member-accounts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.member-account-count {
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.member-header {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    margin-bottom: var(--space-6);
}

.member-header h2 {
    margin: 0;
}

.member-avatar--lg {
    width: 64px;
    height: 64px;
}

/* ===== Refresh Row ===== */
.refresh-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-6);
}

.refresh-msg {
    font-size: var(--text-sm);
    animation: fadeIn 0.2s ease;
}

.refresh-msg--ok {
    color: var(--color-success);
}

.refresh-msg--err {
    color: var(--color-danger);
}

.subtitle-meta {
    margin-left: var(--space-3);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* ===== Blazor Reconnect Modal ===== */
#components-reconnect-modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(4px);
    place-items: center;
}

#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: grid;
}

.kb-reconnect {
    text-align: center;
    padding: var(--space-8);
    background: var(--color-bg-raised);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    max-width: 360px;
}

.kb-reconnect__spinner {
    width: 40px;
    height: 40px;
    margin: 0 auto var(--space-4);
    border: 3px solid var(--color-border);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: kb-spin 0.8s linear infinite;
}

#components-reconnect-modal.components-reconnect-failed .kb-reconnect__spinner,
#components-reconnect-modal.components-reconnect-rejected .kb-reconnect__spinner {
    display: none;
}

.kb-reconnect__title {
    font-size: var(--text-lg);
    font-weight: 700;
    color: var(--color-text-heading);
    margin: 0 0 var(--space-2);
}

.kb-reconnect__msg {
    display: none;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    margin: 0;
}

.kb-reconnect__msg a {
    color: var(--color-primary);
    text-decoration: underline;
    cursor: pointer;
}

#components-reconnect-modal.components-reconnect-show .show-when-reconnecting,
#components-reconnect-modal.components-reconnect-failed .show-when-failed,
#components-reconnect-modal.components-reconnect-rejected .show-when-rejected {
    display: block;
}

@keyframes kb-spin {
    to { transform: rotate(360deg); }
}

/* ── OSRS loot ledger ─────────────────────────────────────────────────── */
.loot-picker {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin: 1rem 0;
}

.loot-picker select {
    background: var(--color-bg-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 0.4rem 0.6rem;
    font-size: var(--text-sm);
}

.loot-source-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.loot-source-card {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    text-align: left;
    padding: 0.55rem 0.7rem;
    background: var(--color-bg-raised);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-text);
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s;
}

.loot-source-card:hover {
    background: var(--color-bg-hover);
    border-color: var(--color-border-strong);
}

.loot-source-card__icon {
    flex: 0 0 auto;
    object-fit: contain;
}

.loot-source-card__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.loot-profile-tag {
    margin-left: 0.4rem;
    font-size: var(--text-xs);
    color: var(--color-text-muted);
}

/* Breathing room between the player name and the gamemode badge in the loot
   drill-down's per-player breakdown. */
.loot-player-name {
    margin-right: 0.6rem;
}

.loot-back {
    background: none;
    border: none;
    color: var(--color-text-link);
    cursor: pointer;
    padding: 0;
    margin: 0.5rem 0;
    font-size: var(--text-sm);
}

.loot-back:hover {
    color: var(--color-text-link-hover);
}

/* Loot ledger loading state with spinner */
.loot-loading {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 1.5rem 1rem;
    color: var(--color-text-muted);
    font-size: var(--text-sm);
}
.loot-loading::before {
    content: "";
    width: 14px;
    height: 14px;
    border: 2px solid var(--color-border-strong);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: kb-spin 0.7s linear infinite;
    flex: 0 0 auto;
}

/* Typeable filter input for loot source grid + drill-down items */
.loot-search {
    width: 100%;
    max-width: 360px;
    margin: 0.5rem 0;
    padding: 0.45rem 0.7rem;
    background: var(--color-bg-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
}
.loot-search:focus {
    outline: none;
    border-color: var(--color-primary);
}
.loot-search::placeholder { color: var(--color-text-muted); }

.loot-synth {
    color: var(--text-secondary, #888);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Pop-in animation: plays each time a .loot-source-card is mounted, so cards
   that arrive via the streaming source query visibly bubble in one by one. */
@keyframes kb-pop-in {
    from { opacity: 0; transform: scale(0.85); }
    to   { opacity: 1; transform: scale(1); }
}
.loot-source-card {
    animation: kb-pop-in 0.18s ease-out;
}

/* Admin-only icon filter. Each .loot-source-card carries data-icon-state set
   client-side via the <img> onload/onerror handlers ("loading" -> "loaded" or
   "broken"). The grid's data-icon-filter ("has" / "missing") drives which
   cards stay visible. Reflects actual rendering, not a server-side prediction,
   so it stays accurate even when our curated cascade or the wiki fallback
   disagrees about whether an image will resolve. */
.loot-source-grid[data-icon-filter="has"] .loot-source-card:not([data-icon-state="loaded"]) {
    display: none;
}
.loot-source-grid[data-icon-filter="missing"] .loot-source-card:not([data-icon-state="broken"]) {
    display: none;
}
/* When a card's image failed to load, dim it and keep a placeholder square in
   place of the icon so the row layout stays consistent in the no-icon view. */
.loot-source-card[data-icon-state="broken"] .loot-source-card__icon {
    visibility: hidden;
}

/* KC / drop-count subtitle under the source heading. */
.loot-source-meta {
    margin: 0.1rem 0 0.35rem;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
    font-variant-numeric: tabular-nums;
}
/* Admin-only logged-loot date range. Red to match the admin visual language. */
.loot-source-range {
    margin: 0 0 0.6rem;
    font-size: var(--text-xs);
    color: var(--color-danger);
    font-variant-numeric: tabular-nums;
}

/* ===== Admin-only controls =====
   Privileged controls swap the default blue highlight for red so admin-only
   affordances are visually distinct from normal navigation. Selectors carry
   extra specificity so they win over the per-component scoped styles. */
.kb-pill-toggle.kb-pill-toggle--admin {
    border-color: var(--color-danger);
}
.kb-pill-toggle.kb-pill-toggle--admin .kb-pill-toggle__btn--active {
    background: var(--color-danger);
    color: var(--color-primary-text);
}
.kb-pill-toggle.kb-pill-toggle--admin .kb-pill-toggle__btn:hover:not(.kb-pill-toggle__btn--active) {
    color: var(--color-danger);
}
/* Reusable hook for non-toggle admin buttons/affordances. */
.kb-admin-action {
    border-color: var(--color-danger);
    color: var(--color-danger);
}
.kb-admin-action:hover {
    background: var(--color-danger-bg);
    color: var(--color-danger);
}
