/* ==========================================================================
   Jobivoire — Feuille de style principale
   --------------------------------------------------------------------------
   Tout style structurant et réutilisable vit ici. Une vue ne porte que ce qui
   lui est strictement propre, dans @section('style') (CLAUDE.md).

   Direction artistique (CLAUDE.md § Direction artistique) :
   orange en accent et CTA, noir pour les contrastes forts, fond blanc ou gris
   très clair, cartes sobres. Objectif explicite de la refonte v3 : réduire la
   charge visuelle. Concrètement, et ce sont des règles, pas des préférences :

     - aucun dégradé sur une carte, un bouton ou un badge ;
     - aucune ombre colorée sous un bouton ;
     - aucune bordure large sur un champ ou un bouton (1px suffit) ;
     - aucune carte bordée d'un seul côté ;
     - une seule action principale par écran ou par carte, le reste en
       dropdown (bouton ellipsis).
   ========================================================================== */

/* ==========================================================================
   1. Jetons de design
   ========================================================================== */

:root {
    /* Palette de marque */
    --jb-orange: #fe6703;
    --jb-orange-dark: #e25a02;
    --jb-orange-soft: #fff2e9;
    --color-primary-light: #fdecd8;
    --color-primary-lighter: #fff6ee;
    --jb-black: #0b0a0a;
    --jb-white: #ffffff;
    --color-text-muted: #6b7076;
    --color-text-faint: #9a9fa6;

    /* Gris : une seule échelle, pour que rien ne se rapproche « à peu près ». */
    --jb-gray-900: #17161a;
    --jb-gray-800: #2b2a2f;
    --jb-gray-700: #4a484f;
    --jb-gray-600: #6b6870;
    --jb-gray-500: #8e8b94;
    --jb-gray-400: #b4b1ba;
    --jb-gray-300: #dcdadf;
    --jb-gray-200: #e9e7ec;
    --jb-gray-100: #f4f3f6;
    --jb-gray-50: #fafafb;

    --color-bg-soft: #f8f7f6;
    --color-bg-soft-2: #f1efec;
    --color-border: #e8e6e2;
    --color-border-soft: #f0eeeb;

    /* États. Le vert « disponible » de la maquette Talents vit ici. */
    --jb-success: #16a34a;
    --jb-success-soft: #eaf7ef;
    --jb-warning: #d97706;
    --jb-warning-soft: #fdf4e7;
    --jb-danger: #dc2626;
    --jb-danger-soft: #fdecec;
    --jb-info: #2563eb;
    --jb-info-soft: #eaf0fd;

    /* Typographie */
    --jb-font: 'Mulish', 'Google Sans', 'Inter', -apple-system,
        BlinkMacSystemFont, 'Segoe UI', sans-serif;

    --jb-fs-xs: 0.75rem;
    --jb-fs-sm: 0.8125rem;
    --jb-fs-base: 0.9375rem;
    --jb-fs-lg: 1.0625rem;
    --jb-fs-xl: 1.25rem;
    --jb-fs-2xl: 1.5rem;
    --jb-fs-3xl: 2rem;
    --jb-fs-4xl: 2.75rem;

    /* Rayons */
    --jb-radius-sm: 8px;
    --jb-radius: 12px;
    --jb-radius-md: 16px;
    --jb-radius-lg: 20px;
    --jb-radius-pill: 999px;

    /* Ombres : neutres et discrètes, jamais teintées. */
    --jb-shadow-sm: 0 1px 2px rgba(11, 10, 10, .05);
    --jb-shadow: 0 2px 8px rgba(11, 10, 10, .06);
    --jb-shadow-lg: 0 8px 24px rgba(11, 10, 10, .08);

    /* Rythme vertical des sections de page publique. */
    --jb-section-gap: 3.5rem;

    --jb-header-height: 72px;
}

/* Bootstrap 5 : on redéfinit ses variables plutôt que de surcharger ses
   sélecteurs. Les composants natifs (alertes, pagination, dropdowns) suivent
   alors la charte sans qu'on ait à les réécrire un par un. */
:root {
    --bs-primary: var(--jb-orange);
    --bs-primary-rgb: 254, 103, 3;
    --bs-body-font-family: var(--jb-font);
    --bs-body-font-size: var(--jb-fs-base);
    --bs-body-color: var(--jb-gray-800);
    --bs-body-bg: var(--jb-white);
    --bs-border-color: var(--jb-gray-200);
    --bs-border-radius: var(--jb-radius);
    --bs-link-color: var(--jb-orange);
    --bs-link-hover-color: var(--jb-orange-dark);
    /* `.btn-outline-secondary`/`.badge.bg-secondary` restaient au gris-bleu
       Bootstrap stock : personne n'avait redéfini ces deux variables. */
    --bs-secondary: var(--jb-gray-800);
    --bs-secondary-rgb: 43, 42, 47;
    /* Halo de focus natif (inputs/selects/boutons) : bleu Bootstrap stock par
       défaut, jamais raccordé à --bs-primary-rgb (valeur figée à la
       compilation Sass, pas dynamique). */
    --bs-focus-ring-color: rgba(var(--bs-primary-rgb), .25);
}

/* ==========================================================================
   2. Base
   ========================================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: var(--jb-font);
    font-size: var(--jb-fs-base);
    color: var(--jb-gray-900);
    background: var(--jb-white);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
    color: var(--jb-black);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.2;
    margin: 0 0 .5rem;
}

h1 { font-size: var(--jb-fs-3xl); }
h2 { font-size: var(--jb-fs-2xl); }
h3 { font-size: var(--jb-fs-xl); }

p { margin: 0 0 1rem;}

a {
    color: var(--jb-orange);
    text-decoration: none;
    transition: color .15s ease;
}

a:hover { color: var(--jb-orange-dark); }

img {
    max-width: 100%;
    height: auto;
}

/* Cible de toucher d'au moins 44px sur mobile : l'audience visée est décrite
   comme peu à l'aise avec le numérique, et un lien de 30px se rate. */
@media (max-width: 767.98px) {
    .jb-nav-link,
    .jb-btn:not(.jb-btn--sm),  
    .jb-user-menu {
        min-height: 44px;
    } 
}
svg.lucide{ 
  width: 17px;
  height: 17px;
}
/* ====================== 
   3. Mise en page
   ====================== */

.jb-container {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 1rem;
}

@media (min-width: 768px) {
    .jb-container { padding: 0 1.5rem; }
}

.jb-section {
    padding: 1rem 0 2rem 0;
}

.jb-section--tinted {
    background: var(--jb-gray-50);
}

/* Grille de cartes commune aux listings (offres, talents, services, articles). */
.jb-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr;
}

@media (min-width: 576px) { .jb-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 992px) { .jb-grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 992px) { .jb-grid--4 { grid-template-columns: repeat(4, 1fr); } }

/* ==========================================================================
   4. Boutons
   ========================================================================== */

.jb-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .6875rem 1.25rem;
    border: 1px solid transparent;
    border-radius: var(--jb-radius-sm);
    font-family: inherit;
    font-size: var(--jb-fs-base);
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.jb-btn:disabled,
.jb-btn.is-disabled {
    opacity: .55;
    cursor: not-allowed;
}

/* ----- État de chargement (plugin btn-loader) -----
   Le spinner est le premier enfant du bouton (voir btn-loader.js) : le
   `gap` de .jb-btn le place naturellement avant le libellé, jamais après. */
.jb-btn.is-loading {
    opacity: .85;
    cursor: wait;
}

/* `.js-btn-loader` est aussi posé sur des boutons Bootstrap bruts du
   back-office (`.btn`, jamais convertis en `.jb-btn`) : le curseur d'attente
   doit s'appliquer là aussi, pas seulement sur le composant `.jb-btn`. */
.btn.is-loading {
    cursor: wait;
}

/* Une seule icône visible pendant le chargement : celle que le bouton
   portait déjà (flèche, enveloppe...) reste dans le DOM mais s'efface —
   voir le docblock de btn-loader.js. Couvre aussi les boutons Bootstrap
   bruts du back-office (icônes FontAwesome plutôt que SVG Lucide). */
.jb-btn.is-loading > svg,
.jb-btn.is-loading > i:not(.jb-btn-spinner),
.btn.is-loading > svg,
.btn.is-loading > i:not(.jb-btn-spinner) {
    display: none;
}

/* `.js-btn-loader` posé sur un bouton icône seul (définir comme principal,
   bascule de confidentialité — Mon CV) : mêmes règles que `.jb-btn` ci-dessus,
   le cercle reste figé pendant le chargement plutôt que de se redimensionner. */
.jb-icon-btn.is-loading {
    opacity: .85;
    cursor: wait;
    pointer-events: none;
}

.jb-icon-btn.is-loading > svg,
.jb-icon-btn.is-loading > i:not(.jb-btn-spinner) {
    display: none;
}

.jb-icon-btn .jb-btn-spinner {
    margin-inline-end: 0;
}

.jb-btn-spinner {
    display: inline-block;
    width: 1em;
    height: 1em;
    margin-inline-end: .5em;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    opacity: .85;
    animation: jb-spin .7s linear infinite;
    vertical-align: -.15em;
    flex: none;
}

/* Le `gap` de .jb-btn espace déjà les enfants : la marge du spinner ferait
   doublon avec le libellé. Hors .jb-btn (bouton Bootstrap brut du
   back-office), le spinner porte sa propre marge — voir le docblock du
   plugin `btn-loader.js`. */
.jb-btn .jb-btn-spinner {
    margin-inline-end: 0;
}

@media (prefers-reduced-motion: reduce) {
    .jb-btn-spinner { animation: none; }
}

.jb-btn--primary {
    background: var(--jb-orange);
    color: var(--jb-white);
}

.jb-btn--primary:hover {
    background: var(--jb-orange-dark);
    color: var(--jb-white);
}

.jb-btn--dark {
    background: var(--jb-black);
    color: var(--jb-white);
}

.jb-btn--dark:hover {
    background: var(--jb-gray-900);
    color: var(--jb-white);
}

.jb-btn--danger {
    background: var(--jb-danger);
    color: var(--jb-white);
}

.jb-btn--danger:hover {
    background: #b91c1c;
    color: var(--jb-white);
}

.jb-btn--outline {
    background: transparent;
    border-color: var(--jb-gray-300);
    color: var(--jb-gray-800);
}

.jb-btn--outline:hover {
    border-color: var(--jb-gray-500);
    color: var(--jb-black);
}

.jb-btn--ghost {
    background: #f7f8f6;
    color: var(--jb-gray-700);
}

.jb-btn--ghost:hover {
    background: var(--jb-gray-200);
    color: var(--jb-black);
}

.jb-btn--block { width: 100%; }

.jb-btn--sm {
    padding: .5rem .875rem !important;
    font-size: var(--jb-fs-sm);
}

.jb-btn--lg {
    padding: .875rem 1.75rem;
    font-size: var(--jb-fs-lg);
}

/* Bouton icône circulaire : c'est l'ellipsis qui porte les actions secondaires
   des cartes-listes (CLAUDE.md). */
.jb-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--jb-gray-200);
    border-radius: 50%;
    background: var(--jb-white);
    color: var(--jb-gray-600);
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}

.jb-icon-btn:hover {
    border-color: var(--jb-gray-400);
    color: var(--jb-black);
}

/* Bouton icône porteur d'un compteur (messages, notifications) — jamais un
   simple point rouge Bootstrap par défaut (ui-design-system). */


.jb-icon-btn--bare {
    border-color: transparent;
    background: transparent;
}

/* ==========================================================================
   5. Cartes
   ========================================================================== */

.jb-card {
    display: flex;
    flex-direction: column;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    overflow: hidden;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.jb-card:hover {
    border-color: var(--jb-gray-300);
    box-shadow: var(--jb-shadow);
}

.jb-card__body {
    flex: 1 1 auto;
    padding: 1.125rem;
}

.jb-card__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .75rem 1.125rem;
    border-top: 1px solid var(--jb-gray-100);
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-500);
}

.jb-card__title {
    margin: 0 0 .25rem;
    font-size: var(--jb-fs-lg);
    font-weight: 700;
}

.jb-card__subtitle {
    margin: 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

/* Bandeau visuel d'une carte (miniature de Service, couverture d'article). */
.jb-card__media {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    background: var(--jb-gray-100);
    overflow: hidden;
}

.jb-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Métadonnées en pied de carte : commune, contrat, date. */
.jb-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .375rem 1rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

.jb-meta__item {
    display: inline-flex;
    align-items: center;
    gap: .3125rem;
}

.jb-meta__item svg {
    width: 14px;
    height: 14px;
    flex: 0 0 auto;
}

/* ==========================================================================
   6. Badges, puces et pastilles
   ========================================================================== */

.jb-badge {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .25rem .5rem;
    border-radius: var(--jb-radius-sm);
    font-size: var(--jb-fs-xs);
    font-weight: 600;
    line-height: 1.3;
    white-space: nowrap;
}

.jb-badge--orange { background: var(--jb-orange-soft); color: var(--jb-orange-dark); }
.jb-badge--neutral { background: var(--jb-gray-100); color: var(--jb-gray-700); }
.jb-badge--success { background: var(--jb-success-soft); color: var(--jb-success); }
.jb-badge--warning { background: var(--jb-warning-soft); color: var(--jb-warning); }
.jb-badge--danger { background: var(--jb-danger-soft); color: var(--jb-danger); }
.jb-badge--info { background: var(--jb-info-soft); color: var(--jb-info); }

.jb-badge svg { width: 12px; height: 12px; flex: 0 0 auto; }

/* Badge « Urgent » plein et animé : le badge en soft-bg suffit pour une
   information passive (le contrat, le mode de travail), mais une urgence est
   un signal qui doit se remarquer sans qu'on le cherche (carte Offre). */
.jb-badge--urgent {
    position: relative;
    padding-left: 1.375rem;
    background: var(--jb-danger);
    color: var(--jb-white);
}

.jb-badge--urgent::before {
    content: '';
    position: absolute;
    top: 50%;
    left: .5rem;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--jb-white);
    transform: translateY(-50%);
    animation: jb-pulse 1.6s ease-in-out infinite;
}

@keyframes jb-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, .55); }
    50% { box-shadow: 0 0 0 4px rgba(255, 255, 255, 0); }
}

/* Étiquette de compétence sur une carte Talent. */
/* .jb-chip {
    display: inline-flex;
    align-items: center;
    padding: .3125rem .625rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-50);
    font-size: var(--jb-fs-xs);
    font-weight: 500;
    color: var(--jb-gray-700);
} */

/* Pastille de disponibilité (point + libellé) de l'annuaire Talents. */
.jb-dot {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    font-size: var(--jb-fs-xs);
    font-weight: 600;
    color: var(--jb-success);
}

.jb-dot::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

/* ==========================================================================
   7. Avatars et logos
   --------------------------------------------------------------------------
   Le repli en initiales n'est pas un cas d'exception : un profil en visibilité
   discrète n'expose jamais sa photo (SPEC.md §3), et une fiche entreprise
   gratuite est créée sans logo.
   ========================================================================== */

.jb-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--jb-gray-100);
    color: var(--jb-gray-600);
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    overflow: hidden;
}

.jb-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.jb-avatar--sm { width: 32px; height: 32px; font-size: var(--jb-fs-xs); }

/* Logo d'entreprise : cadre carré à fond blanc, l'image est contenue et non
   recadrée — un logo rogné devient méconnaissable. */
.jb-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    padding: .5rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-white);
    font-weight: 700;
    color: var(--jb-gray-700);
}

.jb-logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* ==========================================================================
   8. Formulaires
   ========================================================================== */

.jb-field {
    margin-bottom: 1rem;
}

.jb-label {
    display: block;
    margin-bottom: .375rem;
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-800);
}

.form-control:not([type="file"], .filter-amount-input),
.jb-input,
.jb-select,
.jb-textarea {
    display: block;
    width: 100%;
    padding: .55rem .875rem;
    border: 1px solid var(--jb-gray-300);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-white);
    font-family: inherit;
    font-size: var(--jb-fs-base);
    color: var(--jb-gray-900);
    transition: border-color .15s ease;
}

.form-control:focus,
.jb-input:focus,
.jb-select:focus,
.jb-textarea:focus {
    box-shadow: 0 0 0 3px rgba(239, 105, 68, 0.18);
    outline: none;
    border-color: var(--jb-orange);
}

.jb-input::placeholder,
.jb-textarea::placeholder {
    color: var(--jb-gray-400);
}

.jb-textarea {
    min-height: 120px;
    resize: vertical;
}

.jb-input.is-invalid,
.jb-select.is-invalid,
.jb-textarea.is-invalid {
    border-color: var(--jb-danger);
}

.jb-error {
    display: block;
    margin-top: .375rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-danger);
}

.jb-help {
    display: block;
    margin-top: .375rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-500);
}

/* Champ téléphone international (x-phone-field) : indicatif accolé au numéro,
   un select par champ (téléphone, WhatsApp...) plutôt qu'un select partagé. */
.jb-phone-group {
    display: grid;
    grid-template-columns: 9.5rem 1fr;
    gap: .5rem;
}

@media (max-width: 360px) {
    .jb-phone-group {
        grid-template-columns: 1fr;
    }
}

/* Champ à icône (barre de recherche du hero). */
.jb-input-icon {
    position: relative;
}

.jb-input-icon svg {
    position: absolute;
    top: 50%;
    left: .875rem;
    width: 18px;
    height: 18px;
    transform: translateY(-50%);
    color: var(--jb-gray-400);
    pointer-events: none;
}

.jb-input-icon .jb-input {
    padding-left: 2.625rem;
}

/* Saisie du code à 6 chiffres (SPEC.md §7). Caractères espacés et centrés
   pour que la relecture d'un code lu sur un téléphone reste facile. */


/* Saisie du code à 6 chiffres, une case par chiffre (plugin otp-input.js) —
   remplace .jb-code-input pour les écrans OTP. */
.jb-otp-boxes {
    display: flex;
    justify-content: center;
    gap: .5rem;
}

.jb-otp-box {
    width: 2.75rem;
    height: 3.25rem;
    border: 1px solid var(--jb-gray-300);
    border-radius: var(--jb-radius-sm);
    font-family: inherit;
    font-size: 1.5rem;
    font-weight: 700;
    text-align: center;
    color: var(--jb-black);
}

.jb-otp-box:focus {
    outline: none;
    border-color: var(--jb-orange);
    box-shadow: 0 0 0 3px var(--jb-orange-soft);
}

@media (max-width: 400px) {
    .jb-otp-box {
        width: 2.375rem;
        height: 2.875rem;
        font-size: 1.25rem;
    }
}

/* Choix visuel (type de compte à l'inscription, mode de candidature). */
.jb-choice {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: 1rem;
    border: 1px solid var(--jb-gray-300);
    border-radius: var(--jb-radius);
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
}

.jb-choice:hover {
    border-color: var(--jb-gray-400);
}

.jb-choice input {
    margin-top: .1875rem;
    accent-color: var(--jb-orange);
}

.jb-choice__title {
    display: block;
    font-weight: 600;
    color: var(--jb-black);
}

.jb-choice__help {
    display: block;
    margin-top: .125rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

.jb-choice:has(input:checked) {
    border-color: var(--jb-orange);
    background: var(--jb-orange-soft);
}

/* Grille de catégories du wizard Service (ADDENDUM-service-categories.md §1) :
   variante de .jb-choice, icône + libellé centrés au lieu d'un titre/sous-titre
   alignés à gauche. */
/* .jb-category-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
    gap: .75rem;
} */

.jb-category-card {
    position: relative;
    display: flex;
    /* flex-direction: column; */
    align-items: center;
    text-align: center;
    gap: .5rem;
    padding: 1rem .75rem;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-300);
    border-radius: var(--jb-radius);
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
}

.jb-category-card:hover { border-color: var(--jb-gray-400); }

.jb-category-card input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.jb-category-card__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.55rem;
    height: 2.55rem;
    border-radius: 50%;
    background: var(--jb-gray-100);
    color: var(--jb-orange);
    font-size: 1.1rem;
}
@media screen and (max-width: 768px){
    .jb-category-card{padding: .85rem .75rem;}
    .jb-category-card__icon { 
    width: 2rem;
    height: 2rem; 
    font-size: .95rem;
}
}

.jb-category-card__label {
    font-weight: 600;
    font-size: var(--jb-fs-sm);
    color: var(--jb-black);
}

.jb-category-card:has(input:checked) {
    border-color: var(--jb-orange);
    background: var(--jb-orange-soft);
}

.jb-category-card:has(input:checked) .jb-category-card__icon {
    background: var(--jb-orange);
    color: #fff;
}

/* Mobile : la grille de catégories tient dans une hauteur fixe et défile
   verticalement plutôt que d'allonger la page (14 catégories) — barre de
   défilement masquée (Firefox + Chrome/Safari/Edge), le geste de scroll reste
   disponible. Desktop : hauteur naturelle, pas de contrainte. */
@media (max-width: 991.98px) {
    .jb-category-scroll {
        max-height: 21rem;
        overflow-y: auto;
        scrollbar-width: none;
        padding-right: .25rem;
    }

    .jb-category-scroll::-webkit-scrollbar { display: none; }
}

/* Compteur +/- : remplace input[type=number], interdit par CLAUDE.md. */
.jb-stepper {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--jb-gray-300);
    border-radius: var(--jb-radius-sm);
    overflow: hidden;
}

.jb-stepper button {
    width: 42px;
    border: 0;
    background: var(--jb-white);
    color: var(--jb-gray-700);
    font-size: var(--jb-fs-lg);
    font-weight: 600;
    cursor: pointer;
}

.jb-stepper button:hover {
    background: var(--jb-gray-200);
    color: var(--jb-black);
}

.jb-stepper input:not(.filter-amount-input) {
    width: 80px;
    border: 0;
    border-left: 1px solid var(--jb-gray-300);
    border-right: 1px solid var(--jb-gray-300);
    padding: .625rem .5rem;
    font-family: inherit;
    font-size: var(--jb-fs-base);
    font-weight: 600;
    text-align: center;
    color: var(--jb-black);
}

.jb-stepper input:focus { outline: none; }

/* Habillage Quill (éditeur riche des formulaires du back-office) : le CDN ne
   fournit que la forme brute, ces règles l'alignent sur l'identité Jobivoire
   (mêmes rayons/bordures que les autres champs, pas de box-shadow colorée). */
.ql-toolbar.ql-snow { border-color: var(--jb-gray-300); border-radius: var(--jb-radius-sm) var(--jb-radius-sm) 0 0; background: var(--jb-gray-50); }
.ql-container.ql-snow { border-color: var(--jb-gray-300); border-radius: 0 0 var(--jb-radius-sm) var(--jb-radius-sm); font-family: inherit; font-size: var(--jb-fs-base); }
.ql-editor { min-height: 160px; }
.ql-editor.ql-blank::before { color: var(--jb-gray-600); font-style: normal; }
.ql-snow .ql-stroke { stroke: var(--jb-gray-700); }
.ql-snow .ql-fill { fill: var(--jb-gray-700); }
.ql-snow.ql-toolbar button:hover, .ql-snow .ql-toolbar button:hover,
.ql-snow.ql-toolbar button.ql-active, .ql-snow .ql-toolbar button.ql-active { color: var(--jb-orange); }
.ql-snow.ql-toolbar button:hover .ql-stroke, .ql-snow .ql-toolbar button:hover .ql-stroke,
.ql-snow.ql-toolbar button.ql-active .ql-stroke, .ql-snow .ql-toolbar button.ql-active .ql-stroke { stroke: var(--jb-orange); }
.ql-snow.ql-toolbar button:hover .ql-fill, .ql-snow .ql-toolbar button:hover .ql-fill,
.ql-snow.ql-toolbar button.ql-active .ql-fill, .ql-snow .ql-toolbar button.ql-active .ql-fill { fill: var(--jb-orange); }

/* Parcours en étapes (publication d'offre recruteur/admin). */
.jb-wizard-head {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.jb-wizard-badge {
    flex: none;
    width: 44px;
    height: 44px;
    border-radius: var(--jb-radius);
    background: var(--jb-orange);
    color: var(--jb-white);
    font-weight: 700;
    font-size: var(--jb-fs-lg);
    display: flex;
    align-items: center;
    justify-content: center;
}

.jb-wizard-title {
    font-size: var(--jb-fs-xl);
    margin: 0;
}

.jb-wizard-subtitle {
    margin: .25rem 0 0;
    color: var(--jb-gray-600);
    font-size: var(--jb-fs-sm);
}

.jb-wizard-progress {
    display: flex;
    gap: .375rem;
    margin-bottom: 1.75rem;
}

.jb-wizard-progress__bar {
    flex: 1;
    height: 6px;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-gray-200);
}

.jb-wizard-progress__bar.is-done { background: var(--jb-orange); }

.jb-wizard-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--jb-gray-200);
}

/* Écrin du wizard : fond gris qui fait ressortir les champs blancs (remplace
   le .card blanc plein-largeur d'origine). La colonne centrée elle-même est
   posée par le composant <x-wizard-shell> via les classes grille Bootstrap
   habituelles (col-lg-9 col-xl-8 col-xxl-7 mx-auto), pas ici. */
.jb-wizard-shell {
    background: var(--jb-gray-50);
    border-radius: var(--jb-radius-md);
    padding: 1.75rem;
}

@media (max-width: 575.98px) {
    .jb-wizard-shell { padding: 1.25rem; }
}

/* Sélection courte (mode de travail, type de recruteur externe). Pill
   volontaire ici : ce sont des puces de sélection, pas des boutons d'action,
   et la forme doit les distinguer au premier coup d'oeil (CLAUDE.md § UI/UX,
   qui réserve la mise en garde contre le "tout en pilule" aux CTA). */
.jb-chip-group {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.jb-chip { position: relative; }

.jb-chip input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.jb-chip label {
    display: inline-flex;
    align-items: center;
    padding: .5rem 1rem;
    border: 1px solid var(--jb-gray-300);
    border-radius: var(--jb-radius-pill);
    font-size: var(--jb-fs-sm);
    font-weight: 500;
    color: var(--jb-gray-900);
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease, color .15s ease;
}

.jb-chip.chip-sm label { 
    padding: .4rem .85rem; 
    font-size: var(--jb-fs-xs); 
}

.jb-chip label:hover { border-color: var(--jb-gray-500); }

.jb-chip input:checked + label {
    border-color: var(--jb-orange);
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
    font-weight: 600;
}

.jb-chip input:focus-visible + label { outline: 2px solid var(--jb-orange); outline-offset: 1px; }

/* Sous-catégories du wizard Service (ADDENDUM-service-categories.md §1) :
   chips pleine largeur empilées plutôt qu'en ligne, plus lisibles quand une
   catégorie compte de nombreuses sous-catégories. */
.jb-chip-group--block {
    flex-direction: column;
}

.jb-chip--block { width: 100%; }

.jb-chip--block label {
    display: flex;
    align-items: center;
    gap: .625rem;
    width: 100%;
    justify-content: flex-start;
    background: var(--jb-white);
}

/* Cercle radio dessiné en CSS (l'input réel reste masqué, technique déjà en
   place pour .jb-chip) : anneau gris au repos, anneau + pastille orange une
   fois la sous-catégorie cochée. */
.jb-chip--block label::before {
    content: '';
    flex-shrink: 0;
    width: 1.125rem;
    height: 1.125rem;
    border-radius: 50%;
    border: 2px solid var(--jb-gray-400);
    background: var(--jb-white);
    transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease;
}

.jb-chip--block input:checked + label::before {
    border-color: var(--jb-orange);
    background: var(--jb-orange);
    box-shadow: inset 0 0 0 3px var(--jb-white);
}

/* Tags libres (compétences clés). Composant maison : aucun plugin de tag dans
   le projet, même esprit "hand-rolled" que .jb-stepper. */
.jb-tag-input {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
    padding: .5rem;
    border: 1px solid var(--jb-gray-300);
    border-radius: var(--jb-radius-sm);
    background-color: white;
    min-height: 48px;
    cursor: text;
}

.jb-tag-input:focus-within { border-color: var(--jb-gray-500); }

.jb-tag-input__tag {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .3rem .6rem;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-gray-100);
    color: var(--jb-black);
    font-size: var(--jb-fs-sm);
    font-weight: 500;
    white-space: nowrap;
}

.jb-tag-input__tag button {
    border: 0;
    background: none;
    padding: 0;
    line-height: 1;
    color: var(--jb-danger);
    cursor: pointer;
    font-size: 1.25rem;
}

.jb-tag-input__tag button:hover { color: var(--jb-black); }

.jb-tag-input__field {
    flex: 1 1 120px;
    min-width: 120px;
    border: 0;
    outline: 0;
    padding: .3rem;
    font-family: inherit;
    font-size: var(--jb-fs-base);
    background: transparent;
}

/* Ligne "langue requise" (case à cocher + niveau), étape Critères du wizard. */


.jb-lang-row.is-disabled select { opacity: .5; pointer-events: none; }

/* Kanban candidatures (mini-ATS, écran Candidatures recruteur). */


/* Accent de couleur par statut, sur les mêmes tones que .jb-badge (colonne =
   même lecture visuelle que la carte qu'elle contient). */


/* Menu d'actions de la carte (TODO.md Chantier V3.15 Lot B). Posé au-dessus
   du lien, discret au repos : l'action principale reste « ouvrir le dossier »,
   qui est la carte entière. */


/* Identité du candidat en tête de carte (TODO.md Chantier V3.15 Lot A). */


/* ==========================================================================
   9. En-tête et pied de page
   ========================================================================== */

.jb-header {
    position: sticky;
    top: 0;
    z-index: 1030;
    height: var(--jb-header-height);
    background: var(--jb-white);
    border-bottom: 1px solid var(--jb-gray-200);
}
@media screen and (max-width: 991px){
    .jb-header { 
    height: 64px;
    }
}

.jb-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    height: 100%;
}

.jb-brand {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-size: var(--jb-fs-xl);
    font-weight: 800;
    color: var(--jb-black);
    letter-spacing: -0.03em;
}
.jb-brand img { width: 150px}
.jb-nav {
    display: none;
    align-items: center;
    gap: .25rem;
}
@media (min-width: 992px) {
    .jb-nav { display: flex; } 
}
@media screen and (max-width: 885px){
    .jb-brand > img { width: 115px}
}

.jb-nav-link {
    display: inline-flex;
    align-items: center;
    padding: .4rem .73rem;
    border-radius: var(--jb-radius-sm);
    font-size: 14.23px;
    font-weight: 500;
    color: var(--jb-gray-700);
}

.jb-nav-link:hover {
    background: var(--jb-gray-100);
    color: var(--jb-black);
}

.jb-nav-link.is-active {
    color: var(--jb-orange);
    font-weight: 600;
}

.jb-header__actions {
    display: flex;
    align-items: center;
    gap: .5rem;
}

/* Bannière de vérification d'email, sous la navigation principale, sur toutes
   les pages tant que l'adresse n'est pas confirmée (SPEC.md §7). */
.jb-verify-banner {
    background: var(--jb-warning-soft);
    border-bottom: 1px solid rgba(217, 119, 6, .2);
    color: #8a5308;
    font-size: var(--jb-fs-sm);
}

.jb-verify-banner__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
    padding: .75rem 0;
}

.jb-verify-banner a {
    color: #8a5308;
    font-weight: 700;
    text-decoration: underline;
}

.jb-footer {background: var(--jb-black); color: rgba(255,255,255,0.7); }
.jb-footer h5, .jb-footer .jb-footer__title { color: var(--jb-white); font-size: 1rem; margin-bottom: 1rem; }
.jb-footer a { color: rgba(255,255,255,0.68); }
.jb-footer a:hover { color: var(--jb-white); }
.jb-footer .jb-footer__bottom { border-top: 1px solid rgba(255,255,255,0.12); font-size: 0.85rem; color: rgba(255,255,255,0.5); }
.jb-footer .brand-icon { background: var(--jb-orange); }

.jb-footer__grid {
    display: grid;
    gap: 2rem;
    grid-template-columns: 1fr;
    margin-bottom: 2rem;
}

@media (min-width: 576px) { .jb-footer__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 992px) { .jb-footer__grid { grid-template-columns: 1.4fr repeat(4, 1fr); } }

.jb-footer__title {
    margin-bottom: .75rem;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    color: var(--jb-black);
}

.jb-footer__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .5rem;
}
.jb-footer__list > li > a{
 font-size: var(--jb-fs-sm)
}

.jb-footer__bottom {
    padding-top: 1.5rem;
    border-top: 1px solid var(--jb-gray-200);
    text-align: center;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
}

/* ==========================================================================
   10. États vides
   --------------------------------------------------------------------------
   Chaque listing en a un, soigné (SPEC.md §4). Cas critique du lancement :
   la rubrique Événements professionnels reste en navigation dès J1, même sans
   contenu, avec un CTA d'appel aux organismes.
   ========================================================================== */

.jb-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 3rem 1.5rem;
    border: 1px dashed var(--jb-gray-300);
    border-radius: var(--jb-radius-md);
    background: var(--jb-gray-50);
}

.jb-empty__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    margin-bottom: 1rem;
    border-radius: 50%;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-200);
    color: var(--jb-gray-400);
    font-size: 1.375rem;
}

.jb-empty__title {
    margin: 0 0 .375rem;
    font-size: var(--jb-fs-lg);
}

.jb-empty__text {
    max-width: 34rem;
    margin: 0 0 1.25rem;
    color: var(--jb-gray-600);
}

/* ==========================================================================
   11. Zone verrouillée (premium)
   --------------------------------------------------------------------------
   Jamais un blocage total : la structure reste lisible, le détail est flouté
   sous un cadenas, avec un CTA de mise à niveau (SPEC.md §5.8, CLAUDE.md).

   Le flou CSS n'est **pas** une protection : ce qu'il masque doit avoir été
   retiré de la réponse côté serveur. Il ne sert qu'à donner à voir la forme de
   ce qui est verrouillé.
   ========================================================================== */

.jb-locked {
    position: relative;
    overflow: hidden;
    border-radius: var(--jb-radius);
}

.jb-locked__content {
    filter: blur(6px);
    pointer-events: none;
    user-select: none;
}

.jb-locked__overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .625rem;
    padding: 1rem;
    text-align: center;
    background: rgba(255, 255, 255, .72);
}

.jb-locked__label {
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-800);
}

/* ==========================================================================
   12. Écrans d'authentification
   ========================================================================== */

.jb-auth {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: calc(100dvh - var(--jb-header-height));
    padding: 2.5rem 1rem;
    background: var(--jb-gray-50);
}

.jb-auth__card {
    width: 100%;
    max-width: 460px;
    padding: 2rem 1.5rem;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-lg);
}

@media (min-width: 576px) {
    .jb-auth__card { padding: 2.5rem; }
}

.jb-auth__title {
    margin-bottom: .5rem;
    font-size: var(--jb-fs-2xl);
}

.jb-auth__lead {
    margin-bottom: 1.75rem;
    color: var(--jb-gray-600);
}

.jb-auth__foot {
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--jb-gray-100);
    text-align: center;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

/* ==========================================================================
   13. Utilitaires
   ========================================================================== */

.jb-text-muted { color: var(--jb-gray-500); }
.jb-text-dark { color: var(--jb-black); }
.jb-text-orange { color: var(--jb-orange); }
.jb-text-sm { font-size: var(--jb-fs-sm); }
.jb-text-xs { font-size: var(--jb-fs-xs); }
.jb-fw-600 { font-weight: 600; }
.jb-fw-700 { font-weight: 700; }

/* Coupe un titre de carte à deux lignes : sans cela, une offre au libellé
   interminable décale toute la grille. */
.jb-clamp-1,
.jb-clamp-2,
.jb-clamp-3 {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.jb-clamp-1 { -webkit-line-clamp: 1; line-clamp: 1; }
.jb-clamp-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.jb-clamp-3 { -webkit-line-clamp: 3; line-clamp: 3; }

.jb-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ==========================================================================
   15. Blog
   ========================================================================== */

.jb-blog-filters {
    display: flex;
    flex-wrap: wrap;
    gap: .625rem;
    align-items: center;
}

.jb-article {
    max-width: 46rem;
}

.jb-article__head {
    margin-bottom: 1.75rem;
}

.jb-article__title {
    margin: .75rem 0 1rem;
    font-size: 1.75rem;
    line-height: 1.2;
}

@media (min-width: 768px) {
    .jb-article__title { font-size: var(--jb-fs-3xl); }
}

.jb-article__cover {
    width: 100%;
    margin-bottom: 2rem;
    border-radius: var(--jb-radius-md);
}

/* Corps rédigé depuis l'Administration : la mise en forme du contenu est
   normalisée ici, pas dans l'éditeur, pour qu'un copier-coller depuis Word ne
   déforme pas la page. */
.jb-article__body {
    font-size: var(--jb-fs-lg);
    line-height: 1.75;
    color: var(--jb-gray-800);
}

.jb-article__body h2 {
    margin: 2.25rem 0 .75rem;
    font-size: var(--jb-fs-xl);
}

.jb-article__body h3 {
    margin: 1.75rem 0 .5rem;
    font-size: var(--jb-fs-lg);
}

.jb-article__body ul,
.jb-article__body ol {
    margin: 0 0 1.25rem;
    padding-left: 1.25rem;
}

.jb-article__body li { margin-bottom: .375rem; }

.jb-article__body img {
    margin: 1.5rem 0;
    border-radius: var(--jb-radius);
}

.jb-article__body blockquote {
    margin: 1.75rem 0;
    padding: .25rem 0 .25rem 1.25rem;
    border-left: 3px solid var(--jb-orange);
    color: var(--jb-gray-700);
    font-style: italic;
}

/* Balises supplémentaires acceptées pour un article collé en HTML brut
   (mode « HTML brut » de l'Administration) : sans ces règles, un tableau ou
   un séparateur arriverait sur la page avec le rendu par défaut du
   navigateur, en rupture avec le reste de l'article. */
.jb-article__body h4 {
    margin: 1.5rem 0 .5rem;
    font-size: var(--jb-fs-lg);
}

.jb-article__body h5,
.jb-article__body h6 {
    margin: 1.25rem 0 .5rem;
    font-size: var(--jb-fs-base);
    font-weight: 700;
}

.jb-article__body hr {
    margin: 2rem 0;
    border: 0;
    border-top: 1px solid var(--jb-gray-200);
}

.jb-article__body figure { margin: 1.5rem 0; }
.jb-article__body figure img { margin: 0; }

.jb-article__body figcaption {
    margin-top: .5rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

/* Un tableau collé peut dépasser la colonne de lecture sur mobile : il
   défile dans son propre cadre, la page ne défile jamais latéralement. */
.jb-article__body table {
    display: block;
    width: 100%;
    overflow-x: auto;
    margin: 1.5rem 0;
    border-collapse: collapse;
    font-size: var(--jb-fs-base);
}

.jb-article__body th,
.jb-article__body td {
    padding: .625rem .75rem;
    border: 1px solid var(--jb-gray-200);
    text-align: left;
    vertical-align: top;
}

.jb-article__body thead th {
    background: var(--jb-gray-100);
    font-weight: 700;
}

.jb-article__body pre {
    margin: 1.5rem 0;
    padding: 1rem 1.25rem;
    overflow-x: auto;
    border-radius: var(--jb-radius);
    background: var(--jb-gray-100);
    font-size: var(--jb-fs-sm);
}

.jb-article__body code {
    padding: .125rem .375rem;
    border-radius: 4px;
    background: var(--jb-gray-100);
    font-size: .9em;
}

.jb-article__body pre code { padding: 0; background: none; }

.jb-article__tags {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin-top: 1.5rem;
}

.jb-article__tags a {
    text-decoration: none;
    transition: background-color .15s ease;
}

.jb-article__tags a:hover {
    background: var(--jb-gray-200);
}

.jb-article__nav {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr;
    margin-top: 2.5rem;
    padding-top: 1.75rem;
    border-top: 1px solid var(--jb-gray-200);
}

@media (min-width: 576px) {
    .jb-article__nav { grid-template-columns: repeat(2, 1fr); }
}

.jb-article__nav-link {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    padding: 1rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius);
    color: var(--jb-gray-800);
}

.jb-article__nav-link:hover {
    border-color: var(--jb-gray-300);
    color: var(--jb-black);
}

/* ==========================================================================
   16. Écrans de paiement
   ========================================================================== */

.jb-pay-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin: 0 auto 1.25rem;
    border-radius: 50%;
}

.jb-pay-icon--waiting {
    background: var(--jb-orange-soft);
    color: var(--jb-orange);
}

/* La rotation signale que la vérification est en cours : sans elle, un
   utilisateur qui attend la confirmation de son opérateur croit la page figée
   et relance le paiement. */
.jb-pay-icon--waiting svg {
    animation: jb-spin 1.1s linear infinite;
}

@keyframes jb-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .jb-pay-icon--waiting svg { animation: none; }
}

.jb-pay-icon--failed {
    background: var(--jb-danger-soft);
    color: var(--jb-danger);
}

/* Récapitulatif de transaction. */
.jb-recap {
    margin: 0 0 1.5rem;
    padding: 1rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius);
    background: var(--jb-gray-50);
    text-align: left;
    font-size: var(--jb-fs-sm);
}

.jb-recap__line {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: .4375rem 0;
}

.jb-recap__line + .jb-recap__line {
    border-top: 1px solid var(--jb-gray-200);
}

.jb-recap dt {
    margin: 0;
    color: var(--jb-gray-600);
    font-weight: 400;
}

.jb-recap dd {
    margin: 0;
    color: var(--jb-black);
    font-weight: 600;
    text-align: right;
}

.jb-recap code {
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-800);
}


/* ==========================================================================
   17. Emploi — listings, fiches, espace candidat
   --------------------------------------------------------------------------
   Rappel des règles de la charte, qui valent aussi ici : aucun dégradé, aucune
   ombre colorée, aucune bordure large, aucune carte bordée d'un seul côté, une
   seule action principale par carte (CLAUDE.md § Direction artistique).
   ========================================================================== */

/* ── Barre de filtres ──────────────────────────────────────────────────── */

.jb-filters {
    margin-top: 1.5rem;
    padding: 1rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
}

.jb-filters__row {
    display: flex;
    flex-wrap: wrap;
    gap: .625rem;
    align-items: center;
}


.jb-filters__search {
    flex: 1 1 16rem;
}

.jb-filters .jb-select {
    flex: 0 1 13rem;
}


/* Interrupteur textuel des filtres booléens. Cible de toucher volontairement
   large : l'audience visée est décrite comme peu à l'aise avec le numérique. */


/* ── Carte d'offre ─────────────────────────────────────────────────────── */

.jb-job-list {
    display: flex;
    flex-direction: column;
    gap: 1.35rem;
    margin-top: 1.75rem;
}

.jb-job-card {
    position: relative;
    display: flex;
    gap: 1.125rem;
    align-items: flex-start;
    padding: 1.375rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-lg);
    background: var(--jb-white);
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}

.jb-job-card:hover {
    border-color: var(--jb-gray-300);
    box-shadow: var(--jb-shadow-lg);
    transform: translateY(-2px);
}

.jb-job-card:hover .jb-job-card__title {
    color: var(--jb-orange-dark);
}

/* Mise en avant par le fond, jamais par une bordure d'un seul côté. L'ombre
   teintée (au lieu d'une bordure épaisse) est ce qui fait « détacher » une
   carte sponsorisée du reste du listing. */
.jb-job-card.is-highlighted {
    background: var(--jb-orange-soft);
    border-color: rgba(254, 103, 3, .3);
box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, rgba(0, 0, 0, 0.06) 0px 1px 2px 0px;
}

.jb-job-card.is-highlighted:hover {
box-shadow: rgba(0, 0, 0, 0.08) 0px 4px 12px;
    transform: translateY(-2px);
}

/* Toute la carte est cliquable. Le lien est posé en surimpression plutôt que
   d'englober le contenu : imbriquer un bouton favori dans un <a> produit un
   HTML invalide et une navigation au clavier incohérente. */
.jb-job-card__link {
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
}

.jb-job-card__logo,
.jb-company-card__logo {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    overflow: hidden;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-50);
    color: var(--jb-gray-700);
    font-weight: 700;
    font-size: var(--jb-fs-sm);
}

.jb-job-card__logo img,
.jb-company-card__logo img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Offre sans logo : le visuel générique des offres remplace les initiales qui
   servaient de repli. C'est une photographie et non une marque, elle remplit
   donc son cadre au lieu d'y flotter entre deux bandes vides. */
.jb-job-card__logo.is-illustration img,
.jb-offer-head__logo.is-illustration img {
    object-fit: cover;
}

/* Un peu plus imposant que le gabarit de base partagé avec les autres
   modules (skill ui-design-system : chaque type de carte reflète ce qui
   compte pour son contenu — ici, l'identité de l'entreprise). */
.jb-job-card__logo {
    width: 60px;
    height: 60px;
    border-radius: var(--jb-radius);
    font-size: var(--jb-fs-base);
}
@media screen and (max-width: 768px) {
    .jb-job-card__logo {
        width: 50px;
        height: 50px;
        border-radius: var(--jb-radius-sm);
    }

    .jb-job-card {
        gap: 0.8rem;
    }

    .jb-job-card .jb-job-card__actions .jb-btn {
        gap: .5rem;
        padding: .45rem 1rem;
        font-size: var(--jb-fs-sm);
    }
}

.jb-job-card__main {
    flex: 1 1 auto;
    min-width: 0;
}

.jb-job-card__head {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    flex-wrap: wrap;
}

.jb-job-card__title {
    margin: 0;
    font-size: var(--jb-fs-xl);
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--jb-black);
    transition: color .15s ease;
}

.jb-job-card__company {
    margin: .25rem 0 .625rem;
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-600);
}

.jb-job-card__aside {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .625rem;
    position: relative;
    z-index: 2;
}

.jb-job-card__date {
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
    white-space: nowrap;
}

.jb-job-card__actions {
    display: flex;
    align-items: center;
    gap: .375rem;
}

@media (max-width: 767.98px) {
    .jb-job-card {
        flex-wrap: wrap;
    }

    .jb-job-card__aside {
        width: 100%;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        padding-top: .75rem;
        border-top: 1px solid var(--jb-gray-200);
    }
}

/* Bouton favori. Rempli une fois posé : un contour seul se lit mal sur un
   écran de téléphone en plein soleil. */
.jb-fav-btn.is-on {
    color: var(--jb-orange);
    border-color: var(--jb-orange);
}

.jb-fav-btn.is-on svg {
    fill: currentColor;
}

/* ── Barre de filtres compacte (listing Offres) ──────────────────────────
   Remplace le formulaire empilé d'origine, propre au listing Emploi : une
   barre horizontale (recherche + secteur + un seul bouton « Filtres » qui
   ouvre un grand panneau), pour ne pas répéter le bloc générique .jb-filters
   déjà utilisé tel quel par les autres listings (Talents, Services...). ── */

.jb-job-filters {
    margin-top: 1.5rem;
}

.jb-job-filters__bar {
    display: flex;
    align-items: stretch;
    gap: .625rem;
    padding: .625rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
}

.jb-job-filters__search {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
}

.jb-job-filters__search svg {
    position: absolute;
    left: .875rem;
    width: 18px;
    height: 18px;
    color: var(--jb-gray-400);
    pointer-events: none;
}

.jb-job-filters__search input {
    width: 100%;
    padding: .6875rem .875rem .6875rem 2.625rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-50);
    font-family: inherit;
    font-size: var(--jb-fs-base);
    color: var(--jb-gray-900);
    transition: border-color .15s ease, background-color .15s ease;
}

.jb-job-filters__search input:focus {
    outline: none;
    border-color: var(--jb-orange);
    background: var(--jb-white);
}

.jb-job-filters__sector {
    flex: 0 0 auto;
    width: 13rem;
}

.jb-job-filters .ms-control {
    min-height: 44px;
}

.jb-job-filters__toggle-wrap {
    position: relative;
    flex: 0 0 auto;
}

.jb-job-filters__toggle {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    height: 100%;
    padding: 0 1rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-white);
    color: var(--jb-gray-800);
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}

.jb-job-filters__toggle:hover,
.jb-job-filters__toggle[aria-expanded="true"] {
    border-color: var(--jb-orange);
    color: var(--jb-orange-dark);
}

.jb-job-filters__toggle svg {
    width: 16px;
    height: 16px;
}

.jb-job-filters__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-orange);
    color: var(--jb-white);
    font-size: 10px;
    font-weight: 700;
}

.jb-job-filters__submit {
    flex: 0 0 auto;
}

/* Panneau de filtres avancés. `data-bs-display="static"` (sur le bouton)
   désactive le repositionnement dynamique de Popper, mais Bootstrap pose
   quand même `data-bs-popper="static"` sur le menu, et sa règle
   `.dropdown-menu[data-bs-popper]` (position + top + left) reste chargée
   après ce fichier avec une spécificité de deux sélecteurs : un simple
   `.jb-job-filters__panel` ne suffit pas à la emporter. D'où le doublon de
   classe `.dropdown-menu` ci-dessous, qui égalise la spécificité et gagne
   grâce à l'ordre de chargement, sans `!important`. */
.dropdown-menu.jb-job-filters__panel {
    position: absolute;
    top: calc(100% + .5rem);
    left: auto;
    right: 0;
    width: 24rem;
    max-width: calc(100vw - 2rem);
    max-height: 75vh;
    overflow-y: auto;
    padding: 1.25rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    box-shadow: var(--jb-shadow-lg);
}

.jb-job-filters__panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1rem;
    font-size: var(--jb-fs-base);
    font-weight: 700;
    color: var(--jb-black);
}

.jb-job-filters__clear {
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-500);
}

.jb-job-filters__clear:hover {
    color: var(--jb-orange);
}

.jb-job-filters__group {
    margin-bottom: 1.125rem;
}

.jb-job-filters__panel-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 .875rem;
}

.jb-job-filters__panel-foot {
    margin-top: .25rem;
}

@media (max-width: 767.98px) {
    .jb-job-filters__bar {
        flex-wrap: wrap;
    }

    .jb-job-filters__search { flex: 1 1 100%; order: 1; }
    .jb-job-filters__sector { flex: 1 1 auto; order: 2; width: auto; }
    .jb-job-filters__toggle-wrap { order: 3; }
    .jb-job-filters__submit { order: 4; }

    .jb-job-filters__panel-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 575.98px) {
    .dropdown-menu.jb-job-filters__panel {
        position: fixed;
        left: 1rem;
        right: 1rem;
        top: 335px;
        bottom: 1rem;
        width: auto;
        max-width: none;
        max-height: 70vh;
    }
}

@media (max-width: 420px) {

    .jb-job-filters__submit {
        padding-left: .875rem;
        padding-right: .875rem;
        width: 100%;
    }
}

/* Thème du plugin modern-select aligné sur la charte Jobivoire (le thème
   "orange" fourni par le plugin est une teinte proche mais différente). */

/* ── Colonne latérale du listing Offres (offres sponsorisées, encarts) ── */

.jb-job-aside {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    position: sticky;
    top: calc(var(--jb-header-height) + 1rem);
}

@media (max-width: 991.98px) {
    .jb-job-aside {
        position: static;
        margin-top: 2rem;
    }
}

.jb-side-card--accent {
    background: var(--jb-orange-soft);
    border-color: rgba(254, 103, 3, .2);
}

.jb-promo-list {
    display: flex;
    flex-direction: column;
    gap: .625rem;
}

.jb-promo-item {
    display: flex;
    align-items: flex-start;
    gap: .625rem;
    padding: .5rem;
    margin: 0 -.5rem;
    border-radius: var(--jb-radius-sm);
    transition: background-color .15s ease;
}

.jb-promo-item:hover {
    background: var(--jb-gray-50);
}

.jb-promo-item__logo {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    overflow: hidden;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-white);
    color: var(--jb-gray-700);
    font-weight: 700;
    font-size: var(--jb-fs-xs);
}

.jb-promo-item__logo img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.jb-promo-item__title {
    margin: 0;
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-black);
}

.jb-promo-item__company {
    margin: .125rem 0 0;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
}

/* Encart publicitaire : traitement en pointillé pour se distinguer d'une
   vraie carte de contenu, jamais présenté comme un contenu réel. */
.jb-ad-slot {
    padding: 1.25rem;
    border: 1.5px dashed var(--jb-gray-300);
    border-radius: var(--jb-radius-md);
    text-align: center;
}

.jb-ad-slot__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    margin: 0 auto .625rem;
    border-radius: 50%;
    background: var(--jb-gray-100);
    color: var(--jb-gray-500);
}

/* ── Carte d'entreprise ────────────────────────────────────────────────── */

.jb-company-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .5rem;
    padding: 1.25rem 1rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
    text-align: center;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.jb-company-card:hover {
    border-color: var(--jb-gray-300);
    box-shadow: var(--jb-shadow);
}

.jb-company-card.is-highlighted {
    background: var(--jb-orange-soft);
    border-color: rgba(254, 103, 3, .25);
}

.jb-company-card__logo {
    width: 64px;
    height: 64px;
    font-size: var(--jb-fs-lg);
}

.jb-company-card__name {
    margin: .25rem 0 0;
    font-size: var(--jb-fs-base);
    color: var(--jb-black);
}

.jb-company-card__sector,
.jb-company-card__place,
.jb-company-card__followers {
    margin: 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

.jb-company-card__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
}

.jb-company-card__place,
.jb-company-card__followers {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
}

.jb-company-card__place svg,
.jb-company-card__followers svg {
    width: 14px;
    height: 14px;
}

.jb-company-card__foot {
    margin-top: .375rem;
}

.jb-verified-mark {
    width: 16px;
    height: 16px;
    color: var(--jb-info);
    vertical-align: -2px;
}

/* ── Mise en page fiche (2 colonnes) ───────────────────────────────────── */

.jb-detail {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20rem;
    gap: 2rem;
    align-items: start;
    margin-top: 1.5rem;
}

@media (max-width: 991.98px) {
    .jb-detail {
        grid-template-columns: minmax(0, 1fr);
    }
}

.jb-detail__aside {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    position: sticky;
    top: calc(var(--jb-header-height) + 1rem);
}

@media (max-width: 991.98px) {
    .jb-detail__aside {
        position: static;
    }
}

.jb-side-card {
    padding: 1.25rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
}

.jb-side-card__title {
    margin: 0 0 .875rem;
    font-size: var(--jb-fs-base);
    color: var(--jb-black);
}

.jb-side-card__actions {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    margin-top: 1rem;
}

.jb-side-card .jb-recap {
    margin-bottom: 0;
    padding: 0;
    border: 0;
    background: transparent;
}

.jb-side-company {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin-bottom: .75rem;
}

.jb-back-link {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    margin-bottom: 1rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

.jb-back-link:hover {
    color: var(--jb-orange);
}

.jb-back-link svg {
    width: 16px;
    height: 16px;
}

/* ── Lien discret « Signaler » (fiche Offre/Service/Mission) ────────────── */

.jb-report-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .375rem;
    width: 100%;
    margin-top: .75rem;
    padding: 0;
    border: none;
    background: none;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-500);
    cursor: pointer;
}

.jb-report-link:hover {
    color: var(--jb-gray-700);
}

.jb-report-link svg {
    width: 14px;
    height: 14px;
}

/* ── En-tête d'une fiche offre ─────────────────────────────────────────── */

.jb-offer-head {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--jb-gray-200);
}

.jb-offer-head__logo {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    overflow: hidden;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius);
    background: var(--jb-gray-50);
    font-weight: 700;
    color: var(--jb-gray-700);
}

.jb-offer-head__logo img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.jb-offer-head__text {
    min-width: 0;
}

.jb-offer-head__title {
    margin: 0 0 .25rem;
    font-size: var(--jb-fs-2xl);
}

.jb-offer-head__company {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    font-weight: 600;
    color: var(--jb-gray-700);
}

.jb-offer-head__company:hover {
    color: var(--jb-orange);
}

/* Numéro de référence affiché en meta de fiche (CLAUDE.md, demande porteur
   de projet) : chiffres tabulaires pour qu'il ne « saute » pas au regard. */
.jb-ref-tag {
    font-variant-numeric: tabular-nums;
}

/* ── Carte d'en-tête de fiche (badges, partage, indicateurs clés) ───────── */

.jb-offer-hero {
    position: relative;
    padding: 1.5rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
    overflow: hidden;
}

@media (max-width: 575.98px) {
    .jb-offer-hero {
        padding: 1.25rem;
    }
}

/* Un liseré de couleur en haut de carte suffit à signaler « sponsorisée »
   ou « urgent » sans teinter tout le bloc (direction artistique : pas de
   surcharge de couleur). */
.jb-offer-hero::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: transparent;
}

.jb-offer-hero.is-boosted::before { background: var(--jb-orange); }
.jb-offer-hero.is-urgent::before { background: var(--jb-danger); }

.jb-offer-hero__flags {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin-bottom: 1.125rem;
}

.jb-badge--lg {
    padding-top: .4rem;
    padding-bottom: .4rem;
    padding-right: .75rem;
    font-size: var(--jb-fs-sm);
}

.jb-badge--lg svg {
    width: 14px;
    height: 14px;
}

.jb-offer-hero__top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.jb-offer-hero__top > .jb-offer-head {
    min-width: 0;
    flex: 1 1 auto;
}

.jb-offer-hero__top > .jb-share {
    flex: 0 0 auto;
}

@media (max-width: 575.98px) {
    .jb-offer-hero__top {
        flex-direction: column;
    }
}

/* ── Partage (WhatsApp/Facebook/email/copie sur PC, feuille native sur
   mobile) : icônes neutres au repos, teinte de la plateforme au survol
   seulement — les couleurs de marque tierces ne comptent pas comme une
   rupture de la charte, elles identifient le canal. ─────────────────────── */

.jb-share {
    flex: 0 0 auto;
}

.jb-share__group {
    gap: .5rem;
}

.jb-share-btn,
.jb-copy-link-btn,
.jb-native-share-btn {
    width: 38px;
    height: 38px;
}

.jb-share-btn--whatsapp:hover { border-color: #25d366; color: #25d366; }
.jb-share-btn--facebook:hover { border-color: #1877f2; color: #1877f2; }
.jb-share-btn--email:hover { border-color: var(--jb-gray-500); color: var(--jb-black); }

/* ── Indicateurs clés (salaire, contrat, expérience...) ──────────────────
   Objectif explicite de la refonte de cette fiche : ces informations
   passaient inaperçues, reléguées dans la colonne latérale. */

.jb-quick-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11.5rem, 1fr));
    gap: .75rem;
    margin-top: 1.25rem;
}

@media (max-width: 575.98px) {
    .jb-quick-facts {
        grid-template-columns: 1fr;
    }
}

.jb-fact-card {
    display: flex;
    align-items: center;
    gap: .75rem;
    min-width: 0;
    padding: .875rem 1rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius);
    background: var(--jb-gray-50);
}

.jb-fact-card__label,
.jb-fact-card__value {
    min-width: 0;
    overflow-wrap: break-word;
}

.jb-fact-card--accent {
    border-color: rgba(254, 103, 3, .25);
    background: var(--jb-orange-soft);
}

.jb-fact-card__icon {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--jb-white);
    color: var(--jb-gray-600);
}

.jb-fact-card--accent .jb-fact-card__icon {
    color: var(--jb-orange-dark);
}

.jb-fact-card__icon svg {
    width: 17px;
    height: 17px;
}

.jb-fact-card__label {
    margin: 0;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
}

.jb-fact-card__value {
    margin: .0625rem 0 0;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    color: var(--jb-black);
}

.jb-fact-card--accent .jb-fact-card__value {
    color: var(--jb-orange-dark);
}

/* ── Bandeaux d'information ────────────────────────────────────────────── */

.jb-notice {
    display: flex;
    align-items: flex-start;
    gap: .625rem;
    margin: 1rem 0;
    padding: .875rem 1rem;
    border: 1px solid transparent;
    border-radius: var(--jb-radius);
    font-size: var(--jb-fs-sm);
}

.jb-notice svg {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    margin-top: 1px;
}

.jb-notice--info {
    background: var(--jb-info-soft);
    border-color: rgba(37, 99, 235, .18);
    color: var(--jb-info);
}

.jb-notice--warning {
    background: var(--jb-warning-soft);
    border-color: rgba(217, 119, 6, .18);
    color: var(--jb-warning);
}

.jb-notice--success {
    background: var(--jb-success-soft);
    border-color: rgba(22, 163, 74, .18);
    color: var(--jb-success);
}

/* ── Contenu rédigé (description d'offre, à propos d'une entreprise) ───── */

.jb-prose {
    margin: 1.75rem 0;
    color: var(--jb-gray-700);
    line-height: 1.7;
}

.jb-prose h2 {
    margin: 0 0 .75rem;
    font-size: var(--jb-fs-xl);
}

/* Mention de provenance d'une offre importée : une note de bas de contenu, pas
   un encart. Elle doit se lire sans détourner du bouton de candidature. */
.jb-source-note {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    margin: -.5rem 0 1.75rem;
    padding: .625rem .875rem;
    border-left: 2px solid var(--jb-gray-200);
    background: var(--jb-gray-50);
    border-radius: var(--jb-radius-sm);
}

.jb-source-note i {
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    margin-top: .15rem;
}

.jb-prose h3,
.jb-prose h4 {
    margin: 1.25rem 0 .5rem;
    font-size: var(--jb-fs-lg);
}

.jb-prose ul,
.jb-prose ol {
    margin: 0 0 1rem;
    padding-left: 1.25rem;
}

.jb-prose li {
    margin-bottom: .375rem;
}

/* ── Bloc de candidature ───────────────────────────────────────────────── */

.jb-apply {
    margin-top: 2rem;
    padding: 1.5rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-gray-50);
}

.jb-apply__title {
    margin: 0 0 1rem;
    font-size: var(--jb-fs-xl);
}

.jb-apply__actions {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.jb-apply__form .jb-field {
    margin-bottom: 1rem;
}

/* ── Bandeau de fiche entreprise ───────────────────────────────────────── */

.jb-company-cover {
    height: 200px;
    overflow: hidden;
    background: var(--jb-gray-100);
}

/* Fond uni quand aucune couverture n'a été téléversée : jamais de dégradé
   (CLAUDE.md, SPEC.md §9). */
.jb-company-cover.is-plain {
    background: var(--jb-black);
}

.jb-company-cover img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

@media (max-width: 767.98px) {
    .jb-company-cover {
        height: 120px;
    }
}


/* ==========================================================================
   18. Espace privé Candidat — onglets et cartes de suivi
   --------------------------------------------------------------------------
   Onglets à soulignement pour le premier niveau, pilules arrondies pour le
   second (TODO.md Lot 4). Rien n'est masqué derrière un menu : une option qu'on
   ne voit pas n'existe pas pour l'audience visée.
   ========================================================================== */

.jb-tabs {
    display: flex;
    gap: .25rem;
    overflow-x: auto;
    border-bottom: 1px solid var(--jb-gray-200);
    scrollbar-width: none;
}

.jb-tabs::-webkit-scrollbar {
    display: none;
}

.jb-tab {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: .75rem 1rem;
    border-bottom: 2px solid transparent;
    color: var(--jb-gray-600);
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    white-space: nowrap;
}

.jb-tab:hover {
    color: var(--jb-black);
}

.jb-tab.is-active {
    border-bottom-color: var(--jb-orange);
    color: var(--jb-orange);
}

.jb-tab svg {
    width: 16px;
    height: 16px;
}

.jb-subtabs {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
    margin-bottom: 1.5rem;
}

.jb-subtab {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: .4375rem .875rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-pill);
    background: var(--jb-white);
    color: var(--jb-gray-700);
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    box-shadow: var(--jb-shadow-sm);
}

.jb-subtab:hover {
    border-color: var(--jb-gray-300);
    color: var(--jb-black);
}

.jb-subtab.is-active {
    border-color: var(--jb-black);
    background: var(--jb-black);
    color: var(--jb-white);
}

.jb-subtab__count {
    padding: 0 .375rem;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-gray-100);
    color: var(--jb-gray-700);
    font-size: var(--jb-fs-xs);
}

.jb-subtab.is-active .jb-subtab__count {
    background: rgba(255, 255, 255, .18);
    color: var(--jb-white);
}

/* Carte de suivi (candidature envoyée, offre enregistrée). */
.jb-track-card {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    justify-content: space-between;
    padding: 1.125rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
}

.jb-track-card__main {
    min-width: 0;
}

.jb-track-card__title {
    margin: .5rem 0;
    font-size: var(--jb-fs-lg);
}

.jb-track-card__title a {
    color: var(--jb-black);
}

.jb-track-card__title a:hover {
    color: var(--jb-orange);
}

.jb-track-card__aside {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: .5rem;
}

@media (max-width: 768px) {
    .jb-track-card {
        flex-direction: column;
        padding: .95rem
    }

    .jb-track-card__aside {
        width: 100%;
        justify-content: flex-start;
        padding-top: .75rem;
        border-top: 1px solid var(--jb-gray-200);
    }
}

/* Variante avec avatar (candidature, talent, agent d'équipe) : le nom compte
   autant que ce qui l'accompagne, pas un simple gabarit texte recopié. */


/* Miniature d'annonce de Service ("Mes services") : même position que
   `.jb-track-card__avatar`, format carré au lieu de pastille ronde, avec
   badge du nombre de photos de la galerie (services/wizard §3). */
.jb-track-card__thumb {
    position: relative;
    flex: 0 0 auto;
    width: 64px;
    height: 64px;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-100);
    overflow: hidden;
}

.jb-track-card__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.jb-track-card__thumb-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: var(--jb-gray-400);
}

.jb-track-card__thumb-count {
    position: absolute;
    bottom: .25rem;
    right: .25rem;
    display: inline-flex;
    align-items: center;
    gap: .1875rem;
    padding: .0625rem .3125rem;
    border-radius: var(--jb-radius-pill);
    background: rgba(11, 10, 10, .65);
    color: var(--jb-white);
    font-size: 10px;
    font-weight: 700;
}

.jb-track-card__thumb-count svg,
.jb-track-card__thumb-count i {
    width: 10px;
    height: 10px;
}

.jb-track-card__body { display: flex; gap: 1rem; align-items: center; min-width: 0; }

.jb-track-card__body .jb-track-card__main { flex: 1 1 auto; }

/* Ligne de mini-stats (vues/clics/candidatures, réponses, inscrits...). */
.jb-track-card__stats {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .375rem .875rem;
    margin-top: .5rem;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-600);
}

.jb-track-card__stat {
    display: inline-flex;
    align-items: center;
    gap: .3125rem;
}

.jb-track-card__stat i { width: 13px; text-align: center; color: var(--jb-gray-400); }

.jb-track-card__stat.is-highlight {
    color: var(--jb-orange-dark);
    font-weight: 700;
}

.jb-track-card__stat.is-highlight i { color: var(--jb-orange); }

/* ==========================================================================
   19. Annuaire Talents & catalogue Services
   --------------------------------------------------------------------------
   Trois familles de cartes pour un même espace (SPEC.md §5.2/§5.3) : Talent
   (le profil est l'objet), Prestataire (la vignette d'activité passe devant),
   Service (la prestation, avec le profil du prestataire rappelé en pied de
   carte). Repli toujours en couleur pleine, jamais en dégradé (CLAUDE.md
   § Direction artistique).
   ========================================================================== */

/* ── Carte Talent ──────────────────────────────────────────────────────── */

.jb-talent-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .375rem;
    padding: 1.5rem 1rem 1.25rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
    text-align: center;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}

.jb-talent-card:hover {
    border-color: var(--jb-gray-300);
    box-shadow: var(--jb-shadow);
    transform: translateY(-3px);
}

.jb-talent-card__avatar {
    width: 72px;
    height: 72px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: 50%;
    background: var(--jb-gray-50);
    border: 2px solid var(--jb-gray-200);
    color: var(--jb-gray-700);
    font-weight: 700;
    font-size: var(--jb-fs-lg);
    transition: border-color .15s ease;
}

.jb-talent-card:hover .jb-talent-card__avatar {
    border-color: var(--jb-orange);
}

.jb-talent-card__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.jb-talent-card__name {
    margin: .25rem 0 0;
    font-size: var(--jb-fs-base);
    color: var(--jb-black);
}

.jb-talent-card__role {
    margin: 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

.jb-talent-card__badges {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .375rem;
    margin: .125rem 0;
}

.jb-talent-card__actions {
    position: relative;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .375rem;
    width: 100%;
    margin-top: .5rem;
}

/* Couleurs de la pastille de disponibilité (jeton déclaré section 6). */
.jb-dot--success { color: var(--jb-success); }
.jb-dot--warning { color: var(--jb-warning); }
.jb-dot--secondary { color: var(--jb-gray-500); }

/* ── Carte Prestataire ─────────────────────────────────────────────────── */


/* ── Carte Service ─────────────────────────────────────────────────────── */

.jb-service-card {
    position: relative;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
    overflow: hidden;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.jb-service-card:hover {
    border-color: var(--jb-gray-300);
    box-shadow: var(--jb-shadow);
}

.jb-service-card.is-highlighted {
    border-color: rgba(254, 103, 3, .25);
}

.jb-service-card__thumb {
    position: relative;
    aspect-ratio: 1 / 1;
    background: var(--jb-gray-100);
}

.jb-service-card__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.jb-service-card__thumb-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: var(--jb-gray-400);
}

.jb-service-card__pin {
    position: absolute;
    top: .625rem;
    left: .625rem;
}

/* Badge "+N photos" : la galerie a plus d'une image (services/wizard §3). */
.jb-service-card__gallery-badge {
    position: absolute;
    bottom: .625rem;
    left: .625rem;
    background: rgba(11, 10, 10, .65);
    color: var(--jb-white);
    backdrop-filter: blur(2px);
}

.jb-service-card__gallery-badge svg {
    width: 12px;
    height: 12px;
}

.jb-service-card__body {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    padding: .875rem 1rem 1.125rem;
}

.jb-service-card__title {
    margin: 0;
    font-size: var(--jb-fs-base);
    color: var(--jb-black);
}

.jb-service-card__price {
    margin: 0 0 .25rem;
    font-weight: 700;
    color: var(--jb-orange);
}

.jb-service-card__provider {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

.jb-service-card__provider-avatar {
    flex: 0 0 auto;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: 50%;
    background: var(--jb-gray-100);
    color: var(--jb-gray-700);
    font-size: var(--jb-fs-xs);
    font-weight: 700;
}

.jb-service-card__provider-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ── En-tête de fiche Talent ───────────────────────────────────────────── */

.jb-talent-head {
    padding-bottom: 1.25rem;
    margin-bottom: 1.5rem;
    border-bottom: 1px solid var(--jb-gray-200);
}


.jb-talent-head__avatar {
    flex: 0 0 auto;
    width: 88px;
    height: 88px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: 50%;
    background: var(--jb-gray-50);
    border: 1px solid var(--jb-gray-200);
    color: var(--jb-gray-700);
    font-weight: 700;
    font-size: var(--jb-fs-xl);
}

.jb-talent-head__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}


/* ── Contact en bas de fiche (au lieu d'une sidebar discrète) ─────────────── */

.jb-talent-contact {
    margin-top: 2rem;
    padding: 2.5rem 1.5rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-lg);
    background: var(--jb-white);
    text-align: center;
}


.jb-talent-contact__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    margin-bottom: 1rem;
    border-radius: 50%;
    background: var(--jb-gray-50);
    border: 1px solid var(--jb-gray-200);
    color: var(--jb-orange);
}

.jb-talent-contact__icon svg,
.jb-talent-contact__icon i {
    width: 22px;
    height: 22px;
}


.jb-talent-contact .jb-locked,
.jb-talent-contact .jb-recap {
    max-width: 20rem;
    margin: 0 auto 1.5rem;
    text-align: left;
}


/* Galerie de Service (wizard étape 3) : dropzone à upload direct par AJAX,
   carrée sur PC, pleine largeur sur mobile (demande porteur de projet). */
.jb-gallery__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: .75rem;
}

@media (max-width: 575.98px) {
    .jb-gallery__grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

.jb-gallery__thumb {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: var(--jb-radius-md);
    overflow: hidden;
    background: var(--jb-gray-100);
    border: 1px solid var(--jb-gray-200);
}

.jb-gallery__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.jb-gallery__badge {
    position: absolute;
    top: .5rem;
    left: .5rem;
    padding: .1875rem .5rem;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-orange);
    color: var(--jb-white);
    font-size: var(--jb-fs-xs);
    font-weight: 700;
}

.jb-gallery__action {
    position: absolute;
    top: .5rem;
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(11, 10, 10, .55);
    color: var(--jb-white);
    cursor: pointer;
}

.jb-gallery__action svg,
.jb-gallery__action i {
    width: 14px;
    height: 14px;
}

.jb-gallery__action--remove { right: .5rem; }
.jb-gallery__action--star { right: 2.125rem; }

.jb-gallery__action--star:hover { background: var(--jb-orange); }
.jb-gallery__action--remove:hover { background: var(--jb-danger); }

.jb-gallery__drop {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .375rem;
    aspect-ratio: 1 / 1;
    max-width: 220px;
    border: 1.5px dashed var(--jb-gray-400);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
    color: var(--jb-gray-500);
    font-size: var(--jb-fs-sm);
    text-align: center;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}

.jb-gallery__drop:hover,
.jb-gallery__drop.is-dragover {
    border-color: var(--jb-orange);
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-gallery__drop svg,
.jb-gallery__drop i {
    width: 22px;
    height: 22px;
}

.jb-gallery__drop.is-uploading {
    cursor: progress;
    pointer-events: none;
    opacity: .75;
}

@media (max-width: 575.98px) {
    .jb-gallery__drop {
        aspect-ratio: 16 / 9;
        max-width: none;
        grid-column: 1 / -1;
    }
}

.jb-gallery__progress {
    width: 80%;
    height: 6px;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-gray-200);
    overflow: hidden;
}

.jb-gallery__progress-bar {
    height: 100%;
    width: 0;
    background: var(--jb-orange);
    transition: width .2s ease;
}

/* ==========================================================================
   26. Panneaux de réglages (Mon profil, Mon CV) — Lot 3
   ========================================================================== */

.jb-panel {
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-300);
    border-radius: var(--jb-radius-md);
    margin-bottom: 1.5rem;
}

.jb-panel__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.125rem 1.25rem;
    border-bottom: 1px solid var(--jb-gray-100);
}

.jb-panel__title {
    margin: 0 0 .2rem;
    font-size: var(--jb-fs-lg);
    font-weight: 700;
}

.jb-panel__subtitle {
    margin: 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

.jb-panel__body {
    padding: 1.25rem;
}

@media screen and (max-width: 885px){
    .jb-panel__body {
    padding: .95rem;
}

}

/* Sélecteur de spécialités Mode Prestataire (TODO.md Chantier V3.3 Lot B) :
   groupes empilés (une catégorie = un bloc), pas un accordéon replié — cohérent
   avec la consigne « aucune option ne doit être trop cachée ». */
.jb-specialty-picker {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    max-height: 26rem;
    overflow-y: auto;
    padding: 1rem;
    border: 1px solid var(--jb-gray-100);
    border-radius: var(--jb-radius-md);
}

.jb-specialty-picker__group + .jb-specialty-picker__group {
    padding-top: 1rem;
    border-top: 1px solid var(--jb-gray-100);
}

.jb-specialty-picker__title {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: 0 0 .6rem;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    color: var(--jb-gray-900);
}

.jb-specialty-picker__group.is-disabled .jb-chip label {
    opacity: .45;
    cursor: not-allowed;
}

/* Alerte orange (jamais le jaune Bootstrap générique) : ton d'accent Jobivoire
   déjà utilisé pour les badges/états actifs (--jb-orange-soft/--jb-orange-dark). */
.jb-alert {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .65rem .9rem;
    border-radius: var(--jb-radius-md);
    font-size: var(--jb-fs-sm);
    font-weight: 600;
}

.jb-alert svg, .jb-alert i {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
}

.jb-alert--warning {
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-list-item {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: .9rem 0;
    border-bottom: 1px solid var(--jb-gray-100);
}

.jb-list-item:last-child { border-bottom: none; }

.jb-list-item__title {
    margin: 0 0 .15rem;
    font-weight: 700;
    font-size: var(--jb-fs-base);
}

.jb-list-item__meta {
    margin: 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

.jb-list-item__actions {
    flex: 0 0 auto;
    display: flex;
    gap: .4rem;
}

/* Ligne compétence/langue avec repère visuel du palier déclaré (TODO.md
   Chantier V3.2 Lot G) — jamais une mesure exacte inventée (SkillLevel::percent()). */
.jb-list-item--meter { align-items: center; }

.jb-list-item__main { flex: 1 1 auto; min-width: 0; }

.jb-list-item__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .4rem;
}

.jb-list-item__head .jb-list-item__title,
.jb-list-item__head .jb-list-item__meta { margin: 0; }

.jb-meter {
    width: 100%;
    height: 5px;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-gray-100);
    overflow: hidden;
}

.jb-meter span {
    display: block;
    height: 100%;
    background: var(--jb-orange);
    border-radius: var(--jb-radius-pill);
}

/* Widget de dépôt de fichier : jamais de bordure en pointillés générique
   (ui-design-system), un traitement de carte cohérent avec le reste du site. */
.jb-file-drop {
    display: flex;
    align-items: center;
    gap: .9rem;
    padding: 1rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius);
    background: var(--jb-gray-50);
}

.jb-file-drop__icon {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-file-drop__body { flex: 1 1 auto; min-width: 0; }

.jb-file-drop__name {
    margin: 0;
    font-weight: 600;
    font-size: var(--jb-fs-sm);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.jb-file-drop__hint {
    margin: 0;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
}

/* Tuile de statistique du tableau de bord candidat — densité maîtrisée,
   pas de décoration superflue (ui-design-system). */
.jb-stat-tile {
    display: block;
    padding: 1.125rem;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.jb-stat-tile:hover {
    border-color: var(--jb-gray-300);
    box-shadow: var(--jb-shadow);
}

.jb-stat-tile__value {
    margin: 0;
    font-size: var(--jb-fs-3xl);
    font-weight: 800;
    color: var(--jb-black);
}

.jb-stat-tile__label {
    margin: .15rem 0 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
    display: flex;
    align-items: center;
    gap: .4rem;
}

/* Bandeau de complétion de profil — pas un dégradé décoratif générique
   (ui-design-system) : fond neutre, une barre de progression discrète. */
.jb-completion-banner {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    padding: 1.25rem;
    background: var(--jb-black);
    color: var(--jb-white);
    border-radius: var(--jb-radius-md);
    margin-bottom: 1.5rem;
}

.jb-completion-banner__bar {
    width: 100%;
    height: 6px;
    border-radius: var(--jb-radius-pill);
    background: rgba(255, 255, 255, .15);
    overflow: hidden;
    margin-top: .5rem;
}

.jb-completion-banner__bar span {
    display: block;
    height: 100%;
    background: var(--jb-orange);
    border-radius: var(--jb-radius-pill);
}

@media (max-width: 575.98px) {
    .jb-completion-banner {
        flex-direction: column;
        align-items: stretch;
    }
}

/* Dropdown d'actions secondaires (bouton ellipsis) sur une carte de gestion,
   dans l'espace privé Candidat — CLAUDE.md : une action principale visible,
   le reste en dropdown. */
.jb-list-item .dropdown-menu,
.jb-track-card .dropdown-menu {
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-sm);
    box-shadow: var(--jb-shadow);
    padding: .4rem;
}

.jb-list-item .dropdown-item,
.jb-track-card .dropdown-item {
    border-radius: var(--jb-radius-sm);
    font-size: var(--jb-fs-sm);
    padding: .5rem .6rem;
}

.jb-list-item .dropdown-item:hover,
.jb-track-card .dropdown-item:hover {
    background: var(--jb-gray-100);
}
.ftg-container {
    display: flex;
    gap: 0;
    background: white;
    border-radius: 30px;
    padding: 5px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.12);
    max-width: 800px;
    position: fixed;
    top: 90px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 200;
    border: 1.5px solid rgba(0, 0, 0, 0.15);
}
.fixed-tab-item {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 9px 16px;
    border-radius: 30px;
    text-decoration: none;
    color: #5f6368;
    font-weight: 600;
    font-size: 14px;
    transition: all 0.2s;
}
.fixed-tab-item.active {
    background: var(--jb-black);
    color: white;
    box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
}

@media screen and (max-width: 885px) {
    .ftg-container {
        padding: 5px;
        max-width: 100%;
        position: fixed;
        top: 90px;
        left: 50%;
    }

    .fixed-tab-item {
        flex: 1;
        gap: 4px;
        padding: 7px 10px;
        font-size: 12px;
    }

    .fixed-tab-item.active .label {
        display: none;
    }
}

/* ==========================================================================
   27. Navigation étendue — dropdowns desktop, menu utilisateur, offcanvas
   --------------------------------------------------------------------------
   Les dropdowns Emploi / Talents & Services / Ressources ne réutilisent pas
   le `.dropdown-menu` par défaut de Bootstrap tel quel : seule sa mécanique
   JS (positionnement, ouverture/fermeture) est gardée, l'habillage vient d'ici.
   ========================================================================== */

.dropdown-menu { 
    --bs-dropdown-padding-x: .65rem;
    --bs-dropdown-padding-y: 0.78rem; 
    --bs-dropdown-border-radius: 0.375rem; 
    --bs-dropdown-link-color: #212529;
    --bs-dropdown-link-hover-color: #1e2125;
    --bs-dropdown-link-hover-bg: #e9ecef;
    --bs-dropdown-link-active-color: var(--jb-orange);
    --bs-dropdown-link-active-bg: var(--jb-orange-soft);
    --bs-dropdown-link-disabled-color: #adb5bd;
    --bs-dropdown-item-padding-x: 1.3rem;
    --bs-dropdown-item-padding-y: 0.45rem;
    --bs-dropdown-header-color: #6c757d;
    --bs-dropdown-header-padding-x: 1rem;
    --bs-dropdown-header-padding-y: 0.5rem; 
    display: none; 
    padding: var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);
    border-radius: var(--bs-dropdown-border-radius);
    box-shadow: rgba(17, 17, 26, 0.05) 0px 4px 16px, rgba(17, 17, 26, 0.05) 0px 8px 32px;
}
.dropdown-item { 
  border-radius: 8px
}
.jb-nav-item {
    position: relative;
}

/* Le déclencheur d'un dropdown doit rester visuellement identique à un lien
   de nav simple : c'est un <button> pour l'accessibilité (data-bs-toggle),
   pas une raison de le faire ressembler à un bouton. */
.jb-nav-link--toggle {
    border: 0;
    background: transparent;
    cursor: pointer;
    gap: .25rem;
}

.jb-nav-link__caret {
    width: 14px;
    height: 14px;
    transition: transform .15s ease;
}

.jb-nav-link--toggle[aria-expanded="true"] .jb-nav-link__caret,
.jb-user-menu[aria-expanded="true"] .jb-nav-link__caret {
    transform: rotate(180deg);
}

.dropdown-menu:not(.admin-dropdown).show {
    display: block;
    animation: dropdownFadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
    visibility: visible;
    opacity: 1;
    transform: translateY(36px);
    pointer-events: auto;
    z-index: 150;
}

@keyframes dropdownFadeIn {
    from {
        opacity: 0;
        transform: translateY(52px); 
    }

    to {
        opacity: 1;
        transform: translateY(36px); 
    }
}

.jb-mega-menu {
    min-width: 300px;
    padding: .5rem;
    margin-top: .656rem !important;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    box-shadow: var(--jb-shadow-lg);
}

.jb-mega-menu__link {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .625rem .625rem;
    border-radius: var(--jb-radius-sm);
    color: var(--jb-gray-800);
}

.jb-mega-menu__link:hover {
    background: var(--jb-gray-100);
    color: var(--jb-black);
}

.jb-mega-menu__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--jb-gray-100);
    color: var(--jb-gray-600);
}

.jb-mega-menu__link:hover .jb-mega-menu__icon,
.jb-mega-menu__link.is-active .jb-mega-menu__icon {
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-mega-menu__title {
    display: block;
    font-size: var(--jb-fs-base);
    font-weight: 600;
    color: var(--jb-black);
}

.jb-mega-menu__link.is-active .jb-mega-menu__title {
    color: var(--jb-orange-dark);
}

.jb-mega-menu__desc {
    display: block;
    margin-top: .0625rem;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
}

/* ── Menu utilisateur (avatar + prénom + dropdown) ───────────────────────── */

.jb-user-menu {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .25rem .75rem .25rem .25rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-pill);
    background: var(--jb-white);
    cursor: pointer;
}

.jb-user-menu:hover {
    border-color: var(--jb-gray-400);
}

.jb-user-menu__name {
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-black);
}

.jb-user-menu__panel {
    width: 280px;
    padding: .5rem;
    margin-top: .625rem !important;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    box-shadow: var(--jb-shadow-lg);
}

.jb-user-menu__header {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .5rem .625rem .75rem;
    margin-bottom: .375rem;
    border-bottom: 1px solid var(--jb-gray-100);
    min-width: 0;
}

.jb-user-menu__fullname {
    display: block;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    color: var(--jb-black);
}

.jb-user-menu__email {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
}

.jb-user-menu__link {
    display: flex;
    align-items: center;
    gap: .625rem;
    width: 100%;
    padding: .625rem;
    border: 0;
    background: transparent;
    border-radius: var(--jb-radius-sm);
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-700);
    text-align: left;
}

.jb-user-menu__link:hover {
    background: var(--jb-gray-100);
    color: var(--jb-black);
}

.jb-user-menu__link--danger {
    color: var(--jb-danger);
}

.jb-user-menu__link--danger:hover {
    background: var(--jb-danger-soft);
    color: var(--jb-danger);
}

.jb-user-menu__badge {
    margin-left: auto;
    padding: .125rem .4375rem;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-orange);
    color: var(--jb-white);
    font-size: var(--jb-fs-xs);
    font-weight: 700;
    line-height: 1.4;
}

.jb-user-menu__divider {
    height: 1px;
    margin: .375rem 0;
    background: var(--jb-gray-100);
}

/* ── Menu mobile (offcanvas) ──────────────────────────────────────────────── */

.jb-offcanvas {
    width: min(340px, 88vw);
}

.jb-offcanvas__body {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.jb-offcanvas__group {
    display: flex;
    flex-direction: column;
    gap: .125rem;
}

.jb-offcanvas__group-title {
    padding: 0 .5rem;
    margin-bottom: .25rem;
    font-size: var(--jb-fs-xs);
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--jb-orange);
}

.jb-offcanvas__link {
    display: flex;
    align-items: center;
    gap: .75rem;
    min-height: 44px;
    padding: .5rem;
    border-radius: var(--jb-radius-sm);
    font-size: var(--jb-fs-base);
    font-weight: 500;
    color: var(--jb-gray-800);
}

.jb-offcanvas__link:hover {
    background: var(--jb-gray-100);
    color: var(--jb-black);
}

.jb-offcanvas__link svg {
    flex: 0 0 auto;
    color: var(--jb-gray-500);
}

.jb-offcanvas__logout {
    border-color: var(--jb-danger-soft);
    color: var(--jb-danger);
}

.jb-offcanvas__logout:hover {
    background: var(--jb-danger-soft);
    border-color: var(--jb-danger-soft);
    color: var(--jb-danger);
}

/* ==========================================================================
   28. Landing « bientôt disponible » et sélecteur Connexion/Inscription
   ========================================================================== */

.jb-hero--tight { padding-bottom: 1.5rem; }

.jb-section--flush-top { padding-top: 0; }

/* Variante sombre du bandeau hero (CLAUDE.md : noir pour les CTA à fort
   contraste), réservée aux pages de conversion ponctuelles — jamais un
   habillage générique répété sans lien avec le contenu de la page. */


.jb-hero__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .75rem;
    margin-top: .5rem;
}

.jb-btn--ghost-invert {
    border: 1px solid rgba(255, 255, 255, .3);
    color: var(--jb-white);
}

.jb-btn--ghost-invert:hover {
    border-color: var(--jb-white);
    background: rgba(255, 255, 255, .08);
    color: var(--jb-white);
}

.jb-auth-chooser {
    padding: var(--jb-section-gap) 0;
    background: var(--jb-gray-50);
    min-height: calc(100dvh - var(--jb-header-height));
}

.jb-auth-chooser__inner {
    max-width: 900px;
}

.jb-auth-chooser__intro {
    margin-bottom: 2rem;
    text-align: center;
}

.jb-auth-chooser__intro p {
    font-size: var(--jb-fs-lg);
}

.jb-account-choice-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
}

@media (min-width: 640px) {
    .jb-account-choice-grid { grid-template-columns: 1fr 1fr; }
}

/* Reprise de lisibilité (TODO.md Chantier V3.1 §V3.1.1) : la structure de la
   page est jugée bonne, seule la taille de texte du titre/sous-titre/liste
   posait problème — relevée d'un cran, jamais jusqu'au très grand, et
   scopée à `.jb-account-choice` pour ne pas toucher `.jb-card__title` /
   `.jb-card__subtitle` ailleurs sur le site (Service, Talent, Article...). */
.jb-account-choice .jb-card__title {
    font-size: var(--jb-fs-2xl);
}

.jb-account-choice .jb-card__subtitle {
    margin-top: .375rem;
    font-size: var(--jb-fs-base);
    line-height: 1.5;
}

.jb-account-choice__features {
    list-style: none;
    margin: 1.25rem 0 0;
    padding: 0;
}

.jb-account-choice__features li {
    display: flex;
    align-items: center;
    gap: .625rem;
    padding: .5rem 0;
    font-size: var(--jb-fs-base);
    color: var(--jb-gray-700);
}

.jb-account-choice__features svg {
    flex: 0 0 auto;
    color: var(--jb-orange);
}

.jb-account-choice__actions {
    display: flex;
    gap: .625rem;
    padding: 1.125rem;
    border-top: 1px solid var(--jb-gray-100);
}

.jb-account-choice__actions .jb-btn {
    flex: 1 1 0;
}

/* Largeur de la barre verticale / Hauteur de la barre horizontale */
::-webkit-scrollbar {
  width: thin;   
  height: thin;  
}
.btn-reset {
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  box-sizing: border-box;
  cursor: pointer;
  display: inline-block;
  font-weight: inherit;
  padding: 0;
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
  white-space: nowrap;
}.btn-reset:focus{
  outline: none;
  box-shadow: none;
}

.form-control.filter-amount-input{
    background-color: #f5f5f5; border: var(--bs-border-width) solid #e9e9e9;
}
.form-control.filter-amount-input:focus{box-shadow: none; border-color: var(--jb-black);}
/* ----- Page header / hero band --------  */
.page-band { background: var(--color-primary-lighter); border-bottom: 1px solid var(--color-border-soft); }
.breadcrumb-jv { font-size: 0.85rem; }
.breadcrumb-jv a { color: var(--color-text-muted);}
.breadcrumb-jv .active { color: var(--jb-gray-800); font-weight: 600; }

.form-check-input:checked {
  background-color: var(--jb-success);
  border-color: var(--jb-success);
}.color-inherit{
  color: inherit;
}
/* ==========================================================================
   Sidebar de filtres à facettes — CVthèque Talents
   (TODO.md Chantier V3.4 Lot C)

   Volontairement dans styles.css et non dans talents.css : c'est un composant
   structurant réutilisable (CLAUDE.md), destiné à servir aussi les listings
   Offres et Prestataires. Il s'appuie donc sur les tokens --jb-*, jamais sur
   les --color-* propres à talents.css.

   Parti pris visuel : la sidebar doit s'effacer derrière les résultats. Pas de
   fond de couleur par groupe, pas d'en-tête coloré — le seul accent orange est
   la coche d'une option retenue et le compteur qui l'accompagne.
   ========================================================================== */

.jb-facets {
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    overflow: hidden;
}

.jb-facets__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    padding: .875rem 1rem;
    border-bottom: 1px solid var(--jb-gray-200);
}

.jb-facets__title {
    font-size: var(--jb-fs-base);
    font-weight: 700;
    color: var(--jb-black);
}

.jb-facets__clear {
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-600);
    text-decoration: underline;
}

.jb-facets__clear:hover {
    color: var(--jb-orange);
}

/* ── Un groupe ─────────────────────────────────────────────────────────── */

.jb-facet + .jb-facet {
    border-top: 1px solid var(--jb-gray-100);
}

.jb-facet__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    width: 100%;
    padding: .75rem 1rem;
    background: none;
    border: 0;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    color: var(--jb-gray-800);
    text-align: left;
    cursor: pointer;
}

.jb-facet__head:hover {
    color: var(--jb-black);
}

.jb-facet__caret {
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    color: var(--jb-gray-500);
    transition: transform .15s ease;
}

.jb-facet.is-collapsed .jb-facet__caret {
    transform: rotate(180deg);
}

.jb-facet.is-collapsed .jb-facet__body {
    display: none;
}

.jb-facet__body {
    padding: 0 1rem .875rem;
}

.jb-facet__search {
    width: 100%;
    margin-bottom: .5rem;
    padding: .4rem .625rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-800);
    background: var(--jb-gray-50);
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-sm);
}

.jb-facet__search:focus {
    outline: none;
    border-color: var(--jb-gray-400);
    background: var(--jb-white);
}

.jb-facet__list {
    margin: 0;
    padding: 0;
    list-style: none;
    max-height: 19rem;
    overflow-y: auto;
}

/* ── Une option ────────────────────────────────────────────────────────── */

.jb-facet__check {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .3rem 0;
    cursor: pointer;
}

.jb-facet__check--solo {
    padding: .75rem 1rem;
}

.jb-facet__check input {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    accent-color: var(--jb-orange);
    cursor: pointer;
}

.jb-facet__label {
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--jb-fs-sm);
    line-height: 1.35;
    color: var(--jb-gray-700);
}

.jb-facet__check input:checked ~ .jb-facet__label {
    color: var(--jb-black);
    font-weight: 600;
}

.jb-facet__count {
    flex: 0 0 auto;
    font-size: var(--jb-fs-xs);
    font-variant-numeric: tabular-nums;
    color: var(--jb-gray-500);
}

.jb-facet__check input:checked ~ .jb-facet__count {
    color: var(--jb-orange);
    font-weight: 700;
}

.jb-facet__more {
    margin-top: .375rem;
    padding: 0;
    background: none;
    border: 0;
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-orange);
    cursor: pointer;
}

.jb-facet__more:hover {
    color: var(--jb-orange-dark);
    text-decoration: underline;
}

.jb-facet__empty {
    margin: .5rem 0 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-500);
}

/* ── Chips « filtres appliqués » ───────────────────────────────────────── */

.jb-applied {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .375rem;
}

.jb-applied__chip {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: .25rem .5rem .25rem .625rem;
    font-size: var(--jb-fs-xs);
    font-weight: 600;
    color: var(--jb-gray-800);
    background: var(--jb-orange-soft);
    border: 1px solid #f8d6bd;
    border-radius: var(--jb-radius-sm);
    text-decoration: none;
}

.jb-applied__chip:hover {
    color: var(--jb-black);
    border-color: var(--jb-orange);
}

.jb-applied__chip i {
    width: 13px;
    height: 13px;
    color: var(--jb-orange);
}

.jb-applied__clear {
    font-size: var(--jb-fs-xs);
    font-weight: 600;
    color: var(--jb-gray-600);
    text-decoration: underline;
}

.jb-applied__clear:hover {
    color: var(--jb-orange);
}

/* ==========================================================================
   Modale pédagogique CVthèque (TODO.md Chantier V3.4 Lot D)
   ========================================================================== */

/* `.jb-tab` était jusqu'ici toujours un lien avec `.is-active` posé par Blade.
   Le plugin d'onglets Bootstrap, lui, pose `.active` : l'alias évite d'avoir à
   maintenir deux composants d'onglets pour la même apparence. */
.jb-tab {
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    cursor: pointer;
}

.jb-tab.active {
    border-bottom-color: var(--jb-orange);
    color: var(--jb-orange);
}

.jb-steps {
    margin: 0;
    padding-left: 1.1rem;
    display: grid;
    gap: .875rem;
}

.jb-steps li {
    font-size: var(--jb-fs-sm);
    line-height: 1.55;
    color: var(--jb-gray-700);
}

.jb-steps strong {
    display: block;
    color: var(--jb-black);
}

.jb-tips {
    margin: 0;
    padding-left: 1.1rem;
    display: grid;
    gap: .625rem;
}

.jb-tips li {
    font-size: var(--jb-fs-sm);
    line-height: 1.55;
    color: var(--jb-gray-700);
}

.jb-note {
    margin-top: 1rem;
    padding: .75rem .875rem;
    font-size: var(--jb-fs-sm);
    line-height: 1.5;
    color: var(--jb-gray-800);
    background: var(--jb-orange-soft);
    border-radius: var(--jb-radius-sm);
}

/* Variantes de note contextuelle : validation en attente et refus motivé
   (point 14 de `file_test.md`). La note orange par défaut ne distingue pas
   « on vous attend » de « quelque chose ne va pas ». */
.jb-note--warning {
    background: #fff7ed;
    border-left: 3px solid #f59e0b;
}

.jb-note--danger {
    background: #fef2f2;
    border-left: 3px solid #dc2626;
}

.jb-note i,
.jb-note svg {
    width: 16px;
    height: 16px;
    vertical-align: -3px;
    margin-right: .25rem;
}

.jb-plan-brief + .jb-plan-brief {
    margin-top: .75rem;
}

.jb-plan-brief {
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius);
    padding: .875rem 1rem;
}

.jb-plan-brief__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .5rem;
}

.jb-plan-brief__name {
    font-weight: 700;
    color: var(--jb-black);
}

.jb-plan-brief__price {
    font-weight: 700;
    color: var(--jb-orange);
}

.jb-plan-brief__price small {
    font-weight: 500;
    color: var(--jb-gray-500);
}

.jb-plan-brief__list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: .3rem;
}

.jb-plan-brief__list li {
    display: flex;
    align-items: flex-start;
    gap: .4rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-700);
}

.jb-plan-brief__list svg {
    width: 15px;
    height: 15px;
    flex: 0 0 auto;
    margin-top: .15rem;
    color: var(--jb-success);
}

/* ── Bandeau de conversion recruteur ─────────────────────────────────────── */

.jb-cvtheque-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .75rem 1rem;
    background: var(--jb-orange-soft);
    border: 1px solid #f8d6bd;
    border-radius: var(--jb-radius);
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-800);
}

.jb-cvtheque-banner a {
    font-weight: 700;
    color: var(--jb-orange-dark);
    text-decoration: underline;
}

.jb-cvtheque-banner a:hover {
    color: var(--jb-black);
}

.jb-cvtheque-help {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: 0;
    background: none;
    border: 0;
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-700);
    text-decoration: underline;
    cursor: pointer;
}

.jb-cvtheque-help:hover {
    color: var(--jb-orange);
}

.jb-cvtheque-help svg {
    width: 16px;
    height: 16px;
}

/* Variante « Sourcing IA » : le même bouton discret, mais en bouton plein
   d'accent plutôt qu'en lien souligné. C'est une découverte, pas une aide :
   souligné comme son voisin, il aurait été lu comme une seconde question
   d'assistance et personne ne l'aurait ouvert (chantier V3.11 Lot D). */
.jb-cvtheque-help--ai {
    padding: .375rem .75rem;
    border-radius: 999px;
    background-color: var(--jb-orange);
    color: var(--jb-white);
    text-decoration: none;
}

.jb-cvtheque-help--ai:hover {
    background-color: var(--jb-black);
    color: var(--jb-white);
}

/* ── Pastille d'icône des blocs « icon box » ─────────────────────────────── */

.jb-icon-box {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 12px;
    background-color: rgba(254, 103, 3, .12);
    color: var(--jb-orange);
    font-size: 1rem;
}

/* ── CTA de bas de liste, adressé aux candidats ──────────────────────────── */

.jb-talent-cta {
    margin-top: 2.5rem;
    padding: 1.5rem;
    text-align: center;
    background: var(--jb-black);
    border-radius: var(--jb-radius-md);
}

.jb-talent-cta__title {
    margin: 0 0 .25rem;
    font-size: var(--jb-fs-lg);
    font-weight: 700;
    color: var(--jb-white);
}

.jb-talent-cta__text {
    margin: 0 0 1rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-400);
}

/* ==========================================================================
   Sélecteur de dossiers de favoris Talents (TODO.md Chantier V3.4 Lot E)
   ==========================================================================
   Apparence portée du gabarit `_fav-modal` remis par le porteur de projet :
   surbrillance orange douce + bordure orange sur un dossier retenu. Elle vit
   ici et non dans `talents.css` parce que la même modale sert l'espace
   recruteur, qui ne charge pas cette feuille.

   L'orange n'apparaît que sur l'état retenu : dans une liste de dossiers, la
   seule information à repérer d'un coup d'œil est « ce talent y est déjà ».
   ========================================================================== */

.jb-folder-list {
    display: grid;
    gap: .5rem;
}

.jb-folder-option {
    display: flex;
    align-items: center;
    gap: .75rem;
    width: 100%;
    padding: .75rem .875rem;
    text-align: left;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-sm);
    color: inherit;
    transition: background .15s ease, border-color .15s ease;
}

button.jb-folder-option {
    cursor: pointer;
}

button.jb-folder-option:hover {
    background: var(--jb-gray-50);
    border-color: var(--jb-gray-300);
}

.jb-folder-option.is-in-folder {
    background: var(--jb-orange-soft);
    border-color: var(--jb-orange);
}

.jb-folder-option__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 38px;
    height: 38px;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-100);
    color: var(--jb-gray-600);
}

.jb-folder-option.is-in-folder .jb-folder-option__icon {
    background: var(--jb-white);
    color: var(--jb-orange);
}

.jb-folder-option__body {
    display: block;
    flex: 1 1 auto;
    min-width: 0;
}

.jb-folder-option__name {
    display: block;
    font-weight: 600;
    font-size: var(--jb-fs-sm);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.jb-folder-option__count {
    display: block;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
}

.jb-folder-option__check {
    flex: none;
    color: var(--jb-orange);
}

/* Aperçu montré au visiteur non connecté : inerte et étiqueté, pour qu'aucun
   dossier d'exemple ne puisse passer pour un dossier réel. */
.jb-folder-option--demo {
    cursor: default;
}

.jb-folder-option--demo .jb-folder-option__name,
.jb-folder-option--demo .jb-folder-option__count {
    color: var(--jb-gray-500);
}

.jb-folder-option__tag {
    flex: none;
    padding: .125rem .5rem;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-100);
    color: var(--jb-gray-600);
    font-size: var(--jb-fs-xs);
    font-weight: 600;
}

.jb-folder-notice {
    display: flex;
    align-items: flex-start;
    gap: .625rem;
    padding: .75rem .875rem;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-50);
    border: 1px solid var(--jb-gray-200);
    font-size: var(--jb-fs-sm);
    line-height: 1.5;
}

.jb-folder-notice i {
    margin-top: .2rem;
    color: var(--jb-gray-500);
}

.jb-folder-notice a {
    color: var(--jb-orange);
    text-decoration: underline;
}

/* ── Bouton inerte avec explication (survol et focus clavier) ─────────────── */
/* Un `disabled` sortirait le bouton de la tabulation : l'explication serait
   alors inatteignable au clavier, exactement pour l'utilisateur qui en a le
   plus besoin. Le bouton reste focusable, `aria-disabled` dit qu'il n'agit
   pas, et l'infobulle apparaît au survol comme au focus. */
.jb-tip {
    position: relative;
    opacity: .55;
    cursor: not-allowed;
}

.jb-tip::after {
    content: attr(data-tip);
    position: absolute;
    left: 50%;
    bottom: calc(100% + .5rem);
    z-index: 20;
    width: max-content;
    max-width: 15rem;
    padding: .5rem .625rem;
    transform: translateX(-50%);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-black);
    color: var(--jb-white);
    font-size: var(--jb-fs-xs);
    font-weight: 500;
    line-height: 1.4;
    text-align: center;
    white-space: normal;
    box-shadow: var(--jb-shadow-lg);
    opacity: 0;
    visibility: hidden;
    transition: opacity .15s ease;
    pointer-events: none;
}

.jb-tip:hover::after,
.jb-tip:focus-visible::after {
    opacity: 1;
    visibility: visible;
}

/* ==========================================================================
   Carte de dossier de talents (TODO.md Chantier V3.4 Lot G)
   ==========================================================================
   Remplace le tableau de l'écran « Mes dossiers de talents ». Une carte de
   dossier n'a que trois choses à dire — le nom, combien de profils, et ce
   qu'on peut en faire — donc pas d'ombre au repos ni d'accent coloré : ce
   qui doit se détacher ici, c'est le nom du recrutement en cours, pas le
   contenant.
   ========================================================================== */


/* Lien de couverture : la carte entière mène au détail, sans imbriquer le
   dropdown d'actions dans un `<a>` (un bouton dans un lien n'est pas valide
   et se comporte mal au clavier). */


/* ==========================================================================
   Onboarding (TODO.md Chantier V3.4 Lots H et I)
   --------------------------------------------------------------------------
   Écrans intermédiaires entre l'inscription et l'espace privé : plus larges
   qu'une carte d'authentification (il y a de vraies questions à poser), plus
   sobres qu'un tableau de bord (rien d'autre ne doit distraire). Aucun bandeau
   décoratif générique, aucun dégradé : fond gris clair, carte blanche, et
   l'orange réservé à l'étape en cours et au bouton principal.
   ========================================================================== */

.jb-onboarding {
    padding: 2.5rem 1rem 3.5rem;
    background: var(--jb-gray-50);
    min-height: calc(100dvh - var(--jb-header-height));
}

.jb-onboarding__shell {
    width: 100%;
    max-width: 46rem;
    margin: 0 auto;
}

.jb-onboarding__shell--narrow { max-width: 34rem; }

.jb-onboarding__head { margin-bottom: 1.5rem; }

.jb-onboarding__badge {
    display: inline-block;
    padding: .25rem .625rem;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
    font-size: var(--jb-fs-xs);
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.jb-onboarding__title {
    margin: .75rem 0 .5rem;
    font-size: var(--jb-fs-2xl);
    line-height: 1.25;
}

@media (min-width: 768px) {
    .jb-onboarding__title { font-size: var(--jb-fs-3xl); }
}

.jb-onboarding__lead {
    margin: 0;
    max-width: 38rem;
    color: var(--jb-gray-600);
}

/* Trois traits, pas un stepper numéroté : l'écran dit déjà à quelle étape on
   est, la barre ne sert qu'à montrer qu'il en reste peu. */
.jb-onboarding__progress {
    display: flex;
    gap: .375rem;
    margin-top: 1.25rem;
}

.jb-onboarding__progress span {
    flex: 1;
    height: 4px;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-gray-200);
}

.jb-onboarding__progress span.is-done { background: var(--jb-black); }
.jb-onboarding__progress span.is-current { background: var(--jb-orange); }

.jb-onboarding__card {
    padding: 1.5rem 1.25rem;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-lg);
}

@media (min-width: 576px) {
    .jb-onboarding__card { padding: 2rem; }
}

.jb-onboarding__section + .jb-onboarding__section {
    margin-top: 1.75rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--jb-gray-100);
}

.jb-onboarding__section-title {
    margin: 0 0 1rem;
    font-size: var(--jb-fs-base);
    font-weight: 700;
    color: var(--jb-gray-700);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.jb-onboarding__row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 1rem;
}

@media (min-width: 640px) {
    .jb-onboarding__row { grid-template-columns: 1fr 1fr; }
}

.jb-onboarding__row--tight { gap: .625rem; }

.jb-onboarding__choices {
    display: grid;
    gap: .625rem;
}

.jb-onboarding__birth {
    display: grid;
    grid-template-columns: 1fr 1.4fr 1.2fr;
    gap: .5rem;
}

.jb-onboarding__aside-field { margin-top: 1.25rem; }

.jb-onboarding__actions {
    margin-top: 1.75rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--jb-gray-100);
    display: grid;
    gap: .625rem;
}

.jb-onboarding__actions--stacked { border-top: none; }

.jb-onboarding__foot {
    margin-top: 1.25rem;
    text-align: center;
}

/* Aide affichée sous un libellé et au-dessus du champ : la consigne
   « plusieurs réponses possibles » n'a aucune utilité une fois le choix fait. */
.jb-help--above {
    display: block;
    margin: -.25rem 0 .625rem;
}

.jb-label__optional {
    margin-left: .375rem;
    font-weight: 500;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
    text-transform: none;
}

/* Case à cocher de consentement : alignée sur la première ligne du texte,
   jamais centrée sur un paragraphe de deux lignes. */
.jb-consent {
    display: flex;
    gap: .5rem;
    align-items: flex-start;
    font-size: var(--jb-fs-sm);
}

.jb-consent input {
    margin-top: .1875rem;
    accent-color: var(--jb-orange);
}

.jb-auth__field-note { margin-top: -.75rem; }

/* Repère d'étape des écrans d'authentification, même vocabulaire que la barre
   de progression de l'onboarding, en plus discret. */
.jb-auth__steps {
    display: flex;
    gap: .375rem;
    margin-bottom: 1.25rem;
}

.jb-auth__step {
    flex: 1;
    height: 4px;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-gray-200);
}

.jb-auth__step.is-current { background: var(--jb-orange); }

.jb-auth__switch {
    margin-top: .5rem;
    padding-top: .5rem;
}

/* Dépôt de document (CV à l'inscription, logo d'entreprise) : traitement
   propre au projet, médaillon orange plutôt que le rectangle en pointillés
   générique (ui-design-system § Formulaires et zones d'upload). */
.jb-cv-drop {
    display: flex;
    align-items: center;
    gap: .875rem;
    width: 100%;
    padding: 1rem;
    background: var(--jb-gray-50);
    border: 1px solid var(--jb-gray-300);
    border-radius: var(--jb-radius-md);
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
}

.jb-cv-drop:hover {
    border-color: var(--jb-gray-400);
    background: var(--jb-white);
}

.jb-cv-drop.is-filled {
    border-color: var(--jb-orange);
    background: var(--jb-orange-soft);
}

.jb-cv-drop__icon {
    flex: 0 0 auto;
    width: 46px;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border-radius: var(--jb-radius);
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-cv-drop.is-filled .jb-cv-drop__icon {
    background: var(--jb-orange);
    color: var(--jb-white);
}

.jb-cv-drop__icon img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.jb-cv-drop__body {
    flex: 1 1 auto;
    min-width: 0;
}

.jb-cv-drop__title {
    display: block;
    font-weight: 600;
    color: var(--jb-black);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.jb-cv-drop__hint {
    display: block;
    margin-top: .125rem;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-600);
}

.jb-cv-drop__action {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-300);
    color: var(--jb-gray-700);
}

.jb-cv-drop__note { margin: .625rem 0 0; }

/* Intention du recruteur : trois cartes-boutons, une action par carte. La
   troisième est le choix par défaut (le tableau de bord), d'où le seul
   traitement orange de l'écran. */
.jb-goal-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: .75rem;
}

@media (min-width: 768px) {
    .jb-goal-grid { grid-template-columns: repeat(3, 1fr); }
}

.jb-goal-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .5rem;
    padding: 1.25rem;
    text-align: left;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-300);
    border-radius: var(--jb-radius-md);
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.jb-goal-card:hover {
    border-color: var(--jb-gray-400);
    box-shadow: var(--jb-shadow);
}

.jb-goal-card__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: var(--jb-radius);
    background: var(--jb-gray-100);
    color: var(--jb-gray-800);
}

.jb-goal-card--primary { border-color: var(--jb-orange); }

.jb-goal-card--primary .jb-goal-card__icon {
    background: var(--jb-orange);
    color: var(--jb-white);
}

.jb-goal-card__title {
    font-weight: 700;
    color: var(--jb-black);
}

.jb-goal-card__help {
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
    line-height: 1.45;
}

/* Les trois fonctions de l'espace recruteur, rappelées sous le choix : de la
   pédagogie, pas une carte cliquable de plus. */
.jb-onboarding__brief {
    margin-top: 2rem;
    padding-top: 1.75rem;
    border-top: 1px solid var(--jb-gray-200);
}

.jb-onboarding__brief-title {
    margin: 0 0 1.25rem;
    font-size: var(--jb-fs-base);
    font-weight: 700;
    color: var(--jb-gray-700);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.jb-onboarding__brief-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
}

@media (min-width: 768px) {
    .jb-onboarding__brief-grid { grid-template-columns: repeat(3, 1fr); }
}

.jb-onboarding__brief-item svg,
.jb-onboarding__brief-item i {
    width: 20px;
    height: 20px;
    color: var(--jb-orange);
}

.jb-onboarding__brief-item h3 {
    margin: .5rem 0 .25rem;
    font-size: var(--jb-fs-base);
}

.jb-onboarding__brief-item p {
    margin: 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
    line-height: 1.5;
}

/* Sélecteur Connexion/Inscription : médaillon d'intention en tête de carte,
   pour que les deux cartes se distinguent avant même d'être lues. */
.jb-account-choice__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-bottom: .875rem;
    border-radius: var(--jb-radius);
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-account-choice__icon--dark {
    background: var(--jb-gray-100);
    color: var(--jb-black);
}

.jb-auth-chooser__note {
    margin: 1.5rem auto 0;
    max-width: 32rem;
    text-align: center;
}

/* Barre de sélection multiple (TODO.md Chantier V3.5 Lot D) : bandeau noir de
   la charte, sans dégradé (CLAUDE.md), fixée en bas d'écran pour rester
   atteignable pendant qu'on continue de cocher des cartes plus bas dans la
   liste. Composant structurant, réutilisable au-delà de Talents. */
.jb-bulk-bar {
    position: sticky;
    bottom: 1rem;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin: 1.5rem 0;
    padding: .85rem 1.25rem;
    border-radius: var(--jb-radius);
    background: var(--jb-black);
    color: var(--jb-white);
    box-shadow: var(--jb-shadow-lg);
}

.jb-bulk-bar__count {
    font-size: var(--jb-fs-sm);
    font-weight: 600;
}

.jb-bulk-bar__actions {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.jb-bulk-bar .jb-btn--outline {
    border-color: rgba(255, 255, 255, .3);
    color: var(--jb-white);
}

.jb-bulk-bar .jb-btn--outline:hover {
    border-color: var(--jb-white);
    color: var(--jb-white);
}

/* ==========================================================================
   Dépôt d'image carré, envoyé en Ajax (TODO.md Chantier V3.6 Lot B)
   --------------------------------------------------------------------------
   Complète `.jb-cv-drop` (bandeau horizontal, document) : ici l'image *est*
   le composant, parce que ce qu'on dépose est un logo carré et que le
   recruteur doit voir tout de suite le rendu réel. L'aperçu affiché est
   toujours le fichier renvoyé par le serveur, jamais un aperçu local.
   ========================================================================== */
.jb-square-drop {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 168px;
    height: 168px;
    padding: .75rem;
    text-align: center;
    background: var(--jb-gray-50);
    border: 1px dashed var(--jb-gray-300);
    border-radius: var(--jb-radius-md);
    cursor: pointer;
    overflow: hidden;
    transition: border-color .15s ease, background-color .15s ease;
}

.jb-square-drop:hover,
.jb-square-drop.is-dragover {
    border-color: var(--jb-orange);
    background: var(--jb-orange-soft);
}

.jb-square-drop.is-filled {
    border-style: solid;
    border-color: var(--jb-gray-200);
    background: var(--jb-white);
    padding: 0;
}

.jb-square-drop__placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .5rem;
    color: var(--jb-gray-600);
    font-size: var(--jb-fs-xs);
    line-height: 1.35;
}

.jb-square-drop__placeholder i,
.jb-square-drop__placeholder svg {
    width: 28px;
    height: 28px;
    color: var(--jb-orange);
}

.jb-square-drop.is-filled .jb-square-drop__placeholder {
    display: none;
}

.jb-square-drop__image {
    display: none;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.jb-square-drop.is-filled .jb-square-drop__image {
    display: block;
}

/* Voile d'action : visible au survol d'une zone déjà remplie, pour que
   « on peut changer l'image » reste évident sans ajouter un bouton de plus. */
.jb-square-drop__overlay {
    position: absolute;
    inset: auto 0 0 0;
    padding: .375rem .5rem;
    font-size: var(--jb-fs-xs);
    font-weight: 600;
    color: var(--jb-white);
    background: rgba(11, 10, 10, .72);
    opacity: 0;
    transition: opacity .15s ease;
}

.jb-square-drop.is-filled:hover .jb-square-drop__overlay {
    opacity: 1;
}

/* État d'envoi : la zone se fige et annonce le transfert en cours, plutôt
   que de laisser croire à un clic sans effet sur une connexion lente. */
.jb-square-drop.is-busy {
    pointer-events: none;
    opacity: .6;
}

.jb-square-drop__spinner {
    position: absolute;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, .75);
    color: var(--jb-orange);
}

.jb-square-drop.is-busy .jb-square-drop__spinner {
    display: flex;
}

/* ==========================================================================
   Sections de formulaire des espaces privés (TODO.md Chantier V3.6 Lot B)
   --------------------------------------------------------------------------
   Un long formulaire d'une seule carte se lit mal : chaque bloc porte son
   titre et son intention, avec un filet discret plutôt qu'une carte de plus.
   ========================================================================== */
.jb-form-section {
    padding: 1.25rem 0;
    border-top: 1px solid var(--jb-gray-200);
}

.jb-form-section:first-child {
    padding-top: 0;
    border-top: 0;
}


.jb-form-section__title {
    margin: 0;
    font-size: var(--jb-fs-base);
    font-weight: 700;
    color: var(--jb-black);
}

.jb-form-section__hint {
    margin: .125rem 0 0;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-600);
}

/* Barre de complétion de la fiche entreprise : dit ce qui manque, pas
   seulement un pourcentage (SPEC.md §4, règle d'état vide soignée). */
.jb-completion {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem 1.25rem;
    padding: .875rem 1.125rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
}


/* ==========================================================================
   Sélecteur de dossiers : lignes cochables (TODO.md Chantier V3.6 Lot D)
   --------------------------------------------------------------------------
   La ligne devient un `<label>` : toute sa surface coche la case, sans
   dépendre d'un clic précis sur un carré de 16 pixels au doigt.
   ========================================================================== */
.jb-folder-option__check-input {
    flex: none;
    width: 18px;
    height: 18px;
    margin: 0;
    accent-color: var(--jb-orange);
    cursor: pointer;
}

label.jb-folder-option {
    cursor: pointer;
    margin-bottom: .5rem;
}

label.jb-folder-option:hover {
    background: var(--jb-gray-50);
    border-color: var(--jb-gray-300);
}

.jb-folder-option.is-checked {
    background: var(--jb-orange-soft);
    border-color: var(--jb-orange);
}

.jb-folder-option.is-checked .jb-folder-option__icon {
    background: var(--jb-white);
    color: var(--jb-orange);
}

/* Dossier qui contient déjà le profil : coché et verrouillé, pour dire
   « destination déjà atteinte » sans laisser croire qu'on peut l'en retirer
   d'ici (le retrait se fait depuis la page du dossier). */
.jb-folder-option__check-input:disabled {
    cursor: default;
    opacity: .55;
}


/* ==========================================================================
   Dossiers de talents : couleur, description, sélection (Chantier V3.6 Lot E)
   ========================================================================== */

/* Palette fermée : sept pastilles, pas un sélecteur de couleur libre. La
   couleur sert de repère dans une liste, pas de décoration. */


/* Description du dossier sur sa carte : deux lignes au maximum, le reste est
   sur la page du dossier. */

/* Case de sélection d'un profil dans un dossier : dans le flux de la carte,
   pas en superposition comme sur les cartes de la CVthèque, où la carte est
   entièrement cliquable. */


/* ==========================================================================
   Modal de paiement partagé (TODO.md Chantier V3.6 Lot F)
   --------------------------------------------------------------------------
   Un seul gabarit pour tous les achats du produit : abonnement, crédits,
   boost, badge, publication à l'unité. Les cartes tarifaires ne portent plus
   de formulaire, elles ouvrent cette fenêtre.
   ========================================================================== */

/* Montant à payer : bandeau horizontal, première chose lue. */
.jb-checkout__total {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: .875rem 1.125rem;
    margin-bottom: 1.25rem;
    border-radius: var(--jb-radius-md);
    background: var(--jb-black);
    color: var(--jb-white);
}

.jb-checkout__total-label {
    font-size: var(--jb-fs-sm);
    opacity: .8;
}

.jb-checkout__total-value {
    font-size: 1.4rem;
    font-weight: 800;
    color: var(--jb-orange);
}

.jb-checkout__legend {
    float: none;
    width: auto;
    margin-bottom: .5rem;
    font-size: var(--jb-fs-xs);
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--jb-gray-600);
}

/* Trois opérateurs côte à côte, en grille : la carte reste lisible sur un
   écran étroit sans passer en liste, l'utilisateur voyant les trois choix
   d'un seul coup d'oeil. */
.jb-pay-methods {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .5rem;
    margin: 0 0 1.25rem;
    padding: 0;
    border: 0;
}

.jb-pay-method {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .375rem;
    padding: .75rem .375rem 1.5rem;
    text-align: center;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
    cursor: pointer;
    transition: border-color .15s ease, background-color .15s ease;
}

.jb-pay-method:hover {
    border-color: var(--jb-gray-400);
}

.jb-pay-method.is-selected {
    border-color: var(--jb-orange);
    background: var(--jb-orange-soft);
}

.jb-pay-method input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

/* Logo dans un cercle blanc : les images des opérateurs ont des fonds et des
   proportions très différents, le cercle les remet sur un pied d'égalité. */
.jb-pay-method__logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: .375rem;
    border-radius: 50%;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-200);
    overflow: hidden;
}

.jb-pay-method__logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.jb-pay-method__name {
    font-size: var(--jb-fs-xs);
    font-weight: 600;
    line-height: 1.2;
    color: var(--jb-black);
}

/* Pseudo-radio : le vrai contrôle reste le champ natif, masqué mais focusable
   (le contour de focus est repris sur la carte). */
.jb-pay-method__radio {
    position: absolute;
    bottom: .5rem;
    left: 50%;
    transform: translateX(-50%);
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 1.5px solid var(--jb-gray-300);
    background: var(--jb-white);
}

.jb-pay-method.is-selected .jb-pay-method__radio {
    border-color: var(--jb-orange);
    box-shadow: inset 0 0 0 3px var(--jb-orange);
}

.jb-pay-method input:focus-visible ~ .jb-pay-method__radio {
    outline: 2px solid var(--jb-orange);
    outline-offset: 2px;
}

/* Carte bancaire choisie : le numéro n'est plus demandé ici, il est saisi
   chez l'agrégateur. La zone reste visible mais éteinte, plutôt que de
   disparaître et de faire sauter la fenêtre. */
.jb-checkout__phone.is-disabled {
    opacity: .5;
    pointer-events: none;
}

/* Récapitulatif : encadré gris léger, replié par défaut. */
.jb-checkout__summary {
    margin-top: 1rem;
    padding: .75rem .875rem;
    border-radius: var(--jb-radius-md);
    background: var(--jb-gray-50);
    border: 1px solid var(--jb-gray-200);
}

.jb-checkout__summary-toggle {
    padding: 0;
    border: 0;
    background: none;
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-700);
    cursor: pointer;
}

.jb-checkout__summary-list {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: .375rem 1rem;
    margin: .75rem 0 0;
    font-size: var(--jb-fs-sm);
}

.jb-checkout__summary-list dt {
    font-weight: 500;
    color: var(--jb-gray-600);
}

.jb-checkout__summary-list dd {
    margin: 0;
    text-align: right;
    font-weight: 600;
    color: var(--jb-black);
}

/* Le lien d'annulation reste atteignable mais discret : la demande est
   explicite, il ne doit pas concurrencer l'action de paiement. */
.js-checkout-cancel {
    text-decoration: none;
    font-size: var(--jb-fs-xs);
}

/* ==========================================================================
   Back-office (layout manager) : Administration et espace Recruteur
   --------------------------------------------------------------------------
   Le back-office tournait en Bootstrap d'origine : cartes blanches, onglets
   gris, tableaux nus. Ces composants lui donnent le même vocabulaire visuel
   que le site public (mêmes jetons, même sobriété), sans remplacer Bootstrap
   qui continue de porter la grille, les modales et les dropdowns.
   ========================================================================== */

/* En-tête de page : titre, contexte, action principale à droite. Pas de
   bandeau décoratif, la hiérarchie vient du poids typographique. */


/* Onglets de file de travail. Le compteur fait partie de l'onglet : on doit
   voir d'un coup d'oeil où est le travail, sans ouvrir chaque file. */


.jb-mg-tab.is-active {
    color: var(--jb-black);
    border-bottom-color: var(--jb-orange);
}


.jb-mg-tab.is-active .jb-mg-tab__count {
    background: var(--jb-black);
    color: var(--jb-white);
}

/* L'orange ne signale qu'une chose ici : du travail réellement en attente. */
.jb-mg-tab__count--alert,
.jb-mg-tab.is-active .jb-mg-tab__count--alert {
    background: var(--jb-orange);
    color: var(--jb-white);
}

/* Bandeau de contexte : ce que l'admin doit faire dans la file ouverte. */


/* Barre de filtres. Sobre : elle sert la liste, elle ne la concurrence pas. */


/* Liste de dossiers. Un tableau nu ne dit pas qui est le demandeur : la
   vignette et le nom passent devant, les métadonnées suivent. */


/* Étiquette de contexte : type de compte, ancienneté, alerte de retard. */


/* État vide : une file à jour est une bonne nouvelle, pas une page cassée. */


/* Panneau de contenu (remplace .card sur les écrans retravaillés). */


/* Paire libellé/valeur, pour les blocs de contexte d'un dossier. */


/* Pièces jointes d'un dossier de vérification. */


/* Points de contrôle avant décision : deux administrateurs doivent juger sur
   les mêmes critères. */


/* Barre de décision, collée en bas de l'écran d'examen : l'action ne doit
   jamais sortir du champ de vision pendant qu'on inspecte une piece. */


@media (max-width: 575.98px) {


    .jb-mg-decision__actions .btn {
        flex: 1 1 0;
    }
}

/* Fenêtre de filtres mobile (listings Talents et Entreprises).
   Le même composant de facettes sert la colonne desktop et cette fenêtre :
   ici on retire son encadrement (la fenêtre en tient déjà lieu) et on colle
   le bouton « Appliquer » en bas, pour qu'il reste atteignable après avoir
   fait défiler dix groupes de critères. */
.jb-filters-modal .modal-content {
    border: 0;
    border-radius: var(--jb-radius-md);
}

.jb-filters-modal .modal-header {
    border-bottom: 1px solid var(--jb-gray-200);
}

.jb-filters-modal .modal-body {
    padding: 0;
}

.jb-filters-modal .jb-facets {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 1rem;
}

.jb-filters-modal .js-facet-submit {
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin-top: 1rem;
}

/* L'ombre sépare le bouton collé du dernier groupe de critères qui défile
   dessous, sans ajouter de barre décorative. */
.jb-filters-modal .js-facet-submit::after {
    content: "";
    position: absolute;
    left: -1rem;
    right: -1rem;
    top: -1rem;
    bottom: -1rem;
    z-index: -1;
    background: var(--jb-white);
    box-shadow: 0 -8px 16px rgba(255, 255, 255, .9);
}

@media (max-width: 575.98px) {
    .jb-filters-modal .modal-content {
        border-radius: 0;
    }
}

/* Recherche dans les dossiers du sélecteur Talents (Chantier V3.7 Lot C).
   Le champ n'est rendu visible par le script qu'à partir de quatre dossiers ;
   la liste passe alors en zone défilante à hauteur fixe, pour qu'une
   entreprise à quinze dossiers n'obtienne pas une modale à rallonge. */
.jb-folder-search {
    position: relative;
    margin-bottom: .625rem;
}

.jb-folder-search svg {
    position: absolute;
    top: 50%;
    left: .75rem;
    width: 16px;
    height: 16px;
    transform: translateY(-50%);
    color: var(--jb-gray-500);
    pointer-events: none;
}

.jb-folder-search input {
    width: 100%;
    padding: .5rem .75rem .5rem 2.25rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-50);
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-800);
}

.jb-folder-search input:focus {
    outline: none;
    background: var(--jb-white);
    border-color: var(--jb-orange);
}

.jb-folder-list.is-scrollable {
    max-height: 260px;
    overflow-y: auto;
    padding-right: .25rem;
}

/* Formulaires d'offres du back-office (Chantier V3.7 Lot D). Un quota se
   saisit dans un encadré avec son interrupteur et son compteur : coché sans
   valeur, il vaut « illimité », ce que le texte d'aide dit sous le champ. */

.jb-mg-quota .form-text {
    margin-top: .25rem;
    font-size: var(--jb-fs-xs);
}


.jb-mg-flag .form-check-label {
    cursor: pointer;
}


/* ==========================================================================
   Cartes tarifaires (paliers d'abonnement)
   --------------------------------------------------------------------------
   L'en-tête tout blanc ne hiérarchisait rien et l'étiquette « Populaire »
   passait inaperçue. Ici l'en-tête est teinté, le palier mis en avant prend
   le fond noir de la marque, et l'orange est réservé à deux choses : son
   étiquette et le prix. Aucun dégradé (règle de la feuille).
   ========================================================================== */


.jb-plan-card.is-current {
    border-color: var(--jb-orange);
}


/* Le palier mis en avant se distingue par le contraste, pas par une couleur
   de plus : fond noir de la marque, étiquette orange. */


/* Les trois chiffres qui décident d'un achat, comparables d'une carte à
   l'autre parce qu'ils sont toujours à la même place. */


/* Nouveauté du palier : le seul endroit de la liste où l'orange apparaît,
   parce que c'est exactement ce qu'on achète en montant d'un cran. */


/* Chapeau de section : introduit un bloc de la page sans le déguiser en
   bannière décorative. */

/* ==========================================================================
   Habillage global du back-office
   --------------------------------------------------------------------------
   Le layout manager sert une trentaine d'écrans encore écrits en Bootstrap
   d'origine (cartes blanches à coins carrés, tableaux nus, en-têtes gris).
   Les reprendre un par un aurait pris le chantier entier ; ces règles portent
   sur les composants que ces écrans utilisent déjà, ce qui les remonte tous
   d'un cran d'un seul coup, sans toucher à leur balisage.

   Elles restent volontairement sobres : bordure fine, rayon cohérent avec le
   site public, ombre réservée à ce qui doit se détacher (menu ouvert, fenêtre
   modale). Un écran repris ensuite en composants `jb-mg-*` gagne davantage,
   mais aucun n'est laissé au rendu par défaut en attendant.
   ========================================================================== */


/* Titres de page : le back-office employait `h1.h3` un peu partout. */


/* Cartes : c'est le conteneur de presque tous les écrans admin. */
#layoutSidenav_content .card {
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    box-shadow: none;
}

#layoutSidenav_content .card > .card-header,
#layoutSidenav_content .card > .card-header.bg-white {
    padding: .875rem 1.125rem;
    border-bottom: 1px solid var(--jb-gray-200);
    background: var(--jb-gray-50);
    font-weight: 700;
    color: var(--jb-black);
}

/* Tableaux : en-tête lisible, lignes qui se distinguent au survol, aucune
   bordure superflue entre les cellules. */
#layoutSidenav_content .table > thead > tr > th {
    padding: .75rem 1rem;
    border-bottom: 1px solid var(--jb-gray-200);
    background: var(--jb-gray-50);
    font-size: var(--jb-fs-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--jb-gray-600);
    white-space: nowrap;
}

#layoutSidenav_content .table > tbody > tr > td {
    padding: .75rem 1rem;
    border-bottom: 1px solid var(--jb-gray-100);
    vertical-align: middle;
}

#layoutSidenav_content .table > tbody > tr:last-child > td {
    border-bottom: 0;
}

#layoutSidenav_content .table > tbody > tr:hover {
    background: var(--jb-gray-50);
}

/* Boutons : hiérarchie explicite, rayon aligné sur le site public, jamais de
   pilule appliquée par réflexe (anti-pattern refusé). */
#layoutSidenav_content .btn,
.sb-topnav .btn {
    border-radius: var(--jb-radius-sm);
    font-weight: 600;
}

#layoutSidenav_content .btn-primary {
    background: var(--jb-orange);
    border-color: var(--jb-orange);
    color: var(--jb-white);
}

#layoutSidenav_content .btn-primary:hover,
#layoutSidenav_content .btn-primary:focus {
    background: var(--jb-orange-dark);
    border-color: var(--jb-orange-dark);
}

#layoutSidenav_content .btn-dark {
    background: var(--jb-black);
    border-color: var(--jb-black);
}


/* Champs de formulaire : même trait que le site public. */
#layoutSidenav_content .form-control,
#layoutSidenav_content .form-select {
    border-color: var(--jb-gray-300);
    border-radius: var(--jb-radius-sm);
}

#layoutSidenav_content .form-control:focus,
#layoutSidenav_content .form-select:focus {
    border-color: var(--jb-orange);
    box-shadow: 0 0 0 3px rgba(254, 103, 3, .12);
}

#layoutSidenav_content .form-label {
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-700);
}

#layoutSidenav_content .form-check-input:checked {
    background-color: var(--jb-orange);
    border-color: var(--jb-orange);
}

/* Onglets Bootstrap encore utilisés par les écrans non repris : même trait
   que les files de travail `jb-mg-tabs`, pour éviter deux styles d'onglets
   dans le même back-office. */
#layoutSidenav_content .nav-tabs {
    border-bottom: 1px solid var(--jb-gray-200);
}

#layoutSidenav_content .nav-tabs .nav-link {
    border: 0;
    border-bottom: 2px solid transparent;
    font-weight: 600;
    color: var(--jb-gray-600);
}

#layoutSidenav_content .nav-tabs .nav-link:hover {
    color: var(--jb-black);
}

#layoutSidenav_content .nav-tabs .nav-link.active {
    background: none;
    color: var(--jb-black);
    border-bottom-color: var(--jb-orange);
}

/* Pastilles d'état : rayon doux plutôt que pilule, et un gris qui reste
   lisible sur fond clair. */
#layoutSidenav_content .badge {
    border-radius: var(--jb-radius-sm);
    font-weight: 700;
    letter-spacing: .01em;
}

/* Fenêtres modales et menus déroulants : les deux seuls endroits du
   back-office où une ombre est justifiée. */
#layoutSidenav_content .modal-content,
.sb-topnav .dropdown-menu {
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    box-shadow: var(--jb-shadow-lg);
}

#layoutSidenav_content .modal-header,
#layoutSidenav_content .modal-footer {
    border-color: var(--jb-gray-200);
}

/* Pagination : alignée sur celle du site public. */
#layoutSidenav_content .page-link {
    border-color: var(--jb-gray-200);
    color: var(--jb-gray-700);
}

#layoutSidenav_content .page-item.active .page-link {
    background: var(--jb-black);
    border-color: var(--jb-black);
    color: var(--jb-white);
}

/* Icônes Lucide dans les boutons du back-office : alignées sur le texte et
   dimensionnées, sinon elles arrivent en 24px et déforment le bouton. */
#layoutSidenav_content .btn svg,
.sb-topnav .btn svg {
    width: 16px;
    height: 16px;
    vertical-align: -3px;
    margin-right: .25rem;
}

#layoutSidenav_content .btn-sm svg {
    width: 14px;
    height: 14px;
}

/* ==========================================================================
   Avantages de palier appliqués au produit (Chantier V3.7 Lot G)
   --------------------------------------------------------------------------
   Deux traitements seulement, tous deux au service de la même règle : ce qui
   est payant reste visible, verrouillé, avec de quoi y accéder. Rien n'est
   masqué, sinon personne n'aurait de raison de souscrire.
   ========================================================================== */

/* Groupe de facettes réservé à un palier (filtres avancés de la CVthèque). */
.jb-facet--locked {
    opacity: .85;
}

.jb-facet--locked .jb-facet__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    color: var(--jb-gray-500);
    cursor: default;
}

.jb-facet__lock {
    width: 15px;
    height: 15px;
    color: var(--jb-orange);
}

.jb-facet__locked-text {
    margin: .25rem 0 0;
    font-size: var(--jb-fs-xs);
    line-height: 1.4;
    color: var(--color-text-muted);
}

.jb-facet__locked-text a {
    font-weight: 600;
    color: var(--jb-orange);
}

/* Option de publication réservée à un palier (mode incognito). */

.jb-plan-option.is-locked {
    background: var(--jb-gray-50);
    border-style: dashed;
}

.jb-plan-option.is-locked .form-check-label {
    color: var(--jb-gray-600);
}

.jb-plan-option .form-check-label svg {
    width: 14px;
    height: 14px;
    vertical-align: -2px;
    color: var(--jb-orange);
}


/* ============================================================================
   CARTES DE ROLE D'EQUIPE (TODO.md Chantier V3.8 Lot C)
   ----------------------------------------------------------------------------
   Un role se lit comme une fiche de poste, pas comme une ligne de tableau :
   ce qui compte est son nom, combien de personnes le portent et l'etendue de
   ce qu'il ouvre. Le bouton d'actions flotte en haut a droite, a la place ou
   les cartes du produit le posent deja.
   ========================================================================== */


/* Un role suspendu n'accorde plus rien : la carte le dit sans le cacher. */


/* Le second chiffre porte l'etendue des droits : c'est lui qui distingue deux
   roles de meme taille, d'ou l'accent reserve a cette colonne. */


/* Bouton d'actions rond et discret, aligne sur le badge de statut. */

/* ============================================================================
   PACKS DE CREDITS (TODO.md Chantier V3.8 Lot E)
   ----------------------------------------------------------------------------
   Les paliers d'abonnement ont ete refondus au Chantier V3.7 ; les packs, eux,
   etaient restes sur la carte plate generique. Ils recoivent ici leur propre
   traitement, volontairement different de celui des paliers : un pack est un
   achat unique, et ce qu'on compare d'un pack a l'autre n'est pas un prix
   mensuel mais une quantite et un prix a l'unite.
   ========================================================================== */

/* Le CTA qui introduit la section : contraste fort, comme le bandeau d'etat en
   haut de page. Sans lui, les packs arrivaient apres la grille tarifaire sans
   aucune rupture visuelle, et se lisaient comme une seconde grille concurrente. */


/* La quantite achetee, seul chiffre reellement comparable d'un pack a l'autre. */


/* L'orange ne signale qu'une chose ici : une economie reelle. */


/* ============================================================================
   PUBLICATION ET SUIVI D'UN EVENEMENT PROFESSIONNEL (Chantier V3.8, Lots F/I)
   ----------------------------------------------------------------------------
   Le parcours vit sur le site public et non dans un back-office : il doit
   pouvoir etre suivi par un organisme qui n'a pas de compte et ne reviendra
   peut-etre jamais. D'ou une pedagogie visible plutot que devinable.
   ========================================================================== */

/* Bandeau pedagogique en tete du parcours. Le lien souligne ouvre le modal :
   c'est un lien, il doit ressembler a un lien, pas a un bouton de plus. */
.jb-event-notice {
    margin-bottom: 1.25rem;
}

.jb-linkish {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    font-weight: 600;
    color: var(--jb-orange);
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
}

.jb-linkish:hover {
    color: var(--jb-black);
}

/* Contenu du modal « Comment ca marche ». */
.jb-how__title {
    margin: 1.25rem 0 .375rem;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--jb-orange);
}

.jb-how__title:first-child {
    margin-top: 0;
}

.jb-how__text {
    margin: 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-700);
}

.jb-how__steps {
    margin: 0;
    padding-left: 1.125rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-700);
}

.jb-how__steps li {
    margin-bottom: .5rem;
}

/* Lien de rappel dans le recapitulatif : discret, il ne doit pas concurrencer
   le bouton d'envoi qui est l'action principale de l'ecran. */
.jb-recap dd a {
    margin-left: .5rem;
    font-size: var(--jb-fs-xs);
    font-weight: 500;
    color: var(--jb-gray-600);
    text-decoration: underline;
}

.jb-recap dd a:hover {
    color: var(--jb-orange);
}

/* Aide sous une tuile de statistique : un chiffre sans sa definition se
   surinterprete, surtout quand quatre chiffres se suivent. */
.jb-stat-tile__help {
    display: block;
    margin-top: .375rem;
    font-size: var(--jb-fs-xs);
    line-height: 1.35;
    color: var(--jb-gray-600);
}

/* Confirmation d'envoi : un seul bloc, contraste, sans decor generique. */
.jb-success-panel {
    padding: 2rem 1.5rem;
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
    text-align: center;
}

.jb-success-panel__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    margin-bottom: .875rem;
    border-radius: 50%;
    background: var(--jb-orange);
    color: var(--jb-white);
    font-size: 1.25rem;
}

.jb-success-panel__title {
    margin: 0 0 .5rem;
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--jb-black);
}

.jb-success-panel__text {
    margin: 0;
    color: var(--jb-gray-600);
}

/* Ligne cliquable d'une liste courte (annonces deja ouvertes sur l'appareil). */
.jb-linkrow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .75rem .25rem;
    color: var(--jb-black);
    font-weight: 600;
    text-decoration: none;
}

.jb-linkrow + .jb-linkrow {
    border-top: 1px solid var(--jb-gray-200);
}

.jb-linkrow:hover {
    color: var(--jb-orange);
}

/* ============================================================================
   CARTE DE MODERATION D'EVENEMENT (TODO.md Chantier V3.8 Lot G)
   ----------------------------------------------------------------------------
   Decider d'une mise en ligne demande de voir le programme, pas une ligne de
   tableau tronquee : la carte porte ce qui permet de trier (dates, lieu, voie
   d'arrivee), la fiche reste necessaire pour lire le contenu et decider.
   ========================================================================== */


/* =========================================================================
   ÉVÉNEMENTS PROFESSIONNELS — miniature, grille tarifaire, fiche
   (Chantier V3.9, demande porteur de projet du 2026-08-30)
   ========================================================================= */

/* Zone de dépôt horizontale : même plugin et mêmes classes internes que
   `.jb-square-drop` (image-dropzone.js cible `.jb-square-drop__image`), seule
   la boîte change. Une affiche d'événement se juge sur sa largeur, la
   déposer dans un carré de 168 px ne dit rien de ce qui sera publié. */
.jb-square-drop--wide {
    width: 100%;
    max-width: 520px;
    height: auto;
    aspect-ratio: 16 / 9;
}

.jb-square-drop--wide .jb-square-drop__placeholder {
    font-size: var(--jb-fs-sm);
}

/* ----- Bandeau visuel de la fiche événement -----
   L'affiche est montrée entière (`contain`) sur un fond neutre, jamais
   recadrée : le titre et la date d'un événement sont souvent imprimés dans
   les bords de l'image, et un `cover` les couperait précisément. */
.jb-event-cover {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    max-height: 420px;
    margin-bottom: 1.25rem;
    background: var(--jb-gray-100);
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
    overflow: hidden;
}

.jb-event-cover img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* ----- Grille tarifaire -----
   Cartes plutôt que tableau : trois paliers au maximum se lisent côte à
   côte, et un tableau HTML est proscrit sur les listes du produit
   (CLAUDE.md § Règles UI/UX). */
.jb-fee-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: .75rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.jb-fee-card {
    padding: .875rem 1rem;
    background: var(--jb-white);
    border: 1px solid var(--jb-gray-200);
    border-radius: var(--jb-radius-md);
}

.jb-fee-card__label {
    margin: 0 0 .25rem;
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-600);
}

.jb-fee-card__price {
    margin: 0;
    font-size: var(--jb-fs-lg);
    font-weight: 700;
    color: var(--jb-orange);
}

.jb-fee-card__desc {
    margin: .35rem 0 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

/* ==========================================================================
   Générateurs de documents — aperçu et catalogue de modèles
   (TODO.md Chantier V3.10 Lot E)
   --------------------------------------------------------------------------
   Le contenu de ces cartes est un document. C'est donc le document qu'on
   montre, à sa vraie mise en page, et pas une carte de plus décorée autour
   d'un titre : sur un choix de modèle de CV, l'aperçu EST l'information.

   L'aperçu est une page A4 réelle (210 mm) posée dans une iframe et réduite
   par `document-preview.js`. Le CSS ci-dessous ne fixe donc jamais de facteur
   d'échelle : il cadre, il ne mesure pas.
   ========================================================================== */

.doc-preview {
    position: relative;
    width: 100%;
    background-color: var(--jb-white);
}

.doc-preview__stage {
    position: relative;
    width: 100%;
    overflow: hidden;
}

/* La vignette d'une carte ne montre que le haut de la page, avec un fondu en
   pied : montrer une A4 entière sur une carte de grille donnerait une carte
   trois fois plus haute que large, illisible en liste. */
.doc-preview--head .doc-preview__stage {
    height: 290px;
}

.doc-preview--head .doc-preview__stage::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 56px;
    background-color: var(--jb-white);
    -webkit-mask-image: linear-gradient(to top, #000 0%, transparent 100%);
    mask-image: linear-gradient(to top, #000 0%, transparent 100%);
    pointer-events: none;
}

.doc-preview__frame {
    display: block;
    border: 0;
    background-color: var(--jb-white);

    /* L'aperçu n'est pas une zone de travail : cliquer dedans ne doit ni
       sélectionner du texte, ni déplacer le curseur dans un document qu'on ne
       modifie pas ici. */
    pointer-events: none;
}

.doc-preview__loader {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--jb-gray-50);
    color: var(--color-text-muted);
    transition: opacity 0.2s ease;
}

.doc-preview__loader.is-done {
    opacity: 0;
    visibility: hidden;
}

/* ----- Carte de modèle ----- */

.doc-template-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    border: 1px solid var(--color-border);
    border-radius: 12px;
    overflow: hidden;
    background-color: var(--jb-white);
    transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.doc-template-card:hover {
    border-color: var(--jb-gray-300);
    box-shadow: 0 10px 26px rgba(11, 10, 10, 0.09);
}

/* Le fond gris fait office de plan de travail : la page blanche s'en détache,
   ce qui la donne à lire comme une feuille et non comme le fond de la carte. */
.doc-template-card__stage {
    position: relative;
    padding: 14px 14px 0;
    background-color: var(--color-bg-soft-2);
}

.doc-template-card__stage .doc-preview {
    border: 1px solid var(--color-border);
    border-bottom: 0;
    border-radius: 4px 4px 0 0;
    overflow: hidden;
}

.doc-template-card__zoom {
    position: absolute;
    right: 20px;
    bottom: 14px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background-color: var(--jb-white);
    color: var(--jb-gray-800);
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    transform: translateY(4px);
    transition: opacity 0.18s ease, transform 0.18s ease;
}

.doc-template-card__zoom i {
    width: 14px;
    height: 14px;
}

.doc-template-card:hover .doc-template-card__zoom,
.doc-template-card__zoom:focus-visible {
    opacity: 1;
    transform: translateY(0);
}

/* Sur mobile, il n'y a pas de survol : le bouton reste visible, sans quoi
   l'agrandissement serait purement et simplement inaccessible. */
@media (hover: none) {
    .doc-template-card__zoom {
        opacity: 1;
        transform: none;
    }
}

.doc-template-card__body {
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 1;
    padding: 16px 16px 18px;
}

.doc-template-card__name {
    margin: 0;
    font-size: 1.02rem;
    font-weight: 700;
    color: var(--jb-black);
}

.doc-template-card__summary {
    margin: 0;
    font-size: 0.86rem;
    line-height: 1.5;
    color: var(--color-text-muted);
}

.doc-template-card__nocolor {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-size: 0.78rem;
    color: var(--color-text-faint);
}

.doc-template-card__nocolor i {
    width: 14px;
    height: 14px;
}

/* Le bouton de départ est poussé en pied de carte : les cartes n'ont pas
   toutes le même nombre de lignes de résumé, et des CTA décalés d'une ligne
   à l'autre se lisent comme un défaut d'alignement. */
.doc-template-card__body .jb-btn {
    margin-top: auto;
}

/* ----- Pastilles de couleur ----- */

.doc-swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.doc-swatch {
    width: 22px;
    height: 22px;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: 50%;
    background-color: var(--doc-swatch, var(--jb-gray-300));
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.doc-swatch:hover {
    transform: scale(1.12);
}

/* La sélection est un anneau, pas une bordure épaisse : la pastille doit
   rester de la couleur qu'elle annonce, à sa taille. */
.doc-swatch.is-active {
    box-shadow: 0 0 0 2px var(--jb-white), 0 0 0 4px var(--jb-black);
}

/* ----- Agrandissement ----- */

.doc-zoom__stage {
    max-width: 560px;
    margin: 0 auto;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    overflow: hidden;
}

.doc-zoom .modal-footer {
    justify-content: space-between;
    gap: 12px;
}

.doc-catalog-intro {
    max-width: 720px;
}

.doc-catalog-intro__title {
    margin: 0 0 6px;
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--jb-black);
}

.doc-catalog-intro__text {
    margin: 0;
    font-size: 0.93rem;
    line-height: 1.6;
    color: var(--color-text-muted);
}

/* Compatibilité avec les logiciels de tri, dite au moment du choix d'un
   modèle (chantier V3.14 Lot I). Une ligne mise en avant, et sa réserve juste
   en dessous en plus petit : la nuance doit rester lisible sans concurrencer
   l'argument. */
.doc-catalog-intro__ats {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin: 12px 0 0;
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-bg-soft);
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--color-text-muted);
}

.doc-catalog-intro__ats i {
    flex: none;
    width: 16px;
    height: 16px;
    margin-top: 2px;
    color: var(--jb-orange);
}

.doc-catalog-intro__ats strong {
    color: var(--jb-black);
}

.doc-catalog-intro__caveat {
    margin: 8px 0 0;
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--color-text-faint);
}

/* Sur la carte, la même information tient en deux lignes : l'ordre de lecture
   du modèle est un critère de choix au même titre que sa couleur. */
.doc-template-card__ats {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 0;
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--color-text-muted);
}

.doc-template-card__ats i {
    flex: none;
    width: 14px;
    height: 14px;
    margin-top: 2px;
    color: var(--jb-orange);
}

.doc-template-card__ats strong {
    color: var(--jb-black);
    font-weight: 600;
}

/* ==========================================================================
   Espace de travail des générateurs (TODO.md Chantier V3.10 Lot F)
   --------------------------------------------------------------------------
   Un écran sans navigation, sans pied de page, sans rien d'autre à faire que
   ce qui est demandé. La seule couleur pleine de l'écran est le bouton qui
   fait avancer : c'est ce qui rend l'action suivante évidente sur un
   formulaire de dix minutes.
   ========================================================================== */

.generator-body {
    min-height: 100vh;
    background-color: var(--color-bg-soft);
}

.generator-head {
    position: sticky;
    top: 0;
    z-index: 30;
    background-color: var(--jb-white);
    border-bottom: 1px solid var(--color-border);
}

.generator-head__inner {
    display: flex;
    align-items: center;
    gap: 16px;
    max-width: 1240px;
    margin: 0 auto;
    padding: 12px 20px;
}

.generator-head__logo {
    display: inline-flex;
    align-items: center;
}
.generator-head__logo img{
    width: 150px;
}

/* Le nom de l'outil est un repère, pas un titre : il se tient derrière un
   séparateur discret plutôt que de concurrencer le titre de l'étape. */
.generator-head__tool {
    padding-left: 16px;
    border-left: 1px solid var(--color-border);
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--jb-gray-700);
}

.generator-head__exit {
    margin-left: auto;
}

.generator-head__link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--color-text-muted);
    text-decoration: none;
}

.generator-head__link:hover {
    color: var(--jb-black);
}

.generator-head__link i {
    width: 16px;
    height: 16px;
}

.generator-main {
    max-width: 1240px;
    margin: 0 auto;
    padding: 0 20px 60px;
}
@media screen and (max-width: 768px) {
    .generator-main {
        padding: 0 12px 40px;
    }
}

/* ----- Stepper en icônes ----- */

.gen-stepper {
    padding: 22px 0 4px;
    overflow-x: auto;
}

.gen-stepper__list {
    display: flex;
    align-items: flex-start;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
    min-width: max-content;
}

/* Le trait de liaison est porté par l'item, pas par un élément à part : il
   suit ainsi automatiquement le nombre d'étapes, qui diffère entre le CV
   (6 étapes) et la lettre (3). */
.gen-stepper__item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    flex: 1;
    min-width: 74px;
    text-align: center;
}

.gen-stepper__item + .gen-stepper__item::before {
    content: "";
    position: absolute;
    top: 19px;
    right: 50%;
    left: -50%;
    height: 2px;
    background-color: var(--jb-gray-200);
}

.gen-stepper__item.is-done::before,
.gen-stepper__item.is-current::before {
    background-color: var(--jb-orange);
}

.gen-stepper__dot {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border: 1px solid var(--color-border);
    border-radius: 50%;
    background-color: var(--jb-white);
    color: var(--jb-gray-500);
    text-decoration: none;
}

.gen-stepper__dot i {
    width: 17px;
    height: 17px;
}

.gen-stepper__item.is-done .gen-stepper__dot {
    border-color: var(--jb-orange);
    color: var(--jb-orange);
}


/* L'étape en cours est la seule pleine : une pastille pleine par écran, comme
   une action principale par écran. */
.gen-stepper__item.is-current .gen-stepper__dot {
    border-color: var(--jb-orange);
    background-color: var(--jb-orange);
    color: var(--jb-white);
}

.gen-stepper__label {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

.gen-stepper__item.is-current .gen-stepper__label {
    color: var(--jb-black);
}
@media screen and (max-width: 768px) {
.gen-stepper__item { 
    min-width: 50px; 
}

.gen-stepper__dot { 
    width: 29px;
    height: 29px; 
}

.gen-stepper__dot i, .gen-stepper__dot svg {
    width: 14px;
    height: 14px;
}
.gen-stepper__label {
    font-size: 0.52rem; 
}
.gen-stepper__item + .gen-stepper__item::before {
    content: "";
    position: absolute;
    top: 12px;
}

}
/* ----- Deux colonnes : saisie et aperçu ----- */

.gen-work {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: 24px;
    align-items: start;
    margin-top: 18px;
}

.gen-step {
    padding: 24px;
    background-color: var(--jb-white);
    border: 1px solid var(--color-border);
    border-radius: 14px;
}

.gen-step__head {
    margin-bottom: 20px;
}

.gen-step__count {
    display: block;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--jb-orange);
}

.gen-step__title {
    margin: 4px 0 0;
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--jb-black);
}

.gen-fields {
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.gen-step__actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 26px;
    padding-top: 18px;
    border-top: 1px solid var(--color-border-soft);
}

/* La suppression n'est pas une action de l'étape : elle vit hors de la carte,
   en pied de colonne, pour ne jamais se retrouver à côté du bouton qui fait
   avancer. */
.gen-step__footer {
    margin-top: 14px;
    text-align: center;
}

.gen-step__discard {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border: 0;
    background: none;
    font-size: 0.82rem;
    color: var(--color-text-faint);
    cursor: pointer;
}

.gen-step__discard:hover {
    color: var(--jb-danger);
}

.gen-step__discard i {
    width: 15px;
    height: 15px;
}

/* ----- Lignes répétables ----- */

.gen-rows {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.gen-row {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 18px;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background-color: var(--jb-gray-50);
}

.gen-rows--tight .gen-row {
    padding: 14px;
}

.gen-row--inline {
    flex-direction: row;
    align-items: flex-end;
    gap: 12px;
}

.gen-row__remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    flex: 0 0 28px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background-color: var(--jb-white);
    color: var(--color-text-faint);
    cursor: pointer;
}

.gen-row:not(.gen-row--inline) .gen-row__remove {
    position: absolute;
    top: 12px;
    right: 12px;
}

.gen-row__remove:hover {
    border-color: var(--jb-danger);
    color: var(--jb-danger);
}

.gen-row__remove i {
    width: 15px;
    height: 15px;
}

.gen-row__check {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 0.82rem;
    color: var(--jb-gray-700);
    cursor: pointer;
}

.gen-group + .gen-group {
    margin-top: 26px;
    padding-top: 24px;
    border-top: 1px solid var(--color-border-soft);
}

.gen-group__title {
    margin: 0 0 14px;
    font-size: 1rem;
    font-weight: 700;
    color: var(--jb-black);
}

.gen-note {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background-color: var(--jb-gray-50);
    font-size: 0.86rem;
    color: var(--jb-gray-700);
}

.gen-note i {
    width: 17px;
    height: 17px;
    flex-shrink: 0;
    color: var(--jb-gray-500);
}

/* ----- Dates en listes (mois + année) -----
   Deux listes côte à côte, qui se replient l'une sous l'autre quand la colonne
   devient trop étroite : sur un téléphone, deux listes de 12 et 68 entrées
   écrasées sur une demi-largeur sont illisibles. */

.gen-date {
    display: flex;
    gap: 8px;
}

.gen-date .form-select {
    min-width: 0;
    flex: 1 1 0;
}

/* Liste neutralisée par la case « en cours ». Grisée mais toujours lisible :
   masquer le champ laisserait croire qu'il a disparu, alors qu'il attend
   seulement que la case soit décochée. */
.gen-date .form-select.is-locked,
.form-select.is-locked {
    background-color: var(--jb-gray-100);
    color: var(--color-text-muted);
    pointer-events: none;
}

/* ----- Photo du CV ----- */

.gen-photo {
    display: flex;
    align-items: flex-start;
    gap: 18px;
    padding-top: 18px;
    border-top: 1px solid var(--color-border-soft);
}

.gen-photo__drop {
    flex: 0 0 120px;
    width: 120px;
    height: 120px;
    border-radius: 12px;
}

.gen-photo__text {
    flex: 1 1 auto;
    min-width: 0;
}

.gen-photo__text .form-label {
    margin-bottom: 2px;
}

.gen-photo__text .form-text {
    margin-bottom: 10px;
}

.gen-photo__remove {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0;
    border: 0;
    background: none;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--jb-danger);
}

.gen-photo__remove i {
    width: 15px;
    height: 15px;
}

@media (max-width: 575.98px) {
    .gen-photo {
        flex-direction: column;
        align-items: center;
        text-align: center;
    }
}

/* ----- Rédaction assistée -----
   Volontairement discrète : c'est une option, jamais le chemin principal du
   wizard (arbitrage du porteur de projet du 2026-08-29). Un encadré coloré en
   haut de l'étape aurait fait de l'IA le parcours par défaut. */

/* Le panneau d'aide est devenu un bouton + un modal (chantier V3.11 Lot F) :
   l'enveloppe ne porte donc plus ni cadre ni fond, elle ne sert qu'à tenir
   ensemble le déclencheur et sa fenêtre pour le script. */
.gen-ai {
    display: inline-flex;
}

/* Violet, et volontairement pas l'orange de marque : c'est une aide
   facultative, elle ne doit pas se disputer l'attention avec l'action
   principale de l'étape, qui est le bouton « Continuer ». */
.gen-ai__trigger {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: .4rem .8rem;
    border: 0;
    border-radius: 999px;
    background-color: #6d3bd4;
    color: var(--jb-white);
    font-size: 0.82rem;
    font-weight: 700;
    cursor: pointer;
}

.gen-ai__trigger:hover {
    background-color: #592fb0;
}

.gen-ai__trigger i,
.gen-ai__trigger svg {
    width: 16px;
    height: 16px;
}

/* Label à gauche, bouton d'aide à droite sur la même ligne ; l'un sous
   l'autre quand la largeur ne le permet plus. */
.gen-field-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}

/* ----- Réalisations d'une expérience, une par ligne ----- */

.gen-task {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
}

.gen-task .form-control {
    flex: 1 1 auto;
}

.gen-task__remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    flex: 0 0 auto;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background-color: var(--jb-white);
    color: var(--jb-gray-500);
    cursor: pointer;
}

.gen-task__remove:hover {
    border-color: var(--jb-orange);
    color: var(--jb-orange);
}

.gen-task__remove i,
.gen-task__remove svg {
    width: 14px;
    height: 14px;
}

/* ----- Champs du générateur -----
   Une seule classe posée sur tous les champs de saisie du wizard, pour
   pouvoir les resserrer d'un seul geste. Sur un téléphone, six étapes de
   champs à hauteur pleine imposent un défilement continu, et le clavier
   virtuel mange déjà la moitié de l'écran. */

.generator-input-control {
    font-size: 0.9rem;
}

@media screen and (max-width: 768px) {
    .generator-input-control {
        padding: .42rem .6rem;
        font-size: 0.85rem;
    }

    select.generator-input-control[data-size="sm"] {
        padding: .38rem 1.6rem .38rem .6rem;
        background-position: right .5rem center;
    }

    .gen-task__remove {
        width: 26px;
        height: 26px;
    }
}

/* ----- Stepper numérique (`stepper.js`) -----
   Le style n'existait que dans la feuille du back-office : sur le site, les
   boutons +/- du niveau de compétence sortaient nus (chantier V3.11 Lot F).
   Recopié ici plutôt qu'importé : les deux feuilles ne partagent aucun
   fichier, et une dépendance de l'une à l'autre casserait la page publique le
   jour où l'admin change de gabarit. */

.stepper-dv {
    display: inline-flex;
    align-items: center;
    overflow: hidden;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background-color: var(--jb-white);
}

.stepper-dv button {
    width: 34px;
    height: 36px;
    flex: 0 0 auto;
    border: 0;
    background-color: var(--jb-gray-50);
    color: var(--jb-gray-700);
    font-size: 1rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.stepper-dv button:hover {
    background-color: var(--jb-orange);
    color: var(--jb-white);
}

.stepper-dv input {
    width: 52px;
    height: 36px;
    border: 0;
    border-left: 1px solid var(--color-border);
    border-right: 1px solid var(--color-border);
    text-align: center;
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--jb-black);
}

.stepper-dv input:focus {
    outline: 0;
}


.gen-ai__hint {
    margin: 8px 0 0;
    font-size: 0.84rem;
    line-height: 1.5;
    color: var(--jb-gray-700);
}

.gen-ai__quota {
    margin: 6px 0 0;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.gen-ai__result {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--color-border-soft);
}

.gen-ai__actions {
    display: flex;
    gap: 10px;
    margin-top: 10px;
    flex-wrap: wrap;
}

/* Bouton en cours d'appel : la génération prend quelques secondes, et un
   bouton qui ne dit rien pendant ce temps se fait cliquer trois fois. */
.gen-ai [data-ai-run].is-busy {
    position: relative;
    color: transparent;
}

.gen-ai [data-ai-run].is-busy::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 15px;
    height: 15px;
    margin: -8px 0 0 -8px;
    border: 2px solid var(--jb-orange);
    border-top-color: transparent;
    border-radius: 50%;
    animation: jb-spin 0.7s linear infinite;
}

/* ----- Panneau d'aperçu ----- */

.gen-preview {
    position: sticky;
    top: 84px;
    padding: 14px;
    background-color: var(--jb-white);
    border: 1px solid var(--color-border);
    border-radius: 14px;
}

.gen-preview__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
}

.gen-preview__title {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--color-text-muted);
}

/* Le bouton de fermeture n'existe que dans l'ouverture plein écran mobile :
   sur un panneau toujours visible, il n'aurait rien à fermer. */
.gen-preview__close,
.gen-preview__open {
    display: none;
}

.gen-preview__doc {
    border: 1px solid var(--color-border);
    border-radius: 6px;
    overflow: hidden;
}

.gen-preview__appearance {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--color-border-soft);
}

.gen-preview__label {
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

@media (max-width: 991.98px) {
    .gen-work {
        grid-template-columns: minmax(0, 1fr);
    }

    /* Sur mobile, l'aperçu n'occupe pas l'écran de saisie : il s'ouvre en
       plein écran et se referme sur l'étape en cours. La règle des champs en
       haut, hors de portée du clavier virtuel, prime sur l'envie de tout
       montrer en même temps (§2.1). */
    .gen-work__preview {
        position: fixed;
        inset: 0;
        z-index: 60;
        display: none;
        padding: 16px;
        overflow-y: auto;
        background-color: var(--color-bg-soft);
    }

    .gen-work__preview.is-open {
        display: block;
    }

    .gen-preview {
        position: static;
    }

    .gen-preview__close {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border: 1px solid var(--color-border);
        border-radius: 8px;
        background-color: var(--jb-white);
        color: var(--jb-gray-700);
        cursor: pointer;
    }

    .gen-preview__open {
        position: fixed;
        right: 16px;
        bottom: 20px;
        z-index: 50;
        display: inline-flex;
        align-items: center;
        gap: 7px;
        padding: 11px 18px;
        border: 0;
        border-radius: 999px;
        background-color: var(--jb-black);
        color: var(--jb-white);
        font-size: 0.86rem;
        font-weight: 600;
        box-shadow: 0 8px 22px rgba(11, 10, 10, 0.24);
        cursor: pointer;
    }

    .gen-preview__open i {
        width: 16px;
        height: 16px;
    }

    body.gen-preview-open {
        overflow: hidden;
    }

    body.gen-preview-open .gen-preview__open {
        display: none;
    }
}

/* ----- Page publique des générateurs ----- */

.gen-tool-card {
    display: flex;
    flex-direction: column;
    gap: 16px;
    height: 100%;
    padding: 24px;
    border: 1px solid var(--color-border);
    border-radius: 14px;
    background-color: var(--jb-white);
}

.gen-tool-card__head {
    display: flex;
    align-items: flex-start;
    gap: 14px;
}

.gen-tool-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    border-radius: 12px;
    background-color: var(--jb-orange-soft);
    color: var(--jb-orange);
}

.gen-tool-card__icon i {
    width: 21px;
    height: 21px;
}

.gen-tool-card__title {
    margin: 0 0 2px;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--jb-black);
}

.gen-tool-card__pitch {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.5;
    color: var(--color-text-muted);
}

.gen-tool-card__facts {
    display: flex;
    flex-direction: column;
    gap: 9px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.gen-tool-card__facts li {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    font-size: 0.87rem;
    color: var(--jb-gray-700);
}

.gen-tool-card__facts i {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    margin-top: 2px;
    color: var(--jb-gray-500);
}

/* Le prix est annoncé avant de commencer, pas découvert après vingt minutes
   de saisie : c'est une décision produit, pas un choix de mise en page. */
.gen-tool-card__price {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-top: auto;
    padding: 12px 14px;
    border-radius: 10px;
    background-color: var(--jb-gray-50);
}

.gen-tool-card__amount {
    font-size: 1.25rem;
    font-weight: 800;
    color: var(--jb-black);
}

.gen-tool-card__note {
    font-size: 0.79rem;
    color: var(--color-text-muted);
}

.gen-resume {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 13px 15px;
    border: 1px solid var(--jb-orange);
    border-radius: 10px;
    background-color: var(--jb-orange-soft);
}

.gen-resume__text {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 0.87rem;
    font-weight: 600;
    color: var(--jb-gray-900);
}

.gen-resume__text i {
    width: 17px;
    height: 17px;
    color: var(--jb-orange);
}

.gen-resume__actions {
    display: flex;
    align-items: center;
    gap: 8px;
}


.gen-preview__tools {
    display: flex;
    align-items: center;
    gap: 8px;
}

.gen-preview__refresh {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 10px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background-color: var(--jb-white);
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--jb-gray-700);
    cursor: pointer;
}

.gen-preview__refresh:hover {
    border-color: var(--jb-gray-300);
    color: var(--jb-black);
}

.gen-preview__refresh:disabled {
    opacity: 0.6;
    cursor: default;
}

.gen-preview__refresh i {
    width: 13px;
    height: 13px;
}

/* ==========================================================================
   Écran de résultat et bibliothèque des documents générés
   (TODO.md Chantier V3.10 Lot I)
   --------------------------------------------------------------------------
   Le document est montré en grand, entier, avant tout argument de vente : ce
   qu'on achète ici est une mise en page, et c'est elle qui doit convaincre.
   Le cadenas se pose par-dessus, il ne remplace jamais le document.

   Le flou de l'aperçu verrouillé est appliqué **dans la page rendue**, côté
   serveur, et le texte lui-même y est déjà brouillé : rien ici ne protège quoi
   que ce soit, et rien ici ne doit être pris pour une protection.
   ========================================================================== */

.doc-result__stage {
    position: relative;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-md);
    background-color: var(--jb-gray-50);
    padding: 14px;
}

.doc-result__preview {
    border-radius: 6px;
    overflow: hidden;
    background-color: var(--jb-white);
}

/* Bandeau de verrouillage : posé en bas, jamais au centre. Au centre, il
   masque précisément la partie du document qu'on cherche à montrer. */
.doc-result__seal {
    position: absolute;
    left: 50%;
    bottom: 26px;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border-radius: 999px;
    background-color: rgba(11, 10, 10, .88);
    color: var(--jb-white);
    font-size: .8rem;
    font-weight: 600;
    white-space: nowrap;
}

.doc-result__seal i {
    width: 15px;
    height: 15px;
}

.doc-result__panel {
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-md);
    background-color: var(--jb-white);
    padding: 22px;
}

.doc-result__badge {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: .74rem;
    font-weight: 700;
}

.doc-result__title {
    margin: 12px 0 2px;
    font-size: var(--jb-fs-lg);
}

.doc-result__meta {
    margin: 0 0 14px;
    font-size: .82rem;
    color: var(--jb-gray-600);
}

.doc-result__lead {
    margin: 0 0 16px;
    color: var(--jb-gray-700);
}

.doc-result__gets {
    list-style: none;
    margin: 0 0 18px;
    padding: 0;
    display: grid;
    gap: 9px;
}

.doc-result__gets li {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: .89rem;
    color: var(--jb-gray-700);
}

.doc-result__gets i {
    width: 16px;
    height: 16px;
    color: var(--jb-orange);
    flex: 0 0 auto;
}

.doc-result__price {
    display: flex;
    align-items: baseline;
    gap: 9px;
    padding: 14px 16px;
    border-radius: var(--jb-radius-sm);
    background-color: var(--jb-gray-50);
}

.doc-result__amount {
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--jb-black);
}

.doc-result__once {
    font-size: .8rem;
    color: var(--jb-gray-600);
}

.doc-result__note {
    margin: 12px 0 0;
    font-size: .8rem;
    color: var(--jb-gray-600);
}

/* ---- Bibliothèque ---- */

.doc-lib-card {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding: 18px;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-md);
    background-color: var(--jb-white);
}

.doc-lib-card__head {
    display: flex;
    align-items: flex-start;
    gap: 11px;
}

.doc-lib-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex: 0 0 auto;
    border-radius: 10px;
    background-color: var(--jb-gray-50);
    color: var(--jb-orange);
}

.doc-lib-card__icon i {
    width: 18px;
    height: 18px;
}

.doc-lib-card__title {
    margin: 0;
    font-size: 1rem;
}

.doc-lib-card__meta {
    margin: 2px 0 0;
    font-size: .78rem;
    color: var(--jb-gray-600);
}

.doc-lib-card__amount {
    margin: 0;
    font-weight: 700;
}

/* Le bouton principal est poussé en bas de carte : sur une grille, des
   boutons alignés se lisent d'un coup d'oeil, des boutons flottants non. */
.doc-lib-card .jb-btn--block {
    margin-top: auto;
}

.doc-lib-card__link {
    align-self: center;
    font-size: .8rem;
    color: var(--jb-gray-600);
    text-decoration: underline;
}

.doc-lib-card__link:hover {
    color: var(--jb-black);
}


/* ==========================================================================
   Tri par IA : barre de progression, note de pertinence, justification
   (TODO.md Chantier V3.10 Lots L et M)
   ========================================================================== */

/* Barre de progression maison plutôt que celle de Bootstrap : la teinte de
   marque suffit, et le composant sert aussi bien au tri des candidatures
   qu'au scan de la CVthèque, sur deux layouts différents. */


/* La note IA, posée sur une carte candidature ou un résultat de scan. Elle
   reste discrète volontairement : c'est un repère de lecture, pas un verdict
   (ADDENDUM-outils-ia.md §4.4). */


/* ── Écran de résultat d'une génération, dans le layout de l'espace de
   travail (TODO.md Chantier V3.11 Lot F) ────────────────────────────────────
   Il vivait dans le layout du site, avec sa navigation complète : la dernière
   étape d'un parcours de dix minutes proposait cinq raisons de partir juste
   avant de payer. */

.gen-result {
    max-width: 1080px;
    margin: 0 auto;
    padding: 18px 0 40px;
}

.gen-result .gen-step__head {
    margin-bottom: 20px;
}

/* Libellés de champ du générateur : noir et demi-gras, pour se distinguer des
   textes d'aide gris posés sous certains champs (TODO.md Chantier V3.11
   Lot H). Un libellé et son aide au même gris se lisaient comme une seule
   phrase, et la question posée par le champ disparaissait dedans. */

.generator-body .form-label,
.gen-fields .form-label {
    font-weight: 600;
    color: var(--jb-black);
}

.generator-body .form-text,
.gen-fields .form-text {
    color: var(--color-text-muted);
}

/* ==========================================================================
   Appels à l'action des générateurs CV / lettre
   --------------------------------------------------------------------------
   Quatre formes pour un même message (partials/site/generator-cta.blade.php),
   posées aux endroits où un candidat décroche : avant de lire l'offre, après
   l'avoir lue, au moment de postuler, et en permanence sur mobile.

   Aucun dégradé ici non plus : la carte latérale tire son impact d'un aplat
   orange plein sur une page qui n'en contient aucun autre, pas d'un effet.
   ========================================================================== */

/* ----- Bande sombre, avant le contenu ----- */
.jb-gen-strip {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1rem 1.25rem;
    margin-bottom: 1.5rem;
    border-radius: var(--jb-radius);
    background: var(--jb-black);
    color: var(--jb-white);
}

.jb-gen-strip__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-orange);
    color: var(--jb-white);
}

.jb-gen-strip__icon svg { width: 20px; height: 20px; }

.jb-gen-strip__text { flex: 1 1 auto; min-width: 0; }

.jb-gen-strip__title {
    margin: 0;
    font-size: var(--jb-fs-base);
    font-weight: 700;
}

.jb-gen-strip__lead {
    margin: .125rem 0 0;
    font-size: var(--jb-fs-sm);
    color: rgba(255, 255, 255, .68);
}

.jb-gen-strip__actions, .jb-cta-band__actions {
    display: flex;
    flex-shrink: 0;
    flex-wrap: wrap;
    gap: .5rem;
}

.jb-gen-strip__actions svg { width: 16px; height: 16px; }

@media (max-width: 767.98px) {
    .jb-gen-strip {
        flex-wrap: wrap;
        padding: 1rem;
    }

    .jb-gen-strip__actions , .jb-cta-band__actions { width: 100%; }
    .jb-gen-strip__actions .jb-btn, .jb-cta-band__actions .jb-btn { width: 100%}
}

/* ----- Deux cartes claires, au fil de la lecture ----- */
.jb-gen-duo {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
    margin: 2rem 0;
}

@media (max-width: 767.98px) {
    .jb-gen-duo { grid-template-columns: 1fr; }
}

.jb-gen-card {
    display: flex;
    flex-direction: column;
    padding: 1.25rem;
    border: 1px solid var(--color-primary-light);
    border-radius: var(--jb-radius);
    background: var(--jb-orange-soft);
}

.jb-gen-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    margin-bottom: .875rem;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-white);
    color: var(--jb-orange);
}

.jb-gen-card__icon svg { width: 20px; height: 20px; }

.jb-gen-card__eyebrow {
    margin: 0 0 .25rem;
    font-size: var(--jb-fs-xs);
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--jb-orange-dark);
}

.jb-gen-card__title {
    margin: 0 0 .5rem;
    font-size: var(--jb-fs-lg);
    font-weight: 700;
    color: var(--jb-black);
}

.jb-gen-card__text {
    margin: 0 0 0.75rem;
    font-size: var(--jb-fs-sm);
    line-height: 1.6;
    color: var(--jb-gray-700);
}

/* La ligne de preuve : ce que le document est vraiment, sous l'argument qui
   dit ce qu'on y gagne (chantier V3.14 Lot I). Plus petite que le texte, elle
   se lit après lui et jamais à sa place. */
.jb-gen-card__proof {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 0 0 1.125rem;
    font-size: var(--jb-fs-xs);
    line-height: 1.5;
    color: var(--jb-gray-600);
}

.jb-gen-card__proof i,
.jb-gen-card__proof svg {
    flex: none;
    width: 14px;
    height: 14px;
    margin-top: 2px;
    color: var(--jb-orange);
}

/* Le bouton se colle au bas de la carte : deux cartes de hauteurs de texte
   différentes doivent aligner leur action, sinon la paire se lit de travers. */
.jb-gen-card .jb-btn { margin-top: auto; }
.jb-gen-card .jb-btn svg { width: 16px; height: 16px; }

/* ----- Rappel d'une ligne, juste avant le geste de candidature ----- */
.jb-gen-inline {
    display: flex;
    align-items: center;
    gap: .875rem;
    padding: .875rem 1rem;
    margin: 1.25rem 0;
    border: 1px solid var(--color-primary-light);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-orange-soft);
}

.jb-gen-inline__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-orange);
    color: var(--jb-white);
}

.jb-gen-inline__icon svg { width: 18px; height: 18px; }

.jb-gen-inline__text { flex: 1 1 auto; min-width: 0; }

.jb-gen-inline__title {
    margin: 0;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    color: var(--jb-black);
}

.jb-gen-inline__lead {
    margin: .125rem 0 0;
    font-size: var(--jb-fs-xs);
    line-height: 1.55;
    color: var(--jb-gray-700);
}

.jb-gen-inline .jb-btn { flex-shrink: 0; }

@media (max-width: 575.98px) {
    .jb-gen-inline { flex-wrap: wrap; }
    .jb-gen-inline .jb-btn { width: 100%; }
}

/* ----- Carte latérale, aplat orange ----- */
.jb-gen-aside {
    padding: 1.5rem 1.25rem;
    border-radius: var(--jb-radius);
    background: var(--jb-orange);
    color: var(--jb-white);
}

.jb-gen-aside__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-bottom: 1rem;
    border-radius: var(--jb-radius-sm);
    background: rgba(255, 255, 255, .18);
    color: var(--jb-white);
}

.jb-gen-aside__icon svg { width: 22px; height: 22px; }

.jb-gen-aside__eyebrow {
    margin: 0 0 .375rem;
    font-size: var(--jb-fs-xs);
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .8);
}

.jb-gen-aside__title {
    margin: 0 0 .5rem;
    font-size: var(--jb-fs-lg);
    font-weight: 800;
    line-height: 1.3;
    color: var(--jb-white);
}

.jb-gen-aside__text {
    margin: 0 0 0.65rem;
    font-size: var(--jb-fs-sm);
    line-height: 1.6;
    color: rgba(255, 255, 255, .88);
}

/* Même ligne de preuve, sur fond orange plein : le blanc est simplement
   moins appuyé que celui de l'argument. */
.jb-gen-aside__proof {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 0 0 1.25rem;
    font-size: var(--jb-fs-xs);
    line-height: 1.5;
    color: rgba(255, 255, 255, .82);
}

.jb-gen-aside__proof i,
.jb-gen-aside__proof svg {
    flex: none;
    width: 14px;
    height: 14px;
    margin-top: 2px;
}

/* Action principale de la carte : blanc plein sur orange, le contraste le plus
   fort disponible ici. Le second outil reste un lien, pas un second bouton. */
.jb-gen-aside__cta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: .6875rem 1rem;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-white);
    font-size: var(--jb-fs-base);
    font-weight: 700;
    color: var(--jb-orange-dark);
    transition: background-color .15s ease;
}

.jb-gen-aside__cta:hover {
    background: rgba(255, 255, 255, .88);
    color: var(--jb-orange-dark);
}

.jb-gen-aside__cta svg { width: 18px; height: 18px; }

.jb-gen-aside__link {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .4375rem;
    margin-top: .75rem;
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: rgba(255, 255, 255, .9);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.jb-gen-aside__link:hover { color: var(--jb-white); }
.jb-gen-aside__link svg { width: 15px; height: 15px; }

/* ----- Barre fixe de bas d'écran (mobile) ----- */
.jb-gen-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1030;
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .625rem .875rem calc(.625rem + env(safe-area-inset-bottom));
    background: var(--jb-black);
    color: var(--jb-white);
    box-shadow: 0 -6px 20px rgba(11, 10, 10, .18);
}

.jb-gen-bar[hidden] { display: none; }

.jb-gen-bar__text { flex: 1 1 auto; min-width: 0; }

.jb-gen-bar__title {
    margin: 0;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
}

.jb-gen-bar__lead {
    margin: 0;
    font-size: var(--jb-fs-xs);
    color: rgba(255, 255, 255, .62);
}

.jb-gen-bar__actions {
    display: flex;
    flex-shrink: 0;
    gap: .375rem;
}

.jb-gen-bar__close {
    flex-shrink: 0;
    padding: .25rem;
    border: 0;
    background: transparent;
    color: rgba(255, 255, 255, .55);
    cursor: pointer;
}

.jb-gen-bar__close svg { width: 16px; height: 16px; }

@media (max-width: 400px) {
    .jb-gen-bar__text { display: none; }
    .jb-gen-bar__actions { flex: 1 1 auto; }
    .jb-gen-bar__actions .jb-btn { flex: 1 1 0; }
}

/* La barre couvre le bas de page : sans cette réserve, le footer et les
   dernières offres similaires restent inatteignables sous elle. */
body.has-generator-bar { padding-bottom: 4.5rem; }

@media (min-width: 992px) {
    body.has-generator-bar { padding-bottom: 0; }
}

/* ==========================================================================
   Exigences de l'offre : compétences et langues
   --------------------------------------------------------------------------
   Deux formes, décidées par le modèle (JobOffer::has_language_levels) et non
   par la vue : jauges quand le recruteur a précisé un niveau partout,
   pastilles quand il n'a donné que des intitulés. Les jauges reprennent la
   lecture de la fiche Talent, pour qu'un même niveau se lise pareil des deux
   côtés du marché.
   ========================================================================== */
.jb-req-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .875rem 1.75rem;
}

@media (max-width: 575.98px) {
    .jb-req-grid { grid-template-columns: 1fr; }
}

.jb-req-row__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .375rem;
}

.jb-req-row__name {
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-900);
}

.jb-req-row__level {
    font-size: var(--jb-fs-xs);
    font-weight: 600;
    color: var(--jb-orange-dark);
}

.jb-req-row__track {
    height: 6px;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-gray-200);
    overflow: hidden;
}

.jb-req-row__fill {
    height: 100%;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-orange);
}

/* Pastilles : forme de lecture, pas de sélection, donc pas d'input caché ni
   d'état coché à gérer comme sur .jb-chip. */
.jb-req-tags {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.jb-req-tag {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: .4375rem .875rem;
    border: 1px solid var(--color-primary-light);
    border-radius: var(--jb-radius-pill);
    background: var(--jb-orange-soft);
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-orange-dark);
}

.jb-req-tag svg { width: 14px; height: 14px; }

.jb-req-tag__level {
    padding-left: .5rem;
    border-left: 1px solid var(--color-primary-light);
    font-weight: 500;
    color: var(--jb-gray-700);
}

/* ==========================================================================
   Étape 0 des générateurs : « Pour quelle offre ? »
   (TODO.md Chantier V3.14 Lot F)

   Trois blocs de choix toujours visibles, jamais repliés : l'audience visée
   est décrite comme peu familière du numérique, et un contenu qui n'apparaît
   qu'après avoir coché la bonne case est un contenu qu'on ne trouve pas. Le
   bloc sélectionné se signale par sa bordure et son fond, pas en faisant
   disparaître les autres.
   ========================================================================== */

.gen-target {
    max-width: 760px;
    margin: 0 auto;
    padding: 24px 16px 48px;
}

.gen-target__lead {
    margin: 10px 0 0;
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--jb-gray-700);
}

/* Rappel de la cible déjà posée. Il vit au-dessus des choix parce qu'il
   répond à la première question de qui revient sur l'étape : « qu'est-ce qui
   est enregistré en ce moment ? ». */
.gen-target__current {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 20px;
    padding: 12px 14px;
    border: 1px solid var(--jb-orange);
    border-radius: 12px;
    background-color: #fff6ef;
    font-size: 0.88rem;
}

.gen-target__current i,
.gen-target__current svg {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    margin-top: 2px;
    color: var(--jb-orange);
}

.gen-target__current strong {
    display: block;
    color: var(--jb-black);
}

.gen-target__current span {
    color: var(--jb-gray-700);
}

.gen-target__option {
    margin-bottom: 16px;
    border: 1px solid var(--color-border);
    border-radius: 12px;
    background-color: var(--jb-white);
    overflow: hidden;
}

.gen-target__option:has(input[name="choice"]:checked) {
    border-color: var(--jb-orange);
    box-shadow: 0 0 0 1px var(--jb-orange) inset;
}

.gen-target__pick {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 16px;
    margin: 0;
    cursor: pointer;
}

.gen-target__pick input {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    margin-top: 2px;
    accent-color: var(--jb-orange);
}

.gen-target__pick strong {
    display: block;
    font-size: 1rem;
    color: var(--jb-black);
}

.gen-target__pick small {
    display: block;
    margin-top: 2px;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--color-text-muted);
}

.gen-target__body {
    padding: 0 16px 16px;
    border-top: 1px solid var(--color-border-soft);
    padding-top: 16px;
}

.gen-target__search {
    display: flex;
    gap: 8px;
    margin-bottom: 12px;
}

.gen-target__search .form-control {
    flex: 1 1 auto;
    min-width: 0;
}

.gen-target__search .jb-btn {
    flex: 0 0 auto;
}

.gen-target__hint {
    margin: 0;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--color-text-muted);
}

.gen-target__results {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.gen-target__result {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    width: 100%;
    padding: 10px 12px;
    margin: 0;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background-color: var(--color-bg-soft);
    cursor: pointer;
}

.gen-target__result:has(input:checked) {
    border-color: var(--jb-orange);
    background-color: #fff6ef;
}

.gen-target__result input {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin-top: 3px;
    accent-color: var(--jb-orange);
}

.gen-target__result strong {
    display: block;
    font-size: 0.92rem;
    color: var(--jb-black);
}

.gen-target__result small {
    display: block;
    font-size: 0.82rem;
    color: var(--color-text-muted);
}

@media (max-width: 575.98px) {
    .gen-target__search {
        flex-direction: column;
    }

    .gen-target__search .jb-btn {
        width: 100%;
        justify-content: center;
    }
}

/* Paragraphe de corps légèrement adouci, pour les blocs de texte long des
   pages publiques. Il remplace un `style="color: ..."` posé en dur dans une
   vue (CLAUDE.md : le style structurant vit ici). */
.jb-text-muted-strong {
    color: var(--jb-gray-700);
}

/* La vignette de modèle du bandeau des générateurs accueille désormais un
   aperçu réel (`x-document-preview`) et non une image : la page A4 est rendue
   dans une iframe, il faut lui donner le même gabarit 3/4 que l'image qu'elle
   remplace, sinon la vignette s'effondre à zéro de hauteur. */
.jb-template .doc-preview {
    width: 100%;
    aspect-ratio: 3 / 4;
    border: 0;
    border-radius: 0;
}

/* ==========================================================================
   Réglages de notification (TODO.md Chantier V3.15 Lot D)
   Partagés par l'espace candidat (layout site) et l'espace recruteur
   (layout manager) : un seul composant pour un seul écran, décliné deux fois.
   ========================================================================== */

.jb-pref__head-icon {
    width: 17px;
    height: 17px;
    color: var(--jb-orange);
    vertical-align: -3px;
    margin-right: .25rem;
}

.jb-pref-list {
    display: flex;
    flex-direction: column;
}

/* Toute la ligne est le label : au doigt, viser un interrupteur de 2 rem est
   le genre de détail qui fait renoncer. */
.jb-pref {
    display: flex;
    align-items: flex-start;
    gap: .875rem;
    padding: .875rem 0;
    margin: 0;
    cursor: pointer;
    border-top: 1px solid var(--jb-gray-100);
}

.jb-pref:first-child { border-top: 0; padding-top: 0; }
.jb-pref:last-child { padding-bottom: 0; }

.jb-pref__icon {
    flex: 0 0 34px;
    width: 34px;
    height: 34px;
    border-radius: var(--jb-radius-sm);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--jb-gray-50);
    color: var(--jb-gray-600);
}

.jb-pref__icon i { width: 17px; height: 17px; }

.jb-pref__text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .15rem;
}

.jb-pref__label {
    font-weight: 600;
    line-height: 1.4;
}

.jb-pref__help {
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
    line-height: 1.5;
}

.jb-pref__switch {
    flex: 0 0 auto;
    padding-left: 2.5em;
    margin-top: .15rem;
}

/* L'interrupteur actif prend l'accent de marque, pas le bleu Bootstrap. */
.jb-pref__switch .form-check-input:checked {
    background-color: var(--jb-orange);
    border-color: var(--jb-orange);
}

.jb-pref__switch .form-check-input:focus {
    border-color: var(--jb-orange);
    box-shadow: 0 0 0 .2rem var(--jb-orange-soft);
}

.jb-pref-actions {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 1.5rem;
}

@media (max-width: 575.98px) {
    .jb-pref-actions .jb-btn { width: 100%; }
}

/* Variante « choisir un fichier » de `jb-file-drop` (page de contact publique,
   TODO.md Chantier V3.15 Lot E) : le même bloc, mais cliquable de bout en bout
   et avec l'input natif retiré de la vue. Le composant d'origine ne servait
   qu'à afficher un fichier déjà déposé. */
.jb-file-drop--pick {
    cursor: pointer;
    margin: 0;
    transition: border-color .15s ease, background .15s ease;
}

.jb-file-drop--pick:hover {
    border-color: var(--jb-orange);
    background: var(--jb-orange-soft);
}

.jb-file-drop--pick .jb-file-drop__name,
.jb-file-drop--pick .jb-file-drop__hint {
    display: block;
}

.jb-file-drop__input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

/* Le leurre anti-robots. Sorti du flux plutôt que `display:none` : certains
   robots ignorent volontairement les champs franchement cachés. */
.jb-honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Autres moyens de nous joindre, colonne latérale de la page de contact. */
.jb-contact-way {
    display: flex;
    align-items: center;
    gap: .875rem;
    padding: .875rem 0;
    border-top: 1px solid var(--jb-gray-100);
    color: inherit;
    text-decoration: none;
}

.jb-contact-way:first-child { border-top: 0; padding-top: 0; }
.jb-contact-way:hover { color: var(--jb-orange-dark); }

.jb-contact-way__icon {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    border-radius: var(--jb-radius-sm);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--jb-gray-50);
    color: var(--jb-gray-600);
}

.jb-contact-way:hover .jb-contact-way__icon {
    background: var(--jb-orange-soft);
    color: var(--jb-orange);
}

.jb-contact-way__label {
    display: block;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
}

.jb-contact-way__value {
    display: block;
    font-weight: 600;
}

/* ==========================================================================
   Messages de contact en Administration (TODO.md Chantier V3.15 Lot E)
   Une liste de courrier, pas un tableau : ce qu'on cherche en la parcourant
   c'est qui écrit et à quel sujet, pas des colonnes alignées.
   ========================================================================== */


/* Un non-lu se repère au filet orange, pas à un fond coloré plein : la liste
   reste calme même quand tout est neuf. */


/* Le corps du message garde les retours à la ligne de la saisie sans qu'aucun
   HTML ne soit fabriqué à partir d'un formulaire public. */


/* Ordre de lecture annoncé sous le sélecteur de modèle du panneau d'aperçu
   (TODO.md Chantier V3.15 Lot G). Discret : c'est une précision qui aide à
   choisir, pas un argument de vente de plus. */
.gen-preview__reading {
    margin: .35rem 0 .5rem;
    font-size: var(--jb-fs-xs);
    line-height: 1.5;
    color: var(--jb-gray-600);
}


/* ==========================================================================
   Jobivoire Premium — landing et suivi d'abonnement
   (ADDENDUM-espace-candidat-premium.md, TODO.md Chantier V3.16 Lots I et J)
   ========================================================================== */

/* Carte de pilier : le bloc porte l'avantage **et** sa preuve. Les deux ne
   sont pas au même niveau de lecture, d'où le pied détaché plutôt qu'un
   paragraphe de plus, qui se lirait comme la suite de l'argumentaire alors
   que c'est précisément ce qui permet de ne pas le croire sur parole. */
.jb-pillar {
    display: flex;
    flex-direction: column;
    padding: 1.5rem;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
}

.jb-pillar__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-bottom: .9rem;
    border-radius: var(--jb-radius);
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-pillar__title {
    margin-bottom: .45rem;
    font-size: var(--jb-fs-lg);
    font-weight: 800;
}

.jb-pillar__text {
    margin-bottom: 1rem;
    font-size: var(--jb-fs-sm);
    line-height: 1.6;
    color: var(--color-text-muted);
}

.jb-pillar__proof {
    margin-top: auto;
    padding-top: .9rem;
    border-top: 1px solid var(--color-border-soft);
}

.jb-pillar__proof-label {
    display: flex;
    align-items: center;
    gap: .4rem;
    margin-bottom: .3rem;
    font-size: var(--jb-fs-xs);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--jb-orange-dark);
}

.jb-pillar__proof-text {
    margin-bottom: 0;
    font-size: var(--jb-fs-sm);
    line-height: 1.55;
    color: var(--jb-gray-700);
}

/* Le chiffre de l'économie. Fond noir plutôt qu'orange : c'est le seul
   chiffre de la page qu'on veut voir en premier, et l'orange sert déjà à
   tous les boutons d'action autour. */
.jb-savings {
    padding: 1.75rem;
    border-radius: var(--jb-radius-md);
    background: var(--jb-black);
    color: var(--jb-white);
    text-align: center;
}

.jb-savings__label {
    margin-bottom: .35rem;
    font-size: var(--jb-fs-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: rgba(255, 255, 255, .6);
}

.jb-savings__value {
    margin-bottom: .5rem;
    font-size: var(--jb-fs-3xl);
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -.02em;
    color: var(--jb-orange);
}

.jb-savings__note {
    margin-bottom: 0;
    font-size: var(--jb-fs-sm);
    line-height: 1.5;
    color: rgba(255, 255, 255, .72);
}

/* Étiquette commerciale d'un palier (colonne `plans.badge`). Posée dans le
   flux et non en absolu : une pastille flottante déborde de la carte au
   premier nom de palier un peu long. */
.jb-plan-badge {
    align-self: flex-start;
    margin-bottom: .6rem;
    padding: .15rem .6rem;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-orange);
    font-size: var(--jb-fs-xs);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--jb-white);
}

.jb-plan-monthly {
    margin: .3rem 0 0;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    color: var(--jb-orange-dark);
}

/* Ligne de document produit par un générateur, dans les panneaux « Mes CV » et
   « Mes lettres de motivation » (TODO.md Chantier V3.16 Lot G).

   Distincte de `.jb-file-drop`, qui sert aux fichiers déposés : ces deux
   familles cohabitent dans le même panneau, et si elles se ressemblaient
   trait pour trait, on ne saurait plus lequel a été téléversé et lequel reste
   à finir ou à débloquer. */
.jb-doc-group__title {
    margin: 1.5rem 0 .65rem;
    font-size: var(--jb-fs-xs);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--jb-gray-500);
}

.jb-doc-line {
    display: flex;
    align-items: center;
    gap: .85rem;
    flex-wrap: wrap;
    padding: .85rem 1rem;
    margin-bottom: .5rem;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius);
    background: var(--jb-white);
}

.jb-doc-line--empty {
    border-style: dashed;
    background: var(--jb-gray-50);
}

.jb-doc-line__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-100);
    color: var(--jb-gray-600);
}

.jb-doc-line__icon--ready {
    background: rgba(25, 135, 84, .1);
    color: var(--jb-success);
}

.jb-doc-line__icon--locked {
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-doc-line__body {
    flex: 1 1 220px;
    min-width: 0;
}

.jb-doc-line__name {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .4rem;
    margin: 0 0 .15rem;
    font-weight: 700;
    color: var(--jb-black);
}

.jb-doc-line__hint {
    margin: 0;
    font-size: var(--jb-fs-sm);
    color: var(--color-text-muted);
}

.jb-doc-line__status {
    padding: .05rem .5rem;
    border-radius: var(--jb-radius-pill);
    font-size: var(--jb-fs-xs);
    font-weight: 700;
}

.jb-doc-line__status--draft {
    background: var(--jb-gray-100);
    color: var(--jb-gray-700);
}

.jb-doc-line__status--locked {
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-doc-line__status--ready {
    background: rgba(25, 135, 84, .1);
    color: var(--jb-success);
}

.jb-doc-line__actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-left: auto;
}

/* Le décompte de crédits vit au-dessus de la liste : c'est le contexte de
   toutes les actions qui suivent, pas une ligne de plus. */
.jb-doc-line__credits {
    display: flex;
    align-items: center;
    gap: .45rem;
    margin: 0 0 .65rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-700);
}

.jb-doc-line__credits svg {
    width: 16px;
    height: 16px;
    color: var(--jb-orange);
}

@media (max-width: 575.98px) {
    .jb-doc-line__actions {
        width: 100%;
        margin-left: 0;
    }

    .jb-doc-line__actions .jb-btn {
        flex: 1 1 auto;
    }
}

/* ==========================================================================
   Tableau de bord Talent — refonte (TODO.md Chantier V3.16 Lot I)
   ========================================================================== */

/* Une alerte qui porte plusieurs lignes et un bouton ne se centre pas :
   l'icône doit rester au niveau du titre, pas au milieu du bloc. */
.jb-alert:has(> div) {
    align-items: flex-start;
}

/* Cartes « Que voulez-vous faire ? ». Ce sont des invitations, pas des
   compteurs : elles ont un titre, une raison, et une flèche. Le fond reste
   blanc, la couleur ne sert qu'à la pastille d'icône, sinon six cartes
   colorées côte à côte ne hiérarchisent plus rien. */
.jb-action-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: .85rem;
}

.jb-action-card {
    display: flex;
    flex-direction: column;
    padding: 1.1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
    color: inherit;
    text-decoration: none;
    transition: border-color .15s ease, transform .15s ease;
}

.jb-action-card:hover {
    border-color: var(--jb-orange);
    transform: translateY(-2px);
    text-decoration: none;
    color: inherit;
}

.jb-action-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin-bottom: .75rem;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-100);
    color: var(--jb-gray-700);
}

.jb-action-card__icon svg {
    width: 20px;
    height: 20px;
}

/* Deux accents seulement, et ils se méritent : ce qui est commencé et qu'on
   peut finir, et l'offre payante. Tout le reste garde le gris, faute de quoi
   la carte importante ne se distinguerait plus des cinq autres. */
.jb-action-card--resume .jb-action-card__icon,
.jb-action-card--premium .jb-action-card__icon {
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-action-card__title {
    margin-bottom: .3rem;
    font-weight: 700;
    line-height: 1.35;
    color: var(--jb-black);
}

.jb-action-card__text {
    flex: 1 1 auto;
    margin-bottom: .8rem;
    font-size: var(--jb-fs-sm);
    line-height: 1.55;
    color: var(--color-text-muted);
}

.jb-action-card__cta {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    color: var(--jb-orange-dark);
}

.jb-action-card__cta svg {
    width: 15px;
    height: 15px;
    transition: transform .15s ease;
}

.jb-action-card:hover .jb-action-card__cta svg {
    transform: translateX(3px);
}

/* Complément des tuiles de statistiques : la seconde fenêtre de mesure, ou ce
   que le chiffre invite à faire. */
.jb-stat-tile__hint {
    margin: .3rem 0 0;
    font-size: var(--jb-fs-xs);
    color: var(--color-text-muted);
}

/* Ventilation des candidatures par statut. Le filet coloré est en pied et non
   sur un côté : posé à gauche, il se lit comme une décoration ; posé sous le
   chiffre, il appartient au chiffre. */
.jb-breakdown {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: .65rem;
}

.jb-breakdown__item {
    padding: .8rem .65rem .65rem;
    border: 1px solid var(--color-border);
    border-bottom-width: 3px;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-white);
    text-align: center;
}

.jb-breakdown__item--orange { border-bottom-color: var(--jb-orange); }
.jb-breakdown__item--info { border-bottom-color: #0d6efd; }
.jb-breakdown__item--success { border-bottom-color: var(--jb-success); }
.jb-breakdown__item--danger { border-bottom-color: #dc3545; }

.jb-breakdown__count {
    display: block;
    font-size: var(--jb-fs-2xl);
    font-weight: 800;
    line-height: 1.1;
    color: var(--jb-black);
}

.jb-breakdown__label {
    display: block;
    margin-top: .2rem;
    font-size: var(--jb-fs-sm);
    color: var(--color-text-muted);
}

/* Bloc de mise en avant d'un état qui appelle une action (paiement en attente,
   abonnement qui expire, demande rejetée).

   Remplace le panneau imbriqué au `border-left` de 3 pixels que le porteur de
   projet a explicitement refusé : un liseré latéral ne donne aucun poids à ce
   qui est, dans le cas du paiement en attente, de l'argent déjà engagé et un
   dossier déjà déposé. Ici l'icône, le fond et le bouton disent ensemble
   qu'il reste un geste à faire. */
.jb-standout {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 1.1rem 1.25rem;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-md);
    background: var(--jb-gray-50);
}

.jb-standout--action {
    border-color: var(--jb-orange);
    background: var(--jb-orange-soft);
}

.jb-standout--danger {
    border-color: #f1aeb5;
    background: #fdf2f3;
}

.jb-standout__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: var(--jb-white);
    color: var(--jb-gray-700);
}

.jb-standout--action .jb-standout__icon { color: var(--jb-orange-dark); }
.jb-standout--danger .jb-standout__icon { color: #b02a37; }

.jb-standout__icon svg {
    width: 22px;
    height: 22px;
}

.jb-standout__body {
    flex: 1 1 260px;
    min-width: 0;
}

.jb-standout__title {
    margin: 0 0 .25rem;
    font-weight: 800;
    color: var(--jb-black);
}

.jb-standout__text {
    margin: 0;
    font-size: var(--jb-fs-sm);
    line-height: 1.55;
    color: var(--jb-gray-700);
}

/* Panneau d'abonnement, état « abonné ». */
.jb-sub-state {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    flex-wrap: wrap;
}

.jb-sub-state__main {
    flex: 1 1 200px;
}

.jb-sub-state__plan {
    margin: .5rem 0 .15rem;
    font-size: var(--jb-fs-lg);
    font-weight: 800;
    color: var(--jb-black);
}

.jb-sub-state__expiry {
    margin: 0;
    font-size: var(--jb-fs-sm);
    color: var(--color-text-muted);
}

.jb-sub-state__credits {
    display: flex;
    gap: .75rem;
    flex-wrap: wrap;
    flex: 2 1 320px;
}

.jb-sub-credit {
    display: flex;
    align-items: center;
    gap: .6rem;
    flex: 1 1 150px;
    padding: .7rem .85rem;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-white);
}

.jb-sub-credit__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex: 0 0 auto;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

.jb-sub-credit__value {
    margin: 0;
    font-weight: 800;
    color: var(--jb-black);
}

.jb-sub-credit__label {
    margin: 0;
    font-size: var(--jb-fs-xs);
    line-height: 1.4;
    color: var(--color-text-muted);
}

.jb-sub-state__actions {
    flex: 0 0 auto;
}

/* Panneau d'abonnement, état « pas abonné ». Un argumentaire court, trois
   lignes, une action principale : ce n'est pas la page de vente, c'est le
   rappel qu'elle existe. */
.jb-sub-pitch {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
    align-items: center;
}

.jb-sub-pitch__body {
    flex: 1 1 320px;
}

.jb-sub-pitch__title {
    margin: 0 0 .7rem;
    font-size: var(--jb-fs-lg);
    font-weight: 800;
    color: var(--jb-black);
}

.jb-sub-pitch__list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: .55rem;
}

.jb-sub-pitch__list li {
    display: flex;
    align-items: flex-start;
    gap: .55rem;
    font-size: var(--jb-fs-sm);
    line-height: 1.55;
    color: var(--jb-gray-700);
}

.jb-sub-pitch__list svg {
    flex: 0 0 auto;
    width: 17px;
    height: 17px;
    margin-top: 2px;
    color: var(--jb-orange);
}

.jb-sub-pitch__actions {
    display: flex;
    flex-direction: column;
    gap: .5rem;
    flex: 0 1 240px;
}

@media (max-width: 575.98px) {
    .jb-sub-state__actions,
    .jb-sub-pitch__actions {
        width: 100%;
    }

    .jb-standout {
        padding: .95rem 1rem;
    }

    .jb-standout .jb-btn {
        width: 100%;
    }
}

/* Grille des formules candidat, écran « Mon abonnement »
   (TODO.md Chantier V3.16 Lots E et I).

   Une carte propre au layout du site : `jb-plan-card` vit dans `common.css`,
   qui n'est chargé que par le back-office, et `jb-plan` de `home.css` est
   taillé pour une landing en pleine largeur, pas pour un panneau d'espace
   privé. Reprendre l'une ou l'autre aurait demandé de charger une feuille
   entière pour trois règles. */
.jb-plan-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: .85rem;
}

.jb-plan-tile {
    display: flex;
    flex-direction: column;
    padding: 1.15rem;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
}

.jb-plan-tile.is-featured {
    border-color: var(--jb-black);
}

/* La formule en cours prime sur la formule mise en avant : ce qu'on veut
   repérer d'un coup d'oeil sur cet écran, c'est la sienne. */
.jb-plan-tile.is-current {
    border-color: var(--jb-orange);
    box-shadow: 0 0 0 1px var(--jb-orange);
}

.jb-plan-tile__tags {
    min-height: 24px;
    margin-bottom: .5rem;
}

.jb-plan-tile__name {
    margin: 0;
    font-size: var(--jb-fs-lg);
    font-weight: 800;
    color: var(--jb-black);
}

.jb-plan-tile__price {
    margin: .35rem 0 0;
    font-size: var(--jb-fs-2xl);
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -.02em;
    color: var(--jb-black);
}

.jb-plan-tile__period {
    margin: .2rem 0 0;
    font-size: var(--jb-fs-sm);
    color: var(--color-text-muted);
}

.jb-plan-tile__pitch {
    margin: .6rem 0 0;
    font-size: var(--jb-fs-sm);
    line-height: 1.5;
    color: var(--color-text-muted);
}

.jb-plan-tile__features {
    flex: 1 1 auto;
    margin: 1rem 0;
    padding: 0;
    list-style: none;
    font-size: var(--jb-fs-sm);
}

.jb-plan-tile__features li {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    padding: .2rem 0;
    color: var(--jb-gray-800);
}

.jb-plan-tile__features svg {
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    margin-top: 2px;
    color: var(--jb-success);
}

/* Un avantage non inclus reste affiché, en gris : c'est ce qui rend deux
   formules comparables. Le faire disparaître donnerait deux listes de
   longueurs différentes qu'on ne peut plus lire côte à côte. */
.jb-plan-tile__features li.is-off {
    color: var(--jb-gray-400);
}

.jb-plan-tile__features li.is-off svg {
    color: var(--jb-gray-400);
}

/* Badge « Profil Premium » (ADDENDUM-espace-candidat-premium.md §3, avantage
   additionnel ; TODO.md Chantier V3.16 Lot B).

   Volontairement plus discret que la pastille « Profil vérifié » posée juste à
   côté : celle-ci atteste d'une identité contrôlée par l'équipe, celle-là dit
   seulement qu'un abonnement est en cours. Les faire se ressembler laisserait
   croire qu'on peut acheter une vérification. */
.jb-premium-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
    color: var(--jb-orange);
}

.jb-premium-mark svg {
    width: 15px;
    height: 15px;
}

.jb-premium-badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .15rem .55rem;
    border: 1px solid var(--jb-orange);
    border-radius: var(--jb-radius-pill);
    background: var(--jb-orange-soft);
    font-size: var(--jb-fs-xs);
    font-weight: 700;
    color: var(--jb-orange-dark);
}

.jb-premium-badge svg {
    width: 13px;
    height: 13px;
}

/* ==========================================================================
   Produits digitaux (TODO.md Chantier V3.17)
   --------------------------------------------------------------------------
   Catalogue, fiche produit, espace « Mes achats » et espace de cours. Rien
   ici n'est décoratif par réflexe : la carte produit se distingue de la carte
   Article par ce qui compte pour elle (le prix, la remise, le type de
   contenu), et l'espace de cours par ce qui compte pour lui (où j'en suis).
   ========================================================================== */

/* ── Carte du catalogue ─────────────────────────────────────────────────── */

.jb-product-card__media {
    position: relative;
    display: block;
    background: var(--jb-gray-100);
}

/* La remise se lit avant le prix : c'est elle qui arrête le regard sur une
   grille de cartes, et elle n'a aucun sens ailleurs que sur la miniature. */
.jb-product-card__discount {
    position: absolute;
    top: .625rem;
    left: .625rem;
    padding: .2rem .5rem;
    border-radius: var(--jb-radius-sm);
    background: var(--jb-orange);
    color: var(--jb-white);
    font-size: var(--jb-fs-xs);
    font-weight: 800;
    letter-spacing: .02em;
}

.jb-product-card__type {
    position: absolute;
    bottom: .625rem;
    left: .625rem;
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .2rem .55rem;
    border-radius: var(--jb-radius-sm);
    background: rgba(11, 10, 10, .78);
    color: var(--jb-white);
    font-size: var(--jb-fs-xs);
    font-weight: 600;
}

.jb-product-card__link {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-weight: 700;
    color: var(--jb-orange-dark);
}

.jb-product-card__link svg {
    width: 14px;
    height: 14px;
}

/* ── Prix ───────────────────────────────────────────────────────────────── */

.jb-product-price {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: .5rem;
}

.jb-product-price__now {
    font-size: var(--jb-fs-xl);
    font-weight: 800;
    color: var(--jb-black);
}

.jb-product-price__was {
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-500);
    text-decoration: line-through;
}

.jb-product-price--lg .jb-product-price__now {
    font-size: var(--jb-fs-3xl);
    line-height: 1.1;
}

/* ── Fiche produit ──────────────────────────────────────────────────────── */

.jb-product-hero__image {
    width: 100%;
    border-radius: var(--jb-radius-md);
    margin-bottom: 1.25rem;
}

.jb-product-hero__title {
    margin: .75rem 0 0;
    font-size: var(--jb-fs-3xl);
    line-height: 1.2;
}

.jb-product-hero__tagline {
    margin: .625rem 0 0;
    font-size: var(--jb-fs-lg);
    color: var(--jb-gray-600);
}

.jb-product-video,
.jb-lesson-video {
    position: relative;
    margin-top: 1.5rem;
    padding-top: 56.25%;
    border-radius: var(--jb-radius-md);
    overflow: hidden;
    background: var(--jb-black);
}

.jb-product-video iframe,
.jb-lesson-video iframe,
.jb-lesson-video video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

.jb-lesson-video {
    margin-top: 0;
}

/* ── Colonne d'achat ────────────────────────────────────────────────────── */

.jb-buybox {
    padding: 1.25rem;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-md);
    background: var(--jb-white);
}

@media (min-width: 992px) {
    /* Elle suit la lecture de la fiche : le prix ne doit jamais sortir de
       l'écran pendant qu'on lit ce qu'on achète. */
    .jb-buybox {
        position: sticky;
        top: 5.5rem;
    }
}

.jb-buybox__once {
    margin: .375rem 0 1rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

.jb-buybox__gets {
    margin: 1.25rem 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: .5rem;
}

.jb-buybox__gets li {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-700);
}

.jb-buybox__gets svg {
    width: 15px;
    height: 15px;
    flex: 0 0 auto;
    color: var(--jb-orange-dark);
}

.jb-buybox__link {
    display: block;
    margin-top: 1rem;
    text-align: center;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600);
}

/* Compte à rebours de fin de promotion (refonte 2026-09-02).

   Quatre petites cases grises plutôt qu'une phrase : « il reste 2 jours et
   3 heures » se lit comme une information, alors qu'une seconde qui tourne se
   regarde. Les chiffres sont en chasse fixe (`tabular-nums`) pour que la case
   ne tressaute pas au passage de 9 à 10. */
.jb-countdown {
    margin-bottom: 1.25rem;
    text-align: center;
}

.jb-countdown__label {
    display: block;
    margin-bottom: .625rem;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    color: var(--jb-gray-900, #0b0a0a);
}

.jb-countdown__boxes {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    gap: .375rem;
}

.jb-countdown__box {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .125rem;
    min-width: 3.25rem;
    padding: .5rem .375rem .375rem;
    border-radius: 10px;
    background: var(--jb-gray-100, #f2f3f5);
    transition: background .2s ease, transform .2s ease;
}

.jb-countdown__box b {
    font-size: 1.375rem;
    font-weight: 800;
    line-height: 1.1;
    color: var(--jb-gray-900, #0b0a0a);
    font-variant-numeric: tabular-nums;
}

.jb-countdown__box small {
    font-size: .625rem;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--jb-gray-600, #6b7280);
}

/* Battement au changement de chiffre : assez court pour se remarquer sans
   attirer l'oeil hors du bouton d'achat. */
.jb-countdown__box.is-ticking {
    background: #ffe8d8;
    transform: translateY(-1px);
}

.jb-countdown__sep {
    padding-top: .625rem;
    font-size: 1rem;
    font-weight: 800;
    color: var(--jb-gray-400, #9ca3af);
}

.jb-countdown__over {
    margin: .75rem 0 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-600, #6b7280);
}

/* ── Série limitée ──────────────────────────────────────────────────────────
   La barre se remplit à l'ouverture de 100 % jusqu'au niveau réellement vendu :
   l'oeil voit la série se vider, ce qu'une barre déjà posée ne raconte pas. La
   couleur suit la tension du stock, décidée côté PHP (`stock_level`). */
.jb-scarcity {
    margin-bottom: 1rem;
    --jb-scarcity-color: #16a34a;
}

.jb-scarcity--tendu { --jb-scarcity-color: #f59e0b; }
.jb-scarcity--critique { --jb-scarcity-color: #dc2626; }
.jb-scarcity--epuise { --jb-scarcity-color: #6b7280; }

.jb-scarcity__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .5rem;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
}

.jb-scarcity__sold {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    color: var(--jb-scarcity-color);
}

.jb-scarcity__sold svg {
    width: 15px;
    height: 15px;
}

.jb-scarcity__left {
    color: var(--jb-gray-700, #374151);
}

.jb-scarcity__bar {
    position: relative;
    height: 9px;
    overflow: hidden;
    border-radius: 999px;
    background: var(--jb-gray-200, #e5e7eb);
}

.jb-scarcity__fill {
    display: block;
    height: 100%;
    width: var(--jb-scarcity-fill, 0%);
    border-radius: 999px;
    background: var(--jb-scarcity-color);
    animation: jb-scarcity-drain 1.1s cubic-bezier(.22, .61, .36, 1) both;
}

@keyframes jb-scarcity-drain {
    from { width: 100%; }
    to { width: var(--jb-scarcity-fill, 0%); }
}

@media (prefers-reduced-motion: reduce) {
    .jb-scarcity__fill { animation: none; }
    .jb-countdown__box { transition: none; }
}

.jb-scarcity__notice {
    margin: .5rem 0 0;
    font-size: var(--jb-fs-xs);
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--jb-scarcity-color);
}

/* ── Moyens de paiement acceptés ────────────────────────────────────────── */
.jb-paylogos {
    margin-top: 1rem;
    text-align: center;
}

.jb-paylogos__label {
    display: block;
    margin-bottom: .5rem;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-600, #6b7280);
}

.jb-paylogos__row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .375rem;
}

.jb-paylogos__item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 2rem;
    padding: .25rem;
    border: 1px solid var(--jb-gray-200, #e5e7eb);
    border-radius: 8px;
    background: #fff;
}

.jb-paylogos__item img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* ── Partage de la fiche produit ────────────────────────────────────────── */
.jb-product-share {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--jb-gray-200, #e5e7eb);
    text-align: center;
}

.jb-product-share__label {
    display: block;
    margin-bottom: .5rem;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-600, #6b7280);
}

.jb-product-share__row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .35rem;
}

.jb-product-share__btn {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .345rem .65rem;
    border: 1px solid var(--jb-gray-200, #e5e7eb);
    border-radius: 999px;
    background: #fff;
    font-size: .65rem;
    font-weight: 600;
    color: var(--jb-gray-700, #374151);
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}

.jb-product-share__btn:hover {
    border-color: var(--jb-orange, #fe6703);
    color: var(--jb-orange, #fe6703);
}

.jb-product-share__btn svg {
    width: 14px;
    height: 14px;
}

/* Barre d'achat fixe du mobile. Le fond est blanc et opaque : posée sur du
   contenu qui défile, une barre translucide devient illisible dès la
   première image claire. */
.jb-buybar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1030;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .75rem 1rem calc(.75rem + env(safe-area-inset-bottom));
    background: var(--jb-white);
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -4px 16px rgba(11, 10, 10, .08);
}

.jb-buybar__now {
    display: block;
    font-size: var(--jb-fs-lg);
    font-weight: 800;
    color: var(--jb-black);
}

.jb-buybar__was {
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
    text-decoration: line-through;
}

.jb-buybar .jb-btn {
    flex: 1 1 auto;
    max-width: 60%;
}

/* La barre couvre le bas de page : sans cette réserve, le dernier avis et le
   pied de page se retrouvent dessous, inatteignables. */
@media (max-width: 991.98px) {
    body:has(.jb-buybar) {
        padding-bottom: 5.5rem;
    }
}

/* ── Sommaire de formation et listes de fichiers ────────────────────────── */

.jb-syllabus {
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: chapter;
}

.jb-syllabus__chapter + .jb-syllabus__chapter {
    margin-top: 1.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--color-border-soft);
}

.jb-syllabus__chapter-title {
    margin: 0 0 .5rem;
    font-weight: 700;
    color: var(--jb-black);
    counter-increment: chapter;
}

.jb-syllabus__chapter-title::before {
    content: counter(chapter) ". ";
    color: var(--jb-orange-dark);
}

.jb-syllabus__lessons {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: .375rem;
}

.jb-syllabus__lessons li {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .375rem .5rem;
    border-radius: var(--jb-radius-sm);
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-700);
}

.jb-syllabus__lessons li.is-current {
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
    font-weight: 700;
}

.jb-syllabus__lessons svg {
    width: 15px;
    height: 15px;
    flex: 0 0 auto;
    color: var(--jb-gray-500);
}

.jb-syllabus__lessons li.is-current svg {
    color: var(--jb-orange-dark);
}

.jb-syllabus__duration {
    margin-left: auto;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
}

.jb-file-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: .5rem;
}

.jb-file-list__item {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .625rem .75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-sm);
    background: var(--jb-gray-50);
}

.jb-file-list__icon {
    color: var(--jb-orange-dark);
}

.jb-file-list__name {
    font-weight: 600;
    color: var(--jb-black);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.jb-file-list__size {
    margin-left: auto;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-500);
}

.jb-file-list__item .jb-btn {
    flex: 0 0 auto;
}

.jb-lesson-files__title {
    margin: 1.5rem 0 .75rem;
    font-size: var(--jb-fs-lg);
}

@media screen and (max-width: 885px) {
    .jb-file-list__name {
        width: 70%;
    }
    .jb-file-list__item {
        max-width: 290px;
    }
}

/* ── Repère de lecture ──────────────────────────────────────────────────────
   Le produit ne comporte **aucun suivi d'avancement** (arbitrage du porteur de
   projet du 2026-09-02) : cette ligne dit seulement où l'on se trouve dans le
   programme, elle ne mesure rien et ne se coche pas. */

.jb-course-position {
    margin: 0 0 1.5rem;
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-600);
}

.jb-course-toc__toggle {
    width: 100%;
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .875rem 1rem;
    border: 0;
    background: transparent;
    font-weight: 700;
    color: var(--jb-black);
}

.jb-lesson-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .75rem;
    padding: 1rem 1.25rem;
    border-top: 1px solid var(--color-border-soft);
}

/* ── Avis ───────────────────────────────────────────────────────────────── */

.jb-review {
    display: flex;
    gap: .875rem;
}

.jb-review + .jb-review {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--color-border-soft);
}

.jb-review__avatar {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--jb-radius-pill);
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
    font-weight: 800;
    overflow: hidden;
}

.jb-review__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.jb-review__author {
    margin: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem;
    font-weight: 700;
    color: var(--jb-black);
}

.jb-review__verdict {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: var(--jb-fs-xs);
    font-weight: 600;
}

.jb-review__verdict.is-positive { color: var(--jb-success); }
.jb-review__verdict.is-negative { color: var(--jb-danger); }

.jb-review__text {
    margin: .375rem 0 0;
    font-size: var(--jb-fs-sm);
    color: var(--jb-gray-700);
}

.jb-review-choice {
    display: grid;
    gap: .5rem;
}

.jb-review-choice__option input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.jb-review-choice__option span {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .625rem .75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--jb-radius-sm);
    cursor: pointer;
    font-size: var(--jb-fs-sm);
    font-weight: 600;
    color: var(--jb-gray-700);
}

.jb-review-choice__option input:checked + span {
    border-color: var(--jb-orange);
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

/* ── Animations du bouton d'achat ───────────────────────────────────────────
   Réglées produit par produit en Administration (App\Enums\ButtonAnimation).
   Toutes s'arrêtent quand le système demande moins de mouvement : attirer
   l'attention ne justifie pas de gêner quelqu'un qui a explicitement réglé
   cette préférence. */

.jb-anim-shake   { animation: jbShake 2s ease-in-out infinite; }
.jb-anim-wiggle  { animation: jbWiggle 1.6s ease-in-out infinite; }
.jb-anim-bounce  { animation: jbBounce 1.8s ease-in-out infinite; }
.jb-anim-breathe { animation: jbBreathe 2.4s ease-in-out infinite; }

@keyframes jbShake {
    0%, 82%, 100% { transform: translateX(0); }
    85% { transform: translateX(-4px); }
    88% { transform: translateX(4px); }
    91% { transform: translateX(-3px); }
    94% { transform: translateX(3px); }
    97% { transform: translateX(-1px); }
}

@keyframes jbWiggle {
    0%, 100% { transform: rotate(0deg); }
    25% { transform: rotate(-1.5deg); }
    75% { transform: rotate(1.5deg); }
}

@keyframes jbBounce {
    0%, 60%, 100% { transform: translateY(0); }
    70% { transform: translateY(-6px); }
    85% { transform: translateY(-3px); }
}

@keyframes jbBreathe {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.03); }
}

@media (prefers-reduced-motion: reduce) {
    .jb-anim-shake,
    .jb-anim-wiggle,
    .jb-anim-bounce,
    .jb-anim-breathe {
        animation: none;
    }
}

/* ==========================================================================
   Dock d'appels a l'action — pastilles fixes de bas d'ecran
   --------------------------------------------------------------------------
   Quelques pages portent une decision que le visiteur peut prendre a tout
   moment de sa lecture. Le dock garde ces gestes a portee sans occuper de
   place : au repos, chaque bouton n'est qu'un cercle avec son icone ; au
   survol, il s'ouvre en largeur et donne son libelle.

   Les couleurs disent la cible, elles ne decorent pas : orange pour l'action
   recruteur qui compte, noir pour la seconde, blanc borde pour le geste
   prestataire, vert pour la chaine WhatsApp (marque tierce, seul cas ou une
   couleur hors charte est justifiee), orange pale pour les outils candidats.
   ========================================================================== */

.jb-cta-dock {
    position: fixed;
    right: 1.125rem;
    bottom: calc(1.125rem + env(safe-area-inset-bottom));
    z-index: 1035;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .5rem;
}

.jb-cta-dock__list {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .5rem;
}

.jb-cta-dock__btn {
    display: flex;
    align-items: center;
    max-width: 47px;
    height: 47px;
    border: 1px solid transparent;
    border-radius: 30px;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    /* Deux ombres, et la premiere n'en est pas une : c'est un liseré blanc qui
       detache la pastille quand elle passe au-dessus du pied de page noir. Sans
       lui, le bouton noir y disparaissait purement et simplement, et le bouton
       clair perdait son bord. Sur fond blanc, ce liseré ne se voit pas. */
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .65), 0 6px 18px rgba(11, 10, 10, .22);
    transition: max-width .3s ease, background-color .18s ease, border-color .18s ease;
}

.jb-cta-dock__icon {
    flex: 0 0 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 48px;
}

.jb-cta-dock__icon svg { width: 20px; height: 20px; }
.jb-cta-dock__icon i { font-size: 1.125rem; }

.jb-cta-dock__label {
    padding-right: 1.25rem;
    opacity: 0;
    transition: opacity .16s ease .08s;
}

.jb-cta-dock__btn:hover,
.jb-cta-dock__btn:focus-visible {
    max-width: 30rem;
    padding-right: 1.85rem;
    text-decoration: none;
}

.jb-cta-dock__btn:hover .jb-cta-dock__label,
.jb-cta-dock__btn:focus-visible .jb-cta-dock__label { opacity: 1; }

/* ----- Couleurs, par cible ----- */
.jb-cta-dock__btn--primary { background: var(--jb-orange); color: var(--jb-white); }
.jb-cta-dock__btn--primary:hover,
.jb-cta-dock__btn--primary:focus-visible { background: var(--jb-orange-dark); color: var(--jb-white); }

.jb-cta-dock__btn--dark { background: var(--jb-black); color: var(--jb-white); }
.jb-cta-dock__btn--dark:hover,
.jb-cta-dock__btn--dark:focus-visible { background: var(--jb-gray-800); color: var(--jb-white); }

/* Bord noir et non gris clair : au repos ce bouton n'est qu'un cercle blanc,
   et un cercle blanc borde de gris sur un fond blanc ne se voit pas. */
.jb-cta-dock__btn--outline {
    background: var(--jb-white);
    color: var(--jb-black);
    border-color: var(--jb-black);
}

.jb-cta-dock__btn--outline:hover,
.jb-cta-dock__btn--outline:focus-visible { background: var(--jb-gray-100); color: var(--jb-black); }

/* Vert de la marque WhatsApp, texte noir : le blanc sur ce vert passe sous le
   seuil de lisibilite, et un bouton illisible ne se clique pas. */
.jb-cta-dock__btn--whatsapp { background: #25d366; color: var(--jb-black); }
.jb-cta-dock__btn--whatsapp:hover,
.jb-cta-dock__btn--whatsapp:focus-visible { background: #1fbb59; color: var(--jb-black); }

/* Outils candidats. Orange pale sur fond blanc, ce bouton ne se voyait pas, et
   c'est le seul que portent les pages Articles : il y passait pour absent.
   Fond blanc, anneau et icone orange pleins, il se lit maintenant partout sans
   prendre la place de l'action principale, qui reste seule en orange plein. */
.jb-cta-dock__btn--soft {
    background: var(--jb-white);
    color: var(--jb-orange-dark);
    border-color: var(--jb-orange);
}

.jb-cta-dock__btn--soft:hover,
.jb-cta-dock__btn--soft:focus-visible {
    background: var(--jb-orange-soft);
    color: var(--jb-orange-dark);
}

/* ----- Bouton d'ouverture (mobile) ----- */
.jb-cta-dock__toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--jb-orange);
    color: var(--jb-white);
    box-shadow: var(--jb-shadow-lg);
    cursor: pointer;
}

.jb-cta-dock__toggle svg { width: 20px; height: 20px; }
.jb-cta-dock__toggle-close { display: none; }
.jb-cta-dock.is-open .jb-cta-dock__toggle { background: var(--jb-black); }
.jb-cta-dock.is-open .jb-cta-dock__toggle-open { display: none; }
.jb-cta-dock.is-open .jb-cta-dock__toggle-close { display: flex; }

.jb-cta-dock__veil {
    position: fixed;
    inset: 0;
    z-index: 1034;
    background: rgba(11, 10, 10, .35);
}

.jb-cta-dock__veil[hidden] { display: none; }

/* ----- Grand ecran : rien ne se replie, donc ni bouton d'ouverture ni voile.
   Ce seuil est porte ici et non par les utilitaires Bootstrap (`d-lg-none`) :
   la visibilite du dock ne doit pas dependre d'une couche d'utilitaires. ----- */
@media (min-width: 992px) {
    .jb-cta-dock__toggle,
    .jb-cta-dock__veil { display: none !important; }
}

/* ----- Mobile : pas de survol, donc un depliage au toucher ----- */
@media (max-width: 991.98px) {
    .jb-cta-dock {
        right: .875rem;
        bottom: calc(.875rem + env(safe-area-inset-bottom));
    }

    /* Les deux ecrans Emploi gardent le bas d'ecran mobile pour la barre fixe
       des generateurs : le dock n'y reparait qu'au grand ecran. */
    .jb-cta-dock--desktop-only { display: none; }

    /* Repliee, la pile n'existe pas : elle ne laisse ni pastille orpheline ni
       zone cliquable invisible par-dessus le contenu. */
    .jb-cta-dock__list { display: none; }
    .jb-cta-dock.is-open .jb-cta-dock__list { display: flex; }

    /* Deploye, chaque bouton donne son libelle d'emblee : sur un ecran
       tactile, une icone seule n'est jamais explicite. */
    .jb-cta-dock__btn {
        max-width: none;
        padding-right: 1.85rem;
        height: 46px;
        animation: jbCtaDockIn .18s ease both;
    }

    .jb-cta-dock__icon { flex-basis: 44px; height: 44px; }
    .jb-cta-dock__label { opacity: 1; }
}

@keyframes jbCtaDockIn {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .jb-cta-dock__btn { animation: none; transition: none; }
    .jb-cta-dock__label { transition: none; }
}

/* =====================================================================
   Boutons `.btn-dv-*` : utilisés par les pages autonomes (erreurs, mail
   de test) qui ne chargent pas le reste des composants Bootstrap. Rayon
   fixe à 30px pour rester cohérent avec `x-mail-button` et le bouton
   principal des cartes de listing, jamais en pilule pure ni carré.
   ===================================================================== */
.btn-dv {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: .8rem 1.5rem;
    border: 1px solid transparent;
    border-radius: 30px;
    font-size: var(--jb-fs-base);
    font-weight: 700;
    line-height: 1.2;
    text-decoration: none;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.btn-dv-block { display: flex; }

.btn-dv-primary { background: var(--jb-orange); color: var(--jb-white); }
.btn-dv-primary:hover, .btn-dv-primary:focus-visible { background: var(--jb-orange-dark); color: var(--jb-white); }

/* Action secondaire : jamais la même couleur pleine que l'action
   principale (SKILL ui-design-system, hiérarchie des boutons). */
.btn-dv-ghost { background: transparent; border-color: var(--jb-gray-300); color: var(--jb-black); }
.btn-dv-ghost:hover, .btn-dv-ghost:focus-visible { background: var(--jb-gray-100); color: var(--jb-black); }

.btn-dv + .btn-dv { margin-top: .625rem; }

/* =====================================================================
   Pages d'erreur (404/403/419/429/500/503), `layouts.site.error`.
   Page volontairement autonome : ni navbar, ni pied de page, ni CTA
   dock. Le code d'erreur en très gros et l'action principale en orange
   restent les deux seuls signaux forts de l'écran.
   ===================================================================== */
.error-body {
    display: flex;
    min-height: 100dvh;
    margin: 0;
    background: var(--jb-gray-100);
}

.error-shell {
    display: flex;
    flex: 1 0 auto;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 2rem 1.25rem calc(2rem + env(safe-area-inset-bottom));
}

.error-card {
    width: 100%;
    max-width: 420px;
    padding: 2.75rem 1.75rem 2rem;
    background: var(--jb-white);
    border-radius: var(--jb-radius-lg);
    box-shadow: var(--jb-shadow-lg);
    text-align: center;
}

.error-code {
    display: block;
    margin-bottom: .5rem;
    font-size: 3.5rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.03em;
    color: var(--jb-orange);
}

.error-title {
    margin: 0 0 .625rem;
    font-size: var(--jb-fs-2xl);
    font-weight: 800;
    letter-spacing: -.01em;
    color: var(--jb-black);
}

.error-message {
    margin: 0 0 1.75rem;
    font-size: var(--jb-fs-base);
    line-height: 1.6;
    color: var(--jb-gray-600);
}

.error-actions {
    display: flex;
    flex-direction: column;
}

.error-brand {
    margin: 1.5rem 0 0;
    font-size: var(--jb-fs-lg);
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--jb-black);
}

.error-brand span { color: var(--jb-orange); }

/* =====================================================================
   Bannière d'installation PWA (`DvPwa`, TODO.md V3.7).
   Fixe en bas d'écran sur tous les gabarits, jamais un geste caché : le
   public cible « moins mature en usage digital » (CLAUDE.md) doit voir
   la proposition sans avoir à la découvrir.
   ===================================================================== */
.jb-install-banner {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1040;
    display: flex;
    align-items: center;
    gap: .875rem;
    padding: .875rem 1rem calc(.875rem + env(safe-area-inset-bottom));
    background: var(--jb-black);
    box-shadow: 0 -8px 24px rgba(11, 10, 10, .18);
    animation: jbInstallIn .22s ease both;
}

.jb-install-banner[hidden] { display: none; }

.jb-install-banner__icon {
    display: flex;
    flex: 0 0 44px;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: var(--jb-radius);
    background: var(--jb-orange);
    overflow: hidden;
}

.jb-install-banner__icon img { width: 100%; height: 100%; object-fit: cover; }

.jb-install-banner__text { flex: 1 1 auto; min-width: 0; }

.jb-install-banner__title {
    margin: 0;
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    color: var(--jb-white);
}

.jb-install-banner__subtitle {
    margin: 0;
    overflow: hidden;
    font-size: var(--jb-fs-xs);
    color: var(--jb-gray-400);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.jb-install-banner__actions { display: flex; flex: 0 0 auto; align-items: center; gap: .5rem; }

.jb-install-banner__btn {
    padding: .5rem 1rem;
    border: 0;
    border-radius: 30px;
    background: var(--jb-orange);
    color: var(--jb-white);
    font-size: var(--jb-fs-sm);
    font-weight: 700;
    white-space: nowrap;
}

.jb-install-banner__btn:hover, .jb-install-banner__btn:focus-visible { background: var(--jb-orange-dark); color: var(--jb-white); }

.jb-install-banner__dismiss {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--jb-gray-400);
}

.jb-install-banner__dismiss:hover, .jb-install-banner__dismiss:focus-visible { background: var(--jb-gray-800); color: var(--jb-white); }
.jb-install-banner__dismiss svg { width: 18px; height: 18px; }

/* Sur mobile, le bandeau bas partage l'espace avec la barre fixe des
   générateurs Emploi et le CTA dock replié : il passe devant les deux, il
   ne se cumule jamais avec eux (un seul geste de bas d'écran à la fois). */
@media (max-width: 575.98px) {
    .jb-install-banner__subtitle { display: none; }
}

@keyframes jbInstallIn {
    from { opacity: 0; transform: translateY(100%); }
    to { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .jb-install-banner { animation: none; }
}
