/*
 * The gaming listing card.
 *
 * It started life inside the /gaming page's own <style> block, which is why the
 * profile page and the similar-accounts carousel were still rendering the old
 * flat panel - the markup could be copied but the styling could not. It lives
 * here so x-platform.gaming-account-card renders the same thing everywhere.
 *
 * The palette is repeated rather than inherited from .gm for the same reason:
 * the card has to look right on a page that is not the gaming grid.
 */

.gcard,
.serviceItem {
    --gm-surface: #16151a;
    --gm-surface-2: #1c1b21;
    --gm-border: #222227;
    --gm-muted: #a3a3ad;
    --gm-accent: #6164ff;
}

/* ---- card ---- */
.serviceItem { display: flex; margin-bottom: 24px; }

.gcard {
    display: flex; flex-direction: column; width: 100%;
    background: var(--gm-surface); border: 1px solid var(--gm-border);
    border-radius: 14px; overflow: hidden;
    transition: border-color .2s ease, transform .2s ease;
}
.gcard:hover { border-color: var(--gm-accent); transform: translateY(-2px); }
.gcard:focus-visible { outline: 2px solid var(--gm-accent); outline-offset: 2px; }

.gcard__cover {
    position: relative; aspect-ratio: 16 / 10; background: #0a0a0a;
    display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.gcard__cover img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Hue is derived from the game id in the view, so every listing for the
   same game gets the same plate instead of a random-looking one. */
.gcard__plate {
    position: absolute; inset: 0;
    background: linear-gradient(140deg,
        hsl(var(--gcard-hue) 58% 24%) 0%,
        hsl(calc(var(--gcard-hue) + 35) 52% 12%) 100%);
    display: flex; align-items: center; justify-content: center;
}
.gcard__initials {
    font-size: 46px; font-weight: 800; letter-spacing: 2px;
    color: rgba(255, 255, 255, .17); text-transform: uppercase; direction: ltr;
}
/* Masked rather than <img>: the files are single-colour marks and the plate
   needs to paint them at its own opacity, which an <img> cannot do.
   The plate is the only place a mark is used - several of the publisher
   marks standing in for a game are wordmarks, and those turn to mush at
   the 15px a chip or a badge would give them. */
.gcard__mark {
    /* Wide box, not square: the logos run from a near-square helmet to the
       9:1 Counter-Strike wordmark, and `contain` only fits them all if the
       box gives the wide ones room. */
    width: 66%; height: 50%;
    background-color: rgba(255, 255, 255, .26);
    -webkit-mask: var(--game-mark) no-repeat center / contain;
    mask: var(--game-mark) no-repeat center / contain;
}

/* No backdrop-filter. There are up to 28 of these badges on a listing page and
   each one is a separate backdrop sample while the page scrolls. They were
   blurring either an opaque gradient (the boost flag) or a screenshot behind a
   72%-opaque chip, and disabling every backdrop-filter on the page and
   re-shooting it produced an identical image - so they cost paint and returned
   nothing. The chips are opaque enough to read on their own. */
.gcard__flag, .gcard__platform, .gcard__shots {
    position: absolute; font-size: 11px; border-radius: 7px;
    padding: 3px 9px;
}
.gcard__flag {
    top: 9px; inset-inline-start: 9px; color: #fff; font-weight: 700;
    background: linear-gradient(to right, #e24997, #2d2ed4);
}
.gcard__platform {
    bottom: 9px; inset-inline-start: 9px; color: #e4e4e7; background: rgba(10, 10, 10, .82);
    max-width: calc(100% - 18px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Opposite corner from the boost flag: side by side at the bottom the two
   collided on "Cross Platform".
   No `direction` here. inset-inline-end resolves against the element's OWN
   direction, so forcing ltr on this badge sent it to the right - the same
   corner the boost flag sits in under RTL - and the two drew on top of each
   other. The count keeps its own order via <bdi dir="ltr"> in the markup,
   which isolates the text without touching where the badge is anchored. */
.gcard__shots { top: 9px; inset-inline-end: 9px; color: #e4e4e7; background: rgba(10, 10, 10, .82); }

.gcard__body { display: flex; flex-direction: column; flex: 1; padding: 14px 15px 15px; }
.gcard__game { color: var(--gm-accent); font-size: 11.5px; font-weight: 700; margin-bottom: 5px; }
.gcard__title {
    color: #fff; font-size: 15px; line-height: 24px; font-weight: 700; margin: 0 0 6px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; word-break: break-word;
}
.gcard__desc {
    color: var(--gm-muted); font-size: 12.5px; line-height: 21px; margin: 0 0 12px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden; word-break: break-word;
}
.gcard__seller { display: flex; align-items: center; gap: 7px; color: var(--gm-muted); font-size: 12.5px; }
.gcard__seller img { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; }
/* Tight against the handle rather than spaced off it by the row gap, and
   nudged down a touch: the disc's optical centre sits above the x-height
   of the text it is annotating. */
.gcard__handle { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.gcard__tick { flex: 0 0 auto; position: relative; top: 1px; }
.gcard__foot {
    margin-top: auto; padding-top: 12px; display: flex;
    align-items: center; justify-content: space-between; gap: 8px;
}
.gcard__price { color: #fff; font-size: 19px; font-weight: 700; direction: ltr; }

.gcard--boosted { border-color: #673ab7a3; animation: simple-glow 2s infinite ease-in-out; }
@keyframes simple-glow {
    0% { border-color: #673ab7a3; box-shadow: 0 0 5px #673ab7a3; }
    50% { border-color: #9c27b0; box-shadow: 0 0 15px #9c27b0; }
    100% { border-color: #673ab7a3; box-shadow: 0 0 5px #673ab7a3; }
}

/* "Add to cart" button feedback.
   ---------------------------------------------------------------------------
   The button posts with htmx and, until now, said nothing while it did. These
   two states cover the whole interaction: pressed-and-working, then confirmed.
   Transform and opacity only, so neither state costs a layout. */
[hx-post="/cart"] {
    transition: transform 140ms cubic-bezier(0.34, 1.4, 0.64, 1), opacity 140ms linear;
}

[hx-post="/cart"]:active {
    transform: scale(0.97);
}

[hx-post="/cart"].is-adding {
    opacity: 0.65;
    cursor: progress;
}

[hx-post="/cart"].is-added {
    animation: cartAddedPulse 620ms cubic-bezier(0.34, 1.4, 0.64, 1);
}

@keyframes cartAddedPulse {
    0%   { transform: scale(1); }
    30%  { transform: scale(1.03); }
    100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    [hx-post="/cart"],
    [hx-post="/cart"]:active,
    [hx-post="/cart"].is-added { transition: none; animation: none; transform: none; }
}

/* Credential fields on the selling and edit forms.
   ---------------------------------------------------------------------------
   These hold someone else's password - the account being sold, and its email -
   so they are masked, and each gets a reveal control because the seller is
   typing a string they do not know by heart and has to be able to check it.
   The control is positioned logically, so it sits at the trailing edge of the
   field in both directions. */
.usr-secret-wrap {
    position: relative;
    display: block;
    /* The wrapper takes the input's place in the layout, so it has to size the
       way the input did. .sign__group is a flex row: a bare block wrapper became
       a flex item that shrank to its content, leaving the password fields half
       the width of the email fields beside them. flex for those parents, width
       for the block ones. */
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
}

.usr-secret-reveal {
    position: absolute;
    inset-inline-end: 10px;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    /* 44px is the smallest comfortable touch target. */
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: none;
    color: #bdbdbd;
    cursor: pointer;
    z-index: 2;
}

.usr-secret-reveal:hover,
.usr-secret-reveal:focus-visible {
    color: #fff;
}

.usr-secret-reveal:focus-visible {
    outline: 2px solid #6164ff;
    outline-offset: 2px;
    border-radius: 6px;
}

/* Room for the control so a long placeholder never runs underneath it.
   !important is not a preference here: .sign__input sets `padding: 0 20px
   !important` (main.css), which no amount of specificity can outrank. Matching
   it is the only way to reserve the space. */
.usr-secret-wrap input.usr-secret {
    padding-inline-end: 48px !important;
}
