/*
 * WinetPay — Marché d'annonces (`.an-*`). 09-CDC-ADS.md, lot 1.
 *
 * IDENTITÉ (ADS-D20, et la règle « le thème possède la COULEUR, le style la FORME »).
 * On n'invente AUCUNE palette : 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 cette section, c'est sa FORME —
 * une grille dense de cartes photo, là où la boutique aligne des produits et le back-office des
 * tableaux. Ajouter une couleur ici reviendrait à ajouter un thème ; ce n'est pas ce qu'on fait.
 *
 * ⚠️ PIÈGE CONNU DU PROJET : la règle générique `button { background: var(--bo-primary) }` de
 * app.css fuit sur tout <button> non redéclaré. Chaque bouton stylé ici REDÉCLARE son fond, survol
 * compris.
 *
 * BUDGET (ADS-D31) : 250 Ko à la première vue. Cette feuille reste volontairement courte, et toutes
 * les animations passent par `transform`/`opacity` — zéro mise en page recalculée, le contrat de
 * performance déjà mesuré sur les écrans d'accès.
 */

/* ===== Scope ===== */
.an-scope {
    --an-ink: var(--c-text);
    --an-dim: var(--c-text-muted);
    --an-card: var(--c-surface);
    --an-line: var(--c-border);
    --an-solid: var(--c-primary-700);
    --an-radius: var(--r-lg);
    /* Durée unique : une seule valeur à changer pour calmer toute la section. */
    --an-dur: 160ms;
}

/* ===== Héros : la recherche, pas une bannière ===== */
/* ═══════════════════════════ LE HÉROS (§12.4) ═══════════════════════════
   « Recherche en évidence, catégories, annonces mises en avant — PAS une bannière décorative. »

   🔑 Tout le décor est en CSS : halo radial, grille, dégradé. Aucune image de fond. Le budget de
   250 Ko de la première vue (ADS-D31) appartient aux PHOTOS D'ANNONCES — une bannière qui le
   mangerait ferait descendre la seule chose que le visiteur est venu voir.

   Animations par `transform` et `opacity` uniquement, et respect de `prefers-reduced-motion` :
   contrat de performance déjà mesuré sur ce projet. */
.an-hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    padding: clamp(var(--sp-10), 7vw, 88px) 0 clamp(var(--sp-8), 5vw, 64px);
    background:
        radial-gradient(120% 100% at 12% 0%, color-mix(in srgb, var(--c-primary) 12%, transparent), transparent 60%),
        linear-gradient(180deg, var(--c-primary-50), var(--c-bg) 78%);
    border-bottom: 1px solid var(--an-line);
}

/* Halo ambré : la signature du marché d'annonces, comme le teal l'est pour la boutique. */
.an-hero-glow {
    position: absolute; z-index: -1; inset-block-start: -30%; inset-inline-end: -10%;
    width: min(560px, 70%); aspect-ratio: 1;
    background: radial-gradient(circle, color-mix(in srgb, var(--c-accent) 22%, transparent), transparent 68%);
    filter: blur(8px);
    pointer-events: none;
}

/* Trame fine : donne de la profondeur sans peser un octet de plus qu'un dégradé. */
.an-hero-grid {
    position: absolute; z-index: -1; inset: 0;
    background-image:
        linear-gradient(color-mix(in srgb, var(--c-primary) 6%, transparent) 1px, transparent 1px),
        linear-gradient(90deg, color-mix(in srgb, var(--c-primary) 6%, transparent) 1px, transparent 1px);
    background-size: 44px 44px;
    /* ⚠️ `black` n'est PAS une couleur ici : dans un masque, seule l'OPACITÉ compte — opaque au
       centre, transparent aux bords. Aucun pixel noir n'est peint, et le mot-clé évite l'hexa que
       la garde de marque refuse à juste titre sans pouvoir distinguer les deux usages. */
    mask-image: radial-gradient(80% 60% at 30% 0%, black, transparent 75%);
    pointer-events: none;
}

.an-hero-in {
    display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
    gap: var(--sp-8); align-items: center;
}

.an-hero-copy { min-width: 0; }

/* La preuve que le marché VIT : première question d'un visiteur qui ne connaît pas le site. */
.an-hero-badge {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    margin-block-end: var(--sp-4); padding: 6px 14px 6px 10px;
    background: var(--c-surface); color: var(--an-ink);
    border: 1px solid var(--an-line); border-radius: var(--r-full);
    box-shadow: var(--e1);
    font-size: var(--fs-caption); font-weight: var(--fw-semibold);
}

.an-hero-dot {
    width: 8px; height: 8px; border-radius: var(--r-full);
    background: var(--c-success);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--c-success) 22%, transparent);
}

.an-hero-t {
    margin: 0 0 var(--sp-3);
    font-size: clamp(2rem, 1.2rem + 3.2vw, 3.25rem);
    font-weight: var(--fw-bold);
    line-height: 1.08;
    letter-spacing: -.02em;
    color: var(--an-ink);
    text-wrap: balance;
}

.an-hero-s {
    max-width: 54ch;
    margin: 0 0 var(--sp-6);
    font-size: var(--fs-body);
    line-height: 1.6;
    color: var(--an-dim);
}

/* Les rubriques : un visiteur qui ne sait pas quoi taper doit pouvoir CLIQUER. */
.an-hero-tags {
    display: flex; flex-wrap: wrap; gap: var(--sp-2);
    margin-block-start: var(--sp-6);
}

.an-tag {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    padding: 8px 14px;
    background: var(--c-surface); color: var(--an-ink);
    border: 1px solid var(--an-line); border-radius: var(--r-full);
    font-size: var(--fs-small); font-weight: var(--fw-medium);
    text-decoration: none;
    transition: transform var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out);
}

.an-tag:hover { transform: translateY(-2px); border-color: var(--c-primary); box-shadow: var(--e2); }
.an-tag:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.an-tag.is-on { background: var(--c-primary); color: var(--c-text-inverse); border-color: var(--c-primary); }

/* Le compte par rubrique : il dit où il y a quelque chose à voir. */
.an-tag-n {
    padding: 1px 7px;
    background: color-mix(in srgb, var(--c-primary) 10%, transparent);
    border-radius: var(--r-full);
    font-size: var(--fs-caption); font-weight: var(--fw-semibold);
    color: var(--c-primary);
}

.an-tag.is-on .an-tag-n { background: color-mix(in srgb, var(--c-text-inverse) 22%, transparent); color: var(--c-text-inverse); }

.an-hero-media img {
    display: block; width: 100%; height: auto;
    filter: drop-shadow(0 24px 48px color-mix(in srgb, var(--c-primary) 18%, transparent));
}

/* ⚠️ SOUS 900 px, L'ILLUSTRATION DISPARAÎT. Sur un téléphone, l'espace au-dessus de la ligne de
   flottaison appartient à la recherche — pas à une image décorative qui la repousserait plus bas. */
@media (max-width: 900px) {
    .an-hero-in { grid-template-columns: 1fr; }
    .an-hero-media { display: none; }
    .an-hero-s { margin-block-end: var(--sp-6); }
}

@media (prefers-reduced-motion: reduce) {
    .an-tag { transition: none; }
    .an-tag:hover { transform: none; }
}

.an-search {
    position: relative;
    display: flex;
    gap: var(--sp-2);
    max-width: 640px;
}

/* La loupe DANS le champ : elle dit ce qu'on attend du visiteur sans consommer une ligne de texte.
   Purement décorative — le champ porte déjà son label (visuellement caché). */
.an-search-ico {
    position: absolute;
    inset-inline-start: 16px;
    inset-block-start: 50%;
    transform: translateY(-50%);
    display: flex;
    width: 20px; height: 20px;
    color: var(--an-dim);
    pointer-events: none;
}

.an-search-ico svg { width: 100%; height: 100%; }

.an-search-in {
    flex: 1 1 auto;
    min-width: 0;
    /* ⚠️ Retrait à gauche pour la loupe : sans lui, le curseur s'écrit PAR-DESSUS l'icône. */
    padding: 16px var(--sp-4) 16px 46px;
    font-size: 16px; /* < 16px : iOS zoome au focus et casse la mise en page */
    color: var(--an-ink);
    background: var(--an-card);
    border: 1px solid var(--an-line);
    border-radius: var(--r-lg);
    /* Surélevée : c'est l'élément central du héros, il doit flotter au-dessus du décor. */
    box-shadow: var(--e2);
    transition: box-shadow var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
}

.an-search-in:hover { border-color: color-mix(in srgb, var(--c-primary) 45%, var(--an-line)); }

.an-search-in:focus-visible {
    outline: 2px solid var(--c-focus);
    outline-offset: 2px;
}

.an-search-go {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    /* ≥ 44 px : cible tactile confortable. L'accessibilité EST le premium (§16.12). */
    min-height: 48px;
    padding: 0 var(--sp-5);
    font-weight: var(--fw-semibold);
    color: var(--c-text-inverse);
    background: var(--an-solid);
    border: 0;
    border-radius: var(--an-radius);
    cursor: pointer;
    transition: transform var(--an-dur) var(--ease-out);
}

.an-search-go:hover { background: color-mix(in srgb, var(--an-solid) 85%, black); }
.an-search-go:active { transform: scale(0.97); }
.an-search-go svg { width: 18px; height: 18px; }

@media (max-width: 520px) {
    .an-search-lbl { display: none; }
    .an-search-go { padding: 0 var(--sp-4); }
}

/* ===== Rubriques et lieux ===== */
.an-rubs,
.an-lieux {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin-bottom: var(--sp-4);
}

.an-rub,
.an-lieu {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 40px;
    padding: 0 var(--sp-4);
    font-size: var(--fs-small);
    font-weight: var(--fw-medium);
    color: var(--an-ink);
    text-decoration: none;
    background: var(--an-card);
    border: 1px solid var(--an-line);
    border-radius: var(--r-full);
    transition: border-color var(--an-dur) var(--ease-out), transform var(--an-dur) var(--ease-out);
}

.an-rub:hover,
.an-lieu:hover { border-color: var(--c-primary-400); }
.an-rub:active,
.an-lieu:active { transform: scale(0.97); }

.an-rub.is-on,
.an-lieu.is-on {
    color: var(--c-text-inverse);
    background: var(--an-solid);
    border-color: var(--an-solid);
}

.an-rub-n,
.an-lieu-n {
    font-variant-numeric: tabular-nums;
    opacity: 0.65;
}

.an-count {
    font-size: var(--fs-small);
    color: var(--an-dim);
    margin: 0 0 var(--sp-4);
}

.an-count-q { font-style: italic; }

/* ===== La grille ===== */
.an-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: var(--sp-4);
    list-style: none;
    margin: 0 0 var(--sp-8);
    padding: 0;
}

@media (max-width: 520px) {
    /* Deux colonnes sur téléphone : une seule colonne oblige à faire défiler pour voir trois
       annonces, et c'est ce défilement qui fait abandonner. */
    .an-grid { grid-template-columns: repeat(2, 1fr); gap: var(--sp-3); }
}

.an-card {
    background: var(--an-card);
    border: 1px solid var(--an-line);
    border-radius: var(--an-radius);
    overflow: hidden;
    transition: transform var(--an-dur) var(--ease-out), box-shadow var(--an-dur) var(--ease-out);
}

.an-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 24px rgb(0 0 0 / 12%);
}

/* Appui tactile : la réponse doit être IMMÉDIATE. Un retour qui traîne fait appuyer deux fois. */
.an-card:active { transform: scale(0.985); }

.an-card-l {
    display: block;
    color: inherit;
    text-decoration: none;
}

.an-card-l:focus-visible {
    outline: 2px solid var(--c-focus);
    outline-offset: -2px;
}

/*
 * 🔴 **LE CADRE DE LA CARTE EST FIXE, ET C'EST TOUT L'INVERSE DE LA FICHE.**
 *
 * ⛔ Le ratio réel de chaque photo était posé EN LIGNE sur l'image ; il gagnait donc sur le 4/3 de
 * cette feuille, et chaque carte prenait la hauteur de SA photo. Résultat, vu à la capture : une
 * grille en escalier, des cartes qui démarrent à des hauteurs différentes et se terminent n'importe
 * où. Rien dans le code ne le disait — le ratio « honnête » était même une intention.
 *
 * 🔑 **Une vignette n'est pas l'objet, c'est une porte vers lui.** Recadrer une carte de catalogue
 * est normal et attendu ; la fiche, elle, montre la photo entière (`object-fit: contain` + le ratio
 * réel). Les deux règles ne se contredisent pas, elles répondent à deux questions différentes.
 *
 * ⚠️ **C'est le PARENT qui porte le ratio maintenant.** L'image reçoit `height: 100%` : ses deux
 * dimensions deviennent définies, donc son `aspect-ratio` en ligne n'a plus d'effet — sans avoir à
 * écrire un `!important` contre le gabarit. La place reste réservée AVANT le chargement, donc rien
 * ne saute quand la photo arrive.
 */
.an-card-img {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    background: var(--c-neutral-100);
}

.an-card-img img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.an-card-nopic {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 4 / 3;
    color: var(--c-neutral-400);
}

.an-card-nopic svg { width: 34px; height: 34px; }

.an-badge {
    position: absolute;
    top: var(--sp-2);
    left: var(--sp-2);
    padding: 3px 9px;
    font-size: var(--fs-caption);
    font-weight: var(--fw-semibold);
    border-radius: var(--r-sm);
}

/* ADS-D5 : « Sponsorisé » est permanent et non désactivable — donc lisible, pas discret. */
.an-badge-avant {
    color: var(--c-text-inverse);
    background: var(--an-solid);
}

.an-badge-vendu {
    right: var(--sp-2);
    left: auto;
    color: var(--c-text-inverse);
    background: var(--c-neutral-700);
}

.an-card-body { padding: var(--sp-3); }

.an-card-t {
    font-size: var(--fs-small);
    font-weight: var(--fw-semibold);
    line-height: 1.35;
    margin: 0 0 6px;
    /* Deux lignes maximum : au-delà, les cartes d'une même rangée cessent d'être comparables. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.an-card-p {
    margin: 0 0 6px;
    font-size: var(--fs-small);
    color: var(--an-ink);
}

.an-card-p strong { font-weight: var(--fw-bold); }
.an-card-free { color: var(--c-success); }
.an-card-ask,
.an-card-neg { font-weight: var(--fw-regular); color: var(--an-dim); }

.an-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px var(--sp-2);
    margin: 0;
    font-size: var(--fs-caption);
    color: var(--an-dim);
}

/* ===== Pagination ===== */
.an-pages { margin-bottom: var(--sp-8); }

/* ===== État vide (ADS-D32) ===== */
.an-vide {
    text-align: center;
    padding: var(--sp-12) var(--sp-4);
}

.an-vide-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    margin-bottom: var(--sp-4);
    color: var(--c-primary-600);
    background: var(--c-primary-50);
    border-radius: var(--r-full);
}

.an-vide-ico svg { width: 26px; height: 26px; }

.an-vide-t {
    font-size: var(--fs-h3);
    font-weight: var(--fw-bold);
    margin: 0 0 var(--sp-2);
    text-wrap: balance;
}

.an-vide-s {
    max-width: 46ch;
    margin: 0 auto var(--sp-5);
    color: var(--an-dim);
}

.an-vide-actions,
.an-maint-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    justify-content: center;
}

.an-vide-rubs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    justify-content: center;
    list-style: none;
    margin: var(--sp-4) 0 0;
    padding: 0;
}

.an-vide-rubs a {
    display: inline-block;
    min-height: 40px;
    padding: 9px var(--sp-4);
    font-size: var(--fs-small);
    color: var(--an-ink);
    text-decoration: none;
    background: var(--an-card);
    border: 1px solid var(--an-line);
    border-radius: var(--r-full);
}

/* ===== Fiche ===== */
.an-fil {
    display: flex;
    gap: var(--sp-2);
    font-size: var(--fs-small);
    color: var(--an-dim);
    margin-bottom: var(--sp-4);
}

.an-fil a { color: inherit; }

.an-fiche-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(280px, 1fr);
    gap: var(--sp-6);
    margin-bottom: var(--sp-8);
}

@media (max-width: 860px) {
    .an-fiche-grid { grid-template-columns: 1fr; }
}

/*
 * LA PHOTO GARDE SA FORME (demande du propriétaire, 2026-08-30).
 *
 * 🔴 **`aspect-ratio: 4/3` + `object-fit: cover` ROGNAIT TOUTE PHOTO QUI N'ÉTAIT PAS EN 4/3.** Une
 * affiche verticale était amputée du haut et du bas, un panorama de ses côtés. On vend un OBJET :
 * le recadrer arbitrairement, c'est en montrer autre chose que ce qui est à vendre — et le vendeur
 * ne s'en aperçoit jamais, puisqu'il a vu sa photo entière au dépôt.
 *
 * 🔑 Le `aspect-ratio` réel est posé EN LIGNE par la vue, depuis les dimensions enregistrées à
 * l'envoi. Il gagne sur le 4/3 ci-dessous, qui ne sert plus que de repli pour les photos d'avant la
 * mesure. Le ratio est là AVANT le chargement : rien ne saute quand l'image arrive.
 *
 * ⚠️ **`max-height` EST INDISPENSABLE, ET ELLE EST LA RAISON DU `contain`.** Une photo prise au
 * téléphone en 9/16 occuperait sinon deux hauteurs d'écran à elle seule, et le prix comme le bouton
 * de contact passeraient sous la ligne de flottaison. La hauteur plafonnée déforme la boîte : sans
 * `contain`, `cover` reprendrait le rognage qu'on vient d'enlever.
 */
.an-gal-main {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    max-height: 72vh;
    object-fit: contain;
    background: var(--c-neutral-100);
    border-radius: var(--an-radius);
}

.an-gal-nopic {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 4 / 3;
    color: var(--c-neutral-400);
    background: var(--c-neutral-100);
    border-radius: var(--an-radius);
}

.an-gal-nopic svg { width: 48px; height: 48px; }

.an-gal-th {
    display: flex;
    gap: var(--sp-2);
    overflow-x: auto;
    list-style: none;
    margin: var(--sp-3) 0 0;
    padding: 0;
}

.an-gal-thb {
    padding: 0;
    background: none;
    border: 2px solid transparent;
    border-radius: var(--r-md);
    cursor: pointer;
    overflow: hidden;
    line-height: 0;
}

.an-gal-thb:hover { border-color: var(--c-primary-400); }

/* La vignette montre elle aussi la FORME : hauteur commune (la bande reste régulière), largeur
   libre jusqu'à un plafond. Un portrait se reconnaît donc AVANT le clic. */
.an-gal-thb img {
    width: auto;
    height: 58px;
    max-width: 104px;
    object-fit: contain;
    background: var(--c-neutral-100);
}

/* La vignette active : on doit savoir laquelle des huit photos est à l'écran. */
.an-gal-thb[aria-current="true"] { border-color: var(--an-solid); }

.an-info-t {
    font-size: var(--fs-h2);
    font-weight: var(--fw-bold);
    margin: 0 0 var(--sp-3);
    text-wrap: balance;
}

.an-info-p {
    font-size: var(--fs-h3);
    margin: 0 0 var(--sp-2);
}

.an-info-p strong { font-weight: var(--fw-bold); }
.an-info-neg { font-size: var(--fs-small); font-weight: var(--fw-regular); color: var(--an-dim); }

.an-info-meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
    margin: 0 0 var(--sp-5);
    font-size: var(--fs-small);
    color: var(--an-dim);
}

/* ===== Contact (ADS-D24) ===== */
.an-contact { margin-bottom: var(--sp-4); }

.an-contact-btn {
    min-height: 48px;
    color: var(--c-text-inverse);
    background: var(--an-solid);
    border: 0;
    cursor: pointer;
}

.an-contact-btn:hover { background: color-mix(in srgb, var(--an-solid) 85%, black); }

/*
 * 🔴 `:not([hidden])` — LA CINQUIÈME OCCURRENCE DU MÊME PIÈGE DANS CE PROJET.
 *
 * `[hidden] { display: none }` est une règle du NAVIGATEUR : sa spécificité est la plus faible qui
 * soit. Un simple `display: flex` sur la classe la bat, et l'élément reste VISIBLE malgré son
 * attribut `hidden`. Ici, cela afficherait le bloc du numéro — vide — avant même que quiconque ait
 * appuyé sur « Voir le numéro », et le compteur de contacts (ADS-D24) perdrait tout son sens.
 *
 * Le garde `HiddenIsReallyHiddenTest` l'a attrapé. Sans lui, personne ne l'aurait vu avant le terrain.
 */
.an-contact-out:not([hidden]) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-3);
}

.an-contact-tel {
    font-size: var(--fs-h4);
    font-weight: var(--fw-bold);
    color: var(--an-ink);
    text-decoration: none;
    font-variant-numeric: tabular-nums;
}

/* ===== Avertissements (§13.4, ADS-D28) ===== */
.an-warn {
    display: flex;
    gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-4);
    font-size: var(--fs-small);
    color: var(--an-ink);
    background: var(--c-warning-bg);
    border: 1px solid var(--c-warning);
    border-radius: var(--r-md);
    margin: 0 0 var(--sp-3);
}

.an-legal {
    font-size: var(--fs-caption);
    color: var(--an-dim);
    margin: 0;
}

.an-desc {
    max-width: 68ch;
    margin-bottom: var(--sp-6);
}

.an-desc h2,
.an-simil h2 {
    font-size: var(--fs-h4);
    font-weight: var(--fw-semibold);
    margin: 0 0 var(--sp-3);
}

.an-desc p {
    color: var(--an-ink);
    line-height: 1.65;
    /* Un mot très long tapé sans espace ne doit pas élargir la page. */
    overflow-wrap: break-word;
}

.an-report {
    margin: 0 0 var(--sp-8);
    font-size: var(--fs-small);
}

.an-report a { color: var(--an-dim); }

/* ===== Rideau ===== */
.an-maint {
    max-width: 560px;
    margin: 0 auto;
    text-align: center;
    padding: var(--sp-12) var(--sp-4);
}

.an-maint-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin-bottom: var(--sp-4);
    color: var(--c-primary-600);
    background: var(--c-primary-50);
    border-radius: var(--r-full);
}

.an-maint-ico svg { width: 30px; height: 30px; }

.an-eyebrow {
    display: block;
    font-size: var(--fs-caption);
    font-weight: var(--fw-semibold);
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--an-dim);
    margin-bottom: var(--sp-2);
}

.an-maint-msg { color: var(--an-dim); margin-bottom: var(--sp-5); }

.an-maint-perks {
    display: inline-block;
    text-align: left;
    color: var(--an-dim);
    font-size: var(--fs-small);
    margin: 0 0 var(--sp-6);
    padding-left: var(--sp-5);
}

.an-maint-perks li { margin-bottom: 6px; }

/* ===== Mouvement réductible =====
   Une animation qu'on ne peut pas refuser n'est pas premium (§16.12). Le mouvement disparaît,
   l'information reste : aucun état ne dépend d'une transition pour être lisible. */
@media (prefers-reduced-motion: reduce) {
    .an-scope *,
    .an-scope *::before,
    .an-scope *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
    }
}

/* ===== Signalement (§13.4) ===== */
.an-signal { max-width: 620px; }

.an-signal h1 {
    font-size: var(--fs-h2);
    font-weight: var(--fw-bold);
    margin: 0 0 var(--sp-2);
}

.an-signal-quoi {
    font-size: var(--fs-small);
    color: var(--an-dim);
    margin: 0 0 var(--sp-4);
}

.an-signal-intro {
    padding: var(--sp-3) var(--sp-4);
    font-size: var(--fs-small);
    background: var(--c-warning-bg);
    border: 1px solid var(--c-warning);
    border-radius: var(--r-md);
    margin-bottom: var(--sp-5);
}

.an-signal-motifs {
    border: 0;
    margin: 0 0 var(--sp-4);
    padding: 0;
}

.an-signal-motifs legend {
    font-weight: var(--fw-semibold);
    margin-bottom: var(--sp-2);
    padding: 0;
}

/* Cible tactile confortable : un choix qu'on rate deux fois est un signalement abandonne. */
.an-signal-motif {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    min-height: 44px;
    padding: 0 var(--sp-2);
    cursor: pointer;
}

.an-signal-lbl {
    display: block;
    font-weight: var(--fw-semibold);
    margin-bottom: var(--sp-2);
}

.an-signal-txt {
    width: 100%;
    padding: var(--sp-3);
    font: inherit;
    font-size: 16px; /* < 16px : iOS zoome au focus */
    color: var(--an-ink);
    background: var(--an-card);
    border: 1px solid var(--an-line);
    border-radius: var(--r-md);
    margin-bottom: var(--sp-4);
}

.an-signal-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-3);
}

/* Le bouton REDECLARE son fond : la regle generique de app.css fuit sinon (piege connu). */
.an-signal-go {
    min-height: 48px;
    color: var(--c-text-inverse);
    background: var(--an-solid);
    border: 0;
    cursor: pointer;
}

.an-signal-go:hover { background: color-mix(in srgb, var(--an-solid) 85%, black); }

/* Mention legale de pied de catalogue (ADS-D28) : discrete, jamais absente. */
.an-legal--pied {
    padding-top: var(--sp-4);
    border-top: 1px solid var(--an-line);
    text-align: center;
}

/* ═══════════════════════════ PARTAGER (§16.6) ═══════════════════════════

   🔑 **CHAQUE RÉSEAU GARDE SA COULEUR, MAIS SEULEMENT AU SURVOL.** Quatre pastilles pleines de
   vert, de bleu et de noir voleraient la vedette au bouton « Voir le numéro », qui est la seule
   action qui rapporte quelque chose au vendeur. Au repos : un contour neutre et le logo en gris.
   Au survol : le fond de la marque. On reconnaît le service, on ne se fait pas happer par lui.

   ⚠️ Ces couleurs sont les couleurs OFFICIELLES des marques, et elles ne suivent aucun thème :
   un WhatsApp violet ne serait plus WhatsApp. C'est la seule exception assumée à la règle « la
   couleur appartient au thème » — le logo d'un tiers n'est pas notre identité.

   ⚠️ Le bouton REDÉCLARE son fond (piège connu : `button { background: var(--bo-primary) }`
   d'app.css fuit sur tout bouton non redéclaré). */
.an-share {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--sp-2);
    margin-top: var(--sp-5);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--an-line);
}

.an-share-l {
    font-size: var(--fs-caption);
    color: var(--an-dim);
    margin-inline-end: var(--sp-1);
}

.an-share-b {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44 px : la cible tactile minimale. En dessous, on rate le bouton un essai sur trois. */
    width: 44px;
    height: 44px;
    padding: 0;
    color: var(--an-dim);
    background: var(--an-card);
    border: 1px solid var(--an-line);
    border-radius: var(--r-full);
    cursor: pointer;
    transition: color var(--an-dur) var(--ease-out),
                background-color var(--an-dur) var(--ease-out),
                border-color var(--an-dur) var(--ease-out),
                transform var(--an-dur) var(--ease-out);
}

.an-share-b svg { width: 20px; height: 20px; display: block; }

.an-share-b:hover,
.an-share-b:focus-visible { transform: translateY(-2px); }

.an-share-wa:hover, .an-share-wa:focus-visible {
    color: var(--c-neutral-0); background: var(--marque-whatsapp); border-color: var(--marque-whatsapp);
}

.an-share-fb:hover, .an-share-fb:focus-visible {
    color: var(--c-neutral-0); background: var(--marque-facebook); border-color: var(--marque-facebook);
}

/* X : noir en clair, blanc en sombre — sur un thème sombre, un rond noir disparaît dans le fond. */
.an-share-x:hover, .an-share-x:focus-visible {
    color: var(--c-surface); background: var(--c-text); border-color: var(--c-text);
}

.an-share-copy:hover, .an-share-copy:focus-visible {
    color: var(--c-text-inverse); background: var(--an-solid); border-color: var(--an-solid);
}

/* Le retour du copier : sans lui, le clic ne produit RIEN de visible et l'on recommence trois fois
   sans savoir si le lien est dans le presse-papier. */
.an-share-copy.is-ok {
    color: var(--c-text-inverse);
    background: var(--c-success);
    border-color: var(--c-success);
}

/* ═══════════════════════════ ANNONCES SIMILAIRES ═══════════════════════════

   🔑 **CE BLOC DOIT SE LIRE COMME UNE SUITE, PAS COMME UNE RÉPÉTITION.** Le visiteur arrive au bas
   d'une fiche : soit il repart, soit on lui montre la chose d'à côté. Un titre `h2` nu au-dessus
   d'une grille identique au catalogue ne dit pas « il y en a d'autres » — il dit « vous êtes
   revenu au début ».

   La séparation se fait par un FOND, pas par un trait : le bloc entier passe sur une teinte à peine
   plus soutenue, débordant la colonne de texte, et le regard comprend qu'il change de section.

   ⚠️ Le liseré du titre prend `--c-accent` — la couleur d'accent du THÈME choisi, pas une teinte
   écrite ici. Elle varie donc d'un exploitant à l'autre, et c'est voulu : la règle du projet veut
   que le thème possède la couleur. Deux pixels suffisent — et le titre reste lisible si elle ne
   charge pas. */
.an-simil {
    position: relative;
    /* ⚠️ `isolation` AVANT le `z-index: -1` du fond : sans contexte d'empilement propre, un fond en
       z-index négatif passe DERRIÈRE le fond d'un ancêtre et disparaît — sans la moindre erreur.
       Même montage que le héros, où le piège avait déjà été rencontré. */
    isolation: isolate;
    margin-top: var(--sp-10);
    padding: var(--sp-8) 0 var(--sp-2);
    border-top: 1px solid var(--an-line);
}

/*
 * 🔴 **CE FOND A DÉBORDÉ LA PAGE, ET DE 4 PIXELS SEULEMENT.**
 *
 * ⛔ Il s'étendait au-delà de la colonne (`inset-inline` négatif) pour « faire section ». Mesuré à
 * 375 px : `scrollWidth` 379 contre `clientWidth` 375 — la page entière gagnait un défilement
 * horizontal. Quatre pixels, invisibles à l'œil sur une capture, mais un doigt qui fait défiler
 * verticalement accroche et la page part de travers. Le catalogue, lui, mesurait 375 sur 375 : la
 * comparaison a désigné le coupable en une mesure.
 *
 * 🔑 Le fond reste DANS la colonne. La séparation tient au trait supérieur, à la teinte et au
 * liseré du titre — elle n'avait pas besoin du débordement.
 */
.an-simil::before {
    content: '';
    position: absolute;
    z-index: -1;
    inset-block: 0;
    inset-inline: 0;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--c-accent) 6%, transparent),
        transparent 62%);
    border-radius: var(--an-radius);
    pointer-events: none;
}

.an-simil h2 {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    font-size: var(--fs-h3);
    margin-bottom: var(--sp-5);
}

/* Le liseré : un trait court avant le titre, dans l'accent du thème. */
.an-simil h2::before {
    content: '';
    flex: none;
    width: 4px;
    height: 1.1em;
    background: var(--c-accent);
    border-radius: var(--r-full);
}

/*
 * L'ARRIVÉE EN CASCADE.
 *
 * ⚠️ `transform` et `opacity` UNIQUEMENT — le contrat de performance mesuré sur les écrans d'accès.
 * Animer `height` ou `top` ferait recalculer la mise en page à chaque image, sur la page qui en
 * porte déjà six.
 *
 * ⚠️ **L'ANIMATION PART DE `opacity: 0`, ET C'EST UN RISQUE À REGARDER EN FACE** : si elle ne
 * s'exécutait pas, les six cartes resteraient INVISIBLES. `animation-fill-mode: both` avec un état
 * final opaque garantit qu'un navigateur qui ignore l'animation affiche l'état final — et
 * `prefers-reduced-motion` ci-dessous la supprime SANS toucher à l'opacité.
 */
@keyframes an-simil-arrive {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

.an-simil .an-card {
    animation: an-simil-arrive 380ms var(--ease-out) both;
}

.an-simil .an-card:nth-child(1) { animation-delay: 0ms; }
.an-simil .an-card:nth-child(2) { animation-delay: 45ms; }
.an-simil .an-card:nth-child(3) { animation-delay: 90ms; }
.an-simil .an-card:nth-child(4) { animation-delay: 135ms; }
.an-simil .an-card:nth-child(5) { animation-delay: 180ms; }
.an-simil .an-card:nth-child(6) { animation-delay: 225ms; }

/* Le survol y est un cran plus marqué qu'au catalogue : ces cartes sont une PROPOSITION, elles ont
   le droit de répondre plus franchement. */
.an-simil .an-card:hover {
    transform: translateY(-5px);
    border-color: color-mix(in srgb, var(--c-accent) 45%, var(--an-line));
}

@media (prefers-reduced-motion: reduce) {
    .an-simil .an-card { animation: none; }
    .an-simil .an-card:hover { transform: none; }
    .an-share-b:hover, .an-share-b:focus-visible { transform: none; }
}
