/*
 * WinetPay — « L'ONDE », la scène du marché d'annonces.
 *
 * 🔴 **HUIT DESSINS REFUSÉS AVANT CELUI-CI** (2026-09-03 → 2026-09-04) : téléphone, cartes
 * d'articles, portail seul, place du marché, collage typographique, constellation d'icônes, rue
 * connectée, puis la mosaïque de six tuiles de verre. Leur point commun, que personne n'avait
 * nommé : **ils étaient tous PLATS.** De l'illustration vectorielle posée sur un fond. Celle-ci
 * change de traitement — profondeur, lumière, mouvement — avant de changer de sujet.
 *
 * 🔑 **CE QU'ELLE RACONTE EST LE MÉCANISME DE LA PAGE** : une étiquette de prix (ce qui se vend),
 * une onde qui en part (la diffusion sur le réseau), des marques WiFi qui s'allument une à une (les
 * portails), deux points qui reviennent (les contacts). Voir le partiel pour le détail.
 *
 * ⚠️ **LE DÉGRADÉ EST DANS L'IMAGE, PAS DERRIÈRE LA PAGE.** Le fond du héros est nu, comme celui de
 * la boutique — mesuré sur les deux pages en production. La couleur a changé de place, elle n'a pas
 * disparu : une toile calme, un sujet riche.
 *
 * 🔴 **CETTE FEUILLE EXISTE PARCE QUE LA SCÈNE SERT DEUX PAGES QUI NE CHARGENT PAS LES MÊMES
 * STYLES.** Le partiel est inclus par `/annonces` ET par la page d'accueil. La première charge
 * `annonces.css`, la seconde non : la scène y arriverait SANS AUCUN STYLE.
 *
 * ⚠️ **PAS DANS `annonces.css`, ET C'EST DÉLIBÉRÉ.** ADS-D31 borne le poids de la première vue du
 * CATALOGUE ; charger toute la feuille du marché sur la page d'accueil pour un décor mangerait ce
 * budget ailleurs, pour rien.
 *
 * ⚠️ Animations par `transform` et `opacity` uniquement — le contrat de performance mesuré sur les
 * écrans d'accès.
 */

/*
 * ═══ LE GARDE-FOU `[hidden]`, EN TÊTE DE FEUILLE ═══
 *
 * 🔴 **ONZE OCCURRENCES DU MÊME PIÈGE SUR CE PROJET.** `[hidden] { display: none }` est une règle du
 * NAVIGATEUR : sa spécificité est la plus faible qui soit. La moindre règle de classe qui pose un
 * `display:` la bat, et l'élément reste rendu — invisible à la relecture, et parfaitement capable de
 * capter les clics de toute la page. Un test du projet le vérifie sur CHAQUE feuille.
 */
[hidden] { display: none !important; }


/* ═══════════════════ LA TOILE ═══════════════════ */
.an-scene {
    position: relative;
    inline-size: 100%;
    aspect-ratio: 4 / 3;
    max-block-size: 380px;

    /*
     * 🔴 **AUCUN RETRAIT, ET C'EST LE CHANGEMENT QUI PORTE L'EFFET.** La mosaïque vivait dans un
     * cadre de 30 px, ce qui la faisait lire comme un contenu POSÉ SUR une toile. Une onde, elle,
     * doit sortir du cadre : c'est ce débordement qui donne l'échelle du réseau. Le dessin remplit
     * donc la toile bord à bord, et `overflow: hidden` coupe ce qui dépasse.
     */
    padding: 0;
    overflow: hidden;

    /*
     * 🔑 **LE DÉGRADÉ SUIT LE THÈME.** Indigo → teal sur le thème par défaut, mais les deux couleurs
     * viennent de la marque : écrites en dur, elles auraient survécu au rebranding et menti sur les
     * huit thèmes.
     */
    background:
        radial-gradient(120% 90% at 12% 8%, color-mix(in srgb, var(--c-primary) 22%, transparent), transparent 58%),
        linear-gradient(142deg, var(--c-primary), var(--c-accent));

    border-radius: clamp(20px, 3vw, 30px);
    box-shadow: 0 26px 60px color-mix(in srgb, var(--c-primary) 26%, transparent);
}

.an-onde {
    display: block;
    inline-size: 100%;
    block-size: 100%;
}


/* ═══════════════════ LES COULEURS TEINTÉES ═══════════════════

   🔴 **AUCUNE COULEUR EN DUR, NULLE PART** : un garde-fou du projet interdit l'hexadécimal hors de
   la source de marque, et il a refusé la première version de cette scène. Les blancs du dessin
   passent donc par `--c-neutral-0` — jamais par `--c-text-inverse`, qui vaut un quasi-noir en thème
   sombre et retournerait toute l'illustration.

   Ce qui est TEINTÉ vit ici, et donc suit `--c-primary`. */

.an-etiq-teinte { stop-color: color-mix(in srgb, var(--c-primary) 7%, var(--c-neutral-0)); }
.an-etiq-filet { stroke: var(--c-primary); stroke-opacity: .13; }
.an-etiq-oeil { fill: var(--c-primary); fill-opacity: .1; }

.an-etiq-prix {
    /* ⚠️ `font-family` héritée : le texte d'un SVG en ligne suit la police du document, et c'est
       voulu — le prix doit être de la même famille que le titre à côté de lui. */
    font-family: inherit;
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -.5px;
    fill: var(--c-primary);
}


/* ═══════════════════ LE MOUVEMENT ═══════════════════
   ⚠️ `transform-box: view-box` est INDISPENSABLE sur chaque élément animé : sans lui,
   `transform-origin` se calcule dans la boîte de l'élément et non dans le repère du dessin — les
   fronts d'onde partiraient chacun d'un centre différent. */

.an-front {
    transform-box: view-box;
    transform-origin: 220px 166px;
    animation: an-front 6s cubic-bezier(.2, .55, .3, 1) infinite;
}

/* Un quart de cycle entre deux fronts : le quatrième entre quand le premier s'éteint. */
.an-front:nth-of-type(2) { animation-delay: 1.5s; }
.an-front:nth-of-type(3) { animation-delay: 3s; }
.an-front:nth-of-type(4) { animation-delay: 4.5s; }

@keyframes an-front {
    0% { transform: scale(.28); opacity: 0; }
    12% { opacity: .9; }
    72% { opacity: .25; }
    100% { transform: scale(1.42); opacity: 0; }
}

.an-portail {
    transform-box: view-box;
    transform-origin: center;
    animation: an-portail 6s ease-in-out infinite;
}

@keyframes an-portail {
    0%, 100% { opacity: .3; transform: scale(.9); }
    12% { opacity: 1; transform: scale(1.12); }
    34% { opacity: .3; transform: scale(.9); }
}

.an-etincelle {
    transform-box: view-box;
    transform-origin: center;
    animation: an-etincelle 6s ease-in-out infinite;
}

@keyframes an-etincelle {
    0%, 100% { opacity: .2; }
    16% { opacity: .9; }
    40% { opacity: .2; }
}

.an-flot {
    transform-box: view-box;
    transform-origin: center;
    animation: an-flot 8s ease-in-out infinite;
}

/* ⚠️ Huit secondes contre six pour l'onde : deux cycles qui ne retombent jamais ensemble donnent
   une scène qui paraît vivante. Des durées égales font battre tout le dessin au même rythme. */
@keyframes an-flot {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-6px); }
}

.an-retour {
    opacity: 0;
    animation: an-retour 6s linear infinite;
}

@keyframes an-retour {
    0% { opacity: 0; }
    8% { opacity: 1; }
    80% { opacity: 0; }
    100% { opacity: 0; }
}

.an-lustre {
    transform-box: view-box;
    transform-origin: center;
    animation: an-lustre 8s ease-in-out infinite;
}

@keyframes an-lustre {
    0%, 100% { transform: translateX(-105px); }
    50% { transform: translateX(105px); }
}


/* ═══════════════════ SUR TÉLÉPHONE ═══════════════════

   ⚠️ **CES SURCHARGES SONT *APRÈS* CE QU'ELLES SURCHARGENT.** Écrites plus haut, elles seraient
   battues par la règle de base — même spécificité, et c'est la dernière déclarée qui gagne. Une
   requête média ne donne aucun poids supplémentaire. Défaut mesuré en production le 2026-09-04 :
   la scène rendait 320 px sur téléphone au lieu de 210.

   🔑 **LE DESSIN N'A PLUS BESOIN D'ÊTRE RÉGLÉ PIÈCE PAR PIÈCE.** La mosaïque demandait six règles de
   taille sur téléphone (tuiles, icônes, prix, lignes) ; une scène en SVG se contente d'un rapport
   et d'une hauteur — `slice` recadre, tout le reste suit. */
@media (max-width: 900px) {
    .an-scene {
        max-inline-size: 380px;
        margin-inline: auto;
        aspect-ratio: 16 / 10;
        max-block-size: 215px;
    }
}

/*
 * ═══ LES ÉCRANS COURTS — mesurés, pas devinés ═══
 *
 * 🔴 **SUR UN IPHONE SE (375 × 667), LA RECHERCHE RESTAIT SOUS LA LIGNE DE FLOTTAISON.** Mesuré :
 * visible à 360 et 390 px de large, invisible à 375 — parce que cet appareil-là est le plus COURT
 * (667 px), pas le plus étroit. C'est la hauteur qui manquait, pas la largeur.
 *
 * ⚠️ **LA REQUÊTE PORTE DONC SUR `max-height`, PAS SUR `max-width`.** Une règle de largeur n'aurait
 * jamais attrapé ce cas : 375 est plus large que 360, où tout tenait. Se tromper de dimension, c'est
 * corriger les appareils qui vont bien et laisser celui qui ne va pas.
 *
 * ⚠️ **CES PALIERS RESTENT UTILES MÊME DEPUIS QUE LA RECHERCHE A QUITTÉ LE HÉROS** (2026-09-04) :
 * ce n'est plus le champ qu'ils protègent, c'est le TITRE et le bouton de dépôt. Une image qui
 * occupe la moitié d'un écran de 640 px repousse la promesse hors de vue.
 */
@media (max-width: 900px) and (max-height: 700px) {
    .an-scene { max-block-size: 180px; }
}

/*
 * ═══ ET LES PLUS COURTS ENCORE (≤ 660 px) ═══
 *
 * 🔴 **MESURÉ EN PRODUCTION SUR 360 × 640**, le plus court des écrans courants.
 *
 * ⚠️ **CETTE RÈGLE DOIT VIVRE ICI, PAS DANS `annonces.css`.** J'y avais d'abord écrit
 * `.an-scene { max-block-size: 164px }` — sans effet : le partiel charge CETTE feuille APRÈS
 * l'autre, et à spécificité égale c'est le dernier fichier qui gagne. Même piège que l'ordre des
 * règles, mais entre deux fichiers cette fois.
 */
@media (max-width: 900px) and (max-height: 660px) {
    .an-scene { max-block-size: 150px; }
}


/* ⚠️ **LE MOUVEMENT EST UN AGRÉMENT.** Il ne porte aucune information que la scène ne montre déjà à
   l'arrêt — c'est la condition pour pouvoir le couper sans rien perdre.

   🔴 **LES ÉLÉMENTS ANIMÉS DEPUIS `opacity: 0` DOIVENT ÊTRE RENDUS VISIBLES.** Couper l'animation
   les laisserait éteints pour toujours : les quatre fronts d'onde et les deux contacts
   disparaîtraient, et il ne resterait qu'une étiquette seule au milieu d'un aplat. On fige donc un
   ÉTAT LISIBLE — un seul front d'onde visible, les portails allumés, les contacts effacés (ils ne
   veulent rien dire immobiles). */
@media (prefers-reduced-motion: reduce) {
    .an-front,
    .an-portail,
    .an-etincelle,
    .an-flot,
    .an-retour,
    .an-lustre { animation: none; }

    .an-front { opacity: 0; transform: scale(1); }
    .an-front:nth-of-type(3) { opacity: .45; }
    .an-portail { opacity: .85; transform: none; }
    .an-etincelle { opacity: .5; }
    .an-retour { opacity: 0; }
}

/* Décalages portés par des CLASSES (2026-09-16) : la CSP des pages publiques refuse les attributs
   style. Placés en FIN de feuille : le raccourci `animation:` plus haut remet le délai à zéro. */
.an-sc-d07 { animation-delay: .7s; }
.an-sc-d10 { animation-delay: 1s; }
.an-sc-d13 { animation-delay: 1.3s; }
.an-sc-d15 { animation-delay: 1.5s; }
.an-sc-d17 { animation-delay: 1.7s; }
.an-sc-d21 { animation-delay: 2.1s; }
.an-sc-d23 { animation-delay: 2.3s; }
.an-sc-d24 { animation-delay: 2.4s; }
.an-sc-d25 { animation-delay: 2.5s; }
.an-sc-d29 { animation-delay: 2.9s; }
.an-sc-d30 { animation-delay: 3s; }
.an-sc-d33 { animation-delay: 3.3s; }
.an-sc-d36 { animation-delay: 3.6s; }
.an-sc-d44 { animation-delay: 4.4s; }
.an-sc-d46 { animation-delay: 4.6s; }
