/* Trade-up contracts (/skins/tradeup).
   Everything that already exists is reused by name: glass-card, weapon-card,
   rarity-*, stat-card, connect-btn, case-roll-item, skin-image, help-section.
   Only the contract slots, the picker's selection state and the strip pointer
   live here — no existing class covers those. */

/* ── Contract header ────────────────────────────────────────────────────── */

/* Compact tag used for the locked rarity / contract-kind / StatTrak pills. */
.tu-tag {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.6rem;
    border-radius: 2rem;
    border: 1px solid rgba(255, 255, 255, 0.15);
    background: rgba(255, 255, 255, 0.06);
    color: rgba(255, 255, 255, 0.85);
    font-weight: 600;
    line-height: 1.6;
    white-space: nowrap;
}

.tu-tag-gold {
    border-color: rgba(255, 203, 49, 0.45);
    background: rgba(255, 203, 49, 0.14);
    color: rgb(255, 203, 49);
}

.tu-tag-stattrak {
    border-color: rgba(255, 193, 7, 0.45);
    background: rgba(255, 193, 7, 0.16);
    color: #ffc107;
}

.tu-progress {
    height: 4px;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.08);
    overflow: hidden;
}

.tu-progress-fill {
    height: 100%;
    border-radius: 2px;
    background: linear-gradient(90deg, rgba(13, 202, 240, 0.55), rgba(13, 202, 240, 1));
    box-shadow: 0 0 12px rgba(13, 202, 240, 0.45);
    transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ── Contract slots ─────────────────────────────────────────────────────── */

/* Empty and filled slots share this shell so the grid never reflows as it fills. */
.tu-slot {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    padding: 0;
    border-radius: 0.6rem;
    overflow: hidden;
    text-align: left;
    border-width: 1px;
    border-style: solid;
    transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.25s ease, background 0.2s ease;
}

/* Zero-specificity fallback so the shared .rarity-* classes win at rest. Declaring these
   on .tu-slot directly would tie with .rarity-* and beat it on source order, since
   tradeup.css loads after skins.css — which is why the rarity tint used to appear only on
   hover, where .rarity-*:hover outranks the plain class. */
:where(.tu-slot) {
    border-color: rgba(255, 255, 255, 0.08);
    background: rgba(0, 0, 0, 0.35);
}

/* Matches .inv-showcase-card-img so a slot reads as the same object as an
   inventory card. flex/min-height are pinned because this is a flex item, and
   a flex item's default min-height:auto lets a tall image override the
   aspect-ratio — which made filled slots taller than empty ones. */
.tu-slot-face {
    position: relative;
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    aspect-ratio: 4 / 3;
    min-height: 0;
    padding: 0.6rem;
    background: rgba(0, 0, 0, 0.3);
}

    .tu-slot-face .skin-image {
        width: auto;
        height: auto;
        max-width: 100%;
        max-height: 100%;
        object-fit: contain;
    }

/* Fixed rather than min-height: an empty slot's hint is one line and a filled
   slot's caption is two, and a mixed row must not have ragged card heights. */
.tu-slot-body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.1rem;
    height: 3.5rem;
    padding: 0.35rem 0.55rem;
    background: rgba(0, 0, 0, 0.4);
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.tu-slot-name {
    color: #fff;
    font-weight: 600;
}

.tu-slot-meta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.35rem;
    min-width: 0;
}

.tu-slot-index {
    position: absolute;
    top: 0.3rem;
    left: 0.4rem;
    z-index: 2;
    color: rgba(255, 255, 255, 0.3);
    font-weight: 700;
    line-height: 1;
}

.tu-slot-st {
    position: absolute;
    top: 0.3rem;
    right: 0.4rem;
    z-index: 2;
    padding: 0 0.3rem;
    border-radius: 0.25rem;
    background: rgba(255, 193, 7, 0.18);
    border: 1px solid rgba(255, 193, 7, 0.45);
    color: #ffc107;
    font-weight: 700;
    line-height: 1.5;
}

/* Empty */
.tu-slot-empty {
    border-style: dashed;
    border-color: rgba(255, 255, 255, 0.14);
    background: rgba(255, 255, 255, 0.015);
    color: rgba(255, 255, 255, 0.35);
}

.tu-slot-plus {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
    transition: all 0.2s ease;
}

.tu-slot-hint {
    color: rgba(255, 255, 255, 0.4);
    text-align: center;
}

.tu-slot-empty:hover:not(:disabled) {
    border-color: rgba(13, 202, 240, 0.55);
    background: rgba(13, 202, 240, 0.06);
    transform: translateY(-3px);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45);
}

    .tu-slot-empty:hover:not(:disabled) .tu-slot-plus {
        background: rgba(13, 202, 240, 0.18);
        border-color: rgba(13, 202, 240, 0.6);
        color: #0dcaf0;
        transform: scale(1.08);
    }

    .tu-slot-empty:hover:not(:disabled) .tu-slot-hint {
        color: rgba(13, 202, 240, 0.9);
    }

.tu-slot-empty:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

/* Filled — background and border come from the shared .rarity-* classes in
   skins.css. This rule must stay after them so it can cancel their hover
   scale(1.05) in favour of the same lift the inventory cards use. */
.tu-slot-filled:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45);
}

.tu-slot-remove {
    position: absolute;
    top: 0.3rem;
    right: 0.4rem;
    z-index: 3;
    width: 1.4rem;
    height: 1.4rem;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(220, 53, 69, 0.3);
    color: #ff8f9a;
    opacity: 0;
    transition: all 0.2s ease;
}

.tu-slot-filled:hover .tu-slot-remove {
    opacity: 1;
}

.tu-slot-remove:hover:not(:disabled) {
    background: rgba(220, 53, 69, 0.75);
    color: #fff;
}

.tu-slot-remove:disabled {
    opacity: 0;
    cursor: not-allowed;
}

/* A slot carrying the remove button hides the StatTrak chip on hover so the two
   never stack in the same corner. */
.tu-slot-filled:hover .tu-slot-st {
    opacity: 0;
}

/* ── Inputs → result ────────────────────────────────────────────────────── */

.tu-arrow {
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    color: rgba(13, 202, 240, 0.55);
}

.tu-arrow-down {
    display: flex;
    width: 100%;
    padding-bottom: 0.25rem;
}

.tu-result {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    min-height: 100%;
    padding: 1.25rem 1rem;
    border-radius: 0.6rem;
    border: 1px dashed rgba(255, 255, 255, 0.14);
    background: rgba(0, 0, 0, 0.25);
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Empty, the card centres a short stack; populated, it stretches so the hero
   image absorbs the column's spare height. */
.tu-result.is-ready {
    align-items: stretch;
    justify-content: flex-start;
    gap: 0.6rem;
    padding: 0.85rem;
    border-style: solid;
    border-color: rgba(13, 202, 240, 0.35);
    background: rgba(13, 202, 240, 0.05);
    box-shadow: inset 0 0 40px rgba(13, 202, 240, 0.06);
}

.tu-result-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.tu-result-foot {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: auto;
}

/* Zero-specificity fallback so the shared .rarity-* classes still win the
   border colour — see the .tu-slot note above for why this matters. */
:where(.tu-result-hero) {
    border: 1px solid rgba(255, 255, 255, 0.08);
}

.tu-result-hero {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.75rem;
    border-radius: 0.5rem;
    background: rgba(0, 0, 0, 0.3);
    overflow: hidden;
}

    /* .rarity-*:hover lifts by scale(1.05); this one is not interactive. */
    .tu-result-hero:hover {
        transform: none;
    }

.tu-result-hero-img {
    position: relative;
    z-index: 1;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.tu-result-hero-wear {
    position: absolute;
    z-index: 2;
    left: 0.5rem;
    bottom: 0.5rem;
    padding: 0.1rem 0.45rem;
    border-radius: 0.35rem;
    color: rgba(255, 255, 255, 0.75);
    background: rgba(0, 0, 0, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.tu-result-label {
    color: rgba(255, 255, 255, 0.45);
    letter-spacing: 0.12em;
    font-weight: 700;
}

.tu-result-face {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 4.5rem;
    height: 4.5rem;
    border-radius: 50%;
    background: rgba(13, 202, 240, 0.12);
    border: 1px solid rgba(13, 202, 240, 0.35);
    color: #0dcaf0;
}

.tu-result-face-empty {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.12);
    color: rgba(255, 255, 255, 0.3);
}

.tu-result-stats {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    padding-top: 0.75rem;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* ── Picker ─────────────────────────────────────────────────────────────── */

/* The modal itself must never scroll — the card grid absorbs the overflow.
   That needs an unbroken `flex: 1 1 auto; min-height: 0` chain from
   .blazored-modal all the way down to .tu-picker-grid; one missing link and
   the grid falls back to its content height and pushes the modal out. */
.tu-picker-modal {
    width: min(1500px, 94vw) !important;
    max-width: min(1500px, 94vw) !important;
    overflow: hidden !important;
}

.tu-picker-modal .bm-content,
.tu-picker-modal .modal-body,
.tu-picker-modal .inv-cat-section {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

/* Bootstrap's .row is flex-wrap: wrap, and a multi-line flex container sizes
   each line to its content — so the card column grew to its full 22 000px
   instead of being bounded by the modal. Forcing a single line is what lets
   the columns be clamped to the row height: stacked below lg, side by side
   above it. */
.tu-picker-modal .modal-body > .row {
    flex: 1 1 auto;
    min-height: 0;
    flex-wrap: nowrap;
    flex-direction: column;
}

.tu-picker-modal .modal-body > .row > main {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

/* The sidebar scrolls independently rather than being clipped when the
   category + rarity facets are both long. */
.tu-picker-modal .modal-body > .row > aside {
    flex: 0 1 auto;
    min-height: 0;
    overflow-y: auto;
}

@media (min-width: 992px) {
    .tu-picker-modal .modal-body > .row {
        flex-direction: row;
    }

    /* Keep the col-lg-3 width instead of letting it shrink in the row axis. */
    .tu-picker-modal .modal-body > .row > aside {
        flex: 0 0 auto;
    }
}

.tu-picker-grid {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: 0.25rem;
}

/* Container-driven card grid, shared by the picker and the outcomes list.
   Bootstrap's column classes resolve against the viewport, which is wrong for
   both surfaces: the picker sits inside a col-lg-9 inside a modal, and the
   outcomes panel is full width while the inventory grid it should visually match
   is not — so identical column classes produced cards a third larger. The min
   track is what pins the card to a physical size instead. */
.tu-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(var(--tu-card-min, 180px), 1fr));
    gap: 1rem;
}

.tu-picker-cards {
    --tu-card-min: 165px;
}

/* Slot budget spent — the card stays readable but cannot be picked. */
.tu-card-disabled {
    opacity: 0.35;
    pointer-events: none;
}

/* Sibling of .market-stattrak-chip for inputs whose collection has no next tier. */
.tu-filler-chip {
    background: rgba(108, 117, 125, 0.25);
    border: 1px solid rgba(255, 255, 255, 0.2);
    color: rgba(255, 255, 255, 0.7);
    padding: 0.05rem 0.35rem;
    border-radius: 0.3rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
    line-height: 1.4;
}

/* ── Outcomes ───────────────────────────────────────────────────────────── */

/* Collection / case the outcome belongs to. Sits in flow above the image
   rather than in .market-card-header, so it can share a row with the odds
   chip instead of overlapping it. */
.tu-collection-bar {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.5rem;
    background: rgba(0, 0, 0, 0.45);
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.tu-collection-icon {
    flex: 0 0 auto;
    width: 1.15rem;
    height: 1.15rem;
    object-fit: contain;
}

.tu-collection-name {
    min-width: 0;
    color: rgba(255, 255, 255, 0.7);
    font-weight: 600;
}

/* Sibling of .market-stattrak-chip carrying an outcome's drop chance. */
.tu-odds-chip {
    background: rgba(13, 202, 240, 0.2);
    border: 1px solid rgba(13, 202, 240, 0.45);
    color: #0dcaf0;
    padding: 0.05rem 0.4rem;
    border-radius: 0.3rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    white-space: nowrap;
    line-height: 1.4;
}

/* ── Reveal strip pointer ───────────────────────────────────────────────── */

.tu-strip-pointer {
    z-index: 10;
    width: 4px;
    height: 100%;
    background: linear-gradient(to bottom, transparent, #ffc107, transparent);
}

.tu-strip-caret {
    filter: drop-shadow(0 0 8px rgba(255, 193, 7, 0.8));
}
