/* ══════════════════════════════════════════════════════
   DarJadida — LOT 3 : Cards annonces
   Namespace .dj-card  ·  tokens --dj-*  (LOT 1 requis)
   RTL via propriétés logiques CSS (inset-inline-*)
══════════════════════════════════════════════════════ */

/* Couleurs opération : voir darjadida-tokens.css (--dj-op-*), seule
   source depuis le retrait du doré 2026-08-25 — ce fichier dupliquait
   ces 5 variables en local (et divergeait meme sur --dj-op-cherche). */

/* ── Card wrapper ────────────────────────────────────── */
/* position:relative : ancre le stretched-link du bouton "Voir l'annonce"
   (§2.6 du plan) — sans ça il se limiterait au 1er ancêtre positionné
   rencontré (.dj-card-img), pas toute la carte. */
.dj-card {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    background: #fff;
    border-radius: var(--dj-radius-lg, 14px);
    box-shadow: var(--dj-shadow-card, 0 2px 12px rgba(0,0,0,.07));
    overflow: hidden;
    transition: transform .2s, box-shadow .2s;
    text-decoration: none;
    color: inherit;
}
.dj-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 12px 32px rgba(0,0,0,.13);
    color: inherit;
    text-decoration: none;
}

/* ── Zone photo ───────────────────────────────────────
   aspect-ratio remplace la hauteur fixe : réserve l'espace AVANT
   chargement quelle que soit la vraie dimension du fichier (CLS),
   s'adapte à la largeur de colonne responsive plutôt qu'un px figé. */
.dj-card-img {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--dj-gris-100, #f4f5f8);
    overflow: hidden;
    flex-shrink: 0;
}
.dj-card-img > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .3s;
}
.dj-card:hover .dj-card-img > img { transform: scale(1.06); }

/* Placeholder "pas de photo" — motif plat des 8 fenêtres du logo sur fond
   clair (34,6 % des annonces). Remplace l'ancien dégradé vert : il violait
   la règle "pas de dégradé" et posait du blanc sur --dj-vert-clair (~3:1,
   sous le seuil AA). Le texte SEO indexable reste construit par
   partials/_annonce_fallback.php. Fond, texte et carrés : tokens
   uniquement, aucune couleur en dur. */
.dj-card-nophoto {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    gap: var(--dj-space-3);
    padding: var(--dj-space-4) var(--dj-space-3);
    text-align: center;
    background: var(--dj-gris-50);
}

/* Les 8 fenêtres du logo (2 groupes de 4) — motif plat, purement
   décoratif : le conteneur porte aria-hidden dans le partial.
   Grille symétrique 4×2 → rien à inverser en RTL. */
.dj-card-nophoto .dj-nophoto-motif {
    display: grid;
    grid-template-columns: repeat(4, 13px);
    grid-template-rows: repeat(2, 13px);
    gap: 6px;
}
.dj-card-nophoto .dj-nophoto-motif span {
    background: var(--dj-gris-300);   /* repli : navigateurs sans color-mix() */
    background: color-mix(in srgb, var(--dj-vert) 22%, var(--dj-surface));
    border-radius: 1px;
}

/* 4,61:1 sur --dj-gris-50 → AA tenu pour du texte normal à 11px. */
.dj-card-nophoto .dj-nophoto-label {
    font-size: 11px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--dj-gris-500);
}
.dj-card-nophoto .dj-nophoto-type {
    font-size: 14px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--dj-gris-900);
}
.dj-card-nophoto .dj-nophoto-loc {
    font-size: 12px;
    line-height: 1.3;
    color: var(--dj-gris-700);
}

/* Arabe : ni tracking ni capitales. L'écriture arabe est cursive — le
   letter-spacing casse les liaisons entre lettres, et text-transform
   n'a aucun effet sur un alphabet sans casse. Même précédent que le
   § RTL de darjadida-nav.css. */
html[dir="rtl"] .dj-card-nophoto .dj-nophoto-label {
    letter-spacing: 0;
    text-transform: none;
}

/* ── Badge opération (haut-start) ────────────────────── */
.dj-badge-op {
    position: absolute;
    top: 10px;
    inset-inline-start: 10px;
    padding: 4px 10px;
    border-radius: 6px;
    font-size: 11px;
    font-weight: 700;
    color: #fff;
    line-height: 1.5;
    white-space: nowrap;
    pointer-events: none;
}
.dj-op-vente    { background: var(--dj-op-vente); }
.dj-op-location { background: var(--dj-op-location); }
.dj-op-vacances { background: var(--dj-op-vacances); }
.dj-op-echange  { background: var(--dj-op-echange); }
.dj-op-cherche  { background: var(--dj-op-cherche); }

/* Badge opération redescendu quand le badge "Nouveau" prend sa place
   habituelle (haut-start) — les 2 ne se chevauchent jamais. */
.dj-badge-op.dj-shifted { margin-top: 32px; }

/* ── Badge "Nouveau" (haut-start, rouge drapeau — created_at < 14j,
   calculé, aucune colonne BDD) ───────────────────────── */
.dj-badge-new {
    position: absolute;
    top: 10px;
    inset-inline-start: 10px;
    background: var(--dj-rouge, #C8102E);
    color: #fff;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .03em;
    padding: 5px 11px;
    border-radius: 6px;
    box-shadow: 0 2px 8px rgba(200, 16, 46, .4);
    pointer-events: none;
    z-index: 1;
}

/* ── Badge référence (haut-end) ──────────────────────── */
.dj-badge-ref {
    position: absolute;
    top: 10px;
    inset-inline-end: 10px;
    /* Fond OPAQUE et non plus un voile noir a 45 %. Le voile laissait
       passer ce qu'il y avait dessous : sur une photo claire le composite
       montait a rgb(140,140,140) et --dj-vert-clair n'y mesurait plus que
       1,12:1 (1,21:1 sur le gris de carte) — le numero etait illisible.
       Une surface sombre franche rend le contraste independant de la
       photo : 5,47:1 dans tous les cas, conforme a la regle CLAUDE.md
       « --dj-vert-clair est le seul accent autorise sur fond sombre ».
       Une variante translucide a ete calculee puis ecartee : meme a 92 %
       d'opacite elle retombe a 4,33:1 sur une photo blanche, sous AA. */
    background: var(--dj-surface-sombre);
    color: var(--dj-vert-clair, #66A185);
    font-size: 10px;
    font-weight: 700;
    /* Chiffres tabulaires : le numero de reference est un nombre,
       il s'aligne d'une carte a l'autre (cf .dj-nums, tokens). */
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    padding: 3px 8px;
    border-radius: 5px;
    white-space: nowrap;
    pointer-events: none;
}

/* ── Bouton favoris (bas-end) ────────────────────────── */
/* z-index > le stretched-link du bouton "Voir l'annonce" (z-index:1,
   Bootstrap) : sans ça, le clic irait au détail au lieu du favori. */
.dj-btn-fav {
    position: absolute;
    bottom: 10px;
    inset-inline-end: 10px;
    width: 36px;
    height: 36px;
    min-width: 36px;
    border-radius: 50%;
    background: rgba(255,255,255,.92);
    border: none;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 16px;
    color: var(--dj-rouge, #C8102E);
    box-shadow: 0 2px 6px rgba(0,0,0,.15);
    transition: transform .15s, background .15s;
    line-height: 1;
    z-index: 2;
}
.dj-btn-fav:hover { transform: scale(1.12); background: #fff; }
.dj-btn-fav:focus-visible {
    outline: 2px solid var(--dj-vert-clair, #66A185);
    outline-offset: 2px;
}

/* ── Corps (flex-grow pour aligner les footers) ─────── */
.dj-card-body {
    flex: 1;
    padding: 14px 16px 10px;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

/* Type de bien */
.dj-card-type {
    font-size: 11px;
    color: var(--dj-gris-500, #888);
    display: flex;
    align-items: center;
    gap: 4px;
}
.dj-card-type i { color: var(--dj-vert, #006233); font-size: 11px; }

/* Titre */
.dj-card-title {
    font-family: var(--dj-font-titre, 'Manrope', sans-serif);
    font-size: 14.5px;
    font-weight: 600;
    color: var(--dj-dark, #1A1F2E);
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: 0;
}

/* Localisation — puce "16 | Alger, Hydra" (livrable Claude Design).
   Le numero de wilaya est un repere national immediat pour le public
   algerien ; il abrege un nom deja present a cote, il ne le remplace
   pas.
   align-self: flex-start — .dj-card-body est un flex column, sans ca
   la puce s'etirerait sur toute la largeur au lieu d'epouser son
   contenu. max-width/min-width: la puce cede avant de deborder, c'est
   le libelle qui s'ellipse (voir .dj-card-loc-txt).
   Paddings SYMETRIQUES partout : aucune propriete directionnelle a
   inverser en RTL. */
.dj-card-loc {
    font-size: 12px;
    color: var(--dj-gris-700, #444);
    display: inline-flex;
    align-items: stretch;
    align-self: flex-start;
    max-width: 100%;
    min-width: 0;
    margin: 0;
    border: 1px solid var(--dj-gris-300, #D1D5DB);
    border-radius: var(--dj-radius-sm, 4px);
    overflow: hidden;
}
.dj-wilaya-num {
    flex: none;
    display: inline-flex;
    align-items: center;
    padding: 2px 6px;
    background: var(--dj-surface-sombre);
    color: var(--dj-surface);
    font-weight: 700;
    font-size: 11px;
    /* Blanc sur --dj-dark : 16,41:1 (calcule). */
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}
.dj-card-loc-txt {
    min-width: 0;
    padding: 2px 8px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Repli sans numero : l'epingle prend la place du bloc sombre. */
.dj-card-loc > i {
    color: var(--dj-vert, #006233);
    flex-shrink: 0;
    font-size: 12px;
    display: inline-flex;
    align-items: center;
    padding-inline-start: 6px;
}

/* Pills caractéristiques (pièces, surface) */
.dj-card-features {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin: 2px 0;
}
.dj-pill {
    background: var(--dj-gris-100, #f4f5f8);
    color: var(--dj-gris-700, #555);
    border-radius: 20px;
    padding: 3px 10px;
    font-size: 11.5px;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    white-space: nowrap;
    /* Surfaces et nombres de pieces alignes verticalement dans la grille. */
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}
.dj-pill i { font-size: 10px; opacity: .65; }

/* Pastille d'ABSENCE — ni surface ni pieces renseignees : 281 des
   1 190 annonces publiques, soit 23,6 % (mesure du 12/09/2026). Elle occupe la place des pills de donnees pour que la
   ligne existe toujours : sans elle, le prix des cartes d'une meme
   rangee ne tombait pas a la meme hauteur.

   Contour pointille + fond transparent : dit "emplacement vide" sans
   recourir a la couleur, et se distingue au premier coup d'oeil d'une
   pastille qui, elle, PORTE une donnee. Aucune teinte d'alerte — une
   annonce incomplete n'est pas un probleme pour celui qui la lit.

   Contraste : --dj-gris-700 sur la carte blanche = 9,74:1 (calcule).
   --dj-gris-500, le choix "discret" reflexe, a ete ecarte : il tombe a
   4,39:1 sur le fond des pills, SOUS le seuil AA. C'est un texte, pas
   un ornement.

   padding reduit de 1px sur chaque axe pour absorber le 1px de bordure
   que les pills de donnees n'ont pas : meme hauteur de boite, donc
   aucun saut de ligne entre une carte complete et une carte vide. */
.dj-pill-vide {
    background: transparent;
    border: 1px dashed var(--dj-gris-300, #D1D5DB);
    color: var(--dj-gris-700, #444);
    padding: 2px 9px;
}

/* Prix — PREMIERE ligne du corps (T1, livrable Claude Design).
   Passe de 18 a 22px : c'est le premier critere de tri d'un acheteur
   et il ouvre desormais la carte. margin-top a 0 — il n'a plus rien
   au-dessus de lui dans le corps. */
.dj-card-prix {
    font-family: var(--dj-font-titre, 'Manrope', sans-serif);
    font-size: 22px;
    font-weight: 700;
    color: var(--dj-vert, #006233);
    margin: 0;
    line-height: 1.15;
    /* Le gain principal du lot : les prix d'une rangee s'alignent au
       chiffre pres. Herite par .dj-prix-val, dont l'isolation bidi
       (unicode-bidi/direction) est orthogonale a la largeur des
       glyphes — les deux cohabitent sans se marcher dessus. */
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}
.dj-card-prix small {
    font-size: 12px;
    font-weight: 400;
    color: var(--dj-gris-500, #888);
}
.dj-prix-nc {
    font-family: var(--dj-font-corps, 'Inter', sans-serif);
    font-size: 13px;
    font-weight: 400;
    color: var(--dj-gris-400, #bbb);
}
/* Isolation bidi : chiffres latins toujours LTR dans un flux RTL —
   bug AR "DA 000 850" au lieu de "850 000 دج".
   MEME regle pour le numero de wilaya : meme piege, donc un seul
   endroit ou elle est ecrite, pas deux qui divergeront. */
.dj-prix-val,
.dj-wilaya-num {
    unicode-bidi: isolate;
    direction: ltr;
}
.dj-prix-val { display: inline-block; }

/* ── Footer card : ligne annonceur seule (actions séparées, §ci-dessous) */
.dj-card-footer {
    padding: 12px 16px 0;
    border-top: 1px solid var(--dj-gris-200, #eee);
    margin-top: 2px;
}

/* ── Ligne annonceur — cliquable vers la fiche annuaire (agence
   validée), neutre sinon (agence non validée / particulier — aucune
   fiche à proposer). z-index:2 : passe AU-DESSUS du stretched-link de
   "Voir l'annonce" (z-index:1), sinon le clic irait au détail au lieu
   d'ouvrir l'annuaire. ────────────────────────────────────────── */
.dj-card-pro {
    position: relative;
    z-index: 2;
}
.dj-pro-link {
    display: flex;
    align-items: flex-start;   /* haut : reste propre si le nom fait 2 lignes */
    gap: 8px;
    padding: 6px;
    margin: -6px;
    border-radius: var(--dj-radius-sm, 8px);
    text-decoration: none;
    color: var(--dj-gris-700, #444);
    transition: background .15s;
}
a.dj-pro-link:hover { background: var(--dj-gris-50, #f9fafb); }

/* Avatar : logo réel (rectangle arrondi) ou icône (rond) */
.dj-card-pro img {
    width: 28px;
    height: 28px;
    min-width: 28px;
    border-radius: 6px;
    object-fit: contain;
    background: var(--dj-gris-100, #f4f5f8);
    margin-top: 1px;
}
.dj-card-pro-icon {
    width: 28px;
    height: 28px;
    min-width: 28px;
    border-radius: 50%;
    background: var(--dj-gris-100, #f4f5f8);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    color: var(--dj-gris-500, #6b7280);
    flex-shrink: 0;
    margin-top: 1px;
}

.dj-pro-info {
    min-width: 0;   /* autorise le retour à la ligne du nom dans une flex-row */
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
/* Activité du pro (Option B) — 1er enfant de .dj-pro-info, au-dessus du
   nom. Même gabarit que .dj-pro-sub (petit, gris) : c'est la même
   information "secondaire" visuellement, juste positionnée avant plutôt
   qu'après le nom. 1 seule ligne (une activité ne justifie jamais un
   retour à la ligne) pour ne pas pousser le nom vers le bas sur les
   petites cartes.
   ⚠️ Hiérarchie activité < nom : font-size en !important sur les 2
   règles ci-dessous. Diagnostic (lecture seule de tout public/css/*.css
   + tous les <style> inline des vues) : AUCUNE media query, règle
   :hover, ou déclaration dupliquée ne touche ces 2 classes nulle part
   dans le projet — les valeurs px sont en plus des unités ABSOLUES,
   insensibles à un éventuel agrandissement hérité (contrairement à des
   em/rem). Cause la plus probable du "plus grand sur PC" observé : le
   CSS de cette classe est TOUT NOUVEAU (ce lot), et son <link> dans
   layouts/public.php n'a pas de cache-busting (?v=...) ni de
   Cache-Control serveur — un navigateur PC avec un cache déjà chaud
   (nombreuses visites cette session) peut donc servir une COPIE
   PÉRIMÉE de ce fichier, antérieure à l'ajout de cette règle : la
   classe n'existant pas encore dans ce cache, le span retombe sur la
   taille par défaut du navigateur (~16px), plus grande que le nom
   (12.5px) — exactement le symptôme. Un mobile testé pour la première
   fois n'a pas ce cache périmé, d'où "sur mobile c'est bon". À
   confirmer par un rafraîchissement forcé (Ctrl+Maj+R) côté PC ; les
   !important ci-dessous rendent la hiérarchie increvable dans tous les
   cas, cache ou pas. */
.dj-card-pro-activite {
    font-size: 10.5px !important;
    color: var(--dj-gris-500, #6b7280);
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.dj-card-pro-name {
    font-weight: 700;
    font-size: 12.5px !important;
    line-height: 1.3;
    color: var(--dj-gris-700, #444);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
a.dj-pro-link .dj-card-pro-name { color: var(--dj-vert, #006233); }
.dj-pro-sub {
    font-size: 10.5px;
    color: var(--dj-gris-500, #6b7280);
    line-height: 1.2;
}
.dj-pro-chev {
    color: var(--dj-vert, #006233);
    font-size: 15px;
    flex-shrink: 0;
    align-self: center;   /* reste centré quelle que soit la hauteur du nom */
}
html[dir="rtl"] .dj-pro-chev { transform: scaleX(-1); } /* pointe vers la gauche en RTL */

/* Annonceur neutre : agence non validée ou particulier — pas de fiche
   à proposer, pas de lien, pas de sur-ligne, pas de chevron. */
.dj-pro-neutre { cursor: default; }
.dj-pro-neutre .dj-card-pro-name { color: var(--dj-gris-700, #444); -webkit-line-clamp: 1; }

/* ── Actions : les 2 boutons distincts ("Voir" corrige le bug qui
   forçait vers #contact, "Contacter" garde ce chemin pour qui le veut
   explicitement).
   ⚠️ B12 (11/10) : .dj-card-actions n'est PAS positionnée. Elle l'était
   (relative + z-index:2) : le ::after du stretched-link de « Voir
   l'annonce » s'ancrait alors sur ELLE au lieu de la carte, recouvrait
   « Contacter » (clic → fiche sans #contact) et ne rendait plus la carte
   cliquable. C'est « Contacter » qui passe au-dessus (z-index:2, comme
   le favori et la ligne annonceur). ── */
.dj-card-actions {
    display: flex;
    gap: 8px;
    padding: 12px 16px 16px;
}
.dj-btn-voir,
.dj-btn-contact {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 44px;
    font-family: var(--dj-font-titre, 'Manrope', sans-serif);
    font-size: 13px;
    font-weight: 700;
    padding: 10px 14px;
    border-radius: var(--dj-radius-md, 8px);
    text-decoration: none !important;
    transition: background .15s, transform .1s, color .15s;
    cursor: pointer;
}
.dj-btn-voir {
    background: var(--dj-vert, #006233);
    color: #fff !important;
    border: none;
}
.dj-btn-voir:hover { background: var(--dj-vert-clair, #66A185); }
.dj-btn-voir:focus-visible {
    outline: 3px solid var(--dj-vert-clair, #66A185);
    outline-offset: 2px;
}
.dj-btn-contact {
    position: relative;
    z-index: 2; /* au-dessus du stretched-link de « Voir l'annonce » (B12) */
    background: #fff;
    color: var(--dj-vert, #006233) !important;
    border: 1.5px solid var(--dj-vert, #006233);
}
.dj-btn-contact:hover {
    background: var(--dj-gris-50, #f9fafb);
    transform: translateY(-1px);
}
.dj-btn-contact:focus-visible {
    outline: 3px solid var(--dj-vert-clair, #66A185);
    outline-offset: 2px;
}

/* ── RTL ─────────────────────────────────────────────── */
/* Les inset-inline-* gèrent déjà badges + fav.
   Le titre arabe bascule sur Noto Naskh Arabic. */
html[dir="rtl"] .dj-card-title {
    font-family: var(--dj-font-ar-titre, 'Noto Naskh Arabic', serif);
    font-size: 15px;
}
