/* =============================================================
   Système de design — couche « produit »
   Partagé par toutes les pages. Extrait du code réellement en
   place dans index.html, pas réinventé.

   À ne pas confondre avec la couche « imitation LinkedIn »
   (--bg, --card, --blue…), qui reste locale à la carte du post :
   elle doit ressembler à LinkedIn, pas à nous.
   ============================================================= */

/* =============================================================
   THÈME
   Toutes les couleurs du produit passent par ces tokens : c'est ce
   qui rend le mode sombre possible sans réécrire les écrans. Une
   couleur en dur dans une page est un écran qui restera clair.

   Trois états, décidés dans Paramètres :
     auto (défaut)  suit le réglage du système
     clair          impose le clair
     sombre         impose le sombre
   L'attribut data-theme est posé sur <html> avant le premier rendu
   (script en tête de page) : sans ça, l'écran clignoterait en blanc
   avant de virer au sombre.
   ============================================================= */
:root{
  /* --- encre --- */
  --ink:        #1a1a2e;   /* texte principal, accents pleins */
  --ink-2:      #8a8a92;   /* texte secondaire, libellés */
  --ink-3:      #b4b4bc;   /* texte désactivé */

  /* --- surfaces --- */
  --page:       #f0f0f3;   /* fond de page */
  --panel:      #ffffff;   /* cartes, modales */
  --surface:    #f2f2f5;   /* champs, boutons neutres */
  --surface-2:  #e6e6ea;   /* survol d'un bouton neutre */
  --surface-3:  #f8f8fa;   /* champ posé sur le gris de la page */
  --line:       #00000014; /* filets de séparation */

  /* Le squelette est sa propre matière, et non celle des champs : il se pose
     AUSSI BIEN sur une carte blanche que sur le gris de la page, ce qu'aucune
     des surfaces ci-dessus ne fait — --surface (#f2f2f5) et --page (#f0f0f3)
     sont à trois points l'un de l'autre, un squelette à même la page y était
     invisible. D'où une teinte franchement plus basse que les deux. */
  --sk-base:    #e2e2e8;
  --sk-lueur:   #f1f1f4;   /* la crête du balayage */

  /* --- accents --- */
  --red:        #e0384f;   /* week-ends, badges, suppression */
  --blue-ios:   #0a84ff;   /* sélection (check « Utilisé ») */
  --blue-link:  #0a66c2;   /* mentions, liens */
  /* Le bleu DE MARQUE LinkedIn (#0a66c2, leur charte) — jamais réécrit en
     sombre, contrairement à --blue-link. Un badge ou un bouton qui montre
     LinkedIn doit porter SA couleur, pas la nôtre adaptée au thème : sinon
     le badge devient bleu pâle en sombre, où --blue-link s'éclaircit pour
     rester lisible en texte sur fond sombre — un besoin qui ne concerne pas
     un aplat plein. */
  --linkedin:   #0a66c2;

  /* --- surface inversée : boutons pleins, lien actif, jour choisi ---
     Ne PAS écrire background:var(--ink); color:#fff : en sombre --ink est
     clair, et le texte blanc disparaîtrait sur un bouton clair. */
  --solid-bg:   #1a1a2e;
  --solid-ink:  #ffffff;
  --solid-bg-2: #2a2a44;   /* survol */

  /* --- pastilles d'état --- */
  --tag-bg:        var(--surface);
  --tag-ink:       var(--ink-2);
  --tag-wait-ink:  #6b6b73;
  --tag-action-bg: #fdecef;  --tag-action-ink: var(--red);
  --tag-ok-bg:     #e7f5ee;  --tag-ok-ink:     #0d7a4f;
  --tag-live-bg:   #e8f0fb;  --tag-live-ink:   var(--blue-link);

  /* --- avertissement (données locales) --- */
  --warn-bg:  #fff9e6;
  --warn-ink: #7a5b00;

  /* --- action destructrice --- */
  --danger-bg:    #fdecef;
  --danger-bg-2:  #fbdae0;

  /* --- double bordure : ce qui est POSÉ --- */
  --edge:       #d0d0d6;
  --edge-w:     2px;
  --edge-gap:   4px;

  /* --- rayons --- */
  --r-panel:    32px;      /* modales, grandes cartes */
  --r-card:     28px;      /* carte du post */
  --r-field:    18px;      /* champs de saisie */
  --r-btn:      18px;      /* boutons */
  --r-pill:     999px;     /* pastilles, toggles */

  /* --- élévation : ce qui FLOTTE --- */
  --lift:       0 18px 44px -12px #00000045;
  /* Le canevas de l'app posé dans sa gouttière. Beaucoup plus discret que
     --lift : il ne s'agit pas de faire flotter, seulement de marquer la
     jointure entre deux teintes très proches (--panel et --page). */
  --canvas-lift: 0 1px 2px #0000000a, 0 4px 14px -6px #00000014;

  /* --- bascules (toggle) : valeurs du toggle des visuels --- */
  --toggle-track: #e4e4e8;   /* la piste */
  --toggle-off:   #6a6a72;   /* option non choisie */
  --toggle-lift:  0 1px 3px #0000001f;   /* l'ombre courte de la pastille */

  /* --- rythme --- */
  --gap:        8px;       /* écart intérieur des panneaux */
  --edge-margin: 10px;     /* marge aux bords d'écran */
}

/* =============================================================
   Barre de scroll — desktop uniquement
   Le trait fin par défaut du système est déjà discret sur mobile
   (survole le contenu, disparaît au repos) ; seul le desktop montre
   une piste et un pouce épais et opaques. On les allège : pas de
   fond de piste, un pouce fin qui reprend --ink-3 (déjà thématisé
   clair/sombre), visible seulement au survol.
   ============================================================= */
@media (min-width: 860px){
  *{
    scrollbar-width: thin;
    scrollbar-color: transparent transparent;
  }
  *:hover{
    scrollbar-color: var(--ink-3) transparent;
  }
  ::-webkit-scrollbar{
    width: 10px;
    height: 10px;
  }
  ::-webkit-scrollbar-track{
    background: transparent;
  }
  ::-webkit-scrollbar-thumb{
    background: transparent;
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: content-box;
  }
  *:hover::-webkit-scrollbar-thumb{
    background: var(--ink-3);
    background-clip: content-box;
  }
}

/* =============================================================
   Palette sombre
   Des gris neutres, jamais de noir pur : sur un écran OLED le noir
   absolu fait baver le texte clair et écrase la hiérarchie. On monte
   par paliers — page, panneau, champ — pour retrouver exactement les
   rapports du clair.
   Les accents sont éclaircis et désaturés : le rouge du clair
   (#e0384f) vibre sur fond sombre et devient illisible en petit.

   Le bloc est écrit deux fois — pour le réglage manuel et pour celui
   du système. CSS ne sait pas partager un bloc entre deux sélecteurs
   sans les lister tous les deux ; les valeurs, elles, restent au même
   endroit.
   ============================================================= */
:root[data-theme="sombre"]{
  --ink:        #ececec;
  --ink-2:      #a0a0a5;
  --ink-3:      #6e6e73;

  --page:       #000000;   /* le fond le plus bas */
  --panel:      #141414;   /* la carte se détache d'un cran */
  --surface:    #1a1a1a;   /* champ ou bouton neutre, un cran de plus */
  --surface-2:  #262626;   /* survol */
  --surface-3:  #1c1c1c;   /* champ creusé DANS une carte : plus bas qu'elle */
  --line:       #ffffff14;

  /* En sombre, le squelette monte au lieu de descendre : il reste plus clair
     que la carte (#212121) comme que le fond (#171717). */
  --sk-base:    #2e2e2e;
  --sk-lueur:   #3c3c3c;

  --solid-bg:   #ececec;
  --solid-ink:  #171717;
  --solid-bg-2: #ffffff;

  --red:        #ff6b73;
  --blue-ios:   #4d9fff;
  --blue-link:  #7cb9ff;

  --tag-wait-ink:  #b9b9c0;
  --tag-action-bg: #3a2027;  --tag-action-ink: #ff8a92;
  --tag-ok-bg:     #142b21;  --tag-ok-ink:     #5fd39b;
  --tag-live-bg:   #15293d;  --tag-live-ink:   #7cbaff;

  --warn-bg:  #2b2412;
  --warn-ink: #e6c169;

  --danger-bg:   #3a2027;
  --danger-bg-2: #4a2830;

  --edge:       #3a3a3a;
  --lift:       0 18px 44px -12px #000000cc;
  /* En sombre la gouttière (--panel) est PLUS CLAIRE que le canevas :
     l'ombre se lit donc sur elle, et doit être un peu plus dense. */
  --canvas-lift: 0 1px 2px #00000038, 0 4px 14px -6px #00000059;

  --toggle-track: #3a3a3a;
  --toggle-off:   #a0a0a5;
  --toggle-lift:  0 1px 3px #00000073;
}

@media (prefers-color-scheme: dark){
  :root:not([data-theme="clair"]):not([data-theme="sombre"]){
    --ink:        #ececec;
    --ink-2:      #a0a0a5;
    --ink-3:      #6e6e73;

    --page:       #000000;
    --panel:      #141414;
    --surface:    #1a1a1a;
    --surface-2:  #262626;
    --surface-3:  #1c1c1c;
    --line:       #ffffff14;

    --sk-base:    #2e2e2e;
    --sk-lueur:   #3c3c3c;

    --solid-bg:   #ececec;
  --solid-ink:  #000000;
  --solid-bg-2: #ffffff;

  --red:        #ff6b73;
    --blue-ios:   #4d9fff;
    --blue-link:  #7cb9ff;

    --tag-wait-ink:  #b9b9c0;
    --tag-action-bg: #3a2027;  --tag-action-ink: #ff8a92;
    --tag-ok-bg:     #142b21;  --tag-ok-ink:     #5fd39b;
    --tag-live-bg:   #15293d;  --tag-live-ink:   #7cbaff;

    --warn-bg:  #2b2412;
    --warn-ink: #e6c169;

    --danger-bg:   #3a2027;
    --danger-bg-2: #4a2830;

    --edge:       #3a3a3a;
    --lift:       0 18px 44px -12px #000000cc;
    --canvas-lift: 0 1px 2px #00000038, 0 4px 14px -6px #00000059;

    --toggle-track: #3a3a3a;
    --toggle-off:   #a0a0a5;
    --toggle-lift:  0 1px 3px #00000073;
  }
}

*{ box-sizing:border-box; }

/* `hidden` cache. Vraiment.

   Le navigateur porte bien un [hidden]{display:none}, mais il vit dans SA
   feuille de style, et la moindre règle d'auteur qui pose un display le bat
   — sans avertissement. Or presque tous nos composants en posent un :
   .u-btn est en inline-flex, .visual-toggle en flex, .modale en grid. Poser
   `el.hidden = true` sur l'un d'eux ne faisait donc RIEN, et le bouton
   restait à l'écran.

   Le symptôme a déjà été soigné huit fois, à huit endroits, à chaque fois
   qu'il mordait (.modale[hidden], .scrim[hidden], .visual-toggle[hidden]…).
   Celles-ci deviennent redondantes ; elles ne gênent pas.

   !important : c'est le seul moyen de passer devant les règles d'auteur qui
   posent un display, puisque c'est précisément contre elles qu'on lutte.
   Un élément marqué hidden n'a aucune raison d'être affiché — il n'y a pas
   de cas où cette règle-ci soit celle qu'on voudrait perdre. */
[hidden]{ display:none !important; }

/* Les contrôles natifs (curseur de saisie, sélection, ascenseurs) suivent
   le thème : sans ça, un champ sombre garde un curseur pensé pour le blanc. */
:root[data-theme="sombre"]{ color-scheme:dark; }
:root[data-theme="clair"]{ color-scheme:light; }
:root:not([data-theme]){ color-scheme:light dark; }

body{
  margin:0;
  background:var(--page);
  color:var(--ink);
  font-family:'Manrope',sans-serif;
  -webkit-font-smoothing:antialiased;
}

/* =============================================================
   Le gris de l'app posé en CARTE (desktop)
   Le fond de page ne va plus jusqu'aux bords : il s'arrête à 15px,
   s'arrondit, et laisse voir le blanc derrière lui. C'est html qui
   porte ce blanc et body qui garde le gris — donc aucune page n'a
   de balise à ajouter, la règle vaut partout d'un coup.
   Les écrans hors app (login, inscription, mot de passe, rejoindre)
   sont déjà blancs : ils remettent margin à 0 dans leur propre
   <style>, sinon leur min-height:100dvh déborderait de 30px.
   ============================================================= */
/* Palier INTERMÉDIAIRE seulement (720–859px) : au-delà, la sidebar fixe prend
   le relais avec SON PROPRE traitement de <body> (cadre fixe + scroll interne,
   plus bas) — les deux règles se disputaient body/html sur les mêmes
   propriétés quand ce bloc n'était pas borné, d'où un cadre qui « disparaissait ». */
@media (min-width:720px) and (max-width:859px){
  /* Le fond derrière la carte : la couleur de la sidebar (--panel), pour que
     la gouttière soit de la même matière que les cartes posées dessus.
     Le token, pas la valeur en dur : il suit donc le thème tout seul. */
  html{ background:var(--panel); }

  body{
    margin:8px;
    border-radius:var(--r-panel);
    min-height:calc(100dvh - 16px);
    /* --panel et --page ne sont qu'à quelques points l'un de l'autre : sans
       ce voile, la jointure ne se lit pas. Une ombre, pas une bordure — on
       marque le relief, on ne trace pas un trait. */
    box-shadow:var(--canvas-lift);
  }
}

/* =============================================================
   Deux règles structurantes, dégagées de l'app existante :
   ce qui FLOTTE porte une ombre, ce qui est POSÉ porte la
   double bordure. Jamais les deux.
   ============================================================= */

/* posé sur la page */
.u-set{
  background:var(--panel);
  border-radius:var(--r-panel);
  outline:var(--edge-w) solid var(--edge);
  outline-offset:var(--edge-gap);
}

/* flottant au-dessus */
.u-float{
  background:var(--panel);
  border-radius:var(--r-panel);
  box-shadow:var(--lift);
}

/* simple carte, sans l'un ni l'autre */
.u-plain{
  background:var(--panel);
  border-radius:var(--r-panel);
}

/* --- typographie --- */
.t-title{ font-size:22px; font-weight:800; letter-spacing:-.3px; }
.t-head { font-size:15px; font-weight:700; }
.t-body { font-size:14px; font-weight:500; line-height:1.45; }
.t-label{ font-size:12px; font-weight:700; letter-spacing:.4px;
          text-transform:uppercase; color:var(--ink-2); }
.t-muted{ font-size:13px; font-weight:500; color:var(--ink-2); }

/* --- boutons --- */
.u-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  border:none; cursor:pointer;
  font-family:'Manrope',sans-serif; font-size:14px; font-weight:700;
  padding:10px 16px; border-radius:var(--r-btn);
  transition:background .12s, transform .1s;
}
.u-btn:active{ transform:scale(.97); }
.u-btn--solid{ background:var(--solid-bg); color:var(--solid-ink); }
.u-btn--solid:hover{ background:var(--solid-bg-2); }
.u-btn--soft{ background:var(--surface); color:var(--ink); }
.u-btn--soft:hover{ background:var(--surface-2); }
.u-btn--ghost{ background:none; color:var(--ink-2); }
.u-btn--ghost:hover{ background:var(--surface); color:var(--ink); }
/* Compact : pour les boutons d'appoint qui s'alignent dans un bandeau, pas
   pour l'action principale d'un écran. */
.u-btn--sm{ padding:7px 12px; font-size:12.5px; gap:6px; }

/* =============================================================
   Bascule — la forme du toggle des visuels, partagée
   Piste grise, pastille blanche à ombre courte. C'est le toggle de
   la page publication qui donne le ton ; ses valeurs sont reprises
   ici pour que les autres ne dérivent pas.
   ============================================================= */
.u-toggle{
  display:inline-flex; padding:4px;
  background:var(--toggle-track); border-radius:var(--r-pill);
}
.u-toggle button{
  border:none; background:transparent; cursor:pointer;
  padding:9px 22px; border-radius:var(--r-pill);
  font-family:'Manrope',sans-serif; font-size:14px; font-weight:600;
  color:var(--toggle-off); white-space:nowrap;
  transition:color .2s, background .2s, box-shadow .2s;
}
.u-toggle button[aria-pressed="true"]{
  background:var(--panel); color:var(--ink);
  box-shadow:var(--toggle-lift);
}

/* Bouton seul qui doit se lire comme une bascule : la pastille blanche,
   posée sur un anneau de la couleur de la piste. Deux ombres plutôt que
   deux éléments — l'anneau est une ombre sans flou. */
.u-toggle-solo{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  border:none; cursor:pointer;
  padding:9px 22px; border-radius:var(--r-pill);
  background:var(--panel); color:var(--ink);
  font-family:'Manrope',sans-serif; font-size:14px; font-weight:600;
  white-space:nowrap;
  box-shadow:var(--toggle-lift), 0 0 0 4px var(--toggle-track);
  transition:transform .1s;
}
.u-toggle-solo:active{ transform:scale(.97); }

/* --- icônes : trait, jamais plein (style Feather) --- */
.u-icon{
  width:20px; height:20px; flex:none;
  fill:none; stroke:currentColor; stroke-width:1.8;
  stroke-linecap:round; stroke-linejoin:round;
}
.u-icon--sm{ width:16px; height:16px; }
.u-icon--lg{ width:24px; height:24px; }

/* --- pastilles d'état --- */
.u-tag{
  display:inline-flex; align-items:center; gap:5px;
  vertical-align:middle;              /* centré sur la ligne des boutons voisins */
  padding:4px 9px; border-radius:var(--r-pill);
  font-size:11px; font-weight:700; letter-spacing:.2px;
  background:var(--tag-bg); color:var(--tag-ink);
}
.u-tag--action{ background:var(--tag-action-bg); color:var(--tag-action-ink); }
/* Gris, pas rouge : le client n'est pas en retard, la publication
   attend simplement son tour. Le texte est plus soutenu que --ink-2
   pour rester lisible sur le gris du fond. */
.u-tag--wait  { background:var(--tag-bg); color:var(--tag-wait-ink); }
.u-tag--ok    { background:var(--tag-ok-bg); color:var(--tag-ok-ink); }
.u-tag--live  { background:var(--tag-live-bg); color:var(--tag-live-ink); }
/* Cassé, et pas « en attente ». --action est un rose pâle qui dit « ça
   attend ton geste » — c'est déjà ce que porte « Chez le client ». Un envoi
   raté n'attend pas : il a échoué. D'où l'aplat plein, qu'on ne confond avec
   rien. --red est défini dans les deux thèmes, le blanc tient sur les deux. */
.u-tag--ko    { background:var(--red); color:#fff; }
/* Un premier jet écrit par le travail de fond : il attend une relecture. Violet
   pour le distinguer d'un coup d'œil des brouillons écrits à la main. */
.u-tag--ia    { background:rgba(124,58,237,.14); color:#7C3AED; }
:root[data-theme="sombre"] .u-tag--ia{ background:rgba(167,139,250,.18); color:#c4b5fd; }
@media (prefers-color-scheme: dark){
  :root:not([data-theme="clair"]) .u-tag--ia{ background:rgba(167,139,250,.18); color:#c4b5fd; }
}

/* --- champ de saisie riche --- */
.u-field{
  width:100%; min-height:56px;
  background:var(--surface); border-radius:var(--r-field);
  padding:10px 12px; outline:none;
  font-family:'Manrope',sans-serif;
  /* 16px minimum : en dessous, iOS zoome au focus, y compris
     sur un contenteditable */
  font-size:16px; line-height:1.45;
  white-space:pre-wrap; word-break:break-word;
}
.u-field:empty::before{ content:attr(data-ph); color:var(--ink-2); pointer-events:none; }
.u-field:focus{ box-shadow:inset 0 0 0 2px var(--surface-2); }

/* --- barre de navigation haute, commune aux pages --- */
.nav{
  display:flex; align-items:center; justify-content:space-between;
  width:100%; max-width:640px; margin:0 auto; padding:0 4px;
}
.nav__btn{
  width:40px; height:40px; padding:0;
  border:none; background:transparent; cursor:pointer;
  color:var(--ink);
  display:flex; align-items:center; justify-content:center;
  transition:transform .1s;
}
.nav__btn:active{ transform:scale(.92); }

/* =============================================================
   Navigation — deux formes selon la largeur, jamais les deux :
     · large  : barre latérale toujours ouverte (.side)
     · étroit : burger + tiroir (.nav / .drawer)
   Le seuil est unique (860px) pour que l'une prenne exactement
   le relais de l'autre.
   ============================================================= */
/* Colonnes reprises de la page publication ; l'écart, lui, est plus large.
   --shell suit l'écart : c'est la somme des trois colonnes plus les deux
   gouttières. Le laisser à 1128 aurait fait rétrécir la colonne centrale
   d'exactement ce qu'on ajoute entre les colonnes. */
:root{
  --col-side:225px; --col-side-icons:68px; --col-main:555px; --col-aside:300px;
  --shell-gap:45px;
  --shell:calc(var(--col-side) + var(--col-main) + var(--col-aside) + var(--shell-gap) * 2);
  --nav-bp:860px; --brand-h:36px;
}

/* =============================================================
   Coquille de page — reprend la grille de la page publication :
   colonne centrale encadrée de deux colonnes de cartes.
   Les colonnes latérales tombent avant le contenu quand la place
   manque : ce sont des accompagnements, pas le sujet.
   ============================================================= */
.shell{ width:100%; max-width:var(--shell); margin:0 auto; }

.topbar{
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; width:100%; max-width:var(--shell); margin:0 auto 16px;
}
/* Le premier bloc de ces pages est une CARTE pleine : son bord dur tombe
   juste sous le logo et étouffe la barre. Sur /publications le premier bloc
   est transparent (la bande des jours), d'où l'impression d'air à mesure
   pourtant égale. On rend cet air aux autres pages.
   La règle vient APRÈS celle du dessus, sinon le raccourci `margin` la
   réécrirait — même spécificité, c'est l'ordre qui tranche. */
@media (min-width:720px){
  .topbar{ margin-bottom:28px; }
}
/* =============================================================
   Cohook — le mot, pas une image
   Écrit en texte : il reste net à toute taille, suit le thème, et se
   lit par les lecteurs d'écran. Une image aurait figé sa couleur.

   La recette d'origine (from-white via-white to-gray-400) est pensée
   pour un fond noir : telle quelle, le mot disparaîtrait sur le thème
   clair. Le dégradé part donc de l'encre en clair, du blanc en sombre,
   et descend vers le gris dans les deux cas.
   ============================================================= */
/* Le mot est un LIEN vers l'accueil. C'est la convention du web, et sur la
   page publication c'est ce qui reprend le travail de la flèche retour quand
   elle s'efface au profit du logo. */
.topbar__brand{
  /* Visible partout. En étroit il se pose AU CENTRE, entre le burger et le
     calendrier : les deux font 40px, donc avec space-between le mot tombe
     pile au milieu de la barre — sans calcul, et sans cesser de suivre si
     l'un des deux disparaît. En large, le burger s'efface et le mot prend
     naturellement la gauche. */
  display:block;
  flex:none;
  text-decoration:none;
  font-family:ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size:var(--brand-h);
  font-weight:700;
  letter-spacing:-.035em;           /* tracking-tight */
  line-height:1;
  background-image:linear-gradient(to bottom, #1a1a2e 0%, #1a1a2e 55%, #6b7280 100%);
  -webkit-background-clip:text; background-clip:text;
  color:transparent;
  user-select:none;
}
:root[data-theme="sombre"] .topbar__brand{
  background-image:linear-gradient(to bottom, #fff 0%, #fff 55%, #9ca3af 100%);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="clair"]):not([data-theme="sombre"]) .topbar__brand{
    background-image:linear-gradient(to bottom, #fff 0%, #fff 55%, #9ca3af 100%);
  }
}

.layout3{
  display:grid;
  /* minmax(0,1fr), pas 1fr : « 1fr » vaut « minmax(auto,1fr) », dont le
     plancher auto prend le min-content de la colonne. Un enfant à large
     min-content — la piste flex du carrousel Actus, dont les sujets sont
     posés côte à côte — gonflait alors la colonne au-delà de l'écran, et
     TOUT le rail (carte, calendrier, compteurs) débordait à droite sur
     mobile. Le desktop utilise déjà minmax(0,1fr) plus bas : on aligne. */
  grid-template-columns:minmax(0,1fr);
  /* l'écart large est celui ENTRE LES COLONNES ; empilé, 45px de vide
     entre deux blocs creuserait la page pour rien */
  column-gap:var(--shell-gap); row-gap:24px;
  width:100%; max-width:var(--shell); margin:0 auto;
  align-items:start;
}

/* Pages dont le titre est une rangée de la grille : le titre, puis la
   colonne de droite, puis le contenu. L'admin, qui garde son titre dans
   la colonne centrale, n'est pas concerné — d'où le :has(). */
.layout3:has(> .hello){ grid-template-areas:'head' 'rail' 'main'; }
/* Sans colonne de droite (idées, profil, paramètres), la rangée « rail »
   n'a pas lieu d'exister : laissée là, elle ajouterait son écart de 24px
   entre le titre et le contenu. */
.layout3:has(> .hello):not(:has(.rail)){ grid-template-areas:'head' 'main'; }
.layout3:has(> .hello) > .hello{ grid-area:head; }
.layout3:has(> .hello) > .page{ grid-area:main; }
.layout3:has(> .hello) > .rail{ grid-area:rail; }
.layout3:has(> .hello) > .side{ grid-area:side; }

/* --- le chargement ---
   Les données viennent de Supabase : entre le premier pixel et la réponse,
   il y a un aller-retour réseau. Sans rien, la page peint sa coquille vide —
   une sidebar sans liens, « Bonjour » sans personne. Le squelette occupe
   cette place : mêmes formes, mêmes tailles, sans le contenu. Rien ne saute
   quand les vraies valeurs arrivent.

   Le balayage va du clair au plus clair et revient : c'est un objet en
   attente, pas une alerte. */
@keyframes sk-balaye{ to{ background-position-x:-200%; } }
.sk{
  background:linear-gradient(90deg,
    var(--sk-base) 0%, var(--sk-lueur) 40%, var(--sk-base) 80%);
  background-size:200% 100%;
  animation:sk-balaye 1.4s linear infinite;
  border-radius:999px;
  color:transparent;            /* si un texte traîne dessous, il se tait */
  user-select:none; pointer-events:none;
}
/* Une animation qui ne s'arrête jamais est exactement ce que ce réglage
   système demande de ne pas faire. */
@media (prefers-reduced-motion:reduce){ .sk{ animation:none; } }

.sk-ligne{ display:block; height:10px; margin:3px 0; }
.sk-rond{ border-radius:50%; }
/* Les lignes n'ont pas toutes la même longueur : un empilement de barres
   identiques ne ressemble à aucun texte. */
.sk-lien{ height:38px; border-radius:var(--r-field); margin-bottom:4px; }
.sk-lien:nth-child(2){ width:82%; }
.sk-lien:nth-child(4){ width:74%; }

/* Les cartes en attente reprennent le gabarit des vraies — .row, .stat,
   la carte de publication. C'est tout l'intérêt : quand les données
   arrivent, elles se posent là où le squelette était, sans rien bousculer.
   Le fond reste celui du panneau, seul le contenu balaye : c'est la carte
   qui attend son texte, pas la carte qui n'existe pas encore. */
.sk-bloc{ display:flex; flex-direction:column; gap:14px; }

.sk-row{
  display:flex; align-items:center; gap:12px;
  background:var(--panel); border-radius:var(--r-field); padding:10px;
}
.sk-row__vis{ width:56px; height:56px; flex:none; border-radius:10px; }
.sk-row__txt{ flex:1; min-width:0; }

/* display:block : sans lui, un <span> reste en ligne et ignore sa hauteur.
   Il ne tenait que parce que .stats est une grille, qui blockifie ses
   enfants — une dépendance invisible au parent. */
.sk-stat{ display:block; height:72px; border-radius:var(--r-field); }

/* La carte de publication : un grand pavé, à la hauteur du vrai. */
.sk-carte{
  background:var(--panel); border-radius:var(--r-panel); padding:18px;
}

/* Dépôt d'idée : les trois cartes de type, puis le champ. Mêmes mesures que
   .types / .type / .box (idees.html) — si celles-ci bougent, celles-là
   doivent suivre. */
.sk-types{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:16px; margin:0 6px 22px;
}
.sk-type{ display:block; height:118px; border-radius:16px; }
.sk-box{
  background:var(--panel); border-radius:var(--r-panel); padding:8px;
  outline:var(--edge-w) solid var(--edge); outline-offset:var(--edge-gap);
  margin-bottom:32px;
}
.sk-champ{ display:block; height:140px; border-radius:var(--r-field); }

/* Le bouton « Déposer une idée » : 16px de marge, une pastille de 40, 16px
   encore — 72 en tout (voir .drop dans dashboard.html). */
.sk-drop{ display:block; height:72px; border-radius:var(--r-panel); }

/* --- barre latérale ---
   POSÉE, comme la carte de publication : double bordure, pas d'ombre.
   Elle est à côté du contenu, pas au-dessus — lui donner l'ombre des
   modales la faisait décoller du reste de l'app. */
.side{ display:none; }

/* Logo en tête de la sidebar (refonte façon ChatGPT/Canva/Lovable) —
   remplace le mot de la topbar, masqué en desktop. */
.side__brand{
  display:flex; align-items:center; flex:none;
  height:40px; padding:0 6px; margin-bottom:10px;
  text-decoration:none;
}
/* Dimensions communes aux deux logos du rail (mot + pastille). */
.side__brand img{ height:24px; width:auto; display:block; }
/* La pastille (icône app, en couleur) garde son ancien traitement monochrome :
   grise en clair, blanche en sombre — elle n'est visible que rail replié. */
.side__brand-mark{ filter:brightness(0) invert(.28); }
:root[data-theme="sombre"] .side__brand-mark{ filter:brightness(0) invert(1); }
/* Le mot-logo : version claire par défaut, version sombre par thème (deux
   fichiers dédiés, cf. .brand-logo). */
.side__brand-full{ content:url("/logo-texte-clair.png"); }
:root[data-theme="sombre"] .side__brand-full{ content:url("/logo-texte-sombre.png"); }
@media (prefers-color-scheme:dark){
  :root:not([data-theme="clair"]):not([data-theme="sombre"]) .side__brand-mark{ filter:brightness(0) invert(1); }
  :root:not([data-theme="clair"]):not([data-theme="sombre"]) .side__brand-full{ content:url("/logo-texte-sombre.png"); }
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="clair"]):not([data-theme="sombre"]) .side__brand img{ filter:brightness(0) invert(1); }
}

/* Identité du connecté — désormais tout EN BAS de la sidebar (après l'espace
   flexible), séparée des liens par un filet au-DESSUS. */
.side__who{
  display:flex; align-items:center; gap:10px;
  padding:12px 6px 2px; margin-top:6px;
  border-top:1px solid var(--line);
}
.side__av{
  width:36px; height:36px; flex:none;
  border-radius:50%; object-fit:cover;
  background:var(--surface);
}
.side__id{ min-width:0; }
.side__nom{
  display:block; font-size:13.5px; font-weight:800;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.side__maison{
  display:block; font-size:11.5px; font-weight:600; color:var(--ink-2);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* Pastille de rappel : ce qui attend l'avis du client */
.side__n{
  margin-left:auto; flex:none;
  min-width:18px; height:18px; padding:0 5px;
  border-radius:9px; background:var(--red); color:var(--panel);
  font-size:10px; font-weight:800;
  display:flex; align-items:center; justify-content:center;
}
/* La pastille reste ROUGE/blanc même sur l'onglet actif : elle signale une
   attente (des posts à valider), pas l'état de la navigation — la fondre
   dans les couleurs actives (solid-ink/solid-bg) la rendait illisible,
   parfois quasi invisible sur un fond déjà sombre. */
.side__link[aria-current="page"] .side__n,
.drawer a[aria-current="page"] .side__n{ background:var(--red); color:#fff; }
.drawer .side__n{ margin-left:auto; }
.drawer .side__label{ display:inline; }
.side__link{
  width:100%; height:46px; padding:0 12px; flex:none;
  border:none; background:none; cursor:pointer;
  border-radius:var(--r-btn);
  display:flex; align-items:center; gap:12px;
  color:var(--ink-2); text-decoration:none;
  font-family:'Manrope',sans-serif; font-size:14.5px; font-weight:700;
  transition:background .12s, color .12s;
}
/* Icônes des liens (dépliés) : u-icon--sm (16px, pensé pour des boutons de
   page compacts) se perdait à côté d'un texte à 14.5px — la rangée d'icônes
   voisine (24px) rendait le contraste encore plus visible. */
.side .u-icon--sm{ width:20px; height:20px; }
.side__link:hover{ background:var(--surface); color:var(--ink); }
.side__link[aria-current="page"]{ background:var(--solid-bg); color:var(--solid-ink); }
.side__spacer{ flex:1; }

/* Bouton « ranger / déplier » la sidebar (façon Pinterest) : même gabarit que
   les liens (.side__link), posé APRÈS eux — c'est une action sur la barre,
   pas une destination, un filet au-dessus le sépare des vraies pages.
   Absent sur /publications, où la barre reste rangée d'office. */
.side__toggle{
  margin-top:6px; padding-top:14px;
  border-top:1px solid var(--line); border-radius:0;
}

/* La sortie n'est pas une destination : elle est séparée du reste, en bas,
   et vire au rouge au survol pour qu'on ne la confonde pas avec un lien. */
.side__sortie{
  width:100%; height:46px; padding:0 12px; flex:none; margin-top:6px;
  border:none; background:none; cursor:pointer;
  border-radius:var(--r-btn);
  display:flex; align-items:center; gap:12px;
  color:var(--ink-2); text-decoration:none;
  font-family:'Manrope',sans-serif; font-size:14.5px; font-weight:700;
  border-top:1px solid var(--line); border-radius:0 0 var(--r-btn) var(--r-btn);
  transition:background .12s, color .12s;
}
.side__sortie:hover{ background:var(--danger-bg); color:var(--red); }
.drawer .side__sortie{ margin-top:10px; }

/* Retour à l'admin — même famille que la sortie : on quitte l'écran, on n'y
   va pas. Mais ce n'est pas un geste risqué, d'où le survol neutre et pas
   le rouge. */
.side__admin{
  width:100%; height:46px; padding:0 12px; flex:none; margin-top:6px;
  border:none; background:none; cursor:pointer;
  border-radius:var(--r-btn);
  display:flex; align-items:center; gap:12px;
  color:var(--ink-2); text-decoration:none;
  font-family:'Manrope',sans-serif; font-size:14.5px; font-weight:700;
  border-top:1px solid var(--line); border-radius:0;
  transition:background .12s, color .12s;
}
.side__admin:hover{ background:var(--surface); color:var(--ink); }
/* Deux traits collés feraient une double ligne : celui du haut suffit à
   détacher le bloc du reste. */
.side__admin + .side__sortie{ border-top:none; margin-top:0; }
.drawer .side__admin{ margin-top:10px; }
.drawer .side__admin + .side__sortie{ margin-top:0; }

/* Colonne de droite. Tant que les trois colonnes ne tiennent pas, elle ne
   disparaît pas : elle se glisse sous le titre. Elle porte des chiffres
   qu'on ne trouve nulle part ailleurs — les masquer en étroit les
   rendrait introuvables sur téléphone.
   L'écart vient du row-gap de la grille, pas d'une marge. */

/* Les deux paliers vont du plus étroit au plus large, et PAS l'inverse :
   à 1280px les deux media queries s'appliquent, c'est la dernière écrite
   qui l'emporte. Inversées, le palier 860 (deux colonnes) écrasait le
   palier 1080 (trois colonnes) et la colonne de droite retombait sous
   la sidebar. */

/* --- moyen : sidebar FIXE pleine hauteur + <body> = le cadre lui-même ---
   Refonte façon ChatGPT/Canva/Lovable : la sidebar est collée au bord gauche,
   posée sur le canevas (--panel, la teinte des tuiles KPI). <body> DEVIENT le
   cadre NOIR (--page) à coins arrondis : position fixe, cadré par une
   gouttière de 10px sur les QUATRE côtés, et SCROLLABLE EN INTERNE
   (overflow-y:auto). Avant, un `body::before` décoratif restait fixe pendant
   que <body> défilait normalement — le contenu débordait alors du cadre au
   scroll. En scrollant `<body>` lui-même (borné, avec overflow-y:auto), le
   contenu ne peut plus jamais dépasser ses limites, jamais. */
@media (min-width:860px){
  html{ background:var(--panel); overflow:hidden; }
  body{
    position:fixed;
    top:10px; right:10px; bottom:10px; left:calc(var(--col-side) + 10px);
    overflow-y:auto; overflow-x:hidden;
    background:var(--page); border-radius:var(--r-panel);
    /* Pas de contour : seule la gouttière (10px, tout autour) sépare le cadre
       du canevas — pas de double bordure. */
  }
  .side{
    display:flex; flex-direction:column; align-items:stretch;
    position:fixed; left:0; top:0; z-index:40;
    width:var(--col-side); height:100dvh; overflow-y:auto;
    gap:2px; padding:14px 12px;
    background:var(--panel); border-radius:0;
  }
  /* Sidebar « rangée » (icônes seules), façon Pinterest. Pilotée par UNE
     classe posée sur <html> TRÈS TÔT (script en tête de page, avant le premier
     paint : aucun saut) — elle rétrécit la barre ET recale le bord gauche du
     cadre <body> d'un seul geste. Verrouillée sur /publications (toujours
     rangée), togglable via le bouton .side__toggle ailleurs. */
  /* Pas de +10px ici (contrairement à la barre large) : la rangée d'icônes
     est déjà étroite, une gouttière en plus la ferait paraître détachée du
     cadre plutôt que collée à son bord. */
  html.side-min body{ left:var(--col-side-icons); }
  html.side-min .side{
    width:var(--col-side-icons); align-items:center; padding:16px 6px;
    /* Plus large que le gap:2px de la barre déployée (pensé pour des lignes
       de texte serrées) : en icônes seules, façon Pinterest, chaque symbole
       veut sa respiration propre pour rester lisible comme une action à part. */
    gap:14px;
    /* Barre de défilement masquée : sinon elle grignote la largeur à droite
       et décentre la colonne d'icônes de quelques pixels. */
    scrollbar-width:none;
  }
  html.side-min .side::-webkit-scrollbar{ display:none; }
  html.side-min .side__brand{
    justify-content:center; padding:0; width:100%; margin-bottom:8px;
  }
  html.side-min .side__link,
  html.side-min .side__sortie,
  html.side-min .side__admin,
  html.side-min .side__toggle{
    width:44px; height:44px; padding:0; margin:0 auto; justify-content:center;
  }
  /* Icônes agrandies : seules à porter le repère, sans libellé à côté —
     16px (u-icon--sm) se perdait dans la colonne. */
  html.side-min .side__link .u-icon,
  html.side-min .side__sortie .u-icon,
  html.side-min .side__admin .u-icon,
  html.side-min .side__toggle .u-icon{ width:24px; height:24px; }
  html.side-min .side__label,
  html.side-min .side__id{ display:none; }
  html.side-min .side__who{ justify-content:center; padding:12px 0 2px; }
  html.side-min .side__link,
  html.side-min .side__sortie,
  html.side-min .side__admin,
  html.side-min .side__toggle{ position:relative; }
  /* Repère de l'onglet actif façon Pinterest : pas de pastille de fond (elle
     s'écraserait sur une icône seule, sans libellé pour la justifier) — la
     couleur passe au plein, et nav.js sort un GLYPHE DÉDIÉ (IC_PLEIN), dessiné
     pour être rempli — pas le linework habituel forcé en fill (ça referme les
     tracés n'importe comment, la maison de l'accueil devenait un bloc informe). */
  html.side-min .side__link[aria-current="page"]{ background:none; color:var(--ink); }
  /* Contour noir fixe (pas --ink, qui blanchit en sombre) autour du
     remplissage : sans lui, un glyphe blanc (mode sombre) se fondait dans un
     fond clair dès qu'il y en avait un à proximité (badge, survol). Le
     contour se pose EN DESSOUS du fill (paint-order) pour rester un simple
     liseré, pas une forme plus épaisse. */
  .u-icon--plein{
    fill:currentColor; stroke:rgba(0,0,0,.55); stroke-width:1;
    stroke-linejoin:round; paint-order:stroke fill; fill-rule:evenodd;
  }
  /* Les creux du glyphe (le trou de la molette réglages, les lignes du
     journal, la case du calendrier) : couleur du fond, pas du glyphe — sinon
     ils se fondent dans le plein et le trou disparaît. */
  .u-icon--plein .u-icon-trou{ fill:var(--panel); stroke:var(--panel); }
  /* Pastille ancrée au coin haut-droit de l'icône (le lien passe en relative). */
  html.side-min .side__link{ position:relative; }
  html.side-min .side__n{ position:absolute; top:2px; right:2px; margin:0; }
  /* Marque seule (le C étoilé) quand rangée, mot-symbole complet quand dépliée :
     COHOOK écrasé sur 44px est illisible. Les deux images cohabitent dans
     .side__brand, on n'en montre qu'une (voir nav.js). */
  /* .side__brand img{display:block; filter:...} (plus haut) est plus
     spécifique qu'une simple classe (élément + classe > classe seule) : sans
     répéter "img" ici, ces deux règles n'auraient aucun effet, écrasées. */
  .side__brand img.side__brand-mark{ display:none; }
  html.side-min .side__brand img.side__brand-full{ display:none; }
  html.side-min .side__brand img.side__brand-mark{
    display:block; height:38px; width:38px; border-radius:10px; filter:none;
  }
  /* La grille ne réserve plus de colonne `side` ; son max-width tombe à la
     largeur du CONTENU (centre + rail), plus celle de la sidebar déjà retirée
     du corps. */
  .layout3{
    grid-template-columns:minmax(0,1fr);
    max-width:calc(var(--col-main) + var(--col-aside) + var(--shell-gap));
  }
  .layout3:has(> .hello){ grid-template-areas:'head' 'rail' 'main'; }
  .layout3:has(> .hello):not(:has(.rail)){ grid-template-areas:'head' 'main'; }
  /* Logo et burger vivent maintenant dans la sidebar : on les retire de la
     topbar (qui ne garde que les actions de page, .topbar__right).
     `.topbar .topbar__brand` et pas `.topbar__brand` seul : plusieurs pages
     portent la classe .desktop-only sur ce logo (elle le masque sous 860px,
     là où la barre du haut montre un bouton retour et un titre à la place).
     À spécificité égale, c'est leur <style> — chargé APRÈS design.css — qui
     l'emportait, et le logo réapparaissait en double avec celui de la
     sidebar. Deux classes suffisent à trancher, sans !important et sans
     toucher au comportement mobile. */
  .topbar .topbar__brand{ display:none; }
  .nav__burger{ display:none; }
}
/* --- large : les trois colonnes --- */
@media (min-width:1080px){
  .layout3:has(.rail){
    grid-template-columns:minmax(0,var(--col-main)) var(--col-aside);
  }
  .layout3:has(> .hello){ grid-template-areas:'head rail' 'main rail'; }
  .layout3:has(> .hello):not(:has(.rail)){ grid-template-areas:'head' 'main'; }
  .rail{ margin-top:0; position:sticky; top:24px; }
}

/* =============================================================
   Mini calendrier (colonne de droite)
   Reprend la grille du calendrier de la page publication, en carte
   posée. Repliable : semaine en cours seule, ou mois entier.
   ============================================================= */
.mc{
  position:relative;   /* ancre de la petite modale des clients (mode admin) */
  background:var(--panel); border-radius:var(--r-panel);
  padding:14px;
}

/* --- la petite modale des clients concernés (calendrier admin) ---
   Posée au-dessus de la grille, en carte flottante. Elle vit dans .mc pour
   que le survol puisse glisser du jour vers ses liens sans la refermer. */
.mc__pop{
  position:absolute; z-index:40;
  min-width:170px; max-width:calc(100% - 12px);
  background:var(--panel); border-radius:14px;
  outline:1px solid var(--line);
  box-shadow:0 18px 44px -14px #00000055;
  padding:6px;
}
.mc__pop[hidden]{ display:none; }
.mc__pop-h{
  font-size:11px; font-weight:800; letter-spacing:.3px; text-transform:capitalize;
  color:var(--ink-2); padding:5px 7px 7px;
}
.mc__pop a{
  display:flex; align-items:center; gap:9px;
  padding:6px 7px; border-radius:9px;
  text-decoration:none; color:inherit;
}
.mc__pop a:hover{ background:var(--surface); }
.mc__pop-av{
  width:26px; height:26px; flex:none; border-radius:50%; object-fit:cover;
  background:var(--surface);
}
.mc__pop-nom{
  flex:1; min-width:0; font-size:13px; font-weight:700;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.mc__pop-tag{ flex:none; }


.mc__head{
  display:flex; align-items:center; justify-content:space-between;
  margin-bottom:10px; padding:0 2px;
}
/* Replié, le calendrier ne montre qu'une semaine : le mois et ses flèches
   n'ont plus de sens — on ne navigue pas dans un mois qu'on ne voit pas. */
.mc:not(.is-open) .mc__head{ display:none; }
.mc__title{ font-size:14px; font-weight:800; text-transform:capitalize; }
.mc__nav{ display:flex; gap:4px; }
.mc__btn{
  width:28px; height:28px; border:none; border-radius:8px;
  background:var(--surface); color:var(--ink); cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  transition:background .12s;
}
.mc__btn:hover{ background:var(--surface-2); }
.mc__dows{ display:grid; grid-template-columns:repeat(7,1fr); margin-bottom:4px; }
.mc__dows span{
  text-align:center; font-size:10px; font-weight:700; letter-spacing:.3px;
  color:var(--ink-2); padding:3px 0;
}
.mc__dows span.we{ color:var(--red); }
/* Fenêtre du volet : c'est elle qu'on ouvre et ferme. La grille en
   dessous dessine toujours le mois entier et coulisse dessous. */
.mc__vue{ overflow:hidden; }
/* .is-pret : posé après la première mesure. Avant, aucune transition —
   le volet doit apparaître à sa hauteur, pas s'y rendre.
   La grille n'anime QUE sa translation : sa hauteur, elle, est la mesure
   de référence du volet. La faire transiter la rendait mouvante pendant
   qu'on la mesurait, et le volet se figeait sur une valeur de passage. */
.mc.is-pret .mc__vue{ transition:height .28s cubic-bezier(.4,0,.2,1); }
.mc.is-pret .mc__grid{ transition:transform .28s cubic-bezier(.4,0,.2,1); }
/* pendant le glissement, le volet colle au doigt : aucune animation */
.mc.is-drag .mc__vue, .mc.is-drag .mc__grid{ transition:none; }
.mc__grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:2px; }
.mc__d{
  position:relative; aspect-ratio:1/1;
  border:none; background:none; border-radius:9px;
  font-family:'Manrope',sans-serif;
  font-size:13px; font-weight:600; color:var(--ink); cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  transition:background .12s;
}
.mc__d:hover:not(.is-sel){ background:var(--surface); }
.mc__d.is-out{ color:var(--ink-3); }
.mc__d.is-we{ color:var(--red); }
.mc__d.is-today{ box-shadow:inset 0 0 0 1.5px var(--ink); }
.mc__d.is-sel{ background:var(--solid-bg); color:var(--solid-ink); box-shadow:none; }
/* Une publication ce jour-là. Le point hérite de la couleur du texte :
   sur un jour sélectionné (fond encre) il passe en blanc tout seul. */
.mc__d[data-post]::after{
  content:''; position:absolute; bottom:4px;
  width:4px; height:4px; border-radius:50%;
  background:currentColor;
}
.mc__d.is-out[data-post]::after{ opacity:.45; }

/* Support du mode admin : la poignée sort de la carte et se pose juste en
   dessous, détachée. La carte garde son fond et son bord ; le support, lui,
   ne fait qu'empiler la carte puis la poignée. */
.mc-host{ display:flex; flex-direction:column; }
.mc-host > .mc__foot{ margin-top:8px; }

/* Poignée du volet. touch-action:none : sans ça, iOS fait défiler la page
   au lieu de laisser le doigt tirer le volet.
   Fond TOUJOURS transparent : hors de la carte, un survol qui remplissait
   toute la largeur dessinait une longue bande. On ne laisse que le petit
   trait — c'est lui, et lui seul, qui réagit au survol. */
.mc__foot{
  display:flex; align-items:center; justify-content:center;
  width:100%; margin-top:6px; padding:9px 7px 5px;
  border:none; border-radius:var(--r-btn);
  background:none; cursor:ns-resize;
  touch-action:none; -webkit-user-select:none; user-select:none;
}
.mc__grip{
  display:block; width:34px; height:4px; border-radius:2px;
  background:var(--edge); transition:background .12s;
}
.mc__foot:hover .mc__grip{ background:var(--ink-3); }

/* --- tiroir (étroit uniquement) --- */
/* =============================================================
   Modale — celle de l'app, pas celle du navigateur

   alert() et confirm() affichent « youkio-app.netlify.app indique », ne
   suivent ni le thème ni la police, et bloquent le fil d'exécution. Sur un
   écran qu'on a peaufiné, elles annoncent qu'on a laissé un bout de brut.

   Elle porte l'ombre ET la double bordure — le seul élément de l'app dans
   ce cas. Une modale flotte vraiment (d'où l'ombre), mais elle est aussi la
   chose qu'on regarde quand tout le reste est éteint : le trait la découpe
   du voile, qui sinon la laisse fondre dans le noir.
   ============================================================= */
.modale{
  position:fixed; inset:0; z-index:200;
  display:flex; align-items:center; justify-content:center;
  padding:20px;
  background:#00000059;
  animation:modale-fond .12s ease-out;
}
.modale[hidden]{ display:none; }
@keyframes modale-fond{ from{ opacity:0 } }

.modale__boite{
  width:100%; max-width:400px;
  background:var(--panel); color:var(--ink);
  border-radius:var(--r-panel);
  box-shadow:var(--lift);
  outline:var(--edge-w) solid var(--edge);
  outline-offset:var(--edge-gap);
  /* L'outline déborde de 6px (2 de trait + 4 d'écart) : sans cette marge,
     il toucherait le bord de l'écran sur un téléphone. */
  margin:6px;
  padding:22px;
  font-family:'Manrope',sans-serif;
  animation:modale-monte .16s cubic-bezier(.2,.8,.3,1);
}
/* Elle monte de peu : assez pour qu'on la voie arriver, pas assez pour
   qu'on l'attende. */
@keyframes modale-monte{ from{ opacity:0; transform:translateY(8px) scale(.98) } }
@media (prefers-reduced-motion:reduce){
  .modale, .modale__boite{ animation:none; }
}

.modale__mot{
  margin:0; font-size:15px; font-weight:600; line-height:1.5;
  white-space:pre-line;        /* les messages portent leurs propres retours */
}
.modale__champ{
  width:100%; margin-top:14px;
  border:none; outline:none;
  background:var(--surface); border-radius:var(--r-field);
  padding:11px 12px;
  font-family:'Manrope',sans-serif;
  /* 16px : en dessous, iOS zoome à la prise de focus */
  font-size:16px; font-weight:500; color:var(--ink);
}
.modale__champ:focus{ box-shadow:inset 0 0 0 2px var(--surface-2); }

.modale__pied{
  display:flex; justify-content:flex-end; gap:8px; margin-top:20px;
}
/* Plusieurs actions nommées : elles s'empilent et prennent toute la largeur.
   Côte à côte, « Lecture seule » et « Avec remarques » se disputeraient la
   place et finiraient tronqués. « Annuler » reste en bas, à sa place de
   sortie — d'où l'ordre inversé, le HTML le pose en premier. */
.modale__pied--liste{
  flex-direction:column-reverse; align-items:stretch; gap:8px;
}
.modale__pied--liste .u-btn{ width:100%; }
/* Le geste qui détruit ne prend pas la couleur du geste qui valide. */
.modale__boite[data-ton="danger"] .u-btn--solid{
  background:var(--red); color:#fff;
}

.scrim{ position:fixed; inset:0; z-index:90; background:#00000059; }
.scrim[hidden]{ display:none; }
/* Info-bulle de la rangée d'icônes : UN SEUL élément partagé, posé sur <body>
   et positionné en JS au survol (nav.js). Pas de ::after par lien — .side a
   overflow-y:auto, et poser overflow-y sans le même overflow-x FORCE le
   navigateur à traiter aussi overflow-x comme non-visible (règle du spec
   CSS Overflow) : toute bulle absolue POSÉE DANS .side, débordant à droite de
   la colonne de 68px, se faisait donc silencieusement rogner. */
#navTip{
  position:fixed; z-index:60;
  background:var(--solid-ink); color:var(--solid-bg);
  font-family:'Manrope',sans-serif; font-size:12.5px; font-weight:700;
  white-space:nowrap; padding:6px 10px; border-radius:8px;
  opacity:0; pointer-events:none;
  transform:translateY(-50%) translateX(-4px);
  transition:opacity .12s ease, transform .12s ease;
}
#navTip.on{ opacity:1; transform:translateY(-50%) translateX(0); transition-delay:.15s; }

.drawer{
  position:fixed; z-index:100; top:0; right:0; bottom:0;
  width:min(280px, 82vw);
  background:var(--panel);
  padding:16px 12px;
  box-shadow:var(--lift);
}
.drawer[hidden]{ display:none; }
.drawer__who{
  display:flex; align-items:center; gap:10px;
  padding:8px 8px 16px; margin-bottom:8px;
  border-bottom:1px solid var(--line);
}
.drawer__av{
  width:38px; height:38px; flex:none; border-radius:50%; object-fit:cover;
  background:var(--surface);
}
.dw__nom{ display:block; font-size:15px; font-weight:700; }
.dw__maison{ display:block; font-size:13px; font-weight:500; color:var(--ink-2); }
.drawer a{
  display:flex; align-items:center; gap:12px;
  padding:11px 10px; border-radius:var(--r-btn);
  text-decoration:none; color:var(--ink);
  font-size:14px; font-weight:700;
}
.drawer a:hover{ background:var(--surface); }
.drawer a[aria-current="page"]{ background:var(--surface); }

/* au-delà du seuil, le tiroir n'existe plus : la sidebar fait le travail.
   Sans ça, un tiroir laissé ouvert resterait affiché en redimensionnant. */
@media (min-width:860px){
  .drawer, .scrim{ display:none !important; }
}

@media (prefers-reduced-motion:reduce){
  *{ transition:none !important; animation:none !important; }
}


/* --- Logo de marque (image) — noir en thème clair, blanchi en thème sombre --- */
/* En clair : logo en gris foncé (pas noir pur) via filtre — brightness(0)
   le rend noir, invert(.22) le remonte à ~#383838. Le mode sombre l'écrase
   plus bas avec invert(1) (blanc). */
/* Logo Cohook — DEUX fichiers dédiés (mot sombre en clair, mot blanc en
   sombre), tous deux à fond transparent. On échange l'image AFFICHÉE via la
   propriété `content` (le src reste en repli) plutôt qu'un filtre : le filtre
   aplatissait le dégradé de l'icône, ici chaque version garde ses couleurs. */
.brand-logo{ height:32px; width:auto; display:block; content:url("/logo-texte-clair.png"); }
.geste__marque .brand-logo{ height:30px; }
:root[data-theme="sombre"] .brand-logo{ content:url("/logo-texte-sombre.png"); }
@media (prefers-color-scheme:dark){
  :root:not([data-theme="clair"]):not([data-theme="sombre"]) .brand-logo{ content:url("/logo-texte-sombre.png"); }
}

/* =============================================================
   Composeur d'idée — chrome PARTAGÉ (promu depuis idees.html pour que le
   composer compact du dashboard, en mode carte, s'en serve aussi).
   Duplication ASSUMÉE avec le <style> local de idees.html (identique,
   jamais divergente) : idées garde sa copie pour l'instant plutôt que de
   risquer une régression sur cette page en la faisant pointer ici. Un futur
   ménage peut supprimer la copie locale une fois vérifié sans risque.
   ============================================================= */
:root{
  --cmt-bg:#fff;
  --cmt-txt:#1a1a2e;
  --cmt-txt-2:#8a8a92;
  --cmt-surface:#f2f2f5;
  --cmt-surface-2:#e6e6ea;
  --cmt-accent:#1a1a2e;
  --cmt-line:#00000014;
  --cmt-rim:0,0,0;
  /* Clair : contour très clair (.07, calé sur le composer de la landing —
     même recette, mêmes valeurs) — le noir à pleine opacité tranchait trop
     sur un fond blanc. */
  --cmt-rim-a:.07;
  /* Placeholder clair, lui aussi calé sur la landing : plus clair que
     --cmt-txt-2 (réservé aux icônes), pour un label plus discret. */
  --cmt-ph:#b4b4bc;
}
:root[data-theme="sombre"]{
  --cmt-bg:#212121;
  --cmt-txt:#ececec;
  --cmt-txt-2:#a0a0a5;
  --cmt-surface:#2f2f2f;
  --cmt-surface-2:#3d3d3d;
  --cmt-accent:#ececec;
  --cmt-line:#ffffff14;
  --cmt-rim:255,255,255;
  --cmt-rim-a:.22;
  --cmt-ph:var(--cmt-txt-2);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="clair"]):not([data-theme="sombre"]){
    --cmt-bg:#212121;
    --cmt-txt:#ececec;
    --cmt-txt-2:#a0a0a5;
    --cmt-surface:#2f2f2f;
    --cmt-surface-2:#3d3d3d;
    --cmt-accent:#ececec;
    --cmt-line:#ffffff14;
    --cmt-rim:255,255,255;
    --cmt-rim-a:.22;
    --cmt-ph:var(--cmt-txt-2);
  }
}
.box{
  position:relative;
  background:var(--cmt-bg);
  border-radius:24px;
  padding:6px;
  margin-bottom:32px;
  font-family:'Manrope',sans-serif;
}
.box::before{
  content:''; position:absolute; inset:0; border-radius:inherit; padding:1px;
  background:conic-gradient(
    rgba(var(--cmt-rim),var(--cmt-rim-a)) 0deg,
    rgba(var(--cmt-rim),var(--cmt-rim-a)) 82deg, rgba(var(--cmt-rim),0) 90deg, rgba(var(--cmt-rim),0) 100deg, rgba(var(--cmt-rim),var(--cmt-rim-a)) 108deg,
    rgba(var(--cmt-rim),var(--cmt-rim-a)) 262deg, rgba(var(--cmt-rim),0) 270deg, rgba(var(--cmt-rim),0) 280deg, rgba(var(--cmt-rim),var(--cmt-rim-a)) 288deg,
    rgba(var(--cmt-rim),var(--cmt-rim-a)) 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude;
  pointer-events:none;
}
.box__content{ position:relative; z-index:1; }
.box__ligne{ display:flex; align-items:center; gap:6px; }
.box__plus{
  flex:none; width:36px; height:36px; padding:0;
  border:none; border-radius:50%; background:none; cursor:pointer;
  color:var(--cmt-txt-2);
  display:flex; align-items:center; justify-content:center;
  transition:background .12s, color .12s, transform .15s;
}
.box__plus svg{ width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; }
.box__plus:hover{ background:var(--cmt-surface); color:var(--cmt-txt); }
.box__plus.on{ color:var(--cmt-txt); transform:rotate(45deg); }
.box .u-field{
  flex:1; min-width:0;
  background:transparent; min-height:36px; max-height:132px; overflow-y:auto;
  border-radius:0; padding:7px 2px;
  color:var(--cmt-txt); font-family:'Manrope',sans-serif; font-size:16px; line-height:1.45;
}
.box .u-field:focus{ box-shadow:none; }
.box .u-field:empty::before{ color:var(--cmt-ph); font-weight:300; }
.bar{ display:flex; flex-direction:column; gap:8px; margin-top:8px; }
.bar[hidden]{ display:none; }
.cmt-tools{ display:flex; gap:6px; }
.cmt-tools button{
  width:30px; height:30px; padding:0;
  border:none; background:none; border-radius:8px;
  cursor:pointer; color:var(--cmt-txt-2);
  display:flex; align-items:center; justify-content:center;
  transition:background .12s, color .12s;
}
.cmt-tools button:hover{ background:var(--cmt-surface); color:var(--cmt-txt); }
.cmt-tools svg{ width:19px; height:19px; fill:none; stroke:currentColor;
                stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.send{
  flex:none; width:40px; height:40px; border:none; border-radius:50%;
  background:var(--cmt-surface); color:var(--cmt-txt-2); cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  transition:background .15s, color .15s, opacity .15s, transform .1s;
}
.send:disabled{ opacity:.35; cursor:default; }
.send:not(:disabled):active{ transform:scale(.94); }
.send svg{ width:20px; height:20px; fill:none; stroke:currentColor;
           stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
.cmt-round{
  flex:none; width:40px; height:40px; border:none; border-radius:50%;
  background:var(--cmt-surface); color:var(--cmt-txt-2); cursor:pointer;
  display:flex; align-items:center; justify-content:center;
  transition:background .15s, color .15s, transform .1s;
}
.cmt-round:hover{ background:var(--cmt-surface-2); color:var(--cmt-txt); }
.cmt-round:active{ transform:scale(.94); }
.cmt-round svg{ width:19px; height:19px; fill:none; stroke:currentColor;
                stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.cmt-attach{ display:none; gap:8px; flex-wrap:wrap; margin-bottom:12px; }
.cmt-attach.on{ display:flex; }
.cmt-attach-item{ position:relative; display:inline-flex; cursor:pointer; }
.cmt-attach-item[draggable="true"]{ cursor:grab; }
.cmt-attach-item img, .cmt-attach-item video{
  width:44px; height:44px; corner-shape:squircle; border-radius:12px;
  display:block; border:none; object-fit:cover;
  outline:2px solid transparent; outline-offset:2px; transition:outline-color .15s;
}
.cmt-attach-item.actif img, .cmt-attach-item.actif video{ outline-color:var(--solid-bg); }
.cmt-attach-item button{
  position:absolute; top:-6px; right:-6px;
  width:18px; height:18px; padding:0;
  border:2px solid var(--panel); border-radius:50%;
  background:var(--solid-bg); color:var(--solid-ink);
  font-size:11px; line-height:1; cursor:pointer;
}
.cmt-opts{ display:flex; flex-direction:column; gap:2px; }
.cmt-opt{ display:flex; align-items:center; gap:8px; padding:3px 2px; }
.cmt-opt__ico{
  flex:none; width:26px; height:20px; display:flex; align-items:center; justify-content:center;
  color:var(--cmt-txt-2);
}
.cmt-opt__ico svg{ width:19px; height:19px; fill:none; stroke:currentColor;
                   stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.cmt-opt__lab{ flex:1; min-width:0; font-size:13px; font-weight:600; color:var(--cmt-txt); }
.cmt-opt .sw{
  flex:none; width:38px; height:22px; padding:0; border:none; border-radius:999px;
  background:var(--cmt-surface-2); cursor:pointer; position:relative;
  transition:background .15s;
  /* Course du pouce pour CE gabarit : 38 (piste) − 3 (marge gauche)
     − 3 (marge droite) − 16 (pouce) = 16px. L'extrait officiel de
     transitions.dev est calé sur son propre gabarit (14.66px) ; on le
     surcharge ici plutôt que dans transitions.css, qui doit rester le
     code du site au caractère près pour rester resynchronisable. */
  --toggle-travel:16px;
}
.cmt-opt .sw span{
  position:absolute; top:3px; left:3px; width:16px; height:16px; border-radius:50%;
  background:#fff; box-shadow:0 1px 2px #0003;
  /* Ni transition ni transform ici : le déplacement du pouce appartient
     désormais aux keyframes officielles (.t-toggle-thumb, propriété
     `translate`). Les cumuler doublerait la course. */
}
.cmt-opt .sw[aria-checked="true"]{ background:#0103fd; }
.cmt-opt:has(.sw[aria-checked="true"]) .cmt-opt__ico{ color:#0103fd; }
:root[data-theme="sombre"] .cmt-opt:has(.sw[aria-checked="true"]) .cmt-opt__ico{ color:#5b6bff; }
@media (prefers-color-scheme: dark){
  :root:not([data-theme="clair"]) .cmt-opt:has(.sw[aria-checked="true"]) .cmt-opt__ico{ color:#5b6bff; }
}
.envoi-champ{ margin-top:14px; }
.envoi-champ label{ display:block; font-size:12px; font-weight:600; color:var(--ink-2); margin-bottom:6px; }
.envoi-champ input{
  width:100%; border:none; outline:none; box-sizing:border-box;
  background:var(--surface); border-radius:var(--r-field);
  padding:11px 12px; font-family:'Manrope',sans-serif; font-size:14px; color:var(--ink);
}
.envoi-champ input:focus{ box-shadow:inset 0 0 0 2px var(--surface-2); }
