/**
 * mio.land - Composants UX partagés
 * Source de vérité pour tous les éléments d'interface utilisateur
 * 
 * Usage: <link rel="stylesheet" href="/ux/ux-components.css?<?= filemtime($_SERVER['DOCUMENT_ROOT'] . '/ux/ux-components.css') ?>">
 * 
 * Ce fichier est conçu pour être embeddable dans des exports HTML standalone.
 * Toutes les icônes sont en SVG inline, jamais d'emojis ou caractères graphiques.
 * 
 * PERSONNALISATION PAR APP:
 * Les apps peuvent définir --accent dans leur CSS pour personnaliser:
 * - La couleur du toast undo (bouton + barre de progression)
 * Exemple: :root { --accent: #7C4DFF; }
 */

/* ============================
   VARIABLES UX (à ne pas surcharger)
   ============================ */

:root {
    /* Couleurs de boutons standard */
    --ux-btn-default: #2ECC71;
    --ux-btn-default-hover: #27AE60;
    --ux-btn-primary: #3498DB;
    --ux-btn-primary-hover: #2980B9;
    --ux-btn-secondary: rgba(255, 255, 255, 0.08);
    --ux-btn-secondary-hover: rgba(255, 255, 255, 0.15);
    --ux-btn-danger: #E74C3C;
    --ux-btn-danger-hover: #C0392B;
    --ux-btn-purple: #8b5cf6;
    --ux-btn-purple-hover: #7c3aed;
    --ux-btn-pink: #ec4899;
    --ux-btn-pink-hover: #db2777;
    --ux-btn-orange: #F39C12;
    --ux-btn-orange-hover: #E67E22;
    --ux-btn-cyan: #00BCD4;
    --ux-btn-cyan-hover: #00ACC1;
    
    /* Couleurs de feedback */
    --ux-success: #2ECC71;
    --ux-error: #E74C3C;
    --ux-warning: #F39C12;
    --ux-info: #3498DB;
    
    /* Transitions */
    --ux-transition-fast: 0.15s ease;
    --ux-transition-normal: 0.25s ease;
}

/* ============================
   MARQUE PRODUCTIVIA
   ============================
   Style officiel du logotype "Productiv<span class="brand-ia">IA</span>".
   Source de verite : productivia.ca (_css/main.css).
   Usage obligatoire dans toute interface visible mentionnant la marque.
   - .brand-ia : applique le style officiel des lettres "IA" (taille reduite + decalage subtil vers le haut)
   - .brand-lock : empeche un retour a la ligne entre "Productiv" et "IA"
   Pattern HTML : <span class="brand-lock">Productiv<span class="brand-ia">IA</span></span>
   ============================ */

.brand-ia {
    display: inline-block;
    font-size: 0.85em;
    transform: translate(0px, -0.20em);
    pointer-events: none;
}

.brand-lock {
    white-space: nowrap;        /* empeche le retour a la ligne */
    display: inline-block;      /* evite certaines cesures bizarres */
    word-break: normal;         /* annule break-all sur des parents */
    overflow-wrap: normal;      /* annule anywhere / break-word */
    hyphens: none;              /* pas de cesure automatique */
}

/* ============================
   INPUTS GLOBAUX
   ============================ */

input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
input[type="number"] {
    -moz-appearance: textfield;
}

/* Listes déroulantes natives : harmoniser avec les champs (thème système + couleurs) */
select:not([multiple]) {
    color-scheme: dark;
}
[data-theme="light"] select:not([multiple]) {
    color-scheme: light;
}

select option {
    background-color: var(--bg-tertiary, #1a1a25);
    color: var(--text-primary, #f0f0f5);
}

select option:checked,
select option:hover {
    background-color: var(--bg-hover, rgba(255, 255, 255, 0.08));
    color: var(--text-primary, #f0f0f5);
}

[data-theme="light"] select option {
    background-color: #ffffff;
    color: #1a1a2e;
}

[data-theme="light"] select option:checked,
[data-theme="light"] select option:hover {
    background-color: #ebedf0;
}

/* Sélecteur stylé (liste HTML = même look que le champ) — activer avec data-ux-custom-select sur <select> */
.ux-select-wrap {
    position: relative;
    width: 100%;
    max-width: 100%;
}

select.ux-select-native-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

.ux-select-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    padding: 12px 40px 12px 16px;
    box-sizing: border-box;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
    border-radius: 10px;
    color: var(--text-primary, #f0f0f5);
    font-family: inherit;
    font-size: 14px;
    font-weight: 400;
    text-align: left;
    cursor: pointer;
    transition: border-color var(--transition-fast, 0.15s ease), background var(--transition-fast, 0.15s ease);
    user-select: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%238888a0' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 16px;
}

.ux-select-trigger:hover {
    border-color: var(--border-hover, rgba(255, 255, 255, 0.12));
}

.ux-select-trigger:focus {
    outline: none;
    border-color: var(--border-focus, var(--accent-purple, #8b5cf6));
    background-color: rgba(139, 92, 246, 0.05);
}

.ux-select-trigger[aria-expanded="true"] {
    border-color: var(--border-focus, var(--accent-purple, #8b5cf6));
}

.ux-select-trigger-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ux-select-dropdown {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    z-index: 4000;
    margin-top: 4px;
    padding: 0;
    background: var(--bg-secondary, #12121a);
    border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
    border-radius: 10px;
    box-shadow: var(--shadow-lg, 0 10px 40px rgba(0, 0, 0, 0.45));
    max-height: min(420px, 60vh);
    max-width: min(360px, calc(100vw - 16px));
    overflow-x: hidden;
    overflow-y: auto;
    animation: uxSelectOpen 0.12s ease;
}

.ux-select-dropdown.ux-select-open {
    display: block;
}

.ux-select-dropdown:focus {
    outline: none;
}

.ux-select-dropdown.ux-select-flip {
    bottom: calc(100% + 4px);
    top: auto;
    margin-top: 0;
    margin-bottom: 4px;
}

/* Variante OS-level (rendue par os/app.js handleUXSelectOpen) :
   le contenu et le scroll sont deportes dans un wrapper interne pour que
   la scrollbar webkit soit clippee proprement par le border-radius du
   container externe. */
.ux-select-dropdown-os {
    overflow: hidden !important;
    padding: 0;
}
.ux-select-scroll {
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    /* Petit padding interne pour que les options ne touchent pas les
       arrondis du container et que la scrollbar reste a l'interieur. */
    padding: 4px 0;
    /* La hauteur max est posee par JS (positionList) en sync avec celle
       du container externe. */
}
.ux-select-scroll::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}
.ux-select-scroll::-webkit-scrollbar-track {
    background: transparent;
}
.ux-select-scroll::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.18);
    border-radius: 0;
    border: 2px solid transparent;
    background-clip: padding-box;
}
.ux-select-scroll::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 255, 255, 0.32);
    background-clip: padding-box;
}
.ux-select-scroll::-webkit-scrollbar-button { display: none !important; }
[data-theme="light"] .ux-select-scroll::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.22);
    background-clip: padding-box;
}
[data-theme="light"] .ux-select-scroll::-webkit-scrollbar-thumb:hover {
    background: rgba(0, 0, 0, 0.36);
    background-clip: padding-box;
}

@keyframes uxSelectOpen {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

.ux-select-option {
    padding: 10px 16px;
    font-size: 14px;
    color: var(--text-primary, #f0f0f5);
    cursor: pointer;
    transition: background 0.1s ease;
    user-select: none;
}

.ux-select-option:hover,
.ux-select-option.ux-select-option-active {
    background: var(--bg-hover, rgba(255, 255, 255, 0.06));
}

.ux-select-option.is-selected {
    color: var(--accent-purple, #8b5cf6);
    font-weight: 500;
}

.ux-select-option[disabled] {
    opacity: 0.45;
    cursor: default;
    pointer-events: none;
}

.ux-select-optgroup-label {
    padding: 8px 16px 4px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-secondary, #a0aec0);
    cursor: default;
    user-select: none;
    opacity: 0.7;
}

.ux-select-optgroup-label:not(:first-child) {
    margin-top: 4px;
    border-top: 1px solid var(--border, rgba(255, 255, 255, 0.06));
    padding-top: 10px;
}

.ux-select-option-grouped {
    padding-left: 24px;
}

[data-theme="light"] .ux-select-optgroup-label {
    color: var(--text-secondary, #64748b);
}

[data-theme="light"] .ux-select-trigger {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.1);
}

[data-theme="light"] .ux-select-dropdown {
    background: #ffffff;
    border-color: rgba(0, 0, 0, 0.1);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12);
}

/* ============================
   MENU D'ACTIONS (popover déclenché par bouton)
   ----------------------------
   Aligné sur .ux-select-dropdown. Pattern utilisé p.ex. par le bouton "+"
   dans la zone de saisie de l'Assistant. Différent de .ux-context-menu
   (clic droit) et de <select data-ux-custom-select>.

   ATTENTION : ne JAMAIS poser padding/border/background/border-radius/
   box-shadow via style inline ou cssText en JS — ces déclarations
   battent le CSS et masquent silencieusement les corrections de style.
   Le JS ne doit positionner que (position, top, left, width, max-height,
   z-index, display).
   ============================ */

.ux-action-menu-wrap {
    position: relative;
    display: inline-block;
}

.ux-action-menu {
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 4000;
    min-width: 240px;
    margin: 0;
    padding: 0;
    background: var(--bg-secondary, #12121a);
    border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
    border-radius: 10px;
    box-shadow: var(--shadow-lg, 0 10px 40px rgba(0, 0, 0, 0.45));
    overflow: hidden;
    animation: uxSelectOpen 0.12s ease;
}

.ux-action-menu.open {
    display: block;
}

.ux-action-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    box-sizing: border-box;
    margin: 0;
    padding: 10px 16px;
    border: none;
    border-radius: 0;
    background: transparent;
    appearance: none;
    -webkit-appearance: none;
    color: var(--text-primary, #f0f0f5);
    font-family: inherit;
    font-size: 14px;
    text-align: left;
    cursor: pointer;
    user-select: none;
    transition: background 0.1s ease;
}

.ux-action-menu-item:hover,
.ux-action-menu-item:focus-visible {
    background: var(--bg-hover, rgba(255, 255, 255, 0.06));
    outline: none;
}

.ux-action-menu-item.is-danger {
    color: var(--error, #ef4444);
}

.ux-action-menu-item.is-danger:hover,
.ux-action-menu-item.is-danger:focus-visible {
    background: rgba(239, 68, 68, 0.12);
}

.ux-action-menu-item[disabled] {
    opacity: 0.45;
    cursor: default;
    pointer-events: none;
}

.ux-action-menu-item svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    stroke: currentColor;
    stroke-width: 2;
    fill: none;
}

.ux-action-menu-separator {
    height: 1px;
    margin: 4px 0;
    background: var(--border, rgba(255, 255, 255, 0.08));
}

[data-theme="light"] .ux-action-menu {
    background: #ffffff;
    border-color: rgba(0, 0, 0, 0.1);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12);
}

[data-theme="light"] .ux-action-menu-item:hover,
[data-theme="light"] .ux-action-menu-item:focus-visible {
    background: rgba(0, 0, 0, 0.05);
}

[data-theme="light"] .ux-action-menu-item.is-danger:hover,
[data-theme="light"] .ux-action-menu-item.is-danger:focus-visible {
    background: rgba(239, 68, 68, 0.08);
}

/* ============================
   BOUTONS STANDARD
   ============================ */

.ux-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 20px;
    border: none;
    border-radius: 10px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--ux-transition-fast);
    user-select: none;
    white-space: nowrap;
}

.ux-btn svg {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    fill: none;
    stroke-width: 2;
    flex-shrink: 0;
}

/* Bouton par défaut = Vert (action principale) */
.ux-btn-default, .ux-btn {
    background: var(--ux-btn-default);
    color: white;
}
.ux-btn-default:hover, .ux-btn:hover {
    background: var(--ux-btn-default-hover);
    transform: translateY(-1px);
}

/* Bouton primaire = Bleu */
.ux-btn-primary {
    background: var(--ux-btn-primary);
    color: white;
}
.ux-btn-primary:hover {
    background: var(--ux-btn-primary-hover);
    transform: translateY(-1px);
}

/* Bouton secondaire */
.ux-btn-secondary {
    background: var(--ux-btn-secondary);
    color: var(--text-primary, #f0f0f5);
    border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
}
.ux-btn-secondary:hover {
    background: var(--ux-btn-secondary-hover);
    border-color: var(--border-hover, rgba(255, 255, 255, 0.15));
}

/* Bouton danger */
.ux-btn-danger {
    background: var(--ux-btn-danger);
    color: white;
}
.ux-btn-danger:hover {
    background: var(--ux-btn-danger-hover);
    transform: translateY(-1px);
}

/* Variations de couleur */
.ux-btn-purple {
    background: var(--ux-btn-purple);
    color: white;
}
.ux-btn-purple:hover {
    background: var(--ux-btn-purple-hover);
    transform: translateY(-1px);
}

.ux-btn-pink {
    background: var(--ux-btn-pink);
    color: white;
}
.ux-btn-pink:hover {
    background: var(--ux-btn-pink-hover);
    transform: translateY(-1px);
}

.ux-btn-orange {
    background: var(--ux-btn-orange);
    color: white;
}
.ux-btn-orange:hover {
    background: var(--ux-btn-orange-hover);
    transform: translateY(-1px);
}

.ux-btn-cyan {
    background: var(--ux-btn-cyan);
    color: white;
}
.ux-btn-cyan:hover {
    background: var(--ux-btn-cyan-hover);
    transform: translateY(-1px);
}

/* Tailles de boutons */
.ux-btn-sm {
    padding: 8px 14px;
    font-size: 13px;
}

.ux-btn-lg {
    padding: 16px 28px;
    font-size: 16px;
}

/* Bouton icone-only (carre, contient un seul SVG) :
   on force le centrage parfait + un padding compact symetrique. */
.ux-btn-icon {
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
    gap: 0;
    padding: 8px;
    line-height: 1;
    flex: 0 0 auto;
}
.ux-btn-icon > svg {
    display: block;
    margin: 0;
}

/* ============================
   SLIDE-TO-DELETE
   
   Principe anti double-clic :
   1. Premier clic → "Confirmer?" apparaît à droite du bouton
   2. Le container s'agrandit → pousse les boutons adjacents vers la gauche
   3. Deuxième clic → exécute l'action (le bouton "Modifier" a bougé)
   
   Structure HTML requise:
   <div class="ux-slide-delete-container">
       <button class="ux-slide-delete-btn">Supprimer</button>
       <span class="ux-slide-delete-confirm">Confirmer?</span>
   </div>
   ============================ */

.ux-slide-delete-container {
    display: inline-flex;
    align-items: center;
    height: 38px;
}

.ux-slide-delete-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 9px 14px;
    background: var(--ux-btn-danger);
    border: none;
    border-radius: 8px;
    color: white;
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s ease;
    user-select: none;
    white-space: nowrap;
    flex-shrink: 0;
}

.ux-slide-delete-btn:hover {
    background: var(--ux-btn-danger-hover);
}

.ux-slide-delete-btn svg {
    width: 14px;
    height: 14px;
    stroke: currentColor;
    stroke-width: 2;
    fill: none;
    flex-shrink: 0;
}

.ux-slide-delete-confirm {
    color: #f87171;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    max-width: 0;
    opacity: 0;
    padding: 0;
    transition: max-width 0.3s cubic-bezier(0.4, 0, 0.2, 1), 
                opacity 0.2s ease 0.1s,
                padding 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* État révélé :
   - Le texte "Confirmer?" apparaît à droite du bouton
   - Le container s'agrandit → pousse les boutons adjacents vers la gauche
*/
.ux-slide-delete-container.revealed .ux-slide-delete-confirm {
    max-width: 90px;
    opacity: 1;
    padding-left: 10px;
}

/* ============================
   SLIDE TO CONFIRM (style iPhone "slide to unlock")

   Slider draggable de gauche a droite pour confirmer une action critique.
   Utilisation via UX.slideToConfirm({ container, label, color, onConfirm }).

   Structure HTML (generee par UX.slideToConfirm) :
   <div class="ux-slide-to-confirm">
       <div class="ux-stc-track">
           <div class="ux-stc-fill"></div>
           <div class="ux-stc-label">Glisser pour confirmer</div>
           <div class="ux-stc-handle"><svg>...</svg></div>
       </div>
   </div>
   ============================ */

.ux-slide-to-confirm {
    --ux-stc-color: #dc2626;
    --ux-stc-height: 52px;
    --ux-stc-handle-size: 44px;
    width: 100%;
    user-select: none;
    -webkit-user-select: none;
}

.ux-slide-to-confirm .ux-stc-track {
    position: relative;
    height: var(--ux-stc-height);
    border-radius: calc(var(--ux-stc-height) / 2);
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    overflow: hidden;
    display: flex;
    align-items: center;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.2);
}

.ux-slide-to-confirm .ux-stc-fill {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: calc(var(--ux-stc-handle-size) + 8px);
    background: var(--ux-stc-color);
    border-radius: calc(var(--ux-stc-height) / 2);
    z-index: 1;
    transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.ux-slide-to-confirm .ux-stc-label {
    position: relative;
    z-index: 2;
    width: 100%;
    text-align: center;
    color: var(--text-secondary, #a0aec0);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.2px;
    pointer-events: none;
    padding: 0 calc(var(--ux-stc-handle-size) + 12px);
    box-sizing: border-box;
    transition: opacity 0.25s ease, color 0.2s ease;
}

.ux-slide-to-confirm .ux-stc-handle {
    position: absolute;
    top: 50%;
    left: 4px;
    width: var(--ux-stc-handle-size);
    height: var(--ux-stc-handle-size);
    margin-top: calc(var(--ux-stc-handle-size) / -2);
    border-radius: 50%;
    background: var(--ux-stc-color);
    color: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: grab;
    z-index: 3;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.2);
    touch-action: none;
    outline: none;
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.15s ease;
}

.ux-slide-to-confirm .ux-stc-handle:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

.ux-slide-to-confirm .ux-stc-handle:focus-visible {
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25), 0 2px 8px rgba(0, 0, 0, 0.35);
}

.ux-slide-to-confirm.dragging .ux-stc-handle,
.ux-slide-to-confirm .ux-stc-handle:active {
    cursor: grabbing;
}

.ux-slide-to-confirm .ux-stc-handle svg {
    width: 22px;
    height: 22px;
}

.ux-slide-to-confirm.confirmed .ux-stc-label {
    color: #ffffff;
    opacity: 1;
}

[data-theme="light"] .ux-slide-to-confirm .ux-stc-track {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.08);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06);
}

/* ============================
   CHECKBOXES & TOGGLES
   ============================ */

.ux-checkbox-group,
.ux-toggle-group {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.ux-checkbox-item,
.ux-toggle-item {
    display: flex;
    align-items: center;
    gap: 12px;
    cursor: pointer;
    user-select: none;
}

.ux-checkbox-item input,
.ux-toggle-item input {
    position: fixed;
    opacity: 0;
    pointer-events: none;
    width: 0;
    height: 0;
    margin: 0;
    padding: 0;
}

.ux-checkbox-custom {
    width: 22px;
    height: 22px;
    border: 2px solid rgba(255, 255, 255, 0.08);
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background var(--ux-transition-fast), border-color var(--ux-transition-fast);
    flex-shrink: 0;
}

.ux-checkbox-item input:checked + .ux-checkbox-custom {
    background: var(--ux-btn-default);
    border-color: var(--ux-btn-default);
}

.ux-checkbox-custom::after {
    content: '';
    width: 12px;
    height: 12px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
    opacity: 0;
    transition: opacity var(--ux-transition-fast);
}

.ux-checkbox-item input:checked + .ux-checkbox-custom::after {
    opacity: 1;
}

/* Radio (meme principe que la case : input masque + pastille personnalisee) */
.ux-radio-group {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.ux-radio-item {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    cursor: pointer;
    user-select: none;
}

.ux-radio-item input {
    position: fixed;
    opacity: 0;
    pointer-events: none;
    width: 0;
    height: 0;
    margin: 0;
    padding: 0;
}

.ux-radio-custom {
    width: 22px;
    height: 22px;
    border: 2px solid rgba(255, 255, 255, 0.22);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: border-color var(--ux-transition-fast), background var(--ux-transition-fast);
    flex-shrink: 0;
    margin-top: 2px;
    box-sizing: border-box;
}

.ux-radio-item input:checked + .ux-radio-custom {
    border-color: var(--ux-btn-default);
    background: rgba(46, 204, 113, 0.12);
}

.ux-radio-custom::after {
    content: '';
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--ux-btn-default);
    opacity: 0;
    transform: scale(0.5);
    transition: opacity var(--ux-transition-fast), transform var(--ux-transition-fast);
}

.ux-radio-item input:checked + .ux-radio-custom::after {
    opacity: 1;
    transform: scale(1);
}

[data-theme="light"] .ux-radio-custom {
    border-color: rgba(0, 0, 0, 0.22);
}

[data-theme="light"] .ux-radio-item input:checked + .ux-radio-custom {
    background: rgba(46, 204, 113, 0.1);
}

/* Toggle switch */
.ux-toggle-switch {
    width: 44px;
    height: 24px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 12px;
    position: relative;
    transition: all var(--ux-transition-fast);
    flex-shrink: 0;
}

.ux-toggle-switch::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 20px;
    height: 20px;
    background: #8888a0;
    border-radius: 50%;
    transition: all var(--ux-transition-fast);
}

.ux-toggle-item input:checked + .ux-toggle-switch {
    background: rgba(46, 204, 113, 0.3);
}

.ux-toggle-item input:checked + .ux-toggle-switch::after {
    left: 22px;
    background: var(--ux-btn-default);
}

/* ============================
   DIALOGUES
   ============================ */

.ux-dialog-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 10000;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.ux-dialog-overlay.visible {
    opacity: 1;
}

.ux-dialog-overlay.closing {
    opacity: 0;
}

.ux-dialog {
    position: absolute;
    min-width: 380px;
    max-width: 90vw;
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    background: var(--bg-secondary, #12121a);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 16px;
    box-shadow: 0 30px 100px rgba(0, 0, 0, 0.5);
    overflow: hidden;
    transform: scale(0.95);
    transition: transform 0.2s ease;
}

.ux-dialog-overlay.visible .ux-dialog {
    transform: scale(1);
}

.ux-dialog-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 16px;
    background: var(--bg-tertiary, #1a1a25);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    cursor: grab;
    flex-shrink: 0;
}

.ux-dialog-header:active {
    cursor: grabbing;
}

.ux-dialog-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--ux-btn-purple);
}

.ux-dialog-close {
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    transition: all var(--ux-transition-fast);
}

.ux-dialog-close:hover {
    background: rgba(239, 68, 68, 0.2);
}

.ux-dialog-close svg {
    width: 16px;
    height: 16px;
    stroke: #8888a0;
}

.ux-dialog-close:hover svg {
    stroke: var(--ux-btn-danger);
}

.ux-dialog-content {
    padding: 24px;
    font-size: 14px;
    line-height: 1.6;
    color: var(--text-primary, #d0d0d8);
    overflow-y: auto;
    flex: 1 1 auto;
    min-height: 0;
}

.ux-dialog-content p {
    margin: 0;
}

/* Largeur intelligente des dialogues : un message simple (texte seul, rendu
   dans un <p> enfant direct du contenu) se lit sur quelques lignes au lieu
   d'une seule ligne tres longue. Les dialogues riches definissent leur propre
   largeur via leur contenu (divs, champs, textarea) et ne sont pas affectes. */
.ux-dialog-content > p {
    max-width: 460px;
}

.ux-dialog-content label {
    color: var(--text-secondary, #a0aec0);
}

.ux-dialog-footer {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    padding: 12px 20px 16px;
    flex-shrink: 0;
}

.ux-dialog-btn {
    padding: 10px 20px;
    border-radius: 10px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--ux-transition-fast);
    border: 1px solid rgba(255, 255, 255, 0.08);
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-primary, #f0f0f5);
}

.ux-dialog-btn:hover {
    background: rgba(255, 255, 255, 0.1);
}

.ux-dialog-btn.primary {
    background: var(--ux-btn-default);
    border: none;
    color: white;
}

.ux-dialog-btn.primary:hover {
    background: var(--ux-btn-default-hover);
}

.ux-dialog-btn.danger {
    background: rgba(231, 76, 60, 0.2);
    border-color: rgba(231, 76, 60, 0.3);
    color: var(--ux-btn-danger);
}

.ux-dialog-btn.danger:hover {
    background: var(--ux-btn-danger);
    color: white;
}

/* ============================
   INFO BAR  (UX.infoBar) — MODE DOCK
   ----------------------------
   Ligne d'info reellement DOCKEE en haut ou en bas de la fenetre :
   - bord a bord (full-width), collee au bord,
   - empile les bars dans la meme direction,
   - POUSSE le contenu de l'app via padding sur <html> (variables CSS
     --ux-infobar-top-h / --ux-infobar-bottom-h gerees par UX.infoBar).
   Aucune zone cliquable de l'app n'est jamais masquee : c'est l'app qui
   se retrecit pour faire de la place a la bar.
   ============================ */

/* Reservation d'espace : on push reellement le contenu de l'app en
   ajustant le padding-top/bottom du <body> via JS (UX.infoBar gere le
   calcul + la restauration de la valeur d'origine).
   Les variables --ux-infobar-top-h / --ux-infobar-bottom-h sont egalement
   exposees sur <html> pour les apps qui veulent les consommer ailleurs
   (ex: layout interne en flex avec height: 100vh) :
       .my-app { height: calc(100vh - var(--ux-infobar-top-h, 0px) - var(--ux-infobar-bottom-h, 0px)); }
   La transition douce est definie ici pour eviter un saut visuel. */
body {
    transition: padding-top .18s ease, padding-bottom .18s ease;
}

.ux-infobar-stack {
    position: fixed;
    left: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    z-index: 20000;
    pointer-events: none;
    width: 100%;
}

.ux-infobar-stack--bottom {
    bottom: 0;
    flex-direction: column-reverse;
}

.ux-infobar-stack--top {
    top: 0;
}

.ux-infobar {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 10px 16px;
    background: var(--bg-secondary, #12121a);
    border: none;
    border-left: 3px solid var(--ux-info);
    border-radius: 0;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.04);
    font-size: 14px;
    line-height: 1.4;
    color: var(--text-primary, #f0f0f5);
    opacity: 0;
    max-height: 0;
    overflow: hidden;
    padding-top: 0;
    padding-bottom: 0;
    transition: opacity .18s ease, max-height .22s ease, padding-top .22s ease, padding-bottom .22s ease;
    pointer-events: auto;
    user-select: none;
    box-sizing: border-box;
}

.ux-infobar-stack--top .ux-infobar {
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.ux-infobar-stack--bottom .ux-infobar {
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.ux-infobar--visible {
    opacity: 1;
    max-height: 200px;
    padding-top: 10px;
    padding-bottom: 10px;
}

.ux-infobar--leaving {
    opacity: 0;
    max-height: 0;
    padding-top: 0;
    padding-bottom: 0;
}

.ux-infobar__icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    stroke: currentColor;
}

.ux-infobar__message {
    flex: 1 1 auto;
    min-width: 0;
    word-wrap: break-word;
    overflow-wrap: anywhere;
}

.ux-infobar__actions {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}

.ux-infobar__action {
    appearance: none;
    border: 1px solid rgba(255, 255, 255, 0.14);
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 13px;
    font-weight: 500;
    padding: 5px 10px;
    border-radius: 6px;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease, filter .15s ease;
}

.ux-infobar__action:hover {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.25);
}

.ux-infobar__action--primary {
    background: var(--accent, var(--ux-btn-primary));
    border-color: transparent;
    color: #fff;
}

.ux-infobar__action--primary:hover {
    filter: brightness(1.12);
    background: var(--accent, var(--ux-btn-primary));
    border-color: transparent;
}

.ux-infobar__action--danger {
    background: var(--ux-error);
    border-color: transparent;
    color: #fff;
}

.ux-infobar__action--danger:hover {
    filter: brightness(1.12);
    background: var(--ux-error);
    border-color: transparent;
}

.ux-infobar__close {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-secondary, rgba(255,255,255,0.55));
    width: 26px;
    height: 26px;
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: background .15s ease, color .15s ease;
}

.ux-infobar__close svg {
    width: 14px;
    height: 14px;
}

.ux-infobar__close:hover {
    background: rgba(255, 255, 255, 0.08);
    color: var(--text-primary, #fff);
}

.ux-infobar--success { border-left-color: var(--ux-success); }
.ux-infobar--success .ux-infobar__icon { color: var(--ux-success); }

.ux-infobar--error { border-left-color: var(--ux-error); }
.ux-infobar--error .ux-infobar__icon { color: var(--ux-error); }

.ux-infobar--info { border-left-color: var(--ux-info); }
.ux-infobar--info .ux-infobar__icon { color: var(--ux-info); }

.ux-infobar--warning { border-left-color: var(--ux-warning); }
.ux-infobar--warning .ux-infobar__icon { color: var(--ux-warning); }

/* ============================
   PANEL RESIZER (redimensionnement de panneaux)
   ============================ */

/**
 * Composant de panneau redimensionnable
 * 
 * Usage:
 *   <div class="ux-resizable-layout">
 *       <aside class="ux-panel ux-panel-left" id="left-panel">...</aside>
 *       <div class="ux-resizer ux-resizer-left" id="left-resizer"></div>
 *       <main class="ux-panel-main">...</main>
 *       <div class="ux-resizer ux-resizer-right" id="right-resizer"></div>
 *       <aside class="ux-panel ux-panel-right" id="right-panel">...</aside>
 *   </div>
 * 
 * JavaScript:
 *   const leftResizer = UX.resizer({
 *       resizerId: 'left-resizer',
 *       panelId: 'left-panel',
 *       side: 'left',
 *       minWidth: 200,
 *       maxWidth: 500,
 *       storageKey: 'myapp_left_panel',
 *       collapsible: true
 *   });
 */

/* Layout conteneur */
.ux-resizable-layout {
    display: flex;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

/* Panneaux latéraux */
.ux-panel {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--bg-secondary, #12121a);
    flex-shrink: 0;
    /* Pas de transition par défaut - géré par .ux-panel-animating pour collapse/expand */
}

.ux-panel-left {
    width: 280px;
    min-width: 200px;
    border-right: 1px solid var(--border, rgba(255, 255, 255, 0.08));
}

.ux-panel-right {
    width: 320px;
    min-width: 200px;
    border-left: 1px solid var(--border, rgba(255, 255, 255, 0.08));
}

/* Zone principale centrale */
.ux-panel-main {
    flex: 1;
    min-width: 200px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* Barre de redimensionnement verticale */
.ux-resizer {
    width: 6px;
    background: var(--ux-resizer-bg, rgba(255, 255, 255, 0.06));
    cursor: col-resize;
    flex-shrink: 0;
    position: relative;
    transition: background 0.2s ease;
    -webkit-user-select: none;
    user-select: none;
    z-index: 10;
}

.ux-resizer:hover,
.ux-resizer.ux-resizer-dragging {
    background: var(--accent, #8b5cf6);
}

/* Indicateur visuel central - barre verticale */
.ux-resizer::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 3px;
    height: 40px;
    background: var(--ux-resizer-color, var(--accent, #8b5cf6));
    opacity: 0.7;
    border-radius: 2px;
    transition: all 0.2s ease;
}

.ux-resizer:hover::after,
.ux-resizer.ux-resizer-dragging::after {
    background: rgba(255, 255, 255, 0.9);
    opacity: 1;
    height: 60px;
    box-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
}

/* État fermé du panneau - GAUCHE */
.ux-resizer-left.ux-resizer-collapsed {
    background: linear-gradient(90deg, var(--accent, #8b5cf6), rgba(139, 92, 246, 0.7));
    cursor: pointer;
    width: 8px;
}

.ux-resizer-left.ux-resizer-collapsed::after {
    width: 3px;
    height: 50px;
    background: rgba(255, 255, 255, 0.7);
    opacity: 1;
}

/* Chevron indiquant qu'on peut réouvrir - vers la droite */
.ux-resizer-left.ux-resizer-collapsed::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, calc(-50% - 35px));
    width: 0;
    height: 0;
    border-top: 5px solid transparent;
    border-bottom: 5px solid transparent;
    border-left: 6px solid rgba(255, 255, 255, 0.8);
}

/* État fermé du panneau - DROITE */
.ux-resizer-right.ux-resizer-collapsed {
    background: linear-gradient(270deg, var(--accent, #8b5cf6), rgba(139, 92, 246, 0.7));
    cursor: pointer;
    width: 8px;
}

.ux-resizer-right.ux-resizer-collapsed::after {
    width: 3px;
    height: 50px;
    background: rgba(255, 255, 255, 0.7);
    opacity: 1;
}

/* Chevron indiquant qu'on peut réouvrir - vers la gauche */
.ux-resizer-right.ux-resizer-collapsed::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, calc(-50% - 35px));
    width: 0;
    height: 0;
    border-top: 5px solid transparent;
    border-bottom: 5px solid transparent;
    border-right: 6px solid rgba(255, 255, 255, 0.8);
}

.ux-resizer.ux-resizer-collapsed:hover {
    background: var(--accent-hover, #7c3aed);
    filter: brightness(1.1);
}

/* Panneau collapsé */
.ux-panel-collapsed {
    min-width: 0 !important;
    width: 0 !important;
    overflow: hidden;
    flex: none !important;
    border: none !important;
}

.ux-panel-collapsed > * {
    opacity: 0;
    pointer-events: none;
}

/* Animation de transition */
.ux-panel-animating {
    transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1), 
                min-width 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* PERFORMANCE: Désactiver les transitions pendant le drag */
.ux-panel-resizing,
.ux-panel-resizing * {
    transition: none !important;
}

/* Empêcher la sélection de texte pendant le resize */
body.ux-resizing,
body.ux-resizing * {
    user-select: none !important;
    -webkit-user-select: none !important;
    cursor: col-resize !important;
}

/* Désactiver les pointer-events sur les iframes pendant le resize */
body.ux-resizing iframe {
    pointer-events: none !important;
}

/* Tooltip au survol du resizer fermé */
.ux-resizer.ux-resizer-collapsed[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    padding: 6px 12px;
    background: var(--bg-tertiary, #1a1a25);
    border: 1px solid var(--border, rgba(255, 255, 255, 0.1));
    border-radius: 6px;
    font-size: 12px;
    color: var(--text-primary, #f0f0f5);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
    z-index: 100;
    width: auto;
    height: auto;
}

.ux-resizer-left.ux-resizer-collapsed[data-tooltip]::after {
    left: calc(100% + 8px);
}

.ux-resizer-right.ux-resizer-collapsed[data-tooltip]::after {
    right: calc(100% + 8px);
}

.ux-resizer.ux-resizer-collapsed:hover[data-tooltip]::after {
    opacity: 1;
}

/* ============================
   RESPONSIVE
   ============================ */

@media (max-width: 768px) {
    .ux-dialog {
        min-width: auto;
        width: calc(100vw - 32px);
        max-width: 400px;
    }
    
    .ux-infobar-stack {
        width: 100%;
    }
    .ux-infobar {
        font-size: 13px;
    }
    .ux-infobar--visible {
        padding: 9px 12px;
    }
}

@media (max-width: 480px) {
    .ux-dialog-footer {
        flex-direction: column;
    }
    
    .ux-dialog-btn {
        width: 100%;
        justify-content: center;
        text-align: center;
    }
}

/* ============================
   APP LOADER (écran de chargement global)
   ============================ */

/**
 * Loader plein écran pour les apps
 * 
 * Usage:
 *   1. Ajouter la classe "app-loading" au <body>
 *   2. Ajouter le HTML du loader (ou utiliser UX.showLoader())
 *   3. Appeler UX.appReady() quand les données sont chargées
 * 
 * Exemple HTML:
 *   <body class="app-loading">
 *       <div class="ux-app-loader">
 *           <div class="ux-app-loader-spinner"></div>
 *       </div>
 *       <!-- contenu de l'app -->
 *   </body>
 */

/* État de chargement - cache tout le contenu sauf le loader */
body.app-loading > *:not(.ux-app-loader):not(script):not(link):not(style) {
    visibility: hidden !important;
    opacity: 0 !important;
    pointer-events: none !important;
}

body.app-loading .ux-app-loader {
    visibility: visible !important;
    opacity: 1 !important;
}

/* Transition fluide à la fin du chargement
   IMPORTANT: Exclure les éléments qui gèrent leur propre opacité (toasts, modals, overlays)
   Sinon l'animation force opacity:1 et override leur état par défaut (opacity:0) */
body.app-loaded > *:not(.ux-app-loader):not(.toast-notification):not(.modal):not(.ux-infobar-stack):not(.ux-dialog-overlay):not(.auth-overlay) {
    animation: uxAppFadeIn 0.3s ease forwards;
}

@keyframes uxAppFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* Container du loader */
.ux-app-loader {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-primary, #0a0a0f);
    z-index: 99999;
    transition: opacity 0.3s ease, visibility 0.3s ease;
}

/* Animation de disparition */
.ux-app-loader.hiding {
    opacity: 0;
    visibility: hidden;
}

/* Spinner animé */
.ux-app-loader-spinner {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    position: relative;
}

.ux-app-loader-spinner::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 3px solid rgba(255, 255, 255, 0.1);
}

.ux-app-loader-spinner::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 3px solid transparent;
    border-top-color: var(--accent, #4a9eff);
    animation: uxSpinnerRotate 0.8s linear infinite;
}

@keyframes uxSpinnerRotate {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* Variante avec message */
.ux-app-loader-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
}

.ux-app-loader-message {
    color: var(--text-secondary, #a0aec0);
    font-size: 14px;
    font-weight: 500;
}

/* ============================
   TEXTAREA AUTO-RESIZE
   
   Textarea qui s'adapte automatiquement en hauteur
   selon son contenu, sans scroll interne tant que
   maxHeight n'est pas atteint.
   
   Usage:
     <textarea class="ux-textarea-auto" rows="1"></textarea>
   
   JavaScript (optionnel, pour contrôle manuel):
     UX.autoResize(document.getElementById('my-textarea'));
     UX.autoResizeAll('.ux-textarea-auto');
   
   Options par défaut:
     - minHeight: hauteur initiale (ou 60px)
     - maxHeight: 400px
     - resetOnEmpty: true (revient à minHeight si vide)
   ============================ */

.ux-textarea-auto {
    width: 100%;
    min-height: 60px;
    max-height: 400px;
    padding: 12px 16px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
    border-radius: 10px;
    color: var(--text-primary, #f0f0f5);
    font-family: inherit;
    font-size: 14px;
    line-height: 1.5;
    resize: none;
    overflow: hidden;
    box-sizing: border-box;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.ux-textarea-auto:focus {
    outline: none;
    border-color: var(--accent, #4a9eff);
    box-shadow: 0 0 0 3px rgba(74, 158, 255, 0.15);
}

.ux-textarea-auto::placeholder {
    color: var(--text-secondary, #a0aec0);
    opacity: 0.7;
}

/* Variante compacte - pour les commentaires */
.ux-textarea-auto-sm {
    min-height: 44px;
    padding: 10px 14px;
    font-size: 13px;
    border-radius: 8px;
}

/* Variante grande - pour les descriptions longues */
.ux-textarea-auto-lg {
    min-height: 100px;
    max-height: 600px;
    padding: 16px 20px;
    font-size: 15px;
}

/* ============================
   THEME CLAIR - Composants UX
   ============================ */

[data-theme="light"] {
    --ux-btn-secondary: rgba(0, 0, 0, 0.07);
    --ux-btn-secondary-hover: rgba(0, 0, 0, 0.12);
}

/* Bouton secondaire en mode clair : forcer un texte/bordure sombres
   meme quand l'app ne redefinit pas --text-primary (fallback sinon = #f0f0f5) */
[data-theme="light"] .ux-btn-secondary {
    color: var(--text-primary, #1a1a2e);
    border-color: var(--border, rgba(0, 0, 0, 0.12));
}
[data-theme="light"] .ux-btn-secondary:hover {
    border-color: var(--border-hover, rgba(0, 0, 0, 0.2));
}

/* Info-bars en mode clair - fond sombre pour contraste */
[data-theme="light"] .ux-infobar {
    background: rgba(20, 20, 32, 0.96);
    color: #f0f0f5;
    border-color: rgba(255, 255, 255, 0.08);
    box-shadow: 0 6px 22px rgba(0, 0, 0, 0.22);
}

[data-theme="light"] .ux-infobar__close {
    color: rgba(255, 255, 255, 0.6);
}

[data-theme="light"] .ux-infobar__close:hover {
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
}

[data-theme="light"] .ux-infobar__action {
    border-color: rgba(255, 255, 255, 0.18);
}

/* Dialogues locaux en mode clair */
[data-theme="light"] .ux-dialog-overlay .ux-dialog {
    background: #ffffff;
    border: 1px solid rgba(0, 0, 0, 0.1);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-header {
    background: #f4f5f7;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
    color: #1a1a2e;
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-header h3 {
    color: #1a1a2e;
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-body {
    color: #5a5f72;
}

/* Contenu et controles a l'interieur d'un dialogue en theme clair */
[data-theme="light"] .ux-dialog-overlay .ux-dialog-content {
    color: #1a1a2e;
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-content p,
[data-theme="light"] .ux-dialog-overlay .ux-dialog-content em,
[data-theme="light"] .ux-dialog-overlay .ux-dialog-content strong,
[data-theme="light"] .ux-dialog-overlay .ux-dialog-content span {
    color: inherit;
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-content label {
    color: #4a5568;
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-content input,
[data-theme="light"] .ux-dialog-overlay .ux-dialog-content select,
[data-theme="light"] .ux-dialog-overlay .ux-dialog-content textarea {
    background: rgba(0, 0, 0, 0.04);
    border: 1px solid rgba(0, 0, 0, 0.12);
    color: #1a1a2e;
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-content input::placeholder,
[data-theme="light"] .ux-dialog-overlay .ux-dialog-content textarea::placeholder {
    color: #8c91a4;
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-content details summary {
    color: #4a5568;
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-content pre {
    background: rgba(0, 0, 0, 0.04);
    color: #1a1a2e;
    border: 1px solid rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-footer {
    background: transparent;
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-footer button {
    color: #1a1a2e;
    border-color: rgba(0, 0, 0, 0.12);
    background: rgba(0, 0, 0, 0.05);
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-footer button:hover {
    background: rgba(0, 0, 0, 0.1);
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-footer button.primary {
    background: var(--ux-btn-default, #16a34a);
    border-color: transparent;
    color: #ffffff;
}

[data-theme="light"] .ux-dialog-overlay .ux-dialog-footer button.danger {
    background: rgba(220, 38, 38, 0.1);
    border-color: rgba(220, 38, 38, 0.2);
    color: #dc2626;
}

/* Slide delete en mode clair */
[data-theme="light"] .ux-slide-delete-container .ux-slide-delete-content {
    background: #ffffff;
    border: 1px solid rgba(0, 0, 0, 0.1);
}

/* Textarea en mode clair */
[data-theme="light"] .ux-textarea-auto {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.1);
    color: #1a1a2e;
}

/* App loader en mode clair */
[data-theme="light"] .ux-app-loader {
    background: #ffffff;
}

/* Inputs en mode clair */
[data-theme="light"] input,
[data-theme="light"] select,
[data-theme="light"] textarea {
    color: #1a1a2e;
}

[data-theme="light"] input::placeholder,
[data-theme="light"] textarea::placeholder {
    color: #8c91a4;
}

/* ============================
   MOBILE NAV (navigation panneau mobile)
   ============================ */

/**
 * Transition slide gauche/droite pour les apps avec sidebar + main panel.
 * 
 * Structure HTML attendue :
 *   <div class="app-container ux-mobile-nav">
 *     <div class="sidebar ux-panel ux-mobile-panel" id="sidebar">...</div>
 *     <div class="ux-resizer" id="sidebar-resizer"></div>
 *     <div class="main-content ux-panel-main ux-mobile-panel">...</div>
 *   </div>
 * 
 * Activation : UX.mobileNav({ containerId, breakpoint })
 */

@media (max-width: 768px) {
    .ux-mobile-nav {
        flex-direction: row;
        overflow: hidden;
        width: 200vw;
        transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
    }

    .ux-mobile-nav.ux-mobile-show-main {
        transform: translateX(-100vw);
    }

    .ux-mobile-nav > .ux-panel,
    .ux-mobile-nav > .sidebar {
        width: 100vw !important;
        min-width: 100vw !important;
        flex-shrink: 0;
        height: 100vh;
        border-right: none !important;
    }

    .ux-mobile-nav > .ux-panel-main,
    .ux-mobile-nav > .main-content {
        width: 100vw;
        min-width: 100vw;
        flex-shrink: 0;
        height: 100vh;
    }

    .ux-mobile-nav > .ux-resizer {
        display: none !important;
    }

    .ux-mobile-back {
        display: flex !important;
    }
}

.ux-mobile-back {
    display: none;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
    background: var(--bg-tertiary, rgba(30, 30, 45, 0.8));
    color: var(--text-primary, #f0f0f5);
    cursor: pointer;
    align-items: center;
    justify-content: center;
    transition: all 0.15s;
    flex-shrink: 0;
    user-select: none;
    padding: 0;
}

.ux-mobile-back:hover {
    background: var(--accent, #8b5cf6);
    border-color: var(--accent, #8b5cf6);
}

.ux-mobile-back svg {
    width: 20px;
    height: 20px;
    stroke: currentColor;
    stroke-width: 2;
    fill: none;
}

/* ProductivIA brand typography */
.productivia-brand {
    white-space: nowrap;
}
.productivia-brand .pia-ia {
    font-size: 0.72em;
    position: relative;
    top: -0.35em;
    font-weight: 700;
    letter-spacing: 0.02em;
}

/* ===== UX Player ===== */

.ux-player {
    background: var(--bg-card, rgba(18, 18, 26, 0.95));
    border: 1px solid var(--border, rgba(255, 255, 255, 0.06));
    border-radius: 10px;
    padding: 12px 16px;
    user-select: none;
}

.ux-player-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted, #a0aec0);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: 10px;
}

.ux-player-controls {
    display: flex;
    align-items: center;
    gap: 12px;
}

.ux-player-play {
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    border: none;
    border-radius: 50%;
    background: var(--accent, #4a9eff);
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    user-select: none;
    transition: transform 0.15s, background 0.15s;
}

.ux-player-play svg {
    width: 16px;
    height: 16px;
}

.ux-player-play:hover {
    transform: scale(1.08);
}

.ux-player-play:active {
    transform: scale(0.95);
}

.ux-player-wf-stack {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.ux-player-wf-wrap {
    flex: 1;
    min-width: 0;
    height: 48px;
    cursor: pointer;
    position: relative;
    border-radius: 4px;
}

/* Dans la pile verticale (timeRuler), ne pas etirer la zone onde sur toute la hauteur */
.ux-player-wf-stack > .ux-player-wf-wrap {
    flex: 0 0 48px;
    height: 48px;
    max-height: 48px;
    align-self: stretch;
}

.ux-player-time-ruler {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 10px;
    line-height: 1.2;
    color: var(--text-muted, #6b7280);
    padding: 0 2px;
    user-select: none;
}

.ux-player-time-ruler-tick {
    flex: 0 0 auto;
}

.ux-player-wf-wrap canvas {
    width: 100%;
    height: 100%;
    display: block;
}

.ux-player-dl {
    width: 26px;
    height: 26px;
    border: none;
    background: transparent;
    color: var(--text-muted, #6b7280);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 5px;
    flex-shrink: 0;
    padding: 0;
    transition: color 0.15s, background 0.15s;
    user-select: none;
}
.ux-player-dl svg { width: 14px; height: 14px; }
.ux-player-dl:hover { color: var(--text-primary, #f0f0f5); background: rgba(255,255,255,0.06); }

.ux-player-time {
    font-size: 12px;
    font-family: var(--font-mono, monospace);
    color: var(--text-muted, #a0aec0);
    white-space: nowrap;
    min-width: 80px;
    text-align: right;
    flex-shrink: 0;
}

.ux-player-vol-wrap {
    position: relative;
    flex-shrink: 0;
}

.ux-player-vol-btn {
    width: 28px;
    height: 28px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--text-muted, #a0aec0);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    user-select: none;
    transition: color 0.15s, background 0.15s;
}

.ux-player-vol-btn svg {
    width: 16px;
    height: 16px;
}

.ux-player-vol-btn:hover {
    color: var(--text-primary, #f0f0f5);
    background: rgba(255, 255, 255, 0.06);
}

.ux-player-vol-popup {
    position: absolute;
    bottom: calc(100% + 8px);
    right: -10px;
    background: var(--bg-secondary, rgba(18, 18, 26, 0.98));
    border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
    border-radius: 8px;
    padding: 10px 14px;
    width: 120px;
    opacity: 0;
    pointer-events: none;
    transform: translateY(4px);
    transition: opacity 0.15s, transform 0.15s;
    z-index: var(--z-dropdown, 100);
    box-shadow: var(--shadow-lg, 0 8px 24px rgba(0,0,0,0.4));
}

.ux-player-vol-popup.open {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}

.ux-player-vol-track {
    width: 100%;
    height: 6px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 3px;
    position: relative;
    cursor: pointer;
}

.ux-player-vol-fill {
    height: 100%;
    background: var(--accent, #4a9eff);
    border-radius: 3px;
    width: 100%;
    pointer-events: none;
}

.ux-player-vol-thumb {
    width: 14px;
    height: 14px;
    background: #fff;
    border-radius: 50%;
    position: absolute;
    top: 50%;
    left: 100%;
    transform: translate(-50%, -50%);
    box-shadow: 0 1px 4px rgba(0,0,0,0.3);
    pointer-events: none;
}

[data-theme="light"] .ux-player {
    background: var(--bg-card, #ffffff);
}

[data-theme="light"] .ux-player-vol-popup {
    background: var(--bg-secondary, #ffffff);
}

[data-theme="light"] .ux-player-vol-track {
    background: rgba(0, 0, 0, 0.1);
}

[data-theme="light"] .ux-player-vol-thumb {
    background: var(--accent, #4a9eff);
    box-shadow: 0 1px 4px rgba(0,0,0,0.15);
}

/* =====================================================
   Lecteur video (UX.videoPlayer)
   ===================================================== */
.ux-video-player {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    background: #000;
    border-radius: 10px;
    overflow: hidden;
    user-select: none;
    outline: none;
    font-family: inherit;
    cursor: default;
}

.ux-video-player:focus-visible {
    box-shadow: 0 0 0 2px var(--accent, #4a9eff);
}

.ux-video-player-el {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    background: #000;
    display: block;
    cursor: pointer;
}

.ux-video-player.is-fullscreen {
    border-radius: 0;
    aspect-ratio: auto;
    height: 100%;
}

/* Gros bouton play central (visible en pause uniquement) */
.ux-video-player-bigplay {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(1);
    width: 72px;
    height: 72px;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s, transform 0.2s, background 0.2s;
    z-index: 3;
}

.ux-video-player.is-paused .ux-video-player-bigplay {
    backdrop-filter: blur(6px);
}

.ux-video-player-bigplay svg {
    width: 32px;
    height: 32px;
    margin-left: 4px;
}

.ux-video-player.is-paused .ux-video-player-bigplay {
    opacity: 1;
    pointer-events: auto;
}

/* Mode clavier : on masque le gros bouton PLAY central pour ne pas gener la visualisation.
   Reactive au prochain mouvement de souris > 15 px. */
.ux-video-player.keyboard-mode .ux-video-player-bigplay {
    opacity: 0;
    pointer-events: none;
}

/* Pendant un chargement (spinner visible) ou en cas d'erreur, on cache le gros
   bouton PLAY pour eviter de superposer play + spinner (UX confuse). */
.ux-video-player.is-loading .ux-video-player-bigplay,
.ux-video-player.has-error .ux-video-player-bigplay {
    opacity: 0 !important;
    pointer-events: none !important;
}

.ux-video-player-bigplay:hover {
    background: rgba(0, 0, 0, 0.75);
    transform: translate(-50%, -50%) scale(1.08);
}

/* Spinner de chargement */
.ux-video-player-loading {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s;
    z-index: 4;
}

.ux-video-player-loading.visible {
    opacity: 1;
}

.ux-video-player-spinner {
    width: 44px;
    height: 44px;
    border: 3px solid rgba(255, 255, 255, 0.18);
    border-top-color: #fff;
    border-radius: 50%;
    animation: ux-video-player-spin 0.8s linear infinite;
}

@keyframes ux-video-player-spin {
    to { transform: rotate(360deg); }
}

.ux-video-player-loading-msg {
    color: rgba(255, 255, 255, 0.85);
    font-size: 12px;
    text-align: center;
    margin-top: 10px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
    min-height: 16px;
}

.ux-video-player-loading {
    flex-direction: column;
}

/* Overlay d'erreur */
.ux-video-player-error {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.85);
    backdrop-filter: blur(4px);
    color: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 24px;
    text-align: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
    z-index: 7;
}

.ux-video-player-error.visible {
    opacity: 1;
    pointer-events: auto;
}

.ux-video-player-error-icon {
    width: 48px;
    height: 48px;
    color: #ef4444;
}

.ux-video-player-error-icon svg {
    width: 100%;
    height: 100%;
}

.ux-video-player-error-title {
    font-size: 16px;
    font-weight: 600;
    color: #fff;
    max-width: 80%;
}

.ux-video-player-error-desc {
    font-size: 13px;
    color: rgba(255, 255, 255, 0.7);
    max-width: 80%;
    line-height: 1.5;
}

.ux-video-player-error-retry {
    margin-top: 8px;
    padding: 8px 18px;
    background: var(--accent, #4a9eff);
    color: #fff;
    border: none;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, transform 0.15s;
    font-family: inherit;
}

.ux-video-player-error-retry:hover {
    transform: translateY(-1px);
    filter: brightness(1.15);
}

/* Thumbnail preview (popup sur hover timeline) */
.ux-video-player-thumb {
    position: absolute;
    left: 0;
    bottom: 80px;
    background: rgba(0, 0, 0, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 6px;
    padding: 4px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.1s;
    z-index: 5;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}

.ux-video-player-thumb.visible {
    opacity: 1;
}

.ux-video-player-thumb canvas {
    display: block;
    border-radius: 4px;
    background: #111;
}

.ux-video-player-thumb-time {
    text-align: center;
    color: #fff;
    font-size: 11px;
    font-family: var(--font-mono, monospace);
    padding: 3px 0 1px;
    letter-spacing: 0.3px;
}

/* Barre de controles (bottom) */
.ux-video-player-controls {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 14px 12px;
    background: linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.35) 60%, rgba(0,0,0,0) 100%);
    color: #fff;
    opacity: 0;
    transform: translateY(4px);
    pointer-events: none;
    transition: opacity 0.2s, transform 0.2s;
    z-index: 6;
}

.ux-video-player.controls-visible .ux-video-player-controls,
.ux-video-player.is-paused .ux-video-player-controls {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.ux-video-player-play {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background 0.15s, transform 0.15s;
}

.ux-video-player-play svg {
    width: 14px;
    height: 14px;
}

.ux-video-player-play:hover {
    background: rgba(255, 255, 255, 0.25);
}

.ux-video-player-play:active {
    transform: scale(0.95);
}

.ux-video-player-time {
    font-size: 12px;
    font-family: var(--font-mono, monospace);
    color: rgba(255, 255, 255, 0.9);
    white-space: nowrap;
    min-width: 80px;
    flex-shrink: 0;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

.ux-video-player-wf-wrap {
    flex: 1;
    min-width: 0;
    height: 36px;
    cursor: pointer;
    position: relative;
    border-radius: 4px;
}

.ux-video-player-wf-wrap canvas {
    width: 100%;
    height: 100%;
    display: block;
}

.ux-video-player-fs {
    width: 32px;
    height: 32px;
    border: none;
    background: transparent;
    color: rgba(255, 255, 255, 0.9);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    flex-shrink: 0;
    border-radius: 6px;
    transition: background 0.15s, color 0.15s;
}

.ux-video-player-fs svg {
    width: 18px;
    height: 18px;
}

.ux-video-player-fs .ux-fs-exit { display: none; }
.ux-video-player.is-fullscreen .ux-video-player-fs .ux-fs-enter { display: none; }
.ux-video-player.is-fullscreen .ux-video-player-fs .ux-fs-exit { display: block; }

.ux-video-player-fs:hover {
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
}

/* Volume (meme structure que UX.player) */
.ux-video-player-vol-wrap {
    position: relative;
    flex-shrink: 0;
}

.ux-video-player-vol-btn {
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: rgba(255, 255, 255, 0.9);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background 0.15s, color 0.15s;
}

.ux-video-player-vol-btn svg {
    width: 18px;
    height: 18px;
}

.ux-video-player-vol-btn:hover {
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
}

.ux-video-player-vol-popup {
    position: absolute;
    bottom: calc(100% + 8px);
    right: -4px;
    background: rgba(18, 18, 26, 0.98);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 8px;
    padding: 10px 14px;
    width: 120px;
    opacity: 0;
    pointer-events: none;
    transform: translateY(4px);
    transition: opacity 0.15s, transform 0.15s;
    z-index: var(--z-dropdown, 100);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}

.ux-video-player-vol-popup.open {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}

.ux-video-player-vol-track {
    width: 100%;
    height: 6px;
    background: rgba(255, 255, 255, 0.15);
    border-radius: 3px;
    position: relative;
    cursor: pointer;
}

.ux-video-player-vol-fill {
    height: 100%;
    background: var(--accent, #4a9eff);
    border-radius: 3px;
    width: 100%;
    pointer-events: none;
}

.ux-video-player-vol-thumb {
    width: 14px;
    height: 14px;
    background: #fff;
    border-radius: 50%;
    position: absolute;
    top: 50%;
    left: 100%;
    transform: translate(-50%, -50%);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
    pointer-events: none;
}

/* Masquer le curseur natif quand les controles sont caches pendant la lecture */
.ux-video-player.is-playing:not(.controls-visible) {
    cursor: none;
}

/* Menu contextuel generique (UX.contextMenu) */
.ux-context-menu {
    position: fixed;
    /* Doit etre au-dessus de tous les overlays applicatifs : agent flottant
       (panel 200040, FAB 200050), modales, loaders. Reste sous le canal
       mentions OS (999999) qui est reserve aux notifications systeme
       critiques. */
    z-index: 999998;
    background: var(--bg-card, rgba(22, 22, 34, 0.98));
    backdrop-filter: blur(12px);
    border: 1px solid var(--border, rgba(255, 255, 255, 0.08));
    border-radius: 10px;
    padding: 0;
    min-width: 180px;
    box-shadow: var(--shadow-lg, 0 10px 40px rgba(0, 0, 0, 0.45));
    animation: uxCtxFadeIn 0.12s ease;
    overflow: hidden;
}

@keyframes uxCtxFadeIn {
    from { opacity: 0; transform: scale(0.96); }
    to { opacity: 1; transform: scale(1); }
}

.ux-context-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 14px;
    box-sizing: border-box;
    background: none;
    border: none;
    color: var(--text-primary, #f0f0f5);
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    user-select: none;
    text-align: left;
}

.ux-context-menu-item:hover {
    background: rgba(255, 255, 255, 0.06);
}

.ux-context-menu-item svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.ux-context-menu-item.danger {
    color: #ef4444;
}

.ux-context-menu-item.danger:hover {
    background: rgba(239, 68, 68, 0.12);
    color: #ef4444;
}

.ux-context-menu-separator {
    display: block;
    height: 1px;
    margin: 0;
    padding: 0;
    border: none;
    background: rgba(255, 255, 255, 0.08);
    flex-shrink: 0;
}

[data-theme="light"] .ux-context-menu {
    background: rgba(255, 255, 255, 0.98);
    border-color: rgba(0, 0, 0, 0.1);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
}

[data-theme="light"] .ux-context-menu-item {
    color: var(--text-primary, #111127);
}

[data-theme="light"] .ux-context-menu-item:hover {
    background: rgba(0, 0, 0, 0.06);
}

[data-theme="light"] .ux-context-menu-separator {
    background: rgba(0, 0, 0, 0.1);
}

[data-theme="light"] .ux-context-menu-item.danger:hover {
    background: rgba(239, 68, 68, 0.1);
    color: #dc2626;
}

/* Visualiseur micro (UX.micLevelWaveform) — canvas block, dimensions fixees par l’app */
.ux-mic-level-waveform {
    display: block;
    vertical-align: middle;
    max-width: 100%;
}

/* ============================================================================
   SUPPRESSION D'ELEMENTS DE LISTE (.nav-item-deletable)

   Pattern UX standard pour rendre n'importe quel item de liste de sidebar
   supprimable. Voir documentation : app UX, section "Suppression dans la
   sidebar". Utilisable avec n'importe quel contenu (.nav-item, ou un item
   personnalise comme .history-item dans l'app Images).

   Structure DOM attendue :
     .nav-item-deletable                  // wrapper, overflow:hidden
       .nav-item-deletable-slide          // contenu glissant (translateX)
         <ITEM>                           // .nav-item ou tout autre conteneur
         .nav-item-delete-zone            // zone rouge a droite (souris)
           .nav-item-trash-btn            // bouton corbeille
           .nav-item-confirm-text         // « Confirmer ? »
       .nav-item-swipe-bg                 // zone rouge derriere (tactile)

   Etats CSS :
     hover-revealed     -> Hover 0.5s sur l'actif : zone rouge 48px
     confirm-revealed   -> Clic corbeille : zone 140px + texte
     swiping            -> Touch drag en cours
     swiped             -> Swipe valide (>30px) : slide a -60px
   ============================================================================ */

.nav-item-deletable {
    position: relative;
    overflow: hidden;
    flex-shrink: 0;
}

.nav-item-deletable-slide {
    display: flex;
    align-items: center;
    position: relative;
    z-index: 1;
    background: var(--bg-secondary, transparent);
    will-change: transform;
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Item interieur : on autorise n'importe quelle classe (pas seulement
   .nav-item) en visant le premier enfant du slide qui n'est pas la zone
   de suppression. Cela laisse les apps utiliser leur propre layout (ex:
   .history-item avec image + meta dans Images). */
.nav-item-deletable .nav-item-deletable-slide > :not(.nav-item-delete-zone) {
    flex: 1;
    min-width: 0;
}

.nav-item-deletable .nav-item {
    border-radius: 0;
}

.nav-item-deletable .nav-item span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: block;
}

.nav-item-delete-zone {
    display: flex;
    align-items: center;
    justify-content: center;
    align-self: stretch;
    width: 0;
    min-width: 0;
    opacity: 0;
    overflow: hidden;
    background: rgba(239, 68, 68, 0.5);
    flex-shrink: 0;
    user-select: none;
    transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1),
                min-width 0.25s cubic-bezier(0.4, 0, 0.2, 1),
                opacity 0.2s ease;
}

.nav-item-deletable.hover-revealed .nav-item-delete-zone {
    width: 48px;
    min-width: 48px;
    opacity: 1;
}

.nav-item-deletable.confirm-revealed .nav-item-delete-zone {
    width: 140px;
    min-width: 140px;
    opacity: 1;
    justify-content: flex-start;
}

.nav-item-trash-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    min-width: 48px;
    align-self: stretch;
    cursor: pointer;
    background: #ef4444;
}

.nav-item-trash-btn:active {
    background: #dc2626;
}

.nav-item-trash-btn svg {
    width: 18px;
    height: 18px;
    stroke: white;
    fill: none;
    stroke-width: 2;
    flex-shrink: 0;
}

.nav-item-confirm-text {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
    flex: 1;
    max-width: 0;
    opacity: 0;
    overflow: hidden;
    white-space: nowrap;
    font-size: 11px;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.85);
    cursor: default;
    letter-spacing: 0.02em;
    transition: max-width 0.25s cubic-bezier(0.4, 0, 0.2, 1),
                opacity 0.2s ease 0.05s;
}

.nav-item-confirm-text svg {
    flex-shrink: 0;
    stroke: rgba(255, 255, 255, 0.6);
}

.nav-item-deletable.confirm-revealed .nav-item-confirm-text {
    max-width: 100px;
    opacity: 1;
}

.nav-item-swipe-bg {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    width: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #ef4444;
    z-index: 0;
    cursor: pointer;
    user-select: none;
    opacity: 0;
    transition: background 0.15s ease, opacity 0.15s ease;
}

.nav-item-deletable.swiping .nav-item-swipe-bg,
.nav-item-deletable.swiped .nav-item-swipe-bg {
    opacity: 1;
}

.nav-item-swipe-bg:active {
    background: #dc2626;
}

.nav-item-swipe-bg svg {
    width: 18px;
    height: 18px;
    stroke: white;
    fill: none;
    stroke-width: 2;
}

/* Fond actif rouge tres leger pendant suppression (souris ou tactile) */
.nav-item-deletable.swiped .nav-item-deletable-slide > :not(.nav-item-delete-zone),
.nav-item-deletable.swiping .nav-item-deletable-slide > :not(.nav-item-delete-zone),
.nav-item-deletable.confirm-revealed .nav-item-deletable-slide > :not(.nav-item-delete-zone) {
    background: rgba(239, 68, 68, 0.1);
}

.nav-item-deletable.swiped .nav-item-deletable-slide {
    transform: translateX(-60px);
}

[data-theme="light"] .nav-item-deletable-slide {
    background: var(--bg-secondary, transparent);
}

[data-theme="light"] .nav-item-delete-zone {
    background: rgba(185, 28, 28, 0.55);
}

[data-theme="light"] .nav-item-confirm-text {
    color: rgba(255, 255, 255, 0.95);
}

[data-theme="light"] .nav-item-confirm-text svg {
    stroke: rgba(255, 255, 255, 0.7);
}

[data-theme="light"] .nav-item-deletable.swiped .nav-item-deletable-slide > :not(.nav-item-delete-zone),
[data-theme="light"] .nav-item-deletable.swiping .nav-item-deletable-slide > :not(.nav-item-delete-zone),
[data-theme="light"] .nav-item-deletable.confirm-revealed .nav-item-deletable-slide > :not(.nav-item-delete-zone) {
    background: rgba(239, 68, 68, 0.08);
}

/* ============================================================================
   ONGLETS DE PANNEAU (.sidebar-tabs-row + .sidebar-tab + .sidebar-tab-add-btn)

   Pattern UX standard pour la barre d'onglets en haut du panneau de gauche.
   Une SEULE ligne contenant :
     - N onglets (.sidebar-tab) qui se partagent la largeur restante
     - Un bouton "+" (.sidebar-tab-add-btn) optionnel, a droite, qui cree un
       nouvel item en fonction de l'onglet actif (l'app gere l'action via
       UX.sidebarTabs.attach({ onAdd })).

   Convention mio.land : ne PAS dupliquer le bouton "+ Nouveau X" sur une ligne
   separee sous les onglets. On integre le "+" dans la barre d'onglets pour
   garder une seule ligne et maximiser l'espace de la liste en dessous.

   Markup attendu :
     <div class="sidebar-tabs-row">
       <div class="sidebar-tabs">
         <button class="sidebar-tab active" data-tab="history"><span>Historique</span></button>
         <button class="sidebar-tab" data-tab="projects"><span>Projets</span></button>
       </div>
       <button class="sidebar-tab-add-btn" title="Nouvel element">
         <svg viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
       </button>
     </div>
     <div class="sidebar-tab-contents">
       <div class="sidebar-tab-content active" data-tab="history">...</div>
       <div class="sidebar-tab-content" data-tab="projects">...</div>
     </div>

   Voir : app UX, section "Onglets de panneau" (demo + API).
   ============================================================================ */

.sidebar-tabs-row {
    display: flex;
    align-items: stretch;
    gap: 6px;
    min-height: 40px;
    padding: 4px 8px 0;
    border-bottom: 1px solid var(--border, rgba(255, 255, 255, 0.08));
    flex-shrink: 0;
}

/* Variante : pas d'onglets, juste le bouton "+" - on l'aligne a droite
   pour rester coherent avec le pattern standard (onglets a gauche, "+" a droite). */
.sidebar-tabs-row-add-only {
    justify-content: flex-end;
}

.sidebar-tabs {
    display: flex;
    gap: 0;
    flex: 1;
    align-items: stretch;
    min-width: 0;
}

.sidebar-tab {
    flex: 1;
    padding: 0 8px;
    border: none;
    background: transparent;
    color: var(--text-secondary, rgba(255, 255, 255, 0.6));
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    user-select: none;
    border-bottom: 2px solid transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 36px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    /* Pas de transition : feedback :active instantane au pointerdown. */
}

.sidebar-tab:hover {
    color: var(--text-primary, #fff);
    background: rgba(255, 255, 255, 0.03);
}

.sidebar-tab:active {
    background: var(--accent, #8b5cf6) !important;
    color: #fff !important;
}

.sidebar-tab.active {
    color: var(--text-primary, #fff);
    border-bottom-color: var(--accent, #8b5cf6);
}

[data-theme="light"] .sidebar-tab:hover {
    background: rgba(0, 0, 0, 0.04);
}

/* Compteur optionnel a droite du libelle (ex: "Historique 100"). Pattern
   utilise par Harmonie, Exercices, etc. Mis en sourdine au repos, pleine
   opacite quand l'onglet est actif. */
.sidebar-tab .tab-count {
    font-size: 10px;
    font-weight: 600;
    color: currentColor;
    opacity: 0.6;
    line-height: 1;
    margin-left: 4px;
}

.sidebar-tab.active .tab-count { opacity: 1; }

/* Bouton "+" a droite : compact, couleur accent, signale l'affordance de
   creation. L'app le wire via UX.sidebarTabs.attach({ onAdd }). */
.sidebar-tab-add-btn {
    flex-shrink: 0;
    align-self: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid rgba(74, 158, 255, 0.25);
    border-radius: 6px;
    background: linear-gradient(135deg, rgba(74, 158, 255, 0.10), rgba(74, 158, 255, 0.04));
    color: var(--accent, #4a9eff);
    cursor: pointer;
    user-select: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background .15s, border-color .15s, transform .08s;
}

.sidebar-tab-add-btn:hover {
    background: linear-gradient(135deg, rgba(74, 158, 255, 0.18), rgba(74, 158, 255, 0.08));
    border-color: rgba(74, 158, 255, 0.45);
}

.sidebar-tab-add-btn:active {
    transform: scale(0.94);
}

.sidebar-tab-add-btn svg {
    width: 16px;
    height: 16px;
    stroke: currentColor;
    stroke-width: 2.2;
    fill: none;
    display: block;
}

/* Conteneurs de contenu d'onglet : panneaux superposes (position absolute)
   pour bascules instantanees. Toggle visibility plutot que display:none/block
   afin d'eviter un layout pass complet sur le panneau entrant. */
.sidebar-tab-contents {
    flex: 1;
    position: relative;
    min-height: 0;
    overflow: hidden;
}

.sidebar-tab-content {
    position: absolute;
    inset: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    visibility: hidden;
    pointer-events: none;
    z-index: 0;
    contain: layout paint style;
}

.sidebar-tab-content.active {
    visibility: visible;
    pointer-events: auto;
    z-index: 1;
}
