/* ==========================================================================
   FACTEO — Couche d'amélioration UI/UX
   --------------------------------------------------------------------------
   Chargée APRÈS main.css / builder.css / legal.css.

   Principe : purement additive. Aucune règle existante n'est supprimée ni
   réécrite ; on ne corrige que des problèmes mesurés :

     1. Contraste  — success/warning/danger échouaient au WCAG AA sur blanc
                     (2,15:1 à 3,76:1 ; le minimum est 4,5:1)
     2. iOS        — les champs à 0.92rem (14,7px) déclenchent le zoom
                     automatique de Safari à chaque focus
     3. Tactile    — cibles < 44px difficiles à viser au doigt
     4. Clavier    — aucun style :focus-visible : navigation au clavier invisible
     5. Mouvement  — 9 animations sans respect de prefers-reduced-motion

   Les couleurs de marque (primaire, dégradés, rayons, ombres) sont conservées
   telles quelles : elles relèvent d'un choix esthétique, pas d'un défaut.
   ========================================================================== */

:root {
    /* Variantes accessibles, utilisées uniquement pour du TEXTE et des icônes.
       Les fonds et bordures continuent d'utiliser les couleurs d'origine :
       elles restent vives, seul le texte devient lisible. */
    --success-text: #047857;   /* 5.48:1 sur blanc */
    --success-on-subtle: #036049;  /* 5.84:1 sur le fond .bg-success-subtle */
    --warning-text: #92400e;   /* 7.02:1 sur blanc */
    --danger-text:  #b91c1c;   /* 6.24:1 sur blanc */
    --primary-text: #0a4a83;   /* 9.05:1 sur blanc — déjà présent en hover */
}

/* --------------------------------------------------------------------------
   1. CONTRASTE DU TEXTE
   Bootstrap applique .text-success/.text-warning/.text-danger à du texte fin,
   souvent en petite taille : ce sont les cas les moins lisibles.
   -------------------------------------------------------------------------- */
.text-success { color: var(--success-text) !important; }
.text-warning { color: var(--warning-text) !important; }
.text-danger  { color: var(--danger-text)  !important; }

/* Badges « subtle » de Bootstrap : fond pâle + texte de la même teinte.
   Sans correction, le texte passe à ~2:1 et devient illisible. */
.text-success-emphasis,
.badge.bg-success-subtle { color: var(--success-on-subtle) !important; }
.text-warning-emphasis,
.badge.bg-warning-subtle { color: var(--warning-text) !important; }
.text-danger-emphasis,
.badge.bg-danger-subtle  { color: var(--danger-text)  !important; }

/* Le texte secondaire sur fond gris passait à 4,55:1 — juste au-dessus du
   seuil. On lui donne un peu de marge. */
.text-muted { color: #5a6675 !important; }

/* --------------------------------------------------------------------------
   2. MOBILE — supprimer le zoom automatique d'iOS
   Safari zoome dès qu'un champ a une police < 16px. Appliqué uniquement sous
   768px : la densité du bureau est préservée.
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .form-control,
    .form-select,
    input[type="text"],
    input[type="email"],
    input[type="password"],
    input[type="number"],
    input[type="tel"],
    input[type="search"],
    input[type="date"],
    textarea,
    select {
        font-size: 16px !important;   /* seuil exact d'iOS */
        padding-top: 0.7rem;
        padding-bottom: 0.7rem;
    }

    /* 3. Cibles tactiles : 44px est le minimum recommandé (Apple HIG,
       Material Design). En dessous, on vise mal au pouce. */
    .btn,
    .nav-link,
    .dropdown-item,
    .page-link {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* Les boutons purement iconographiques doivent aussi être carrés. */
    .btn-icon,
    .btn-doc-sub {
        min-width: 44px;
    }

    /* Les cases à cocher légales sont petites et obligatoires à l'inscription :
       on agrandit la zone cliquable sans changer l'apparence. */
    .form-check-input {
        min-width: 1.15rem;
        min-height: 1.15rem;
        margin-top: 0.2rem;
    }
    .form-check-label {
        padding-left: 0.15rem;
        line-height: 1.5;
    }

    /* Les tableaux larges défilent dans leur conteneur plutôt que d'élargir
       la page entière (évite le défilement horizontal du body). */
    .table-responsive {
        -webkit-overflow-scrolling: touch;
    }
}

/* Sur écran tactile quelle que soit la largeur (tablette en paysage). */
@media (hover: none) and (pointer: coarse) {
    .btn,
    .nav-link {
        min-height: 44px;
    }
}

/* --------------------------------------------------------------------------
   4. CLAVIER — rendre le focus visible
   :focus-visible ne s'active qu'à la navigation clavier : la souris ne voit
   aucun changement, mais l'accessibilité devient conforme.
   -------------------------------------------------------------------------- */
:focus-visible {
    outline: 2px solid var(--primary-text, #0a4a83);
    outline-offset: 2px;
    border-radius: 4px;
}

.btn:focus-visible,
.nav-link:focus-visible,
.dropdown-item:focus-visible {
    outline: 2px solid var(--primary-text, #0a4a83);
    outline-offset: 2px;
    box-shadow: 0 0 0 4px rgba(10, 74, 131, 0.15);
}

.form-control:focus-visible,
.form-select:focus-visible {
    outline: 2px solid var(--primary-text, #0a4a83);
    outline-offset: 1px;
}

/* Lien d'évitement : masqué jusqu'à ce qu'il reçoive le focus au clavier. */
.skip-to-content {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 2000;
    padding: 0.75rem 1.25rem;
    background: #0f172a;
    color: #fff;
    text-decoration: none;
    border-radius: 0 0 8px 0;
    font-weight: 600;
}
.skip-to-content:focus {
    left: 0;
    color: #fff;
}

/* --------------------------------------------------------------------------
   5. MOUVEMENT — respecter prefers-reduced-motion
   Obligation d'accessibilité, et confort réel pour les personnes sensibles
   au mouvement (vertiges, migraines).
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    /* EXCEPTION IMPORTANTE : les indicateurs de chargement sont exclus.
       Un spinner n'est pas une décoration, c'est le seul signal indiquant
       qu'un traitement est en cours (analyse IA, transmission Super PDP...).
       L'arrêter donne une interface qui paraît plantée. La WCAG 2.3.3 vise
       le mouvement décoratif, pas les indicateurs d'état.
       :not() est utilisé plutôt qu'une réactivation après coup, car
       `animation-iteration-count: 1` mettrait fin au spinner après un tour
       même si l'animation était relancée ensuite. */
    *:not(.fa-spin):not(.fa-pulse):not(.spinner-border):not(.spinner-grow):not(.fx-ring):not(.fa-spin *),
    *:not(.loader-illus)::before,
    *:not(.loader-illus)::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    /* Les effets de survol qui déplacent l'élément sont neutralisés. */
    .btn:hover,
    .card-modern:hover,
    .btn-doc-sub:hover {
        transform: none !important;
    }

    /* Filet de sécurité : on réaffirme la rotation des indicateurs de
       chargement, y compris ceux insérés dynamiquement par builder.js,
       dashboard.js et app.js. */
    .fa-spin,
    .fa-pulse,
    .spinner-border,
    .spinner-grow {
        animation-duration: 1s !important;
        animation-iteration-count: infinite !important;
    }
    .spinner-border {
        animation-duration: 0.75s !important;
    }
    .fa-pulse {
        animation-duration: 1s !important;
        animation-timing-function: steps(8) !important;
    }
}

/* --------------------------------------------------------------------------
   6. FINITIONS — améliorations discrètes, sans changement de mise en page
   -------------------------------------------------------------------------- */

/* Rendu du texte plus net sur écrans haute densité (très courant sur mobile). */
body {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

/* Les titres se coupent mieux : évite le mot orphelin sur la dernière ligne. */
h1, h2, h3, .h1, .h2, .h3 {
    text-wrap: balance;
}

/* Les chiffres s'alignent en colonne dans les tableaux et totaux :
   essentiel quand on compare des montants. */
.table td,
.table th,
.kpi-value,
.invoice-total,
[class*="montant"],
[class*="total"] {
    font-variant-numeric: tabular-nums;
}

/* Un tableau large défile dans son propre conteneur, jamais la page. */
.table-responsive {
    overflow-x: auto;
    max-width: 100%;
}

/* Les images ne débordent jamais de leur colonne. */
img {
    max-width: 100%;
    height: auto;
}

/* La sélection de texte reprend la couleur de marque. */
::selection {
    background: rgba(65, 138, 162, 0.22);
    color: #0f172a;
}

/* Barres de défilement discrètes sur les zones internes (bureau uniquement). */
@media (hover: hover) and (min-width: 768px) {
    .table-responsive::-webkit-scrollbar,
    .modal-body::-webkit-scrollbar {
        height: 8px;
        width: 8px;
    }
    .table-responsive::-webkit-scrollbar-thumb,
    .modal-body::-webkit-scrollbar-thumb {
        background: #cbd5e1;
        border-radius: 8px;
    }
    .table-responsive::-webkit-scrollbar-thumb:hover,
    .modal-body::-webkit-scrollbar-thumb:hover {
        background: #94a3b8;
    }
}

/* Un état désactivé doit se lire comme tel. */
.btn:disabled,
.btn.disabled,
.form-control:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* Impression : les PDF sont générés côté serveur, mais un utilisateur peut
   imprimer une page. On retire le superflu. */
@media print {
    .navbar,
    .footer,
    footer,
    .btn,
    .no-print {
        display: none !important;
    }
    body {
        background: #fff !important;
    }
    .card-modern,
    .card {
        box-shadow: none !important;
        border: 1px solid #ddd !important;
    }
}

/* --------------------------------------------------------------------------
   7. BUILDER — builder.css est chargé APRÈS ce fichier sur /builder, donc
   les règles ci-dessous sont plus spécifiques pour rester prioritaires.
   C'est l'écran le plus utilisé sur mobile : chaque champ de ligne y
   déclenchait le zoom iOS.
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
    .live-table .table-input,
    .live-table .table-input.text-end,
    .live-table .price-input-group .table-input,
    .live-table .input-group .table-input {
        font-size: 16px !important;   /* supprime le zoom automatique d'iOS */
    }

    /* Les boutons de suppression de ligne doivent rester atteignables
       au pouce sans agrandir la ligne. */
    .live-table .btn-remove-row,
    .live-table .btn-icon {
        min-width: 40px;
        min-height: 40px;
    }
}

/* --------------------------------------------------------------------------
   8. PIED DE PAGE
   Sept liens sur une seule rangee debordaient : le dernier se retrouvait seul
   sur une deuxieme ligne, desaligne. Le pied de page est desormais organise en
   colonnes, ce qui tient aussi bien en mobile qu en grand ecran.
   -------------------------------------------------------------------------- */
.footer-heading {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-heading, #0f172a);
    margin-bottom: 0.75rem;
}

.footer-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.footer-list .footer-link {
    display: inline-block;
    line-height: 1.4;
}

.footer-bottom {
    margin-top: 1.75rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color, #e2e8f0);
    text-align: center;
}

/* Les deux colonnes de liens passent l une sous l autre sur tres petit ecran,
   plutot que de se serrer sur une demi-largeur illisible. */
@media (max-width: 400px) {
    .footer-custom .col-6 {
        flex: 0 0 100%;
        max-width: 100%;
    }
}

/* --------------------------------------------------------------------------
   9. BASCULE MENSUEL / ANNUEL (page Tarifs)
   Sur mobile, les deux boutons doivent partager la largeur disponible sans
   deborder ; le libelle est raccourci et le badge sort du bouton.
   -------------------------------------------------------------------------- */
.billing-toggle .btn {
    padding: 0.6rem 1.5rem;
    white-space: nowrap;
}

@media (max-width: 575.98px) {
    .billing-toggle {
        display: flex !important;
        width: 100%;
        max-width: 340px;
        /* Un element flex de niveau bloc ne suit plus le text-align:center du
           parent : il faut le centrer explicitement par ses marges. */
        margin-inline: auto;
    }
    .billing-toggle .btn {
        flex: 1 1 50%;
        padding: 0.7rem 0.5rem;
        font-size: 0.88rem;
        min-height: 44px;
    }
}

/* --------------------------------------------------------------------------
   10. ILLUSTRATIONS DES 3 ETAPES (accueil)
   Les trois SVG ont des viewBox differents (380x384, 430x430, 543x542) : a
   largeur egale ils apparaissent de tailles differentes. On leur impose donc
   une BOITE de hauteur fixe et un object-fit: contain, ce qui les met a la
   meme echelle visuelle quelle que soit leur geometrie interne.
   -------------------------------------------------------------------------- */
.step-illus {
    height: 130px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 0.75rem;
    /* Une illustration mise a l echelle ne doit pas deborder sur le texte
       de la carte. */
    overflow: hidden;
}

.step-illus img {
    height: 100%;
    width: auto;
    max-width: 100%;
    object-fit: contain;
}

@media (max-width: 767.98px) {
    .step-illus { height: 110px; }
}

/* Une animation en boucle peut gener : on la met en pause si l utilisateur
   demande a reduire les animations. */
@media (prefers-reduced-motion: reduce) {
    .step-illus img { animation-play-state: paused !important; }
}

/* list.svg dessine son illustration dans une portion seulement de son canvas
   450x450 (le contenu est repositionne par des transformations internes).
   A hauteur de boite egale, elle parait donc plus petite que les deux autres :
   on la met a l echelle pour equilibrer la rangee. */
.step-illus-zoom {
    transform: scale(1.45);
    transform-origin: center;
}

/* --------------------------------------------------------------------------
   7. INDICATEUR DE CHARGEMENT — UN SEUL SYSTEME, TROIS TAILLES
   L anneau est l identite commune : meme forme, meme couleur, meme rotation
   partout. L illustration n apparait qu au-dessus de 64px, ou elle est
   lisible ; en dessous, l anneau seul remplace fa-spin.
   -------------------------------------------------------------------------- */

/* --- Anneau seul : remplace fa-spin dans les boutons et les badges. ------- */
.fx-ring {
    display: inline-block;
    width: 1em;
    height: 1em;
    vertical-align: -0.125em;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-bottom-color: transparent;
    opacity: 0.85;
    animation: fx-ring-spin 0.7s linear infinite;
    flex-shrink: 0;
}

/* Dans un bouton, l anneau herite de la couleur du texte : il reste lisible
   sur fond bleu comme sur fond clair, sans regle supplementaire. */
.fx-ring-sm { border-width: 1.5px; }
.fx-ring-lg { width: 1.6em; height: 1.6em; border-width: 2.5px; }

@keyframes fx-ring-spin {
    to { transform: rotate(360deg); }
}

/* --- Anneau + illustration : attentes longues, 72px et plus. ------------- */
.loader-illus {
    position: relative;
    width: 72px;
    height: 72px;
    display: grid;
    place-items: center;
    margin-inline: auto;
    /* Le dessin est recadre : on masque ce qui deborde du cercle. */
    border-radius: 50%;
    overflow: hidden;
    flex-shrink: 0;
}

/* L anneau est pose PAR-DESSUS le masque, donc en ::after. */
.loader-illus::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2.5px solid var(--primary-light, #dbeafe);
    border-top-color: var(--primary-color, #418aa2);
    border-bottom-color: var(--primary-color, #418aa2);
    animation: loader-ring 1.1s linear infinite;
}

/* Le SVG a un large canvas vide autour de son dessin (le trace utile
   n occupe qu une fraction du viewBox 380x384). On l agrandit et on laisse
   le conteneur rogner : le cercle epouse alors le dessin, sans halo blanc. */
.loader-illus img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: scale(2.15);
    transform-origin: center;
}

@keyframes loader-ring {
    to { transform: rotate(360deg); }
}

/* Variante sur fond sombre (apercu PDF : fond #334155). */
.loader-illus--dark {
    background: #ffffff;
}
.loader-illus--dark::after {
    border-color: rgba(255, 255, 255, 0.25);
    border-top-color: #ffffff;
    border-bottom-color: #ffffff;
}

/* --- Etat "Analyse IA" dans la barre vocale ------------------------------
   Remplace la pastille du micro pendant l appel a l IA. La page reste
   entierement visible et utilisable : rien n est masque. */
.btn-voice-record.is-processing .mic-icon-bubble {
    background: rgba(255, 255, 255, 0.28);
    padding: 0;
    overflow: hidden;
}

/* Mouvement reduit : les anneaux continuent de tourner (indicateurs d etat,
   pas decoration) ; seule l animation interne du SVG est figee. */
@media (prefers-reduced-motion: reduce) {
    .loader-illus::after,
    .fx-ring {
        animation-duration: 1.1s !important;
        animation-iteration-count: infinite !important;
    }
    .loader-illus img {
        animation-play-state: paused !important;
    }
}
