/*
 * Composants partagés — source unique de vérité.
 * Chargé après layout.css, avant les CSS de page.
 * Les noms historiques (.btn-primary, .btn-sm…) restent l'API officielle ;
 * les alias BEM (.btn--primary) sont acceptés pour le code neuf.
 */

/* ═══ Boutons ═══
 * Plaques 5c (Relique d’obsidienne) : biseau, semelle colorée, lueur d’angle.
 * Variantes = --btn-c / --btn-g / --btn-fill / --btn-sole.
 */

.btn {
    --cut: 8px;
    --cut-r: 11px;
    --btn-c: #c8caf0;
    --btn-g: 180, 190, 255;
    --btn-fill: #1a1930;
    --btn-sole: rgba(var(--btn-g), 0.88);
    position: relative;
    isolation: isolate;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: 2.35rem;
    padding: 0.42rem 1.05rem 0.44rem;
    border: 0;
    border-radius: 0;
    color: var(--btn-c);
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: 0.02em;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    clip-path: polygon(
        var(--cut) 0,
        calc(100% - var(--cut-r)) 0,
        100% var(--cut-r),
        100% 100%,
        0 100%,
        0 var(--cut)
    );
    background-color: var(--btn-fill);
    background-image:
        linear-gradient(180deg, rgba(255, 255, 255, 0.16) 0%, transparent 46%),
        radial-gradient(120% 80% at 50% 120%, rgba(var(--btn-g), 0.32), transparent 58%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.22),
        inset 0 -3px 0 var(--btn-sole),
        0 0 14px rgba(var(--btn-g), 0.18),
        0 8px 16px rgba(0, 0, 0, 0.4);
    overflow: hidden;
    transition:
        background var(--t-fast),
        color var(--t-fast),
        box-shadow var(--t-fast),
        transform var(--t-fast);
}

.btn::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: calc(var(--cut) + 1px);
    height: calc(var(--cut) + 1px);
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.8) 0 36%, transparent 38%);
    pointer-events: none;
}

.btn:hover {
    text-decoration: none;
    color: var(--btn-c);
    transform: translateY(-1px);
    background-color: #222140;
    background-image:
        linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, transparent 48%),
        radial-gradient(120% 90% at 50% 120%, rgba(var(--btn-g), 0.46), transparent 60%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.32),
        inset 0 -3px 0 rgb(var(--btn-g)),
        0 0 18px rgba(var(--btn-g), 0.28),
        0 10px 18px rgba(0, 0, 0, 0.42);
}

.btn:focus-visible {
    outline: 2px solid var(--gold-bright);
    outline-offset: 2px;
}

.btn-primary,
.btn--primary {
    --btn-c: #0c0b18;
    --btn-g: 201, 162, 39;
    --btn-fill: #e8c84a;
    --btn-sole: #8a6a12;
    color: #0c0b18;
    font-weight: 800;
    background-image:
        linear-gradient(180deg, rgba(255, 246, 196, 0.55) 0%, transparent 42%),
        radial-gradient(120% 80% at 50% 120%, rgba(255, 224, 138, 0.35), transparent 58%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.55),
        inset 0 -3px 0 var(--btn-sole),
        0 0 16px rgba(232, 200, 74, 0.35),
        0 8px 16px rgba(0, 0, 0, 0.4);
}

.btn-primary:hover,
.btn--primary:hover {
    color: #0c0b18;
    background-color: #f0d45c;
    background-image:
        linear-gradient(180deg, rgba(255, 252, 220, 0.7) 0%, transparent 48%),
        radial-gradient(120% 90% at 50% 120%, rgba(255, 224, 138, 0.45), transparent 60%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.7),
        inset 0 -3px 0 #6a5010,
        0 0 20px rgba(232, 200, 74, 0.48),
        0 10px 18px rgba(0, 0, 0, 0.42);
}

.btn-secondary,
.btn--secondary {
    --btn-c: #c8caf0;
    --btn-g: 180, 190, 255;
}

.btn-ghost,
.btn--ghost {
    --btn-c: #8b8ab0;
    --btn-g: 180, 190, 255;
    --btn-fill: #12111f;
    --btn-sole: rgba(var(--btn-g), 0.35);
}

.btn-ghost:hover,
.btn--ghost:hover {
    --btn-c: #e8eefc;
}

.btn-danger,
.btn--danger {
    --btn-c: #f0a0a0;
    --btn-g: 248, 113, 113;
}

.btn-sm,
.btn--sm {
    --cut: 6px;
    --cut-r: 8px;
    min-height: 2.05rem;
    padding: 0.3rem 0.8rem 0.32rem;
    font-size: var(--fs-xs);
}

.btn-lg,
.btn--lg {
    --cut: 10px;
    --cut-r: 14px;
    min-height: 2.7rem;
    padding: 0.58rem 1.3rem;
    font-size: var(--fs-md);
}

.btn:disabled,
.btn[disabled],
.btn.is-disabled {
    opacity: 0.45;
    cursor: not-allowed;
    transform: none;
    filter: grayscale(0.15);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.12),
        inset 0 -3px 0 var(--btn-sole);
}

/* ═══ En-tête de page unifié ═══ */

.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;
}

.page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-3) var(--space-4);
    margin-bottom: var(--space-4);
}

.page-header--actions {
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--border);
}

.page-header__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

/* Fil d'Ariane */
.breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin: 0 0 var(--space-2);
    padding: 0;
    list-style: none;
    font-size: var(--fs-xs);
    color: var(--text-muted);
}

.breadcrumb__sep {
    color: var(--gold-dim);
}

.breadcrumb a {
    color: var(--text-muted);
}

.breadcrumb a:hover {
    color: var(--gold-light);
}

/* ═══ Barre d'outils ═══ */

/* Le registre pilote la densité : plus serré à l'atelier, plus aéré au sanctuaire. */
.toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ui-gap, var(--space-2)) var(--space-3);
    margin-bottom: var(--space-4);
    min-width: 0;
}

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

.toolbar__count {
    flex-shrink: 0;
    margin-left: auto;
    font-family: var(--font-heading);
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--gold-light);
    white-space: nowrap;
}

.toolbar__group--end {
    margin-left: auto;
}

.toolbar__spacer {
    flex: 1 1 auto;
}

/* ═══ Champs de formulaire ═══ */

.field {
    --cut: 8px;
    --cut-r: 10px;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 2.5rem;
    padding: 0 0.85rem;
    border: 0;
    border-radius: 0;
    background-color: #0c0b18;
    background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.06) 0%, transparent 48%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.1),
        inset 0 -2px 0 rgba(180, 190, 255, 0.28),
        inset 0 2px 8px rgba(0, 0, 0, 0.35);
    min-width: 0;
    clip-path: polygon(
        var(--cut) 0,
        calc(100% - var(--cut-r)) 0,
        100% var(--cut-r),
        100% 100%,
        0 100%,
        0 var(--cut)
    );
}

/* Le champ n'a pas de contour propre : c'est l'enveloppe .field qui s'allume */
.field:focus-within {
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.18),
        inset 0 -2px 0 rgba(180, 190, 255, 0.7),
        0 0 14px rgba(180, 190, 255, 0.22);
}

.field__label {
    flex-shrink: 0;
    font-family: var(--font-heading);
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--gold);
}

.field__glyph {
    flex-shrink: 0;
    color: var(--gold);
    font-size: var(--fs-xs);
}

.field__control {
    flex: 1;
    min-width: 0;
    height: 1.75rem;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--text-card);
    font-family: var(--font-body);
    font-size: var(--fs-sm);
}

.field__control:focus-visible {
    outline: none;
}

.field__control::placeholder {
    color: var(--text-muted);
}

.field__control option {
    background: var(--surface-2);
    color: var(--text-card);
}

select.field__control {
    cursor: pointer;
    min-width: 6rem;
}

/* Code d'édition : court et en capitales */
.field__control--code {
    width: 3.6rem;
    flex: 0 0 auto;
    text-transform: uppercase;
}

.field--search {
    flex: 1 1 15rem;
    max-width: 26rem;
}

.field--search .field__control {
    font-style: italic;
}

/* Champ de formulaire classique (labels empilés) */
.form-field {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    font-size: var(--fs-sm);
    color: var(--text-muted);
}

.form-field > input,
.form-field > select,
.form-field > textarea {
    --cut: 8px;
    --cut-r: 10px;
    padding: 0.5rem 0.75rem;
    border: 0;
    border-radius: 0;
    color: var(--text);
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    background-color: #0c0b18;
    background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.06) 0%, transparent 48%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.1),
        inset 0 -2px 0 rgba(180, 190, 255, 0.28),
        inset 0 2px 8px rgba(0, 0, 0, 0.35);
    clip-path: polygon(
        var(--cut) 0,
        calc(100% - var(--cut-r)) 0,
        100% var(--cut-r),
        100% 100%,
        0 100%,
        0 var(--cut)
    );
}

.form-field > input:focus-visible,
.form-field > select:focus-visible,
.form-field > textarea:focus-visible {
    outline: none;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.18),
        inset 0 -2px 0 rgba(180, 190, 255, 0.7),
        0 0 14px rgba(180, 190, 255, 0.22);
}

/* ═══ Badges et pastilles ═══ */

.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0.15rem 0.5rem;
    border-radius: var(--radius-pill);
    border: 1px solid var(--border-subtle);
    background: var(--surface-sunken);
    font-family: var(--font-heading);
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    white-space: nowrap;
}

.badge--gold {
    border-color: var(--border-strong);
    background: var(--gold-soft);
    color: var(--gold-light);
}

.badge--success {
    border-color: var(--edge-success);
    background: var(--tint-success);
    color: var(--success);
}

.badge--warn {
    border-color: var(--edge-warn);
    background: var(--tint-warn);
    color: var(--warn);
}

.badge--error {
    border-color: var(--edge-danger);
    background: var(--tint-danger);
    color: var(--error);
}

.badge--rarity-common { color: var(--rarity-common); }
.badge--rarity-uncommon { color: var(--rarity-uncommon); }
.badge--rarity-rare { color: var(--rarity-rare); }
.badge--rarity-mythic { color: var(--rarity-mythic); }

/* Pastilles de rareté cliquables — langage couleur MTG */
.rarity-chips {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
}

.rarity-chip {
    width: auto;
    height: 1.7rem;
    padding: 0 0.7rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--surface-2);
    cursor: pointer;
    opacity: 0.6;
    transition: opacity var(--t-fast) ease, transform var(--t-fast) ease, box-shadow var(--t-fast) ease;
}

.rarity-chip > span {
    font-family: var(--font-heading);
    font-size: 0.72rem;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.92);
    line-height: 1;
    letter-spacing: 0.02em;
}

.rarity-chip--common { background: var(--rarity-common); }
.rarity-chip--uncommon { background: var(--rarity-uncommon); }
.rarity-chip--rare { background: linear-gradient(180deg, #e8c84a, #a8841a); }
.rarity-chip--rare > span { color: var(--gold-ink); }
.rarity-chip--mythic { background: var(--rarity-mythic); }

.rarity-chip:hover {
    opacity: 0.95;
    transform: scale(1.06);
}

.rarity-chip.is-active {
    opacity: 1;
    transform: scale(1.08);
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.3),
        0 0 12px var(--rarity-ring, var(--gold-dim));
}

.color-chips {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
}

.color-chip {
    --pip: #8b8ab0;
    width: auto;
    height: 1.7rem;
    padding: 0 0.7rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--pip) 70%, #fff);
    cursor: pointer;
    opacity: 0.92;
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, 0.45),
        0 0 12px color-mix(in srgb, var(--pip) 48%, transparent);
    transition: opacity var(--t-fast) ease, transform var(--t-fast) ease, box-shadow var(--t-fast) ease;
}

.color-chip > span {
    font-family: var(--font-heading);
    font-size: 0.72rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0.02em;
}

.color-chip--W { --pip: #ffe9a8; background: var(--mana-w); color: var(--mana-w-ink); }
.color-chip--U { --pip: #5bb4f0; background: #1578c4; color: var(--mana-u-ink); }
.color-chip--B { --pip: #b89bff; background: #4a3d58; color: var(--mana-b-ink); }
.color-chip--R { --pip: #ff6b6b; background: var(--mana-r); color: var(--mana-r-ink); }
.color-chip--G { --pip: #3dcc7a; background: var(--mana-g); color: var(--mana-g-ink); }
.color-chip--C { --pip: #e4dcd8; background: var(--mana-c); color: var(--mana-c-ink); }

.color-chip:hover {
    opacity: 1;
    transform: scale(1.08);
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.28),
        0 0 16px color-mix(in srgb, var(--pip) 62%, transparent);
}

.color-chip.is-active {
    opacity: 1;
    transform: scale(1.1);
    box-shadow:
        0 0 0 2px #fff,
        0 0 18px var(--pip);
}

/* ═══ Chips filtrantes ═══ */

.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-bottom: var(--space-3);
}

.chip {
    --cut: 6px;
    --cut-r: 8px;
    --g: 180, 190, 255;
    position: relative;
    isolation: isolate;
    min-height: 1.85rem;
    padding: 0.28rem 0.7rem;
    border: 0;
    border-radius: 0;
    color: #c8caf0;
    font-family: var(--font-body);
    font-size: var(--fs-xs);
    font-weight: 650;
    cursor: pointer;
    clip-path: polygon(
        var(--cut) 0,
        calc(100% - var(--cut-r)) 0,
        100% var(--cut-r),
        100% 100%,
        0 100%,
        0 var(--cut)
    );
    background-color: #12111f;
    background-image:
        linear-gradient(180deg, rgba(255, 255, 255, 0.08) 0%, transparent 46%),
        radial-gradient(120% 80% at 50% 120%, rgba(var(--g), 0.18), transparent 58%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.14),
        inset 0 -2px 0 rgba(var(--g), 0.38);
    overflow: hidden;
    transition: box-shadow 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.chip:hover,
.chip.is-active {
    color: #f4f5ff;
    background-color: #1a1930;
    background-image:
        linear-gradient(180deg, rgba(255, 255, 255, 0.14) 0%, transparent 46%),
        radial-gradient(120% 90% at 50% 120%, rgba(var(--g), 0.36), transparent 58%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.22),
        inset 0 -2px 0 rgba(var(--g), 0.72),
        0 0 12px rgba(var(--g), 0.18);
}

/*
 * ═══ Sélecteur segmenté ═══
 * Un groupe de boutons exclusifs : bascule grille/liste, onglets d'une
 * fenêtre, ordre de tri. Cinq implémentations concurrentes vivaient dans les
 * CSS de page (view-toggle, atk-sort, decks-view-toggle, deck-search-tab,
 * deck-coach__tab) ; celle-ci les remplace toutes.
 *
 *   .segmented > .segmented__btn[.is-active|aria-selected|aria-pressed]
 *
 * Variantes : --plain pour des onglets posés sur un bandeau (pas de cadre
 * autour du groupe), --icons pour des boutons carrés sans libellé.
 */

.segmented {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    gap: 0.3rem;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
}

.segmented__btn {
    --cut: 7px;
    --cut-r: 9px;
    --g: 180, 190, 255;
    position: relative;
    isolation: isolate;
    min-height: 2.05rem;
    padding: 0.28rem 0.8rem;
    border: 0;
    border-radius: 0;
    color: #c8caf0;
    cursor: pointer;
    font-family: var(--font-body);
    font-size: var(--fs-xs);
    font-weight: 700;
    letter-spacing: 0.04em;
    clip-path: polygon(
        var(--cut) 0,
        calc(100% - var(--cut-r)) 0,
        100% var(--cut-r),
        100% 100%,
        0 100%,
        0 var(--cut)
    );
    background-color: #12111f;
    background-image:
        linear-gradient(180deg, rgba(255, 255, 255, 0.08) 0%, transparent 46%),
        radial-gradient(120% 80% at 50% 120%, rgba(var(--g), 0.18), transparent 58%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.14),
        inset 0 -2px 0 rgba(var(--g), 0.38);
    overflow: hidden;
    transition: box-shadow 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.segmented__btn:hover {
    color: #f4f5ff;
    background-color: #1a1930;
}

.segmented__btn.is-active,
.segmented__btn[aria-pressed="true"],
.segmented__btn[aria-selected="true"] {
    color: #f4f5ff;
    background-color: #1e1d36;
    background-image:
        linear-gradient(180deg, rgba(255, 255, 255, 0.16) 0%, transparent 46%),
        radial-gradient(120% 90% at 50% 120%, rgba(var(--g), 0.4), transparent 58%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.24),
        inset 0 -3px 0 rgba(var(--g), 0.82),
        0 0 12px rgba(var(--g), 0.2);
}

.segmented--plain {
    flex-wrap: wrap;
    gap: 0.3rem;
    padding: 0;
    border: 0;
    background: none;
}

.segmented--plain .segmented__btn {
    font-family: inherit;
    font-size: var(--fs-xs);
    letter-spacing: 0.02em;
    text-transform: none;
}

.segmented--icons .segmented__btn {
    width: 2.15rem;
    height: 2rem;
    padding: 0;
    font-size: var(--fs-md);
    letter-spacing: 0;
}

/* ═══ Panneaux ═══ */

.panel {
    position: relative;
    background: var(--panel-bg);
    border: 1px solid var(--panel-border);
    border-radius: var(--panel-radius);
    padding: var(--ui-panel-pad, var(--space-5));
    box-shadow: var(--panel-shadow);
}

/* Fleuron d'angle : présent en registre showcase, absent en registre travail */
.panel::before {
    content: '';
    display: var(--panel-flourish);
    position: absolute;
    top: -1px;
    left: -1px;
    width: 1.75rem;
    height: 1.75rem;
    border-top: 2px solid var(--gold);
    border-left: 2px solid var(--gold);
    border-top-left-radius: var(--panel-radius);
    opacity: 0.55;
    pointer-events: none;
}

.panel h2 {
    margin: 0 0 var(--space-4);
    font-size: var(--fs-lg);
    color: var(--gold);
}

/*
 * ═══ Grille de cartes ═══
 * La largeur de colonne est un compromis mesuré : 200px laisse le nom
 * lisible sans réduire la carte à une vignette. Collection, remplissage de
 * case et fenêtres du studio partagent la même trame.
 */

.cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 1.75rem 1.4rem;
    padding-top: 0.5rem;
}

.cards-grid > .empty-state {
    grid-column: 1 / -1;
}

.cards-grid--tight {
    gap: var(--space-3);
}

/*
 * ═══ Ligne média ═══
 * Vignette + informations + actions. C'est le motif des résultats de
 * recherche, des doublons, des cartes à ranger et des prêts : quatre
 * implémentations séparées disaient exactement la même chose.
 *
 *   .media-list > .media-row > .media-row__img
 *                            + .media-row__body > .media-row__name
 *                                               + .media-row__meta
 *                            + .media-row__actions
 *
 * Variantes : --center quand la vignette est petite, --plain sans ombre.
 */

.media-list {
    display: flex;
    flex-direction: column;
    gap: var(--ui-gap, var(--space-2));
}

.media-row {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--ui-row-pad-y, var(--space-3)) var(--ui-row-pad-x, var(--space-4));
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-soft);
}

.media-row--center {
    align-items: center;
}

.media-row--plain {
    box-shadow: none;
}

.media-row__img {
    flex-shrink: 0;
    object-fit: cover;
    object-position: top center;
    border-radius: var(--radius-sm);
}

.media-row__body {
    flex: 1;
    min-width: 0;
}

.media-row__name {
    margin: 0 0 var(--space-1);
    font-family: var(--font-heading);
    font-weight: 700;
    color: var(--text-card);
}

.media-row__meta {
    margin: 0;
    color: var(--text-muted);
    font-family: var(--font-grimoire);
    font-size: var(--fs-xs);
    font-style: italic;
}

.media-row__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    flex-shrink: 0;
}

/*
 * ═══ Compteur de quantité ═══
 * Le triptyque − / valeur / + qui vivait en trois exemplaires : tuile de
 * collection, modale d'emplacement, case de classeur. La valeur porte le
 * sceau de cire ; c'est un bouton, elle ouvre la saisie directe.
 *
 *   .qty-stepper > .qty-stepper__btn + .qty-stepper__value + .qty-stepper__btn
 *
 * Variantes : --tile pour la pose sur une image de carte, --compact pour les
 * lignes de tableau.
 */

.qty-stepper {
    display: inline-flex;
    align-items: stretch;
    overflow: hidden;
    border-radius: var(--radius-pill);
    border: 1px solid var(--gold-dim);
    background: rgba(12, 12, 26, 0.55);
}

.qty-stepper__btn,
.qty-stepper__value {
    margin: 0;
    border: none;
    cursor: pointer;
    font-family: var(--font-heading);
    font-weight: 700;
    line-height: 1;
    color: var(--text);
}

.qty-stepper__btn {
    width: 2rem;
    padding: 0.45rem 0;
    background: transparent;
    font-size: var(--fs-md);
    color: var(--gold);
}

.qty-stepper__btn:hover:not(:disabled) {
    background: var(--gold-soft);
}

.qty-stepper__btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.qty-stepper__value {
    min-width: 2.4rem;
    padding: 0.45rem 0.5rem;
    background: rgba(12, 12, 26, 0.55);
    color: var(--gold-bright);
    font-size: var(--fs-sm);
    text-shadow: none;
}

.qty-stepper__value:hover {
    background: var(--gold-soft);
}

.qty-stepper__value--multi {
    box-shadow: inset 0 0 0 1px var(--gold-dim);
}

/* Posé sur l'image d'une carte : plus petit, et il doit rester lisible. */
.qty-stepper--tile {
    position: absolute;
    top: 0.55rem;
    right: 0.55rem;
    z-index: 3;
    border-color: rgba(180, 190, 255, 0.28);
    background: rgba(12, 12, 26, 0.78);
    backdrop-filter: blur(8px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.qty-stepper--tile .qty-stepper__btn,
.qty-stepper--compact .qty-stepper__btn {
    width: 1.45rem;
    padding: 0;
    font-size: var(--fs-sm);
}

.qty-stepper--tile .qty-stepper__value,
.qty-stepper--compact .qty-stepper__value {
    min-width: 1.9rem;
    padding: 0.28rem 0.35rem;
    font-size: var(--fs-2xs);
}

.qty-stepper--tile .qty-stepper__btn {
    color: var(--gold-bright);
}

.qty-stepper--compact {
    border-color: var(--border-strong);
}

/*
 * ═══ Modales ═══
 * Coquille commune à toutes les fenêtres : le calque, le voile, le panneau.
 * Les appelants ne gardent que ce qui leur est propre — largeur, padding,
 * contenu. Ce qui est ici ne doit plus jamais diverger d'une modale à l'autre.
 *
 * Structure attendue :
 *   .modal[hidden] > .modal__backdrop[data-close-…] + .modal__panel[role=dialog]
 */

.modal {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
}

/* Fenêtres hautes : ancrées en haut pour ne pas sauter quand le contenu grandit. */
.modal--top {
    align-items: flex-start;
}

.modal[hidden] {
    display: none !important;
}

.modal__backdrop {
    position: absolute;
    inset: 0;
    background: var(--scrim);
}

.modal__panel {
    --cut: 14px;
    --cut-r: 18px;
    position: relative;
    z-index: 1;
    max-height: min(92vh, 920px);
    overflow: auto;
    border: 0;
    border-radius: 0;
    background-color: #08070f;
    background-image:
        linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, transparent 36%),
        linear-gradient(180deg, #12111f 0%, #08070f 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.14),
        0 0 28px rgba(180, 190, 255, 0.12),
        var(--shadow-modal);
    clip-path: polygon(
        var(--cut) 0,
        calc(100% - var(--cut-r)) 0,
        100% var(--cut-r),
        100% 100%,
        0 100%,
        0 var(--cut)
    );
}

/*
 * Le fond ne défile plus dès qu'une fenêtre est ouverte. En :has() plutôt
 * qu'en classe posée par JS : plus de modale qui oublie de rendre le scroll.
 */
body:has(.modal:not([hidden])) {
    overflow: hidden;
}

/* ═══ États vides ═══ */

.empty-state {
    --cut: 12px;
    --cut-r: 16px;
    margin: var(--space-5) 0;
    padding: var(--space-5);
    text-align: center;
    color: var(--text-muted);
    font-family: var(--font-grimoire);
    font-size: var(--fs-md);
    font-style: italic;
    border: 0;
    border-radius: 0;
    background-color: #0c0b18;
    background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.05) 0%, transparent 42%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        inset 0 -2px 0 rgba(180, 190, 255, 0.22);
    clip-path: polygon(
        var(--cut) 0,
        calc(100% - var(--cut-r)) 0,
        100% var(--cut-r),
        100% 100%,
        0 100%,
        0 var(--cut)
    );
}

.empty-state--bare,
.empty-state--grimoire {
    padding: var(--space-4) 0;
    border: none;
    background: none;
    box-shadow: none;
    clip-path: none;
}

/*
 * ═══ Bandeau d'état ═══
 * Chargement, succès, avertissement, erreur — un seul vocabulaire visuel.
 * Chaque page avait le sien (archidekt-status, import-result, deck-import-result)
 * et les erreurs bloquantes partaient dans un alert() natif.
 *
 *   <p class="status-banner status-banner--error">Message</p>
 *   <p class="status-banner status-banner--loading"><span class="spinner"></span>Chargement…</p>
 */

.status-banner {
    --cut: 10px;
    --cut-r: 13px;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: var(--space-3) 0;
    padding: var(--space-3) var(--space-4);
    border: 0;
    border-radius: 0;
    background-color: #12111f;
    background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.06) 0%, transparent 46%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.1),
        inset 0 -2px 0 rgba(180, 190, 255, 0.32);
    color: var(--text);
    font-size: var(--fs-sm);
    clip-path: polygon(
        var(--cut) 0,
        calc(100% - var(--cut-r)) 0,
        100% var(--cut-r),
        100% 100%,
        0 100%,
        0 var(--cut)
    );
    line-height: 1.45;
}

.status-banner[hidden] {
    display: none !important;
}

.status-banner--loading {
    color: var(--text-muted);
}

.status-banner--success {
    background-color: #0e1a14;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.1),
        inset 0 -2px 0 rgba(74, 222, 128, 0.7);
    color: var(--success);
}

.status-banner--warn {
    background-color: #1a160c;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.1),
        inset 0 -2px 0 rgba(232, 200, 74, 0.7);
    color: var(--warn);
}

.status-banner--error {
    background-color: #1a1014;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.1),
        inset 0 -2px 0 rgba(248, 113, 113, 0.7);
    color: var(--error);
}

/*
 * ═══ Notifications ═══
 * Le même vocabulaire que le bandeau d'état, mais flottant : c'est ce qui
 * remplace les alert() natifs, qui bloquaient l'interface et cassaient net
 * l'ambiance du site. Empilées en haut à droite, elles s'effacent seules.
 */

.toast-stack {
    position: fixed;
    top: var(--space-4);
    right: var(--space-4);
    z-index: var(--z-toast);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    width: min(26rem, calc(100vw - 2 * var(--space-4)));
    pointer-events: none;
}

.toast {
    margin: 0;
    pointer-events: auto;
    align-items: flex-start;
    /* Les messages d'API arrivent parfois sur plusieurs lignes. */
    white-space: pre-line;
    background: var(--surface-2);
    box-shadow: var(--shadow);
    animation: toast-in var(--t-mid) ease;
}

.toast--error { background: color-mix(in srgb, var(--error) 12%, var(--surface-2)); }
.toast--success { background: color-mix(in srgb, var(--success) 12%, var(--surface-2)); }
.toast--warn { background: color-mix(in srgb, var(--warn) 12%, var(--surface-2)); }

.toast.is-leaving {
    opacity: 0;
    transform: translateX(0.75rem);
    transition: opacity var(--t-mid) ease, transform var(--t-mid) ease;
}

.toast__close {
    flex-shrink: 0;
    margin-left: auto;
    padding: 0 0.15rem;
    border: none;
    background: none;
    color: inherit;
    font-size: var(--fs-md);
    line-height: 1;
    cursor: pointer;
    opacity: 0.7;
}

.toast__close:hover {
    opacity: 1;
}

@keyframes toast-in {
    from { opacity: 0; transform: translateX(1rem); }
    to { opacity: 1; transform: translateX(0); }
}

@media (max-width: 640px) {
    .toast-stack {
        top: auto;
        bottom: var(--space-4);
        left: var(--space-4);
        right: var(--space-4);
        width: auto;
    }
}

/* Attente : un anneau qui tourne plutôt qu'un « Chargement… » figé. */
.spinner {
    flex-shrink: 0;
    width: 1rem;
    height: 1rem;
    border: 2px solid var(--border-subtle);
    border-top-color: var(--gold);
    border-radius: 50%;
    animation: spinner-turn 0.7s linear infinite;
}

@keyframes spinner-turn {
    to { transform: rotate(360deg); }
}

/* ═══ Pagination ═══ */

.pagination {
    display: flex;
    justify-content: center;
    gap: var(--space-2);
    margin-top: var(--space-5);
}

.pagination button {
    --cut: 6px;
    --cut-r: 8px;
    min-height: 2.05rem;
    padding: 0.3rem 0.85rem;
    border: 0;
    border-radius: 0;
    color: #c8caf0;
    font-family: var(--font-body);
    font-size: var(--fs-xs);
    font-weight: 700;
    cursor: pointer;
    clip-path: polygon(
        var(--cut) 0,
        calc(100% - var(--cut-r)) 0,
        100% var(--cut-r),
        100% 100%,
        0 100%,
        0 var(--cut)
    );
    background-color: #1a1930;
    background-image:
        linear-gradient(180deg, rgba(255, 255, 255, 0.14) 0%, transparent 46%),
        radial-gradient(120% 80% at 50% 120%, rgba(180, 190, 255, 0.28), transparent 58%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.2),
        inset 0 -3px 0 rgba(180, 190, 255, 0.7);
}

.pagination button:hover:not(:disabled) {
    color: #f4f5ff;
    background-color: #222140;
}

.pagination button:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.pagination .page-info {
    align-self: center;
    color: var(--text-muted);
    font-size: var(--fs-sm);
}

/*
 * ═══ Responsive ═══
 * Le site est pensé pour le bureau, mais les pages de rangement servent
 * téléphone en main devant un classeur : là, les cibles tactiles et la
 * lisibilité des lignes priment sur la densité.
 */

@media (max-width: 640px) {
    .page-header {
        align-items: flex-start;
        justify-content: flex-start;
    }

    .toolbar__count {
        margin-left: 0;
    }

    .field--search {
        flex-basis: 100%;
        max-width: none;
    }

    /* Une ligne média tient rarement sur une seule ligne : on l'autorise à passer. */
    .media-row {
        flex-wrap: wrap;
        padding: var(--space-3);
    }

    .media-row__body {
        flex-basis: 60%;
    }

    .media-row__actions {
        flex-basis: 100%;
    }

    .media-row__actions .btn {
        flex: 1;
    }

    /* Cibles tactiles : 1,45rem au doigt, c'est trop peu pour incrémenter. */
    .qty-stepper--tile .qty-stepper__btn,
    .qty-stepper--compact .qty-stepper__btn {
        width: 2.1rem;
        padding: 0.35rem 0;
    }

    .qty-stepper--tile .qty-stepper__value,
    .qty-stepper--compact .qty-stepper__value {
        min-width: 2.3rem;
        padding: 0.35rem 0.4rem;
        font-size: var(--fs-xs);
    }

    /* Deux cartes par ligne restent lisibles sur un téléphone récent. */
    .cards-grid {
        grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
        gap: var(--space-3);
    }
}
