/* ============================================================
   V-STORM — COUCHE MOBILE (téléphone)
   ------------------------------------------------------------
   Objectif (20/08/2026) : supprimer l'app séparée et faire du dashboard
   la SEULE surface. Ce n'est donc pas un « responsive » de dépannage :
   sous 860px on remplace la navigation par une vraie coque d'application
   (barre haute compacte, barre d'onglets basse avec bouton central,
   menu plein écran), et on retaille les écrans un par un.

   ⚠️ RÈGLE DE SÛRETÉ : tout ce qui suit vit soit sur des classes .vsm-*
   inexistantes ailleurs, soit DANS @media (max-width:860px). Le bureau ne
   peut pas être touché. Ce fichier se charge APRÈS style.css : il gagne
   donc les conflits sans qu'on ait à toucher aux règles existantes.

   ⚠️ La coque est injectée par js/vs-mobile.js à partir du DOM déjà en
   place (.dash-topnav-links + .pmenu). On ne redéclare AUCUN lien ici :
   le filtrage « employé » et le lien admin restent donc automatiquement
   justes, sans deuxième implémentation à maintenir.
   ============================================================ */

/* ── Variables propres à la coque (indépendantes du thème desktop) ── */
:root {
  --vsm-bar-h: 62px;                       /* hauteur barre d'onglets   */
  --vsm-top-h: 56px;                       /* hauteur barre haute       */
  --vsm-safe-b: env(safe-area-inset-bottom, 0px);
  --vsm-safe-t: env(safe-area-inset-top, 0px);
  --vsm-accent: #a78bfa;
  --vsm-accent-2: #764ee5;
  --vsm-bg: #08080c;
  --vsm-card: #121218;
  --vsm-card-2: #17171f;
  --vsm-line: rgba(255,255,255,.09);
  --vsm-line-2: rgba(255,255,255,.16);
  --vsm-txt: rgba(255,255,255,.95);
  --vsm-dim: rgba(255,255,255,.56);
}

/* Par défaut (bureau) la coque n'existe pas. */
.vsm-appbar, .vsm-tabbar, .vsm-drawer, .vsm-scrim { display: none; }

/* ============================================================
   1. LA COQUE
   ============================================================ */
@media (max-width: 860px) {

  /* — On efface la barre de bureau : elle est remplacée, pas adaptée. — */
  .dash-topnav { display: none !important; }
  .dash-nav-toggle { display: none !important; }
  /* ⚠️ `#navCollapse` (le bouton qui replie la barre de BUREAU) vit EN DEHORS
     de `.dash-topnav` : il survivait à son masquage et flottait tout seul
     au-dessus du titre — le petit chevron orphelin de la capture de Bill.
     Sur mobile il ne veut rien dire : la navigation est la coque. */
  #navCollapse, .navcollapse { display: none !important; }
  .support-bubble { bottom: calc(var(--vsm-bar-h) + var(--vsm-safe-b) + 14px) !important; right: 14px !important; }

  html { -webkit-text-size-adjust: 100%; }
  /* Rien ne doit jamais dépasser en largeur : c'est LE défaut qui rend un
     dashboard inutilisable au doigt (scroll horizontal parasite).
     ⚠️⚠️ `clip` et SURTOUT PAS `hidden` — ni ici ni sur <body> : `hidden`
     crée un conteneur de défilement, ce qui casse le position:sticky de la
     barre haute (elle se décrocherait au premier scroll). `clip`, lui, n'en
     crée pas. Les vieux Safari ignorent simplement la déclaration : pas de
     rognage, mais rien de cassé non plus. */
  .dash-top-layout { overflow-x: clip; }
  .dash-top-content img, .dash-top-content canvas,
  .dash-top-content pre, .dash-top-content iframe { max-width: 100%; }

  /* ⚠️⚠️ ÉTAGEMENT — la coque doit rester SOUS les fenêtres des pages.
     Relevé dans le code existant : .modal du Stock = 200, .drw-ov de
     Publier = 300, Colis = 320, Guide = 250, Cloud = 400. Une coque au-
     dessus de tout ça masquerait les boutons « Valider » de ces fenêtres.
     On se place donc à 150 (au-dessus du contenu, sous les fenêtres), et
     le menu à 160/165 — il n'est jamais ouvert en même temps qu'elles. */

  /* ── 1.1 Barre haute ─────────────────────────────────────── */
  .vsm-appbar {
    display: flex; align-items: center; gap: 8px;
    position: sticky; top: 0; z-index: 150;
    height: calc(var(--vsm-top-h) + var(--vsm-safe-t));
    padding: var(--vsm-safe-t) 12px 0;
    background: rgba(10,10,15,.86);
    backdrop-filter: saturate(150%) blur(14px);
    -webkit-backdrop-filter: saturate(150%) blur(14px);
    border-bottom: 1px solid var(--vsm-line);
  }
  .vsm-appbar__logo { display: flex; align-items: center; flex-shrink: 0; }
  .vsm-appbar__logo img { height: 30px; width: auto; display: block; }

  /* Pastille compte : avatar + prénom + chevron (ouvre le menu profil) */
  .vsm-acct {
    display: inline-flex; align-items: center; gap: 8px;
    height: 38px; padding: 0 12px 0 4px; margin-left: 2px;
    background: var(--vsm-card-2); border: 1px solid var(--vsm-line);
    border-radius: 999px; color: var(--vsm-txt);
    font: 600 13.5px/1 var(--font-sans, system-ui); cursor: pointer;
    max-width: 46vw; min-width: 0;
  }
  .vsm-acct__ava {
    width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
    display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 13px;
    background: linear-gradient(140deg, var(--vsm-accent), var(--vsm-accent-2));
    background-size: cover; background-position: center;
  }
  .vsm-acct__n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
  .vsm-acct__c { width: 14px; height: 14px; flex-shrink: 0; opacity: .6; }
  /* Contexte EMPLOYÉ (« Chez X ») : liseré bleu + pastille sur l'avatar. Sans
     signal visuel, on croit voir SON business alors qu'on voit celui du patron. */
  .vsm-acct--emp { border-color: rgba(95, 168, 255, .55); background: rgba(95, 168, 255, .10); }
  .vsm-acct--emp .vsm-acct__ava { position: relative; }
  .vsm-acct--emp .vsm-acct__ava::after {
    content: ''; position: absolute; right: -1px; bottom: -1px;
    width: 10px; height: 10px; border-radius: 50%;
    background: #5fa8ff; border: 2px solid var(--vsm-bg, #0a0420);
  }
  /* Ligne active de la bascule d'équipe dans le menu */
  .vsm-mi.is-on > svg { color: #4be6a3; }

  .vsm-appbar__sp { flex: 1 1 auto; min-width: 0; }
  .vsm-ico {
    width: 38px; height: 38px; flex-shrink: 0; position: relative;
    display: grid; place-items: center; cursor: pointer;
    background: transparent; border: 0; border-radius: 11px;
    color: var(--vsm-txt);
  }
  .vsm-ico:active { background: rgba(255,255,255,.07); }
  .vsm-ico svg { width: 21px; height: 21px; }
  .vsm-ico__dot {
    position: absolute; top: 7px; right: 7px; min-width: 8px; height: 8px;
    border-radius: 999px; background: #4ade80; border: 2px solid #0a0a0f;
  }

  /* La cloche ET son panneau sont déplacés dans la barre haute par le JS
     (le panneau vivait dans .dash-topnav, qu'on masque). Le panneau est en
     position:absolute : il s'ancre donc sur la barre haute. */
  .vsm-appbar .vs-bell { width: 38px; height: 38px; border-radius: 11px; flex-shrink: 0; }
  .vsm-appbar .vs-notif-panel {
    top: calc(var(--vsm-top-h) + var(--vsm-safe-t) + 4px) !important;
    right: 8px !important; left: 8px !important; width: auto !important;
    max-width: none !important; z-index: 160;
  }

  /* ── 1.2 Barre d'onglets basse ───────────────────────────── */
  .vsm-tabbar {
    display: flex; align-items: flex-start; justify-content: space-around;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 150;
    height: calc(var(--vsm-bar-h) + var(--vsm-safe-b));
    padding-bottom: var(--vsm-safe-b);
    background: rgba(10,10,15,.94);
    backdrop-filter: saturate(150%) blur(16px);
    -webkit-backdrop-filter: saturate(150%) blur(16px);
    border-top: 1px solid var(--vsm-line);
  }
  .vsm-tab {
    flex: 1 1 0; min-width: 0; height: var(--vsm-bar-h);
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    background: none; border: 0; padding: 0 2px; cursor: pointer;
    color: var(--vsm-dim); text-decoration: none;
    font: 600 10.5px/1.1 var(--font-sans, system-ui);
    -webkit-tap-highlight-color: transparent;
  }
  .vsm-tab svg { width: 22px; height: 22px; stroke-width: 1.9; }
  .vsm-tab span {
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .vsm-tab.is-on { color: var(--vsm-accent); }
  .vsm-tab:active { opacity: .6; }

  /* Bouton central en relief (Publier) */
  .vsm-tab--fab { position: relative; }
  .vsm-tab--fab .vsm-fab {
    width: 54px; height: 54px; border-radius: 50%;
    margin-top: -20px; display: grid; place-items: center;
    background: linear-gradient(150deg, var(--vsm-accent) 0%, var(--vsm-accent-2) 100%);
    box-shadow: 0 8px 24px -6px rgba(118,78,229,.9), 0 0 0 5px var(--vsm-bg);
    color: #fff;
  }
  .vsm-tab--fab .vsm-fab svg { width: 24px; height: 24px; stroke-width: 2.1; }
  .vsm-tab--fab span { margin-top: -2px; }
  .vsm-tab--fab.is-on { color: var(--vsm-accent); }
  .vsm-tab--fab:active .vsm-fab { transform: scale(.94); }

  /* ── 1.3 Menu plein écran ────────────────────────────────── */
  .vsm-scrim {
    display: block; position: fixed; inset: 0; z-index: 160;
    background: rgba(0,0,0,.6); opacity: 0; pointer-events: none;
    transition: opacity .22s ease;
  }
  .vsm-scrim.is-open { opacity: 1; pointer-events: auto; }

  .vsm-drawer {
    display: flex; flex-direction: column;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 165;
    max-height: 88vh;
    background: #101017;
    border-top: 1px solid var(--vsm-line-2);
    border-radius: 22px 22px 0 0;
    box-shadow: 0 -20px 60px rgba(0,0,0,.6);
    transform: translateY(101%);
    transition: transform .28s cubic-bezier(.22,1,.36,1);
    padding-bottom: var(--vsm-safe-b);
  }
  .vsm-drawer.is-open { transform: translateY(0); }
  .vsm-drawer__grab {
    width: 40px; height: 4px; border-radius: 999px; background: rgba(255,255,255,.22);
    margin: 10px auto 4px; flex-shrink: 0;
  }
  .vsm-drawer__body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 6px 12px 16px; }
  .vsm-grp { margin-top: 14px; }
  .vsm-grp:first-child { margin-top: 4px; }
  .vsm-grp__t {
    font: 700 11px/1 var(--font-sans, system-ui); letter-spacing: .09em; text-transform: uppercase;
    color: rgba(255,255,255,.34); padding: 0 6px 8px;
  }
  .vsm-grp__i { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .vsm-mi {
    display: flex; align-items: center; gap: 10px; min-height: 52px;
    padding: 10px 12px; border-radius: 14px; text-decoration: none;
    background: var(--vsm-card); border: 1px solid var(--vsm-line);
    color: var(--vsm-txt); font: 600 13.5px/1.25 var(--font-sans, system-ui);
    cursor: pointer; text-align: left; width: 100%;
    -webkit-tap-highlight-color: transparent;
  }
  .vsm-mi:active { background: var(--vsm-card-2); }
  .vsm-mi.is-on { border-color: rgba(167,139,250,.5); background: rgba(118,78,229,.14); color: #fff; }
  .vsm-mi svg { width: 19px; height: 19px; flex-shrink: 0; color: var(--vsm-accent); }
  .vsm-mi span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .vsm-mi--wide { grid-column: 1 / -1; }
  /* Entrées du lanceur (bouton central) : titre + explication sur 2 lignes,
     pour qu'on sache ce que fait l'action sans l'avoir déjà essayée. */
  .vsm-mi--big { min-height: 62px; gap: 13px; }
  .vsm-mi--big svg { width: 22px; height: 22px; }
  .vsm-mi--big span { display: flex; flex-direction: column; gap: 3px; }
  .vsm-mi--big b { font-size: 14.5px; font-weight: 700; }
  .vsm-mi--big i {
    font-style: normal; font-size: 11.5px; font-weight: 500;
    color: var(--vsm-dim);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .vsm-mi--red { color: #ff8a8a; border-color: rgba(255,90,90,.28); }
  .vsm-mi--red svg { color: #ff8a8a; }

  /* Quand un panneau est ouvert, la page dessous ne défile plus. */
  body.vsm-locked { overflow: hidden; }

  /* ============================================================
     2. MISE EN PAGE GÉNÉRALE DU CONTENU
     ============================================================ */
  .dash-top-content {
    padding: 14px 12px calc(var(--vsm-bar-h) + var(--vsm-safe-b) + 22px) !important;
  }
  .wrap, .container { padding-left: 0 !important; padding-right: 0 !important; max-width: 100% !important; }
  /* ⚠️ …SAUF quand `.wrap` EST le conteneur qui porte les marges.
     « Vue d'ensemble » et « Mon serveur » annulent le padding de
     `.dash-top-content` avec `!important` (règle inline, donc gagnante) et
     confient les marges à leur propre `.wrap` niché dans `.stage`. En le
     mettant à zéro, TOUT leur contenu venait coller le bord gauche — titre
     coupé, onglets à cheval, boutons qui débordent : c'est ce que Bill a vu
     et appelé « désordonné ». On rend les marges à ce cas précis. */
  .stage > .wrap { padding-left: 12px !important; padding-right: 12px !important; }

  /* Titres de page : lisibles sans écraser l'écran. */
  .dash-top-content h1 { font-size: 26px !important; line-height: 1.12; letter-spacing: -.02em; }
  .dash-top-content h2 { font-size: 19px !important; }
  .dash-top-content .head p, .dash-top-content .sub { font-size: 13.5px; }

  /* Toute grille multi-colonnes retombe sur une colonne… */
  .dash-top-content [class*="grid"],
  .vs-stats, .vs-nav, .dash-bottom-grid, .cp-overview, .cp-stats-grid,
  .kpis, .biz-grid, .stats-grid, .tiles, .cards, .row2, .row3 {
    grid-template-columns: 1fr !important;
  }
  /* …sauf les vignettes, plus lisibles à deux. */
  .dash-top-content .stats,
  .dash-top-content .grid:not(.list) { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }

  .card, .panel, .box, .cp-card, .vs-card {
    border-radius: 16px !important;
  }

  /* ============================================================
     3. CIBLES TACTILES & FORMULAIRES
     ============================================================ */
  /* 16px = seuil sous lequel iOS zoome tout seul à la mise au point.
     C'est la première cause de « le site saute » sur iPhone. */
  input, select, textarea,
  .inp, .sel, .search input { font-size: 16px !important; }
  input:not([type=checkbox]):not([type=radio]):not([type=range]),
  select, .inp, .sel { min-height: 44px; }
  textarea { min-height: 96px; }

  button, .btn, .tbtn, .abtn, .cxb, .pill, .chip {
    min-height: 40px;
  }
  .btn, .tbtn { padding-left: 14px; padding-right: 14px; }

  /* Rangées d'outils : on fait défiler au doigt au lieu de déborder. */
  .bar1, .toolbar, .seltabs, .tabs, .filters, .segs, .brandsBar, #brandsBar {
    display: flex; flex-wrap: nowrap; overflow-x: auto; gap: 8px;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    padding-bottom: 2px;
  }
  .bar1::-webkit-scrollbar, .toolbar::-webkit-scrollbar, .seltabs::-webkit-scrollbar,
  .tabs::-webkit-scrollbar, .filters::-webkit-scrollbar, .segs::-webkit-scrollbar { display: none; }
  .bar1 > *, .toolbar > * { flex: 0 0 auto; }
  .bar1 .search, .toolbar .search { flex: 1 0 62%; min-width: 200px; }

  /* ============================================================
     4. TABLEAUX → on les rend lisibles au doigt
     ============================================================ */
  .dash-top-content table { min-width: 0 !important; font-size: 13px; }
  .tbl-wrap, .table-wrap, .ptable-wrap, [class*="table"][class*="wrap"],
  .dash-top-content > table, .card > table {
    display: block; overflow-x: auto; -webkit-overflow-scrolling: touch;
  }
  .dash-top-content th, .dash-top-content td { padding: 10px 12px !important; white-space: nowrap; }

  /* ============================================================
     5. MODALES → feuilles remontant du bas
     ============================================================ */
  .modal, .md, .sheet, .vs-modal, .vspm, .dlg {
    align-items: flex-end !important;
  }
  .modal > .box, .modal__box, .md__box, .vs-modal__box, .vspm-box, .dlg__box,
  .modal-content, .md-content {
    width: 100% !important; max-width: 100% !important;
    max-height: 90vh !important; overflow-y: auto;
    border-radius: 20px 20px 0 0 !important;
    margin: 0 !important;
    padding-bottom: calc(16px + var(--vsm-safe-b)) !important;
  }

  /* ============================================================
     6. RETOUCHES PAR ÉCRAN
     ============================================================ */

  /* — Stock : vignettes à deux colonnes, barre d'actions au-dessus des onglets — */
  .stockwrap .stats { grid-template-columns: repeat(2, minmax(0,1fr)) !important; margin-bottom: 16px; }
  .stockwrap .stat { padding: 14px 14px !important; }
  .stockwrap .stat--hero .stat__num { font-size: 22px !important; }
  .abar {
    left: 8px !important; right: 8px !important;
    bottom: calc(var(--vsm-bar-h) + var(--vsm-safe-b) + 10px) !important;
  }
  .fpanel { padding: 12px !important; }
  .fpanel > * { min-width: 0; }

  /* ── MESSAGERIE ────────────────────────────────────────────
     ⚠️⚠️ TROIS DÉFAUTS MESURÉS LE 20/08 SUR UN VRAI FIL OUVERT (390px) —
     mon premier audit ne testait que le débordement et la taille des
     cibles, il n'ouvrait AUCUNE conversation, donc il n'a rien vu :
       1. la zone d'écriture faisait **32px de large** (une lettre par
          ligne). Cause : `.cmp__row` est un flex où 3 boutons de 44px et
          le bouton « Envoyer » sont en flex-shrink:0 — il ne restait rien
          pour le textarea, qui n'a pas de min-width:0 ;
       2. le fil descendait à y=830 alors que la barre d'onglets commence
          à 778 : la zone d'écriture passait DESSOUS ;
       3. l'en-tête de page mangeait 204px, il ne restait que 325px de
          conversation sur un écran de 840px.
     Correction : sur mobile une conversation ouverte est un ÉCRAN, pas un
     panneau dans une page. */
  .main {
    grid-template-columns: 1fr !important;
    height: auto !important;          /* la liste défile avec la page */
    min-height: 0 !important;
  }
  .main .ctx { display: none !important; }
  .main .col { max-height: none !important; }
  .main .convs { overflow: visible !important; max-height: none !important; }

  /* Fil ouvert → plein écran, calé entre la barre haute et la barre basse. */
  .main.showthread .thr {
    position: fixed !important;
    top: calc(var(--vsm-top-h) + var(--vsm-safe-t));
    left: 0; right: 0;
    bottom: calc(var(--vsm-bar-h) + var(--vsm-safe-b));
    z-index: 140;                      /* sous la coque : il s'arrête avant */
    border-radius: 0 !important; border-left: 0; border-right: 0;
  }
  /* Là où `:has()` existe (tous les navigateurs mobiles à jour), on va plus
     loin : la barre d'onglets s'efface pendant la lecture d'un fil et la
     conversation prend tout l'écran — comme une vraie messagerie. Le
     bouton retour du fil ramène à la liste. Sans `:has()`, la règle
     ci-dessus suffit déjà : rien ne se chevauche. */
  body:has(.main.showthread) .vsm-tabbar { display: none; }

  /* ------------------------------------------------------------
     BARRE D ACTION DE « PUBLIER » (27/08/2026) — CORRECTIF CRITIQUE
     Mesure a 390 px : `.bar` occupait 772→824 px alors que la barre
     d onglets commence a 782. Le bouton « Envoyer au patron » etait
     recouvert sur 42 px de ses 52 : INATTEIGNABLE au doigt. C est la
     raison pour laquelle aucune session photo n a jamais ete creee —
     l employe prenait ses photos sans pouvoir les envoyer.
     ⚠️ Meme famille que le bouton « Traduire » de 18 px du 24/08 :
     une action qu on ne peut pas toucher n existe pas.
     Motif repris de .support-bubble, deja remontee de la meme facon.
     ------------------------------------------------------------ */
  .bar {
    bottom: calc(var(--vsm-bar-h) + var(--vsm-safe-b) + 12px) !important;
    width: calc(100% - 20px) !important;
    z-index: 140 !important;
  }
  /* Volt occupe le meme coin et masquerait le bouton : la page pose
     `pub-has-bar` sur le body des qu il y a quelque chose a envoyer. */
  body.pub-has-bar #voltw { display: none !important; }

  body:has(.main.showthread) .main.showthread .thr {
    bottom: 0; padding-bottom: var(--vsm-safe-b);
  }
  body:has(.main.showthread) { overflow: hidden; }

  /* En-tête du fil : identité sur une ligne, actions sur la suivante.
     Mesuré avant correction : les actions prenaient 213px des 384px, le nom
     tombait à 84px (affiché « e… ») et 3 paires d'éléments se chevauchaient
     — c'est le « plusieurs choses superposées » signalé par Bill. */
  .thr__hd { flex-wrap: wrap; row-gap: 8px; padding: 10px 12px !important; }
  /* base 0 (et pas `auto`) : avec `auto`, l'identité refuse de partager la
     ligne du bouton retour et l'en-tête passe à 3 rangées (162px). */
  .thr__prof { flex: 1 1 0; min-width: 0; }
  .thr__acts {
    flex: 1 1 100%; margin-left: 0 !important; justify-content: flex-start;
    overflow-x: auto; scrollbar-width: none;
  }
  .thr__acts::-webkit-scrollbar { display: none; }
  .thr__acts > * { flex: 0 0 auto; }
  .thr__sub { flex-wrap: wrap; white-space: normal; }

  /* Zone d'écriture : le texte sur sa propre ligne, les outils en dessous. */
  .cmp { padding: 10px 12px calc(10px + var(--vsm-safe-b)); }
  .cmp__row { flex-wrap: wrap !important; gap: 8px !important; }
  .cmp__in {
    order: -1;                          /* le champ passe au-dessus */
    flex: 1 1 100% !important;
    min-width: 0 !important;
    width: 100% !important;
    height: 46px; max-height: 120px;
  }
  .cmp__send { margin-left: auto; }
  .cmp__hint { display: none; }        /* place gagnée : l'info est dans le guide */
  .quick { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .quick::-webkit-scrollbar { display: none; }
  .quick .qr { flex: 0 0 auto; }

  /* — Publier : un champ par ligne, photos en grille de 3 — */
  .pubgrid, .pub-cols, .pubwrap .cols { grid-template-columns: 1fr !important; }
  .photos, .phgrid, #photos { grid-template-columns: repeat(3, minmax(0,1fr)) !important; }

  /* — Configuration : les panneaux passent sous la liste des sections — */
  .cp-shell, .cp-layout, .cfg-shell { grid-template-columns: 1fr !important; }
  .cp-side, .cfg-side { position: static !important; max-height: none !important; }
  .cp-side .cp-nav, .cfg-side nav {
    display: flex; overflow-x: auto; gap: 8px; scrollbar-width: none;
  }
  .cp-side .cp-nav::-webkit-scrollbar { display: none; }
  .cp-side .cp-nav > * { flex: 0 0 auto; }

  /* — Compta / Colis : les cartes chiffres à deux colonnes — */
  .compta .kpis, .colis .kpis, .kpi-row { grid-template-columns: repeat(2, minmax(0,1fr)) !important; }

  /* — Guide : images pleine largeur — */
  .guide img, .dash-top-content figure img { width: 100% !important; height: auto !important; }

  /* — Éléments flottants : remontés au-dessus de la barre d'onglets —
       Constaté au test du 20/08 : le robot Volt recouvrait les boutons
       « Publier » et « Messages ». Un assistant qui masque la navigation,
       c'est la navigation qui perd.
       ⚠️ Il se pose en `#voltw` (un ID, pas une classe) avec sa propre règle
       `position:fixed;bottom:24px;z-index:99999` — il faut donc viser l'ID,
       sinon la spécificité est trop faible et rien ne bouge. */
  #voltw {
    bottom: calc(var(--vsm-bar-h) + var(--vsm-safe-b) + 12px) !important;
    right: 12px !important;
  }
  #voltw .voltw-launch { width: 66px; height: 84px; }
  #voltw .voltw-panel { max-width: calc(100vw - 24px); }
  /* Son z-index (99999) passerait AU-DESSUS du menu : on l'efface pendant
     que le menu est ouvert, sinon le robot se pose sur les entrées. */
  body.vsm-locked #voltw, body.vsm-locked .support-bubble { display: none !important; }
  /* Idem quand une conversation est ouverte en plein écran : sans ça le
     robot se pose pile sur le bouton « Envoyer ». */
  body:has(.main.showthread) #voltw,
  body:has(.main.showthread) .support-bubble { display: none !important; }

  /* — Carte « V-Storm Cloud » : en colonne, sinon le statut se casse en
       un mot par ligne (« 2 / sessions / en / marche »). — */
  .cloudw {
    flex-wrap: wrap !important; gap: 12px !important; padding: 14px !important;
  }
  /* `min-width:0` est LA correction : sans lui un élément flex refuse de
     descendre sous la largeur de son contenu, se retrouve écrasé, et le
     texte se casse en un mot par ligne. Mesuré : 186px → 120px de haut. */
  .cloudw > :nth-child(2) { flex: 1 1 0; min-width: 0; }
  /* ⚠️ Le bouton passe SUR SA PROPRE LIGNE (`flex-basis:100%`). En le laissant
     sur la 1ʳᵉ ligne il ne restait que 163px au texte, qui se cassait en 5
     lignes. `margin-left:auto` doit sauter avec, sinon le bouton part se
     coller à droite tout seul au lieu de suivre le reste. */
  .cloudw > :last-child { flex: 1 1 100%; margin-left: 0; }

  /* — En-tête de page : UNE SEULE ligne d'alignement. —
     `.head__r` (sélecteur de période + « Personnaliser ») est en
     `justify-content:flex-end` pour le bureau, où il siège à droite du titre.
     Sur mobile il passe SOUS le titre en pleine largeur : le flex-end le
     pousse alors à droite pendant que le titre reste à gauche → trois
     alignements différents empilés, exactement l'effet « désordonné ». */
  .head__r { justify-content: flex-start !important; }
}

/* ── Très petits écrans (≤ 380px) : on gagne de la place ── */
@media (max-width: 380px) {
  .vsm-acct__n { display: none; }
  /* ⚠️ EXCEPTION : en contexte employé, le libellé « Chez X » RESTE affiché.
     Le masquer ferait disparaître la seule mention indiquant qu'on travaille
     sur le compte du patron — on préfère rogner ailleurs. */
  .vsm-acct--emp .vsm-acct__n { display: block; max-width: 34vw; font-size: 12px; }
  .vsm-acct { padding-right: 6px; }
  .vsm-tab { font-size: 9.5px; }
  .vsm-grp__i { grid-template-columns: 1fr; }
  .dash-top-content { padding-left: 10px !important; padding-right: 10px !important; }
}

/* ── Paysage bas de plafond : on rend la barre plus fine ── */
@media (max-width: 860px) and (max-height: 460px) {
  :root { --vsm-bar-h: 52px; }
  .vsm-tab span { display: none; }
  .vsm-tab--fab .vsm-fab { width: 44px; height: 44px; margin-top: -12px; }
}

/* ── Confort : respecter « moins d'animations » ── */
@media (prefers-reduced-motion: reduce) {
  .vsm-drawer, .vsm-scrim { transition: none !important; }
}

/* ══ STUDIO PHOTO ═══════════════════════════════════════════════════════════
   Écran de capture plein cadre. Volontairement HORS de la media query mobile :
   il s'ouvre à la demande, et s'il est ouvert on veut qu'il occupe tout l'écran
   quelle que soit la largeur. Toutes les classes sont en .vsm-studio*, donc
   invisibles pour le reste du dashboard.

   ⚠️⚠️ IDENTITÉ — LE FLUX EST REPRIS DE CONTROL RESELL, PAS L'HABILLAGE.
   Ce qu'on leur emprunte, c'est la MÉCANIQUE (photographier en rafale →
   « Suivant » ferme un article → « Valider » termine). Tout le reste doit
   être du V-Storm et reprendre les jetons déjà définis plus haut :
     • violet --vsm-accent/--vsm-accent-2, JAMAIS le vert citron de leur appli ;
     • fonds --vsm-bg / --vsm-card, jamais du noir pur ;
     • commandes en carrés arrondis (11-16px) comme .vsm-ico et .vsm-mi,
       et surtout PAS des ronds façon appareil photo natif ;
     • aperçu présenté comme une CARTE encadrée (le dashboard est fait de
       cartes), pas en plein bord à bord.
   Bill l'a repris deux fois — sur Bleam puis ici : on s'inspire d'un
   comportement, on ne décalque pas une interface. */
/* Alerte « la réserve ne s'écrit pas » : elle RESTE tant que le problème dure.
   Un flash de 1,7 s ne suffit pas quand ce qui est en jeu, c'est la séance. */
.vsm-studio__alerte {
  flex: 0 0 auto; background: #7a1226; color: #ffe1e7; font: 700 12px/1.45 inherit;
  padding: 9px 12px calc(9px + var(--vsm-safe-t, 0px)); text-align: center;
}
.vsm-studio {
  position: fixed; inset: 0; z-index: 500;
  display: flex; flex-direction: column;
  background: var(--vsm-bg, #08080c); color: var(--vsm-txt, rgba(255,255,255,.95));
  font-family: inherit;
  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* — Barre haute : même grammaire que .vsm-appbar —
     ⚠️ Serrée au maximum : sur iPhone, Safari mange déjà ~250px en haut et en
     bas, chaque pixel repris ici part dans l'aperçu (retour de Bill : « la zone
     de prise de photo est trop petite »). */
.vsm-studio__top {
  flex: 0 0 auto; display: flex; align-items: center; gap: 10px;
  padding: 6px 10px 8px;
  border-bottom: 1px solid var(--vsm-line, rgba(255,255,255,.09));
}
.vsm-studio__ttl {
  flex: 1; min-width: 0; text-align: center;
  font: 700 11px/1 var(--font-sans, system-ui);
  letter-spacing: .09em; text-transform: uppercase;
  color: rgba(255,255,255,.38);
}
.vsm-studio__ttl b {
  display: inline-block; margin-left: 6px; padding: 3px 9px; border-radius: 999px;
  background: rgba(118,78,229,.18); border: 1px solid rgba(167,139,250,.42);
  color: var(--vsm-accent, #a78bfa); font-size: 12px; letter-spacing: 0;
}
/* — Identité de l'article : numéro d'article + N° DE STOCK toujours visible —
     ⚠️ Ce bloc occupe la place de l'ancien titre « Article N » : le n° de stock
     se saisit sans ouvrir quoi que ce soit ET sans voler un pixel à l'aperçu. */
.vsm-studio__id {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 7px;
}
.vsm-studio__no {
  flex: 0 0 auto;
  font: 700 10px/1 var(--font-sans, system-ui);
  letter-spacing: .08em; text-transform: uppercase;
  color: rgba(255,255,255,.38);
}
.vsm-studio__no b {
  display: inline-block; margin-left: 3px; padding: 3px 7px; border-radius: 999px;
  background: rgba(118,78,229,.18); border: 1px solid rgba(167,139,250,.42);
  color: var(--vsm-accent, #a78bfa); font-size: 11px; letter-spacing: 0;
}
/* ⚠️ 38px, comme les boutons voisins (.vsm-studio__x / __gal) : la pastille ENTIÈRE
   est la cible tactile (le <label> englobe le champ). Elle était à 34px alors que la
   règle mobile impose `min-height:44px` à tout input → le champ dépassait de 10px et
   débordait de la barre. Invisible en thème sombre (fond transparent), très visible
   en clair où le champ prenait un fond blanc. */
.vsm-studio__sku {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 2px;
  height: 38px; padding: 0 9px; border-radius: 10px;
  background: var(--vsm-card-2, #17171f);
  border: 1px solid var(--vsm-line, rgba(255,255,255,.09));
}
.vsm-studio__sku:focus-within {
  border-color: rgba(167,139,250,.55);
  box-shadow: 0 0 0 3px rgba(118,78,229,.16);
}
.vsm-studio__sku > span {
  flex: 0 0 auto; font: 800 13px/1 var(--font-sans, system-ui);
  color: var(--vsm-accent, #a78bfa);
}
/* ⚠️ Les trois `:not()` sont OBLIGATOIRES. La règle mobile générique
   `input:not([type=checkbox]):not([type=radio]):not([type=range]) { min-height:44px }`
   pèse (0,3,1) : un simple `.vsm-studio__sku input` (0,1,1) perd et le champ reste à
   44px dans une pastille de 38px. Mesuré deux fois avant de comprendre — dans ce
   fichier, toute surcharge d'un input DOIT recopier la même chaîne de `:not()`. */
.vsm-studio__sku input:not([type=checkbox]):not([type=radio]):not([type=range]) {
  flex: 1 1 auto; min-width: 0; width: 100%;
  /* La cible tactile, c'est la pastille (38px) — pas le champ. */
  min-height: 0; height: 100%;
  background: none; border: 0; outline: none; padding: 0;
  /* 16px minimum : en dessous, iOS zoome sur le champ au focus. */
  font: 700 16px/1 var(--font-sans, system-ui);
  color: var(--vsm-txt, #fff);
}
.vsm-studio__sku input::placeholder { font-weight: 500; color: rgba(255,255,255,.3); }

/* — Complément / défaut : discret par construction (pastille posée sur
     l'aperçu). On ne le remplit pas à chaque article, il ne doit donc pas
     occuper la même place que le n° de stock. — */
.vsm-studio__note {
  position: absolute; top: 10px; right: 10px; z-index: 3;
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px; padding: 0 11px; border-radius: 999px; cursor: pointer;
  background: rgba(10,10,16,.6); backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,.14);
  color: rgba(255,255,255,.72);
  font: 600 11.5px/1 var(--font-sans, system-ui);
}
.vsm-studio__note svg { width: 13px; height: 13px; stroke-width: 2; }
.vsm-studio__note.is-on {
  background: rgba(118,78,229,.62); border-color: rgba(167,139,250,.7); color: #fff;
}
.vsm-studio__note:active { transform: scale(.96); }

/* Feuille de saisie du complément. */
.vsm-note {
  position: absolute; inset: 0; z-index: 40;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(4,2,14,.6);
}
.vsm-note__sheet {
  width: 100%; padding: 16px 14px calc(16px + env(safe-area-inset-bottom, 0px));
  border-radius: 18px 18px 0 0;
  background: var(--vsm-card, #101017);
  border-top: 1px solid var(--vsm-line, rgba(255,255,255,.09));
}
.vsm-note__ttl {
  font: 700 11px/1 var(--font-sans, system-ui);
  letter-spacing: .09em; text-transform: uppercase; color: rgba(255,255,255,.42);
}
.vsm-note__ttl b { color: var(--vsm-accent, #a78bfa); }
.vsm-note__hint {
  margin: 8px 0 10px; font: 500 12px/1.45 var(--font-sans, system-ui);
  color: var(--vsm-dim, rgba(255,255,255,.56));
}
.vsm-note textarea {
  width: 100%; box-sizing: border-box; resize: none;
  padding: 11px 12px; border-radius: 12px;
  background: var(--vsm-card-2, #17171f);
  border: 1px solid var(--vsm-line, rgba(255,255,255,.09));
  color: var(--vsm-txt, #fff);
  font: 500 16px/1.45 var(--font-sans, system-ui);
  outline: none;
}
.vsm-note textarea:focus { border-color: rgba(167,139,250,.55); }
.vsm-note__acts { display: flex; gap: 10px; margin-top: 12px; }
.vsm-note__acts button {
  flex: 1; height: 46px; border-radius: 13px; cursor: pointer;
  font: 700 14px/1 var(--font-sans, system-ui);
  background: var(--vsm-card-2, #17171f);
  border: 1px solid var(--vsm-line, rgba(255,255,255,.09));
  color: var(--vsm-txt, #fff);
}
.vsm-note__acts [data-ok] {
  background: linear-gradient(135deg, var(--vsm-accent-2, #764ee5), var(--vsm-accent, #a78bfa));
  border-color: transparent; color: #fff;
}

/* Carrés arrondis, pas des cercles : c'est la signature du dashboard. */
.vsm-studio__x, .vsm-studio__gal {
  flex: 0 0 auto; width: 38px; height: 38px; border-radius: 11px;
  display: grid; place-items: center; cursor: pointer;
  background: var(--vsm-card-2, #17171f);
  border: 1px solid var(--vsm-line, rgba(255,255,255,.09));
  color: var(--vsm-txt, #fff);
}
.vsm-studio__x:active, .vsm-studio__gal:active, .vsm-studio__gr:active { background: rgba(118,78,229,.16); }
.vsm-studio__x svg, .vsm-studio__gal svg, .vsm-studio__gr svg { width: 19px; height: 19px; }
.vsm-studio__gal { color: var(--vsm-accent, #a78bfa); }

/* Bouton grille : mêmes dimensions que les autres, allumé quand la grille
   est affichée (l'état doit se voir d'un coup d'œil, sans l'essayer). */
.vsm-studio__gr {
  flex: 0 0 auto; width: 38px; height: 38px; border-radius: 11px;
  display: grid; place-items: center; cursor: pointer;
  background: var(--vsm-card-2, #17171f);
  border: 1px solid var(--vsm-line, rgba(255,255,255,.09));
  color: var(--vsm-dim, rgba(255,255,255,.56));
}
.vsm-studio__gr.is-on {
  background: rgba(118,78,229,.2);
  border-color: rgba(167,139,250,.5);
  color: var(--vsm-accent, #a78bfa);
}

/* — Grille des tiers : aide au cadrage, posée SUR l'aperçu.
     ⚠️ Purement visuelle : la capture passe par un canvas qui ne dessine que
     le flux vidéo — la grille n'apparaît JAMAIS sur la photo enregistrée. — */
.vsm-studio__grille {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background-image:
    linear-gradient(to right,  rgba(255,255,255,.34) 1px, transparent 1px),
    linear-gradient(to right,  rgba(255,255,255,.34) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.34) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255,255,255,.34) 1px, transparent 1px);
  background-size: 1px 100%, 1px 100%, 100% 1px, 100% 1px;
  background-position: 33.333% 0, 66.666% 0, 0 33.333%, 0 66.666%;
  background-repeat: no-repeat;
}
.vsm-studio__grille[hidden] { display: none; }
/* Repère central discret : le point où poser le milieu de l'article. */
.vsm-studio__grille::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  width: 26px; height: 26px; margin: -13px 0 0 -13px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.26);
}

/* — Aperçu : une carte encadrée, pas un plein cadre d'appli photo.
     Marges réduites au strict minimum : c'est la zone utile. — */
.vsm-studio__view {
  flex: 1 1 auto; position: relative; min-height: 0; overflow: hidden;
  margin: 8px 8px 0; border-radius: 16px;
  background: #0d0d13;
  border: 1px solid var(--vsm-line, rgba(255,255,255,.09));
  box-shadow: 0 12px 34px -18px rgba(118,78,229,.55);
}
.vsm-studio__view video { width: 100%; height: 100%; object-fit: contain; display: block; background: #000; }
/* ── Réglage de luminosité, posé sur l'aperçu (zéro hauteur prise) ── */
.vsm-studio__lum { position: absolute; right: 10px; top: 58px; display: flex; flex-direction: column; align-items: center; gap: 8px; z-index: 3; }
.vsm-studio__lumb {
  width: 38px; height: 38px; border-radius: 12px; display: grid; place-items: center;
  background: rgba(10,10,16,.62); border: 1px solid rgba(255,255,255,.16);
  color: #fff; cursor: pointer; backdrop-filter: blur(7px); padding: 0;
}
.vsm-studio__lumb svg { width: 19px; height: 19px; }
.vsm-studio__lum.is-on .vsm-studio__lumb { border-color: var(--vsm-accent, #a78bfa); color: var(--vsm-accent, #a78bfa); }
/* Glissière VERTICALE : le pouce est déjà de ce côté quand on tient le
   téléphone, et elle ne mange pas la largeur de l'aperçu. */
.vsm-studio__lumr {
  writing-mode: vertical-lr; direction: rtl;
  width: 38px; height: 132px; margin: 0; accent-color: var(--vsm-accent, #a78bfa);
  background: rgba(10,10,16,.62); border: 1px solid rgba(255,255,255,.16);
  border-radius: 12px; padding: 8px 0; touch-action: none;
}

.vsm-studio__err {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px; padding: 26px; text-align: center;
}
.vsm-studio__err b { font-size: 15px; }
.vsm-studio__err span {
  font-size: 12.5px; color: var(--vsm-dim, rgba(255,255,255,.56));
  line-height: 1.5; max-width: 260px;
}

/* Éclair au déclenchement — teinté violet, pas un flash blanc générique. */
.vsm-studio.is-flash .vsm-studio__view::after {
  content: ''; position: absolute; inset: 0; background: var(--vsm-accent, #a78bfa);
  animation: vsmFlash .16s ease-out;
}
@keyframes vsmFlash { from { opacity: .7; } to { opacity: 0; } }

/* — Ligne d'état : ce que Control Resell n'a pas — on dit toujours où on
     en est (photos de cet article, articles déjà bouclés).
     ⚠️ POSÉE SUR l'aperçu, pas au-dessus : elle ne lui vole aucune hauteur. — */
.vsm-studio__meta {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 20px 12px 9px;
  font: 600 11.5px/1.3 var(--font-sans, system-ui);
  color: rgba(255,255,255,.86);
  background: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,.62));
  pointer-events: none;
}
.vsm-studio__meta b { color: #fff; font-weight: 800; }
.vsm-studio__meta i {
  font-style: normal; flex: 0 0 auto;
  padding: 4px 10px; border-radius: 999px;
  background: rgba(118,78,229,.55); border: 1px solid rgba(167,139,250,.6);
  color: #fff;
}
.vsm-studio__meta i:empty { display: none; }

/* — Vignettes de l'article EN COURS —
     Tapoter = ouvrir la visionneuse (tourner / déplacer / couverture).
     Appui long = glisser pour réordonner. */
.vsm-studio__strip {
  flex: 0 0 auto; display: flex; gap: 8px; overflow-x: auto; overflow-y: hidden;
  padding: 8px 10px 4px; min-height: 4px;
  scrollbar-width: none; touch-action: pan-x;
}
.vsm-studio__strip::-webkit-scrollbar { display: none; }
.vsm-studio__strip:empty { padding: 0; }
/* Pendant un déplacement, on coupe le défilement pour que le doigt pilote
   la vignette et pas la bande. */
.vsm-studio__strip.is-drag { touch-action: none; overflow-x: hidden; }
.vsm-studio__th {
  position: relative; flex: 0 0 auto; width: 56px; height: 56px; cursor: pointer;
  transition: transform .12s ease;
}
.vsm-studio__th img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  border-radius: 12px; border: 1px solid var(--vsm-line-2, rgba(255,255,255,.16));
  pointer-events: none;                 /* le doigt vise la vignette, pas l'image */
}
/* La 1ʳᵉ photo est la couverture de l'annonce : elle se voit. */
.vsm-studio__th.is-cover img { border-color: var(--vsm-accent, #a78bfa); }
.vsm-studio__cov {
  position: absolute; left: -4px; bottom: -4px; min-width: 17px; height: 17px;
  display: grid; place-items: center; padding: 0 4px; border-radius: 6px;
  background: linear-gradient(150deg, var(--vsm-accent, #a78bfa), var(--vsm-accent-2, #764ee5));
  color: #fff; font: 800 10px/1 var(--font-sans, system-ui); pointer-events: none;
}
.vsm-studio__th.is-porte { transform: scale(1.12); z-index: 3; }
.vsm-studio__th.is-porte img { box-shadow: 0 8px 20px -6px rgba(118,78,229,.95); }
.vsm-studio__th button {
  position: absolute; top: -6px; right: -6px; width: 22px; height: 22px;
  border-radius: 8px; display: grid; place-items: center; padding: 0; cursor: pointer;
  background: var(--vsm-card-2, #17171f);
  border: 1px solid var(--vsm-line-2, rgba(255,255,255,.16));
  color: var(--vsm-txt, #fff);
}
.vsm-studio__th button svg { width: 11px; height: 11px; }

/* — Visionneuse d'une photo (par-dessus le studio) — */
.vsm-photov {
  position: absolute; inset: 0; z-index: 6; display: flex; flex-direction: column;
  background: var(--vsm-bg, #08080c);
  padding-top: env(safe-area-inset-top, 0px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.vsm-photov__top {
  flex: 0 0 auto; display: flex; align-items: center; gap: 10px; padding: 6px 10px 8px;
  border-bottom: 1px solid var(--vsm-line, rgba(255,255,255,.09));
}
.vsm-photov__ttl {
  flex: 1; text-align: center;
  font: 700 11px/1 var(--font-sans, system-ui);
  letter-spacing: .09em; text-transform: uppercase; color: rgba(255,255,255,.38);
}
.vsm-photov__ttl b, .vsm-photov__ttl i {
  font-style: normal; color: var(--vsm-txt, #fff); letter-spacing: 0; font-size: 12.5px;
}
/* ⚠️ `touch-action: none` : sans ça le navigateur happe le pincement pour son
   propre zoom de page et le code ne reçoit jamais les événements. */
.vsm-photov__img {
  flex: 1 1 auto; min-height: 0; display: grid; place-items: center;
  padding: 10px; overflow: hidden; touch-action: none;
}
.vsm-photov__img img {
  max-width: 100%; max-height: 100%; object-fit: contain;
  border-radius: 14px; border: 1px solid var(--vsm-line, rgba(255,255,255,.09));
  transform-origin: center center; will-change: transform;
}
/* Repère visuel quand on est zoomé : le cadre s'allume, on sait qu'un
   glissement va déplacer l'image et pas changer d'écran. */
.vsm-photov__img.is-zoom img { border-color: rgba(167,139,250,.55); }
.vsm-photov__cov {
  flex: 0 0 auto; margin: 0 12px 2px; padding: 7px 12px; border-radius: 11px;
  background: rgba(118,78,229,.16); border: 1px solid rgba(167,139,250,.34);
  color: var(--vsm-accent, #a78bfa); text-align: center;
  font: 700 11.5px/1 var(--font-sans, system-ui);
}
.vsm-photov__acts {
  flex: 0 0 auto; display: grid; grid-template-columns: repeat(5, 1fr);
  gap: 7px; padding: 10px 12px 6px;
}
.vsm-photov__acts button {
  display: inline-flex; flex-direction: column; align-items: center; gap: 5px;
  min-height: 56px; padding: 8px 4px; border-radius: 13px; cursor: pointer;
  background: var(--vsm-card, #121218);
  border: 1px solid var(--vsm-line, rgba(255,255,255,.09));
  color: var(--vsm-txt, rgba(255,255,255,.95));
  font: 600 10.5px/1.1 var(--font-sans, system-ui);
}
.vsm-photov__acts button svg { width: 19px; height: 19px; }
.vsm-photov__acts button:disabled { opacity: .3; cursor: default; }
.vsm-photov__acts button:active:not(:disabled) { background: var(--vsm-card-2, #17171f); }
.vsm-photov__first {
  flex: 0 0 auto; margin: 0 12px 12px; min-height: 46px; border: 0; border-radius: 14px;
  cursor: pointer; color: #fff; font: 700 13px/1 var(--font-sans, system-ui);
  background: linear-gradient(150deg, var(--vsm-accent, #a78bfa) 0%, var(--vsm-accent-2, #764ee5) 100%);
  box-shadow: 0 8px 22px -8px rgba(118,78,229,.95);
}
.vsm-photov__first[hidden] { display: none; }

/* — Barre d'action : (Précédent) Suivant · obturateur · Valider — */
/* ⚠️ HAUTEUR SOUS L'OBTURATEUR (retour de Bill, 05/09) : « le cercle pour prendre
   la photo est situé trop bas par rapport à l'appareil photo iPhone ». C'était
   exact — la barre ne gardait que 12 px sous elle, donc le déclencheur tombait
   dans la zone du geste d'accueil, là où l'appareil natif le place bien plus
   haut. On remonte l'ensemble : 30 px, PLUS la barre d'accueil quand elle
   existe (`env()` est global, il s'additionne à celui de `.vsm-studio`, et c'est
   précisément sur ces téléphones-là que le problème se pose). */
.vsm-studio__bar {
  flex: 0 0 auto; display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 10px;
  padding: 8px 12px calc(30px + env(safe-area-inset-bottom, 0px));
}
/* Emplacement gauche : le retour arrière se colle contre « Suivant ». */
.vsm-studio__left {
  justify-self: start; display: inline-flex; align-items: center; gap: 7px; min-width: 0;
}
.vsm-studio__prev {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border-radius: 14px; cursor: pointer; padding: 0;
  background: var(--vsm-card, #121218);
  border: 1px solid var(--vsm-line, rgba(255,255,255,.09));
  color: var(--vsm-txt, rgba(255,255,255,.95));
  -webkit-tap-highlight-color: transparent;
}
.vsm-studio__prev svg { width: 19px; height: 19px; }
.vsm-studio__prev:active { background: var(--vsm-card-2, #17171f); }
.vsm-studio__prev[hidden] { display: none; }
/* Boutons en PASTILLES horizontales (comme .vsm-mi), pas en icônes empilées. */
.vsm-studio__side, .vsm-studio__ok {
  display: inline-flex; flex-direction: row; align-items: center; gap: 7px;
  min-height: 46px; padding: 0 15px; border-radius: 14px; cursor: pointer;
  font: 700 13px/1 var(--font-sans, system-ui);
  -webkit-tap-highlight-color: transparent;
}
.vsm-studio__side svg, .vsm-studio__ok svg { width: 17px; height: 17px; flex: 0 0 auto; }
.vsm-studio__side {
  min-width: 0;
  background: var(--vsm-card, #121218);
  border: 1px solid var(--vsm-line, rgba(255,255,255,.09));
  color: var(--vsm-txt, rgba(255,255,255,.95));
}
.vsm-studio__side:active { background: var(--vsm-card-2, #17171f); }
/* Valider = l'action principale → dégradé violet V-Storm, comme le bouton
   central de la barre d'onglets. Surtout pas le vert de Control Resell. */
.vsm-studio__ok {
  justify-self: end; border: 0; color: #fff;
  background: linear-gradient(150deg, var(--vsm-accent, #a78bfa) 0%, var(--vsm-accent-2, #764ee5) 100%);
  box-shadow: 0 8px 22px -8px rgba(118,78,229,.95);
}
.vsm-studio__ok:active { transform: scale(.97); }

/* Obturateur : disque violet + anneau clair intérieur. On reconnaît un
   déclencheur, mais aux couleurs de la maison. */
.vsm-studio__shot {
  width: 72px; height: 72px; border-radius: 50%; padding: 0; border: 0; cursor: pointer;
  background: linear-gradient(150deg, var(--vsm-accent, #a78bfa) 0%, var(--vsm-accent-2, #764ee5) 100%);
  box-shadow: inset 0 0 0 4px rgba(255,255,255,.9), 0 10px 28px -8px rgba(118,78,229,.95);
  transition: transform .12s ease;
}
.vsm-studio__shot:active { transform: scale(.93); }
.vsm-studio__shot:disabled { opacity: .32; cursor: default; box-shadow: inset 0 0 0 4px rgba(255,255,255,.5); }
.vsm-studio__shot.is-off {
  background: var(--vsm-card-2, #17171f);
  box-shadow: inset 0 0 0 4px rgba(255,255,255,.22);
}

/* Message éphémère (au-dessus de la barre). */
.vsm-studio__flash {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(148px + env(safe-area-inset-bottom, 0px)); z-index: 510;
  max-width: 84vw; padding: 9px 15px; border-radius: 999px;
  background: rgba(20,20,29,.96); border: 1px solid rgba(196,179,255,.22);
  color: #e8e2ff; font-size: 12.5px; font-weight: 600; text-align: center;
  box-shadow: 0 8px 26px rgba(0,0,0,.5);
  transition: opacity .25s ease;
}
.vsm-studio__flash.is-out { opacity: 0; }

/* ── Écran étroit : la barre du studio tenait sur QUATRE commandes ────────
   Signalé par Bill le 06/09 (iPhone) : le disque de l'obturateur recouvrait le
   mot « Suivant ». Cause : la grille est `1fr auto 1fr`, et sur 390 px de large
   il ne reste que ~137 px par côté une fois l'obturateur (72) et les marges
   retirés — alors que « ‹ » + la pastille « ▷| Suivant » en demandent ~163.
   `.vsm-studio__left` ayant `min-width: 0`, la cellule se comprimait et son
   contenu débordait SOUS l'obturateur.
   On récupère la place là où elle ne coûte rien : l'icône de « Suivant » (le
   mot suffit), quelques pixels d'obturateur et de rembourrage. Le mot reste
   entier — c'est l'action la plus utilisée de l'écran, elle ne se devine pas. */
@media (max-width: 430px) {
  .vsm-studio__shot { width: 64px; height: 64px; }
  .vsm-studio__prev { width: 42px; height: 42px; }
  .vsm-studio__left { gap: 6px; }
  .vsm-studio__side, .vsm-studio__ok { padding: 0 12px; font-size: 12.5px; }
  .vsm-studio__side svg { display: none; }          /* « Suivant » : le mot porte l'action */
  .vsm-studio__bar { gap: 8px; padding-left: 10px; padding-right: 10px; }
}
/* Filet, quelle que soit la largeur : une pastille ne doit jamais déborder de
   sa cellule et passer sous le déclencheur. */
.vsm-studio__side, .vsm-studio__ok { white-space: nowrap; overflow: hidden; }

/* Écran court (paysage) : on resserre sans casser la mécanique. */
@media (max-height: 560px) {
  .vsm-studio__view { margin: 8px 10px 0; border-radius: 14px; }
  .vsm-studio__meta { padding: 8px 12px 4px; }
  .vsm-studio__th { width: 48px; height: 48px; }
  .vsm-studio__shot { width: 58px; height: 58px; }
  .vsm-studio__prev { width: 40px; height: 40px; }
  .vsm-studio__bar { padding: 8px 12px calc(14px + env(safe-area-inset-bottom, 0px)); }
}

/* ── MESSAGERIE : bouton « Traduire » utilisable au doigt ──────────────────
   « La traduction sur mobile marche pas dans messagerie » (Bill, 24/08).
   Le bouton n'est pas cassé : il est MINUSCULE. Mesuré dans le CSS de la
   messagerie — `font-size: 8.5px`, `padding: 3px 9px` → une cible d'environ
   18 px de haut, sous une bulle de message. Au doigt, un tap sur 18 px part
   presque toujours à côté (ou déclenche la sélection de texte du message).
   Une action qui ne peut pas être touchée n'existe pas.

   ⚠️ Recommandation d'accessibilité tactile : 44 px. On monte à 34 px de
   haut (le bouton vit à l'intérieur d'une bulle, 44 déséquilibrerait la
   colonne) avec 12 px de texte — mesurable, tapable, lisible.
   ⚠️ `touch-action: manipulation` supprime le délai de 300 ms et le
   double-tap-zoom : sans lui, le premier tap est parfois avalé.
   Le résultat traduit (.trad) est agrandi de la même façon : traduire un
   message pour le rendre en 9 px ne sert à rien. */
@media (max-width: 860px) {
  .trad-btn {
    font-size: 12px !important;
    padding: 8px 14px !important;
    min-height: 34px;
    border-style: solid !important;
    touch-action: manipulation;
  }
  .trad-btn svg { width: 13px !important; height: 13px !important; }
  .trad { font-size: 12px !important; line-height: 1.45; }
  .trad svg { width: 13px !important; height: 13px !important; flex: none; }
}

/* ============================================================
   STUDIO PHOTO EN THEME CLAIR (27/08/2026)
   ------------------------------------------------------------
   Demande de Bill, repetee : « quand je prends en photo il n y a
   toujours pas le mode white ». Le studio etait fige en sombre.
   Toute sa peinture passe par les variables --vsm-*, il suffit
   donc de les redefinir : aucune regle de composant a dupliquer.
   ⚠️ L APERCU de la photo reste sur un fond neutre sombre
   (--vsm-shot) : juger une photo sur du blanc fausse la
   perception de l exposition, et c est le seul endroit ou le
   fond n est pas de la decoration mais un outil de travail.
   ============================================================ */
:root[data-theme="clair"] {
  --vsm-bg: #f4f3f9;
  --vsm-card: #ffffff;
  --vsm-card-2: #f0eef8;
  --vsm-line: rgba(23,20,43,.12);
  --vsm-line-2: rgba(23,20,43,.20);
  --vsm-txt: #17142b;
  --vsm-dim: #544f6d;
}
/* Les quelques couleurs ecrites en dur dans le studio (une feuille de
   theme ne peut pas les atteindre autrement). */
:root[data-theme="clair"] .vsm-studio__sku input::placeholder { color: rgba(23,20,43,.42); }
:root[data-theme="clair"] .vsm-studio__no { color: rgba(23,20,43,.45); }
:root[data-theme="clair"] .vsm-note__ttl { color: rgba(23,20,43,.50); }
:root[data-theme="clair"] .vsm-note__hint { color: rgba(23,20,43,.62); }
/* Zone d apercu : volontairement sombre dans les deux themes. */
:root[data-theme="clair"] .vsm-studio__photo,
:root[data-theme="clair"] .vsm-studio__view,
:root[data-theme="clair"] .vsm-photov { color-scheme: dark; }

/* ── Invite « Ajouter à l'écran d'accueil » (iPhone, Safari, hors standalone) ──
   Posée au-dessus du studio (z-index 160 < 200 des modales de page). */
.vsm-inst{position:fixed;inset:0;z-index:160;display:flex;align-items:flex-end;justify-content:center;background:rgba(4,3,12,.72);backdrop-filter:blur(4px);padding:14px;}
.vsm-inst__box{width:100%;max-width:420px;background:var(--vsm-card,#15151f);border:1px solid var(--vsm-line,rgba(255,255,255,.1));border-radius:20px;padding:20px 18px 16px;box-shadow:0 24px 60px -20px rgba(0,0,0,.7);}
.vsm-inst__t{font-size:17px;font-weight:800;color:#fff;margin-bottom:8px;}
.vsm-inst__p{font-size:13.5px;line-height:1.5;color:var(--vsm-dim,rgba(255,255,255,.62));margin:0 0 14px;}
.vsm-inst__l{margin:0 0 16px;padding-left:20px;list-style:decimal;font-size:13.5px;line-height:1.75;color:#fff;}
.vsm-inst__l b{color:var(--vsm-accent,#a78bfa);}
.vsm-inst__b{display:flex;gap:10px;}
.vsm-inst__x{flex:1 1 auto;min-height:44px;border-radius:12px;background:transparent;border:1px solid var(--vsm-line,rgba(255,255,255,.14));color:var(--vsm-dim,rgba(255,255,255,.62));font-size:13.5px;font-weight:600;cursor:pointer;}
.vsm-inst__ok{flex:1 1 auto;min-height:44px;border-radius:12px;border:0;cursor:pointer;font-size:14px;font-weight:700;color:#fff;background:linear-gradient(135deg,var(--vsm-accent,#a78bfa),var(--vsm-accent-2,#764ee5));}


/* Feuille d'aide mobile : TOUJOURS en sombre, quel que soit le theme.
   En theme clair la carte devenait blanche (var --vsm-card) alors que le
   titre et les etapes restaient en #fff : texte invisible, seuls les <b>
   violets ressortaient (capture Bill 29/08). On fige donc la palette ici,
   comme l'apercu du studio qui reste sombre volontairement. */
.vsm-inst__box{background:#15151f!important;border-color:rgba(255,255,255,.12)!important;}
.vsm-inst__t{color:#fff!important;}
.vsm-inst__p{color:rgba(255,255,255,.66)!important;}
.vsm-inst__l{color:#fff!important;}
.vsm-inst__l b{color:#a78bfa!important;}
.vsm-inst__x{background:transparent!important;color:rgba(255,255,255,.66)!important;border-color:rgba(255,255,255,.16)!important;}
/* Volt passait par-dessus la feuille (z-index 99999) et masquait les etapes. */
body:has(.vsm-inst) #voltw{display:none!important;}

/* Petit « i » a droite de « Prendre des photos » : rouvre la marche a suivre
   pour autoriser la camera dans les Reglages (l'astuce ne sort qu'une fois). */
.vsm-mi__i{position:absolute;right:12px;top:50%;transform:translateY(-50%);width:26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;font:700 13px/1 Georgia,serif;font-style:italic;color:var(--vsm-accent,#a78bfa);background:rgba(167,139,250,.14);border:1px solid rgba(167,139,250,.35);}
.vsm-mi{position:relative;}
