/* Adjugé! — front. Extrait de app.css (Reset, variables, typographie, écrans (FONDATION)).
   Les app.*.css sont chargés DANS L'ORDRE (la cascade en dépend) ;
   ne pas réordonner les <link>. */
/* Adjugé! — styles mobile only, transposés de la maquette Claude Design.
   Palette : crème #FAF5EF, encre brune #221A12, orange logo #FD6802,
   rouge urgence #D7263D. Typographie : Archivo, chiffres tabulaires. */

:root {
  --bg: #FAF5EF;
  --bg-out: #EDE7DE;
  --ink: #221A12;
  --ink-soft: #4A4136;
  --orange: #FD6802;
  --orange-dark: #CC5402;
  --red: #D7263D;
  --muted: #8A7E70;
  --muted2: #A2937F;
  --faint: #C9BCA9;
  --line: #EBE1D4;
  --card-line: #EFE6D9;
  --chip-bg: #F3EAE0;
  --chip-ink: #6B5E4F;
  --green: #2F9E44;
  --green-ink: #2F7D44;
  --green-bg: #E5F2E4;
}

/* ---------- Marges de zone sûre (safe-area), routées par variables ----------
   TOUT le CSS lit `var(--sat)` / `var(--sab)` au lieu de `env(safe-area-inset-*)`
   en direct (encoche en haut, indicateur d'accueil en bas) → on peut NEUTRALISER
   la valeur du haut dans un seul endroit pour les navigateurs in-app.
   POURQUOI : un navigateur in-app (Instagram, Facebook, TikTok…) est une WKWebView
   EMBARQUÉE dont le contenu est TOUJOURS rendu SOUS la barre d'état système ET
   sous le bandeau de l'app hôte — la WebView ne possède JAMAIS l'encoche. Or, avec
   `viewport-fit=cover`, ces navigateurs signalent à tort un `safe-area-inset-top`
   ≈ hauteur d'encoche (~50-60 px) → une grosse bande VIDE en haut, sous le bandeau
   « vos-encheres.com » (cf. bug Instagram). `app.core.js::isInAppBrowser` pose alors
   la classe `iab` sur <html> et on remet `--sat` à 0 : le contenu se colle proprement
   sous le bandeau de l'app. SANS RISQUE ailleurs : un navigateur in-app qui rapporte
   déjà 0 ne change rien (override no-op) ; Safari/PWA/app native (qui possèdent
   réellement l'encoche) ne portent JAMAIS la classe `iab` → comportement inchangé.
   On ne touche PAS `--sab` (pas de bandeau en bas dans ces navigateurs → l'inset
   bas reste l'indicateur d'accueil, correct). */
:root { --sat: env(safe-area-inset-top); --sab: env(safe-area-inset-bottom); }
html.iab { --sat: 0px; }

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html { background: var(--bg-out); }
/* overflow-x: CLIP au niveau racine = pas de scroll/rubber-band HORIZONTAL du
   document sur la page d'accueil (iOS Safari laisse « glisser » la page sur le
   côté alors qu'il n'y a aucune page à gauche/droite — #app est déjà
   overflow:hidden, mais le document, lui, peut rebondir). Les carrousels internes
   (chips, catégories…) gardent leur propre overflow-x:auto.
   ⚠️ `clip` et NON `hidden` : `overflow-x: hidden` force `overflow-y` à `auto`
   (CSS), ce qui faisait de html/body un conteneur de défilement et CASSAIT le
   scroll molette du document sur Chrome desktop (le scroll programmatique
   marchait, mais pas la molette). `clip` bloque l'axe X SANS créer de conteneur
   → `overflow-y` reste `visible`, le scroll vertical normal est préservé. */
html, body { margin: 0; padding: 0; overflow-x: clip; }
body {
  font-family: 'Archivo', system-ui, sans-serif;
  color: var(--ink);
  background: var(--bg-out);
  /* Bloque le rebond élastique sur les DEUX axes (avant : axe Y seul). */
  overscroll-behavior: none;
}
/* Sur mobile (#app plein écran), le seul endroit où le fond racine apparaît est
   le rebond élastique vertical (overscroll iOS) en haut/bas : il doit matcher le
   crème du contenu, pas le gris du cadre desktop. DOIT venir APRÈS la règle
   `body { background: var(--bg-out) }` ci-dessus : une media query n'augmente pas
   la spécificité, donc à spécificité égale c'est l'ordre source qui tranche —
   placée avant, l'override était écrasé pour `body` (overscroll BAS gris, HAUT
   crème = couleurs différentes). Le cadre --bg-out ne sert qu'aux écrans larges
   (#app centré à 480px) ; on le garde au-delà. */
@media (max-width: 480px) { html, body { background: var(--bg); } }
#app {
  position: relative;
  max-width: 480px;
  margin: 0 auto;
  min-height: 100dvh;
  background: var(--bg);
  overflow: hidden;
}
button {
  font: inherit; color: inherit; background: none; border: none;
  padding: 0; cursor: pointer; touch-action: manipulation;
}
/* GARDE GLOBALE anti-zoom : un champ focalisé sous 16 px fait zoomer la
   page sur iOS Safari (sans retour arrière). Tout champ — présent ou
   futur — démarre à 16 px ; une règle plus spécifique peut grossir,
   JAMAIS réduire sous 16 px. */
input, select, textarea { font: inherit; font-size: 16px; color: var(--ink); }
h1, h2, p { margin: 0; }
[hidden] { display: none !important; }
/* Anti-flash au refresh sur une URL PROFONDE (/a/{id}, /regles, /profil…) :
   le serveur pose data-deep sur <body>, ce qui masque le feed (écran visible
   par défaut) dès le PREMIER paint — avant même que app.js s'exécute. Le JS
   route ensuite vers le bon écran puis retire data-deep. Sur l'accueil (pas
   de data-deep), le feed s'affiche normalement (aucun blanc). */
body[data-deep] #screen-feed { display: none !important; }
.spacer { flex: 1; }

@keyframes pricePulse { 0% { transform: scale(1); } 30% { transform: scale(1.09); color: var(--orange); } 100% { transform: scale(1); } }
@keyframes bidIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
@keyframes urgentPulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(215,38,61,0.45); } 50% { box-shadow: 0 0 0 8px rgba(215,38,61,0); } }
@keyframes livePulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@keyframes confFall { from { transform: translateY(-40px) rotate(0deg); } to { transform: translateY(110vh) rotate(560deg); } }
/* La feuille est centrée par translateX(-50%) : les keyframes doivent le
   conserver, sinon l'animation écrase le centrage. */
@keyframes sheetUp { from { transform: translate(-50%, 70px); opacity: 0; } to { transform: translate(-50%, 0); opacity: 1; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes toastIn { from { opacity: 0; transform: translate(-50%, -10px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes popIn { 0% { transform: scale(0.5); opacity: 0; } 60% { transform: scale(1.07); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }

/* ---------- Badge favori (cœur + nombre, façon Vinted) ----------
   Pilule blanche cliquable, posée en bas à droite de l'image (sur les cartes
   .g-fav-badge comme sur la fiche .d-fav-badge — positions/tailles définies
   dans app.feed.css / app.detail.css). Cœur ROUGE quand l'annonce est dans
   MES favoris, contour grisé sinon ; le nombre est le compteur GLOBAL,
   masqué à 0. Le conteneur image est position:relative. */
.fav-badge {
  position: absolute; z-index: 2;
  display: inline-flex; align-items: center; gap: 4px;
  border-radius: 999px; background: rgba(255,255,255,0.95);
  box-shadow: 0 2px 8px rgba(0,0,0,0.14);
  color: var(--ink); font-weight: 800; font-variant-numeric: tabular-nums;
  cursor: pointer; user-select: none; transition: transform 0.1s;
}
.fav-badge:active { transform: scale(0.9); }
.fav-badge .fav-heart { color: var(--muted); line-height: 1; }
.fav-badge.on .fav-heart { color: var(--red); }
.fav-badge .fav-n { line-height: 1; }

/* ---------- Badge « Vendeur Top Fiabilité » (façon Top Rated Seller eBay) ----
   Pastille de confiance vert sapin (DISTINCTE de l'ambre « ⭐ À la une » du
   boost pour ne pas les confondre), posée en ligne après le nom du vendeur sur
   la carte fiche (#d-seller-name) et le profil (#sp-name). Affichée seulement
   quand le serveur dérive seller.top_seller (avis + ventes conclues). */
.tsbadge {
  display: inline-flex; align-items: center; gap: 3px;
  margin-left: 6px; padding: 2px 7px; border-radius: 999px;
  background: linear-gradient(135deg, #1FB47A, #0E8C5E); color: #FFFFFF;
  font-size: 10px; font-weight: 800; line-height: 1.4;
  vertical-align: middle; white-space: nowrap;
}
.tsbadge-txt { font-size: 10px; }

/* ---------- Écrans ---------- */
.screen { min-height: 100dvh; }
#screen-search, #screen-sell {
  padding-top: calc(8px + var(--sat));
  padding-bottom: calc(110px + var(--sab));
}
/* ---------- Logo de marque cliquable (`.brand-home`) ----------
   Le logo en haut à GAUCHE ramène à l'accueil au tap (comme un logo de site).
   Présent sur l'accueil/profil/mes enchères/mes annonces (en-tête flottant,
   `.feed-brand-logo`) ET sur les écrans-onglets recherche/vendre/messages
   (`.head-logo`, posé dans leur barre de titre). Les écrans à BOUTON RETOUR
   n'en portent pas (le retour suffit). cursor + petit retour tactile au tap. */
.brand-home { cursor: pointer; transition: transform 0.1s; }
.brand-home:active { transform: scale(0.93); }
/* Logo posé dans une barre de titre simple (≠ en-tête flottant) : même badge
   blanc arrondi que `.feed-brand-logo`, taille 36, ne rétrécit jamais. */
.head-logo {
  flex: none; width: 36px; height: 36px; border-radius: 11px;
  object-fit: cover; background: #FFFFFF;
}
/* L'accueil porte un en-tête FLOTTANT plein (.float-header : logo + chips, ≈ 54px)
   qui flotte PAR-DESSUS le contenu. Le padding-top doit dégager la HAUTEUR du
   header PLUS une vraie respiration, sinon le 1ᵉʳ titre de section colle au header
   (et paraît tronqué quand la barre d'adresse de Safari empiète au scroll). */
#screen-feed {
  padding-top: calc(64px + var(--sat));
  padding-bottom: calc(110px + var(--sab));
}
/* Le profil porte le MÊME logo flottant, mais SEUL (pas de chips/titre) : il ne
   doit donc PAS réserver une bande vide à lui tout seul. Le contenu remonte près
   du haut et le logo FLOTTE par-dessus le COIN HAUT-GAUCHE BLANC de la carte
   identité (il s'y fond — look intentionnel) ; l'avatar (62px) passe JUSTE sous
   le logo (≈ 47px de bas). */
#screen-profile {
  padding-top: calc(20px + var(--sat));
  padding-bottom: calc(110px + var(--sab));
}
/* Animation d'entrée au SWITCH d'onglet (façon Betclic) : le nouvel écran
   glisse depuis la droite + apparaît en fondu. Déclenchée par show()
   (app.core.js) via la classe .screen-anim, RETIRÉE en fin d'anim (un transform
   résiduel ferait office de containing block et casserait le position:fixed
   d'éventuels descendants). #app a overflow:hidden → aucun scroll horizontal
   pendant le glissé. La tabbar est un frère des écrans → elle ne bouge pas. */
@keyframes screenIn {
  from { opacity: 0; transform: translate3d(20px, 0, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
.screen-anim { animation: screenIn 0.40s cubic-bezier(0.22, 0.9, 0.32, 1) both; }
@media (prefers-reduced-motion: reduce) { .screen-anim { animation: none; } }

/* Icône BOUCLIER (frais de protection acheteur) en SVG inline plutôt qu'un
   emoji 🛡 : l'emoji ne se rend pas sur certains navigateurs desktop (tofu
   affichant « 01F6E1 »). Hérite couleur (currentColor) et taille (1em). */
.shield-ic { display: inline-flex; align-items: center; vertical-align: -0.15em; }
.shield-ic svg { width: 1em; height: 1em; display: block; }

