/*
   Components: meter, key/value list, table, shop item, process row, player and gang link.
   Tokens only (css/tokens.css). Usage and rules: docs/ai/components.md.
*/

/* ---------- Meter (native <progress>) ---------- */

.bj-meter {
    display: block;
    width: 100%;
    height: 8px;
    border: 0;
    border-radius: var(--bj-radius-pill);
    background: var(--bj-surface-sunken);
    box-shadow: inset 0 0 0 1px var(--bj-border);
    overflow: hidden;
    appearance: none;
    -webkit-appearance: none;
    color: var(--bj-accent);
}

.bj-meter::-webkit-progress-bar {
    background: transparent;
}

.bj-meter::-webkit-progress-value {
    border-radius: var(--bj-radius-pill);
    background: currentColor;
}

.bj-meter::-moz-progress-bar {
    border-radius: var(--bj-radius-pill);
    background: currentColor;
}

.bj-meter--accent { color: var(--bj-accent); }
.bj-meter--respect { color: var(--bj-respect); }
.bj-meter--money,
.bj-meter--warning { color: var(--bj-warning); }
.bj-meter--danger { color: var(--bj-danger); }
.bj-meter--info { color: var(--bj-info); }
.bj-meter--neutral { color: var(--bj-text-muted); }

.bj-meterbox {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.bj-meterbox-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 2px var(--bj-space-3);
    font-size: var(--bj-text-sm);
}

.bj-meterbox-label {
    display: inline-flex;
    align-items: center;
    gap: var(--bj-space-2);
    color: var(--bj-text-muted);
}

.bj-meterbox-label > i {
    font-size: 1.125rem;
}

.bj-meterbox-value {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* The value text follows the tone only where the tone carries meaning beyond "normal". */
.bj-meterbox-value--warning { color: var(--bj-warning); }
.bj-meterbox-value--danger { color: var(--bj-danger); }
.bj-meterbox-value--respect { color: var(--bj-respect); }
.bj-meterbox-value--money { color: var(--bj-money); }

.bj-meterbox-caption {
    display: flex;
    align-items: center;
    gap: 4px;
    color: var(--bj-text-subtle);
    font-size: var(--bj-text-xs);
    font-variant-numeric: tabular-nums;
}

.bj-meterbox--mini {
    display: inline-block;
    width: 40px;
}

.bj-meterbox--mini .bj-meter {
    height: 6px;
}

/* ---------- Key/value list ---------- */

.bj-kv {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    column-gap: var(--bj-space-5);
    margin: 0;
}

.bj-kv-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 2px var(--bj-space-3);
    padding: var(--bj-space-2) 0;
    border-bottom: 1px solid var(--bj-border);
    min-width: 0;
}

.bj-kv-row > dt {
    display: inline-flex;
    align-items: center;
    gap: var(--bj-space-2);
    color: var(--bj-text-muted);
    font-size: var(--bj-text-sm);
    font-weight: 400;
    /* Labels wrap between words only. */
    overflow-wrap: normal;
    word-break: normal;
}

.bj-kv-row > dt > i {
    flex: none;
    font-size: 1.125rem;
}

.bj-kv-row > dd {
    margin: 0 0 0 auto;
    min-width: 0;
    font-weight: 600;
    text-align: right;
    overflow-wrap: break-word;
}

.bj-kv--stacked .bj-kv-row {
    flex-direction: column;
    align-items: flex-start;
}

.bj-kv--stacked .bj-kv-row > dd {
    margin-left: 0;
    text-align: left;
}

.bj-tone-accent { color: var(--bj-accent); }
.bj-tone-warning { color: var(--bj-warning); }
.bj-tone-info { color: var(--bj-info); }

@media (min-width: 768px) {
    .bj-kv--2 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Short values as tiles: <kv-list layout="grid">. Two per row on phones, four from tablet width. */
.bj-kv--grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--bj-space-4);
}

.bj-kv--grid .bj-kv-row {
    flex-direction: column;
    align-items: flex-start;
}

.bj-kv--grid .bj-kv-row > dd {
    margin-left: 0;
    text-align: left;
}

@media (min-width: 768px) {
    .bj-kv--grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* Phones: label above value, so neither is squeezed. */
@media (max-width: 419.98px) {
    .bj-kv:not(.bj-kv--inline) .bj-kv-row {
        flex-direction: column;
        align-items: flex-start;
    }

    .bj-kv:not(.bj-kv--inline) .bj-kv-row > dd {
        margin-left: 0;
        text-align: left;
    }
}

/* ---------- Table ---------- */

.bj-table {
    width: 100%;
    margin: 0;
    border-collapse: collapse;
    color: var(--bj-text);
    font-size: var(--bj-text-sm);
}

.bj-table th,
.bj-table td {
    padding: var(--bj-space-2) var(--bj-space-3);
    border-bottom: 1px solid var(--bj-border);
    text-align: left;
    vertical-align: middle;
}

.bj-table thead th {
    color: var(--bj-text-muted);
    font-size: var(--bj-text-xs);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
}

.bj-table tbody tr:last-child > * {
    border-bottom: 0;
}

.bj-table tbody tr:hover {
    background: rgb(255 255 255 / 0.03);
}

.bj-table--zebra tbody tr:nth-child(even) {
    background: rgb(255 255 255 / 0.03);
}

.bj-table .bj-num {
    text-align: right;
    white-space: nowrap;
}

.bj-table .bj-rank {
    width: 1%;
    color: var(--bj-text-muted);
    font-weight: 600;
    white-space: nowrap;
}

/* Mode 1: scroll. The table keeps its columns; the wrapper scrolls and shows a hint while there is more. */
.bj-table-scroll {
    position: relative;
    overflow-x: auto;
    scrollbar-width: thin;
}

.bj-table-scroll > .bj-table {
    min-width: max-content;
}

.bj-table-scroll.is-scrollable:not(.is-at-end) {
    background:
        linear-gradient(to left, var(--bj-surface-raised), transparent) right center / 28px 100% no-repeat local,
        linear-gradient(to left, rgb(0 0 0 / 0.55), transparent) right center / 14px 100% no-repeat scroll;
}

.bj-table-scroll.is-scrollable::after {
    content: attr(aria-label);
    display: block;
    position: sticky;
    left: 0;
    padding: var(--bj-space-1) var(--bj-space-3);
    color: var(--bj-text-subtle);
    font-size: var(--bj-text-xs);
}

/* Mode 2: stacked. Below 768px every row is a block and each cell shows its data-label. */
@media (max-width: 767.98px) {
    .bj-table--stacked,
    .bj-table--stacked tbody,
    .bj-table--stacked tr,
    .bj-table--stacked td,
    .bj-table--stacked th[scope="row"] {
        display: block;
    }

    .bj-table--stacked thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
    }

    .bj-table--stacked tbody tr {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        gap: 2px var(--bj-space-3);
        padding: var(--bj-space-3) 0;
        border-bottom: 1px solid var(--bj-border);
    }

    .bj-table--stacked tbody tr:last-child {
        border-bottom: 0;
    }

    .bj-table--stacked td,
    .bj-table--stacked th[scope="row"] {
        grid-column: 1 / -1;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        gap: 0 var(--bj-space-3);
        padding: 2px 0;
        border: 0;
        text-align: right;
    }

    .bj-table--stacked td::before,
    .bj-table--stacked th[scope="row"]::before {
        content: attr(data-label);
        color: var(--bj-text-muted);
        font-weight: 400;
        text-align: left;
    }

    /* The cell that names the row (a player, a gang) leads the block, without a label. */
    .bj-table--stacked .bj-cell-title {
        justify-content: flex-start;
        font-size: var(--bj-text-md);
        font-weight: 600;
        text-align: left;
    }

    .bj-table--stacked .bj-cell-title::before,
    .bj-table--stacked .bj-rank::before {
        content: none;
    }

    .bj-table--stacked .bj-rank {
        grid-column: 1;
        width: auto;
        align-items: center;
    }

    .bj-table--stacked .bj-rank + .bj-cell-title {
        grid-column: 2;
        grid-row: 1;
    }

    .bj-table--stacked .bj-num {
        white-space: normal;
    }
}

/* ---------- Shop item ---------- */

.bj-shop-list {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--bj-space-3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.bj-shop-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--bj-space-3);
    padding: var(--bj-space-3) var(--bj-space-4);
    border: 1px solid var(--bj-border);
    border-radius: var(--bj-radius);
    background: var(--bj-surface);
}

.bj-shop-item-main {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--bj-space-2) var(--bj-space-3);
    min-width: 0;
}

.bj-shop-item-name {
    display: flex;
    align-items: center;
    gap: var(--bj-space-2);
    margin: 0;
    font-size: var(--bj-text-md);
    font-weight: 600;
    min-width: 0;
    overflow-wrap: anywhere;
}

.bj-shop-item-name > i {
    flex: none;
    color: var(--bj-text-muted);
    font-size: 1.25rem;
}

.bj-shop-item-stats .bj-kv-row {
    padding: 2px 0;
    border: 0;
}

.bj-shop-item-buy {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--bj-space-2) var(--bj-space-3);
}

/* The price is never cut off: it may wrap as a whole under the name, but not inside the number. */
.bj-shop-item-price {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    color: var(--bj-money);
    font-size: var(--bj-text-md);
    font-weight: 700;
    white-space: nowrap;
}

.bj-shop-item-reason {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 0;
    color: var(--bj-text-muted);
    font-size: var(--bj-text-sm);
}

.bj-shop-item-reason > i {
    flex: none;
    font-size: 1.125rem;
}

/* A line under the stats: what the item costs after the trade-in. */
.bj-shop-item-note {
    margin: var(--bj-space-2) 0 0;
    color: var(--bj-text-muted);
    font-size: var(--bj-text-sm);
}

/* A warning that does not stop the purchase: a moonshine still too big for the warehouse. */
.bj-shop-item-note--warning {
    display: flex;
    gap: var(--bj-space-2);
    align-items: flex-start;
    color: var(--bj-warning);
}

.bj-shop-item-note--warning > i {
    flex: none;
    font-size: 1.125rem;
}

.bj-shop-item--owned {
    border-color: var(--bj-accent);
    background: linear-gradient(var(--bj-accent-soft), var(--bj-accent-soft)), var(--bj-surface);
}

.bj-shop-item--locked .bj-shop-item-name,
.bj-shop-item--locked .bj-shop-item-price {
    color: var(--bj-text-muted);
}

@media (min-width: 768px) {
    .bj-shop-item {
        grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.4fr) minmax(0, 1fr);
        align-items: center;
    }

    .bj-shop-item-buy {
        flex-direction: column;
        align-items: flex-end;
        text-align: right;
    }
}

/* ---------- Row item: one of a list of things to act on (sponsor areas, moonshine buyers, the steps of a loop) ---------- */

.bj-rows {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--bj-space-3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.bj-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--bj-space-3);
    padding: var(--bj-space-3) var(--bj-space-4);
    border: 1px solid var(--bj-border);
    border-radius: var(--bj-radius);
    background: var(--bj-surface);
}

.bj-row-main {
    min-width: 0;
}

.bj-row-main > * + * {
    margin-top: var(--bj-space-2);
}

.bj-row-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--bj-space-2) var(--bj-space-3);
}

.bj-row-title {
    display: flex;
    align-items: center;
    gap: var(--bj-space-2);
    margin: 0;
    font-size: var(--bj-text-md);
    font-weight: 600;
    min-width: 0;
    overflow-wrap: anywhere;
}

.bj-row-title > i {
    flex: none;
    color: var(--bj-text-muted);
    font-size: 1.25rem;
}

.bj-row-text {
    margin-bottom: 0;
    color: var(--bj-text-muted);
    font-size: var(--bj-text-sm);
}

.bj-row .bj-kv-row {
    padding: 2px 0;
    border: 0;
}

/* A one-line row for the items the player is not working on: name, a badge, a small meter. */
.bj-row--compact {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--bj-space-1) var(--bj-space-3);
    padding: var(--bj-space-2) var(--bj-space-3);
}

.bj-row--compact {
    flex-wrap: nowrap;
}

.bj-row--compact .bj-row-title {
    flex: 1 1 6rem;
    font-size: var(--bj-text-sm);
}

.bj-row--compact .bj-row-title > i {
    font-size: 1rem;
}

.bj-row-progress {
    display: inline-flex;
    align-items: center;
    gap: var(--bj-space-2);
    color: var(--bj-text-muted);
    font-size: var(--bj-text-sm);
    white-space: nowrap;
}

.bj-row-progress .bj-meterbox--mini {
    width: 56px;
}

.bj-rows--compact {
    gap: var(--bj-space-2);
}

/* On a narrow phone the number is enough; the small meter comes back when there is room. */
@media (max-width: 419.98px) {
    .bj-row-progress .bj-meterbox--mini {
        display: none;
    }
}

/* The one the player is working on now. */
.bj-row--active {
    border-color: var(--bj-accent);
    background: linear-gradient(var(--bj-accent-soft), var(--bj-accent-soft)), var(--bj-surface);
}

.bj-row--dim .bj-row-title {
    color: var(--bj-text-muted);
}

@media (min-width: 768px) {
    .bj-row {
        grid-template-columns: minmax(0, 1fr) minmax(0, 16rem);
        align-items: center;
    }

    .bj-row--wide {
        grid-template-columns: minmax(0, 1fr);
    }

    .bj-row-action {
        justify-self: end;
        text-align: right;
    }
}

/* ---------- Process row ---------- */

.bj-process-list {
    display: grid;
    gap: var(--bj-space-2);
}

.bj-process {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--bj-space-2) var(--bj-space-4);
    padding: var(--bj-space-3) var(--bj-space-4);
    border: 1px solid var(--bj-border);
    border-radius: var(--bj-radius-sm);
    background: var(--bj-surface-raised);
}

.bj-process-what {
    display: flex;
    align-items: center;
    gap: var(--bj-space-2);
    min-width: 0;
}

.bj-process-what > i {
    flex: none;
    color: var(--bj-text-muted);
    font-size: 1.25rem;
}

.bj-process-name {
    font-weight: 600;
}

.bj-process-amount {
    color: var(--bj-text-muted);
}

.bj-process-state {
    display: flex;
    align-items: center;
    gap: var(--bj-space-2);
    color: var(--bj-text-muted);
    font-size: var(--bj-text-sm);
    font-variant-numeric: tabular-nums;
}

.bj-process-state .bj-countdown {
    color: var(--bj-text);
    font-weight: 600;
}

.bj-process--ready {
    border-color: var(--bj-accent);
}

@media (max-width: 575.98px) {
    .bj-process > form,
    .bj-process .btn {
        width: 100%;
    }
}

/* ---------- Player and gang link ---------- */

.bj-entity {
    display: inline-flex;
    align-items: center;
    gap: var(--bj-space-2);
    max-width: 100%;
    min-width: 0;
    color: var(--bj-accent);
    font-weight: 600;
    vertical-align: middle;
}

.bj-entity:hover {
    color: var(--bj-accent-hover);
}

.bj-entity-name {
    min-width: 0;
    overflow-wrap: anywhere;
}

.bj-entity:hover .bj-entity-name {
    text-decoration: underline;
}

/* Staff names are a little heavier, as they were bold before; no other decoration. */
.bj-entity--staff .bj-entity-name {
    font-weight: 700;
}


.bj-entity-meta {
    display: block;
    color: var(--bj-text-muted);
    font-size: var(--bj-text-xs);
    font-weight: 400;
}

.bj-entity--list {
    gap: var(--bj-space-3);
}

.bj-entity--list .bj-entity-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.bj-avatar-img {
    flex: none;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--bj-surface-raised);
    border: 1px solid var(--bj-border);
}

/* No picture uploaded: an icon on a neutral surface (UserImage and GangImage thumbnails). */
.bj-avatar-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--bj-border);
    color: var(--bj-text-muted);
    font-size: 0.875rem;
}

.bj-avatar-fallback.bj-avatar-img--md {
    font-size: 1.125rem;
}

.bj-avatar-fallback.bj-avatar-img--lg {
    font-size: 1.375rem;
}

.bj-avatar-img--md {
    width: 32px;
    height: 32px;
}

.bj-avatar-img--lg {
    width: 40px;
    height: 40px;
}

/* Full-size profile picture (UserImage and GangImage without thumbnail). */
.bj-avatar-img--full {
    width: auto;
    height: auto;
    max-width: 100%;
    border-radius: var(--bj-radius);
}

/* ---------- Countdown ---------- */

.bj-countdown {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* A note under a table (when the list was last updated, and the like). */
.bj-table-note {
    margin: var(--bj-space-3) 0 0;
    color: var(--bj-text-subtle);
    font-size: var(--bj-text-xs);
}

.bj-table-note strong {
    color: var(--bj-text-muted);
}

/* ---------- Pager: previous, "page n of m", next ---------- */

.bj-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--bj-space-3);
    margin-top: var(--bj-space-4);
}

.bj-pager-status {
    color: var(--bj-text-muted);
    font-size: var(--bj-text-sm);
    text-align: center;
}

/* ---------- Stat cards: a few headline numbers side by side ---------- */

.bj-statcards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: var(--bj-space-3);
    margin: 0 0 var(--bj-space-4);
    padding: 0;
    list-style: none;
}

.bj-statcard {
    display: flex;
    flex-direction: column;
    gap: var(--bj-space-1);
    min-width: 0;
    padding: var(--bj-space-3) var(--bj-space-4);
    border: 1px solid var(--bj-border);
    border-radius: var(--bj-radius);
    background: var(--bj-surface);
}

.bj-statcard-label {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--bj-text-muted);
    font-size: var(--bj-text-sm);
}

.bj-statcard-value {
    font-size: var(--bj-text-lg);
    font-weight: 700;
    overflow-wrap: anywhere;
}

/* ---------- Code panel: raw text such as a log file, scrolling inside the page ---------- */

.bj-code-panel {
    max-height: 70vh;
    margin: 0;
    padding: var(--bj-space-3);
    overflow: auto;
    border: 1px solid var(--bj-border);
    border-radius: var(--bj-radius-sm);
    background: var(--bj-surface-sunken);
    color: var(--bj-text);
    font-family: var(--bj-font-mono);
    font-size: var(--bj-text-sm);
    line-height: 1.5;
    white-space: pre;
    tab-size: 4;
}

/* A muted second line in a table cell, under a name (the rank title on the top list). */
.bj-cell-sub {
    display: block;
    font-size: var(--bj-text-xs);
}
