/*
 * WinetPay — L'espace annonceur (`.ann-*`). 09-CDC-ADS.md, ADS-D33 / ADS-D42.
 *
 * IDENTITÉ. Aucune palette nouvelle : la couleur reste `--c-primary`, donc les sept thèmes et la
 * garantie de contraste AA sont acquis sans rien réécrire. Ce qui distingue ces écrans, c'est leur
 * forme : peu de choses par page, et une action évidente à chaque fois.
 *
 * ⚠️ PIÈGE CONNU DU PROJET : la règle générique `button { background: var(--bo-primary) }` d'app.css
 * fuit sur tout <button> non redéclaré. Chaque bouton stylé ici REDÉCLARE son fond, survol compris.
 *
 * ⚠️ FEUILLE SÉPARÉE : ces écrans ne sont jamais vus par un visiteur du catalogue, et le budget
 * d'ADS-D31 porte sur la première vue de CELUI-CI.
 */

.ann {
    --ann-gap: var(--sp-5);
}

/*
 * ═══════════════════════════════════════════════════════════════════════════════════════════════
 * 🔴 `hidden` DOIT VRAIMENT MASQUER
 * ═══════════════════════════════════════════════════════════════════════════════════════════════
 *
 * `[hidden] { display: none }` est une règle du NAVIGATEUR : la moindre règle de classe posant un
 * `display:` la bat, et l'élément reste rendu — invisible, mais présent, occupant la place et
 * captant les clics. Le garde du projet l'a déjà attrapé six fois ; ces quatre-là sont déclarés
 * AVANT d'écrire leur mise en page, pas après qu'un test l'ait signalé.
 */
.ann-bandeau[hidden],
.ann-liste[hidden],
.ann-vide[hidden],
.ann-verif[hidden],
.ann-erreur[hidden],

/*
 * ⚠️ CES DEUX-LÀ, AUCUN GARDE NE POUVAIT LES VOIR.
 *
 * `.ann-bandeau-a` porte AUSSI `.btn`, qui pose un `display` dans site.css — mais le garde du
 * projet ne lit que la PREMIÈRE classe d'un élément, et c'est celle-ci. Quant à l'aperçu d'image,
 * c'est un `<img>` sans classe du tout. Les deux sont ici parce que le RAISONNEMENT s'applique,
 * pas parce qu'un test l'a signalé : « le bouton reste cliquable » et « l'image reste affichée »
 * sont des défauts réels, que le garde les attrape ou non.
 */
.ann-bandeau-a[hidden],
.ann-image img[hidden] {
    display: none !important;
}

/* ===== Cadres ===== */
.ann-wrap { padding-block: var(--sp-8) var(--sp-10); }
.ann-etroit { max-width: 26rem; }
.ann-moyen { max-width: 44rem; }

.ann-head { margin-bottom: var(--sp-6); }

.ann-head-large {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-4);
    align-items: flex-start;
    justify-content: space-between;
}

.ann-titre {
    font-size: var(--fs-h1);
    font-weight: var(--fw-bold);
    color: var(--an-ink);
    margin: 0 0 var(--sp-1);
    text-wrap: balance;
}

.ann-sous { color: var(--an-dim); margin: 0; }
.ann-nav { display: flex; gap: var(--sp-3); flex-wrap: wrap; }

.ann-carte {
    background: var(--an-card);
    border: 1px solid var(--an-line);
    border-radius: var(--an-radius);
    padding: var(--sp-6);
    margin-bottom: var(--ann-gap);
}

.ann-carte-t { margin: 0 0 var(--sp-4); font-size: var(--fs-h3); color: var(--an-ink); }

/* ===== Formulaires ===== */
.ann-champ { margin-bottom: var(--ann-gap); }

.ann-label {
    display: block;
    font-weight: var(--fw-semibold);
    color: var(--an-ink);
    margin-bottom: var(--sp-2);
}

.ann-in {
    inline-size: 100%;
    padding: var(--sp-3) var(--sp-4);
    font: inherit;
    color: var(--an-ink);
    background: var(--c-surface);
    border: 1px solid var(--an-line);
    border-radius: var(--r-md);
    transition: border-color var(--an-dur) ease, box-shadow var(--an-dur) ease;
}

.ann-in:focus-visible {
    outline: none;
    border-color: var(--c-primary);
    box-shadow: 0 0 0 3px var(--c-primary-100);
}

.ann-sel { appearance: none; background-image: none; }

/*
 * ⚠️ Sans cette règle, les zones de texte de l'éditeur de vitrine tombaient à la hauteur par défaut
 * du navigateur — deux lignes — pour un champ où l'on décrit son commerce. Le défaut ne casse rien
 * et ne lève rien : il rend simplement le formulaire pénible, ce que personne ne signale.
 */
.ann-ta { resize: vertical; min-block-size: 7rem; }

.ann-aide {
    margin: var(--sp-2) 0 0;
    font-size: var(--fs-small);
    color: var(--an-dim);
}

.ann-bouton { inline-size: 100%; }

.ann-pied {
    margin: var(--sp-5) 0 0;
    text-align: center;
    font-size: var(--fs-small);
    color: var(--an-dim);
}

.ann-erreur {
    margin: 0 0 var(--ann-gap);
    padding: var(--sp-3) var(--sp-4);
    color: var(--c-error);
    background: var(--c-error-bg);
    border: 1px solid var(--c-error);
    border-radius: var(--r-md);
}

.ann-etat {
    min-block-size: 1.25rem;
    margin: 0 0 var(--sp-3);
    font-size: var(--fs-small);
    color: var(--an-dim);
}

/* ===== Le bandeau de vérification (ADS-D35) ===== */
.ann-bandeau {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-4);
    align-items: center;
    justify-content: space-between;
    padding: var(--sp-4) var(--sp-5);
    margin-bottom: var(--ann-gap);
    background: var(--c-warning-bg);
    border: 1px solid var(--c-warning);
    border-radius: var(--an-radius);
}

.ann-bandeau-t { display: block; color: var(--an-ink); }
.ann-bandeau-s { margin: var(--sp-1) 0 0; font-size: var(--fs-small); color: var(--an-dim); }
.ann-bandeau-a { flex: none; }

/* ===== La liste des annonces ===== */
.ann-liste {
    display: grid;
    gap: var(--sp-3);
    list-style: none;
    padding: 0;
    margin: 0;
}

.ann-item {
    display: grid;
    grid-template-columns: 5rem 1fr auto;
    gap: var(--sp-4);
    align-items: center;
    padding: var(--sp-3);
    background: var(--an-card);
    border: 1px solid var(--an-line);
    border-radius: var(--an-radius);
}

/* Sur mobile, la vignette passe au-dessus : trois colonnes de 5 rem écrasent le titre. */
@media (max-width: 34rem) {
    .ann-item { grid-template-columns: 4rem 1fr; }
    .ann-item-a { grid-column: 1 / -1; }
}

.ann-item-img {
    inline-size: 100%;
    border-radius: var(--r-md);
    overflow: hidden;
    background: var(--an-line);
    aspect-ratio: 4 / 3;
}

.ann-item-img img { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }

.ann-item-corps { min-inline-size: 0; }

.ann-item-t {
    margin: 0 0 var(--sp-1);
    font-weight: var(--fw-semibold);
    color: var(--an-ink);
    /* Un titre long ne doit pas pousser les actions hors de l'écran. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ann-item-meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    align-items: center;
    margin: 0;
    font-size: var(--fs-small);
    color: var(--an-dim);
}

.ann-item-chiffres { font-variant-numeric: tabular-nums; }

.ann-item-jauge {
    block-size: 0.25rem;
    border-radius: 999px;
    background: var(--an-line);
    overflow: hidden;
    margin-top: var(--sp-2);
    max-inline-size: 12rem;
}

.ann-item-jauge span { display: block; block-size: 100%; background: var(--c-primary); }

.ann-item-a { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* ===== Pastilles d'état ===== */
.ann-badge {
    display: inline-block;
    padding: 0.05rem 0.45rem;
    border-radius: var(--r-sm);
    font-size: var(--fs-caption);
    font-weight: var(--fw-semibold);
    background: var(--an-line);
    color: var(--an-ink);
}

.ann-badge-active { background: var(--c-success); color: var(--c-text-inverse); }
.ann-badge-pending { background: var(--c-warning); color: var(--c-text-inverse); }
.ann-badge-rejetee { background: var(--c-error); color: var(--c-text-inverse); }

/* ===== Squelettes de chargement (§16.10) — pas de page blanche ===== */
.ann-item-squelette {
    block-size: 5.5rem;
    background: var(--an-line);
    border: 0;
    /* `opacity` seule : aucune mise en page recalculée, le contrat de performance du projet. */
    animation: ann-pouls 1.4s ease-in-out infinite;
}

@keyframes ann-pouls {
    0%, 100% { opacity: 0.45; }
    50% { opacity: 0.8; }
}

/* ===== L'écran vide (ADS-D32) — jamais « aucune annonce » ===== */
.ann-vide {
    text-align: center;
    padding: var(--sp-8) var(--sp-4);
    background: var(--an-card);
    border: 1px dashed var(--an-line);
    border-radius: var(--an-radius);
}

.ann-vide-t { margin: 0 0 var(--sp-2); font-size: var(--fs-h3); color: var(--an-ink); }
.ann-vide-s { margin: 0 auto var(--sp-5); max-inline-size: 30rem; color: var(--an-dim); }

/* ===== Compte ===== */
.ann-defs {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--sp-2) var(--sp-5);
    margin: 0 0 var(--sp-4);
}

.ann-defs dt { color: var(--an-dim); font-size: var(--fs-small); }
.ann-defs dd { margin: 0; color: var(--an-ink); }

.ann-verif { padding-top: var(--sp-3); border-top: 1px solid var(--an-line); }
.ann-verif-t { margin: 0 0 var(--sp-3); color: var(--c-warning); }
.ann-verif-ok { margin: 0; color: var(--c-success); font-size: var(--fs-small); }

.ann-sessions { list-style: none; padding: 0; margin: 0 0 var(--sp-4); }

.ann-session {
    display: flex;
    gap: var(--sp-4);
    align-items: center;
    justify-content: space-between;
    padding: var(--sp-3) 0;
    border-bottom: 1px solid var(--an-line);
}

.ann-session:last-child { border-bottom: 0; }
.ann-session-t { margin: 0; color: var(--an-ink); }
.ann-session-s { margin: 0; font-size: var(--fs-small); color: var(--an-dim); }

/* Un geste irréversible se distingue à l'œil AVANT d'être cliqué, pas après. */
.ann-danger { color: var(--c-error); border-color: var(--c-error); }

/* ===== L'éditeur de vitrine (ADS-D19/D20/D40) ===== */

.ann-choix { display: flex; flex-direction: column; gap: var(--sp-2); }

.ann-opt {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    /* 44 px de haut : le même pouce doit pouvoir viser sans se tromper (§16.12). */
    min-block-size: 2.75rem;
    padding: var(--sp-2) var(--sp-4);
    cursor: pointer;
    color: var(--an-ink);
    background: var(--c-surface);
    border: 1px solid var(--an-line);
    border-radius: var(--r-md);
    transition: border-color var(--an-dur) ease;
}

.ann-opt:has(input:checked) { border-color: var(--c-primary); font-weight: var(--fw-semibold); }
.ann-opt:has(input:focus-visible) { outline: 2px solid var(--c-primary); outline-offset: 2px; }

/*
 * Les pastilles de thème.
 *
 * ⚠️ Leur couleur vient du SERVEUR, posée en style inline : elle doit être celle du preset, pas une
 * approximation recopiée ici. Une seconde liste de couleurs mentirait au premier preset modifié.
 */
.ann-themes { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

.ann-theme {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    min-block-size: 2.75rem;
    padding: var(--sp-2) var(--sp-4);
    cursor: pointer;
    border: 1px solid var(--an-line);
    border-radius: 999px;
    transition: border-color var(--an-dur) ease;
}

.ann-theme:has(input:checked) { border-color: var(--c-primary); font-weight: var(--fw-semibold); }
.ann-theme:has(input:focus-visible) { outline: 2px solid var(--c-primary); outline-offset: 2px; }

.ann-theme-p {
    inline-size: 1rem;
    block-size: 1rem;
    border-radius: 50%;
    border: 1px solid var(--an-line);
}

/* ===== Images de la vitrine ===== */

.ann-image { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; }

.ann-image img {
    inline-size: 6rem;
    block-size: 6rem;
    object-fit: cover;
    border-radius: var(--r-md);
    border: 1px solid var(--an-line);
    background: var(--an-line);
}

.ann-galerie {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(6rem, 1fr));
    gap: var(--sp-3);
    list-style: none;
    padding: 0;
    margin: 0 0 var(--sp-4);
}

.ann-galerie-i { position: relative; border-radius: var(--r-md); overflow: hidden; background: var(--an-line); }

.ann-galerie-i img { display: block; inline-size: 100%; aspect-ratio: 1 / 1; object-fit: cover; }

.ann-galerie-x {
    position: absolute;
    inset-block-start: var(--sp-2);
    inset-inline-end: var(--sp-2);
    inline-size: 2.75rem;
    block-size: 2.75rem;
    display: grid;
    place-items: center;
    font-size: 1.25rem;
    line-height: 1;
    color: var(--c-neutral-0);
    /* Redéclaré : sans cela, la règle générique d'app.css impose son propre fond. */
    background: rgba(0, 0, 0, 0.55);
    border: 0;
    border-radius: 50%;
    cursor: pointer;
}

.ann-galerie-x:hover { background: rgba(0, 0, 0, 0.75); }
.ann-galerie-x:focus-visible { outline: 2px solid var(--c-neutral-0); outline-offset: -3px; }

/* La barre de publication reste sous le pouce sur mobile. */
.ann-actions {
    position: sticky;
    inset-block-end: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    align-items: center;
    justify-content: space-between;
    padding: var(--sp-4) 0;
    background: linear-gradient(180deg, transparent, var(--c-bg) 35%);
}

.ann-actions .ann-aide { margin: 0; flex: 1 1 14rem; }

/*
 * Une animation qu'on ne peut pas refuser n'est pas premium (§16.12). Ceci coupe TOUT d'un seul
 * bloc — y compris ce qu'on ajoutera plus tard.
 */
@media (prefers-reduced-motion: reduce) {
    .ann *,
    .ann *::before,
    .ann *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ═══ §15.5 — L'ÉCRAN DE DIFFUSION : curseur de jours, prix, palier suivant ═══
   Tokens seuls. Aucune classe ici n'est rendue `hidden` par le balisage : le voile est CRÉÉ à
   l'ouverture et RETIRÉ à la fermeture, jamais masqué — c'est ce qui évite le piège déjà payé six
   fois sur ce projet (un `display:` qui bat `[hidden]` et laisse un calque invisible capter les
   clics de toute la page). */
.ann-modale-voile {
    position: fixed; inset: 0; z-index: 60;
    display: flex; align-items: center; justify-content: center;
    padding: var(--sp-4);
    background: rgba(10, 12, 20, .55);
}
.ann-modale {
    display: grid; gap: var(--sp-3);
    width: min(420px, 100%); max-height: 90vh; overflow-y: auto;
    padding: var(--sp-5);
    background: var(--c-surface);
    border: 1px solid var(--c-border); border-radius: var(--r-xl);
    box-shadow: var(--e3);
}
.ann-modale-titre { margin: 0; font-size: var(--fs-h4); font-weight: var(--fw-semibold); }
.ann-modale-acquis, .ann-modale-palier { margin: 0; font-size: var(--fs-small); color: var(--c-text-muted); }
.ann-modale-label { display: grid; gap: var(--sp-1); font-size: var(--fs-small); font-weight: var(--fw-medium); }
.ann-modale-champ {
    width: 100%; padding: 10px 12px;
    background: var(--c-bg); color: var(--c-text);
    border: 1px solid var(--c-border); border-radius: var(--r-md);
    font-size: var(--fs-body);
}
.ann-modale-curseur { width: 100%; }
/* Le prix est ce que le vendeur regarde : il doit dominer l'écran, pas s'y fondre. */
.ann-modale-prix { margin: 0; font-size: var(--fs-h3); font-weight: var(--fw-bold); color: var(--c-primary); }
.ann-modale-etat { margin: 0; font-size: var(--fs-small); color: var(--c-text-muted); min-height: 1.2em; }

/* ═══════════════════════ LA DIFFUSION PAYÉE (§15.5) ═══════════════════════

   🔴 **CE PANNEAU RÉPARE UN SILENCE, PAS UN DÉFAUT D'AFFICHAGE.** « Mes annonces » ne disait rien
   d'une mise en avant qu'on venait de payer : ni le niveau, ni les dates, ni ce qu'il restait. Un
   annonceur qui paie et ne constate rien ne repaie pas.

   🔑 **UN ENCADRÉ, PAS UNE LIGNE DE PLUS.** La carte porte déjà l'état, les contacts et les vues ;
   ajouter quatre libellés à la suite les aurait noyés. Le fond ambré isole ce qui a été ACHETÉ de
   ce qui est gratuit — et le liseré de gauche le rend repérable en descendant la liste.

   ⚠️ Aucune couleur nouvelle : `--c-accent` est déjà la signature du marché d'annonces. */
.ann-diff {
    margin-top: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--r-md);
    border: 1px solid var(--an-line);
    /* Le liseré ambré : trois pixels qui disent « cette annonce est en avant ». */
    border-inline-start: 3px solid var(--an-line);
    background: var(--c-surface-raised);
}

/* La diffusion EN COURS se distingue de celle qui est finie — c'est la première question. */
.ann-diff.is-on {
    border-inline-start-color: var(--c-accent);
    background: color-mix(in srgb, var(--c-accent) 7%, var(--c-surface));
}

.ann-diff-tete {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2);
}

.ann-diff-niveau {
    font-size: var(--fs-small);
    font-weight: var(--fw-semibold);
    color: var(--an-ink);
}

/* « Sur les portails WiFi » : ce que le niveau le plus cher achète, et lui seul. */
.ann-diff-portails {
    padding: 2px 8px;
    border-radius: var(--r-full);
    background: color-mix(in srgb, var(--c-accent) 16%, transparent);
    color: var(--an-ink);
    font-size: var(--fs-caption);
    font-weight: var(--fw-semibold);
}

/* 🔑 LES JOURS RESTANTS EN GROS : la seule chose qu'on regarde sur une diffusion en cours. */
.ann-diff-restant {
    margin: var(--sp-2) 0 0;
    font-size: var(--fs-h4);
    font-weight: var(--fw-bold);
    color: var(--an-ink);
    font-variant-numeric: tabular-nums;
}

.ann-diff-finie {
    margin: var(--sp-2) 0 0;
    font-size: var(--fs-small);
    color: var(--an-dim);
}

.ann-diff-barre {
    block-size: 0.25rem;
    margin-top: var(--sp-2);
    border-radius: 999px;
    background: var(--an-line);
    overflow: hidden;
}

/* ⚠️ La barre montre le temps CONSOMMÉ, pas le restant : une barre qui se vide donnerait
   l'impression de perdre quelque chose à chaque jour qui passe. */
.ann-diff-barre span { display: block; block-size: 100%; background: var(--c-accent); }

/* Les détails en deux colonnes : libellé à gauche, valeur à droite, alignés d'une ligne à l'autre. */
.ann-diff-dl {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px var(--sp-3);
    margin: var(--sp-3) 0 0;
    font-size: var(--fs-caption);
}

.ann-diff-dl dt { color: var(--an-dim); }

.ann-diff-dl dd {
    margin: 0;
    color: var(--an-ink);
    font-variant-numeric: tabular-nums;
}

@media (max-width: 520px) {
    /* Sous 520 px, deux colonnes rendent les valeurs illisibles : on empile. */
    .ann-diff-dl { grid-template-columns: 1fr; gap: 0; }
    .ann-diff-dl dd { margin-bottom: var(--sp-2); }
}
