/* ==========================================================================
   Accueil — composants : cartes, liens, plein écran, modales, menu, toasts,
   palette de commandes, corbeille, aide
   ========================================================================== */

/* ---------- Carte-section -------------------------------------------- */

.card { grid-column: span var(--span, 1); min-width: 0; display: flex; flex-direction: column; gap: 12px;
  padding: 16px 17px 14px; border-radius: var(--r-2xl);
  background: var(--glass-card); border: 1px solid var(--glass-card-border);
  backdrop-filter: blur(24px) saturate(1.35); -webkit-backdrop-filter: blur(24px) saturate(1.35);
  box-shadow: var(--sheen), var(--sh-card); }
.card--accent { background: rgba(var(--accent-rgb), .14); border-color: rgba(var(--accent-rgb), .28);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), var(--sh-card); }
/* Espaceur : il occupe ses colonnes dans la grille mais ne se montre qu'en
   édition. Hors édition il ne peint rien et laisse passer les clics — sans
   ça il ferait un trou mort dans la page. */
.card--spacer { background: none; border-color: transparent; box-shadow: none;
  backdrop-filter: none; -webkit-backdrop-filter: none; padding: 12px 13px;
  pointer-events: none;
  /* Plancher seulement : la grille étire déjà l'élément à la hauteur de sa
     ligne, donc une section plus haute à côté l'emporte d'elle-même. */
  min-height: calc(var(--spacer-h, 96) * 1px); }
.is-editing .card--spacer { pointer-events: auto; border: 1px dashed rgba(255, 255, 255, .2);
  background: rgba(255, 255, 255, .022); }
/* L'en-tête d'édition sort du flux : sinon sa propre hauteur (≈ 62 px avec les
   poignées) deviendrait le vrai plancher et les premiers crans du barème
   seraient inatteignables. */
.card--spacer { position: relative; }
.is-editing .card--spacer > .card__head { position: absolute; left: 13px; right: 13px; top: 12px; }
.is-editing .card--spacer .card__title { color: var(--text-4); font-weight: 400; }
.is-editing .card--spacer .card__icon { color: rgba(255, 255, 255, .3); }
.is-editing .card--spacer.is-selected { border-style: solid; border-color: rgba(var(--accent-rgb), .5);
  background: rgba(var(--accent-rgb), .07); }

.card.sortable-ghost { opacity: .35; outline: 1px dashed rgba(var(--accent-rgb), .5); outline-offset: 3px; }
.card.sortable-drag { opacity: .9; }

.card__head { display: flex; align-items: center; gap: 10px; min-height: 26px; min-width: 0; }
.card__dot { width: 7px; height: 7px; flex: none; border-radius: var(--r-pill); background: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .2); }
.card__title { margin: 0; font: 500 13.5px/1 var(--sans); color: var(--text-title);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card__spacer { flex: 1; }
.card__sep { width: 1px; height: 14px; background: rgba(255, 255, 255, .14); margin: 0 4px; flex: none; }

/* Onglets internes discrets */
.tabs { display: flex; align-items: center; gap: 3px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.tabs button { height: 24px; padding: 0 10px; border-radius: var(--r-xs); font: 400 11.5px var(--sans);
  color: var(--text-4); border: 1px solid transparent; white-space: nowrap; }
.tabs button[aria-selected="true"] { background: rgba(var(--accent-rgb), .14); border-color: rgba(var(--accent-rgb), .26);
  color: var(--accent-soft); font-weight: 500; }
.tabs .tabs__add { width: 24px; padding: 0; display: grid; place-items: center; font-size: 11px; color: var(--text-5); }
.tabs .tabs__add:hover { color: var(--accent-soft); }
/* ---- Carte étroite ---------------------------------------------------
   Une section peut ne mesurer qu'une colonne sur douze, ~110 px. Son en-tête
   n'y tient plus du tout : ni titre, ni icône. Ne reste que la barre d'onglets
   réduite à sa plus simple expression — deux flèches et des pastilles — ou,
   s'il n'y a pas d'onglets, rien.

   Requête de CONTENEUR et non media query : la décision suit la largeur réelle
   de la carte, quelle que soit celle de la fenêtre ou le nombre de colonnes.
   Rien à mesurer en JS, donc aucun aller-retour de rendu et aucune bascule qui
   se répondrait à elle-même. */
.card { container-type: inline-size; container-name: card; }

/* ---- Barre d'onglets : apparence des commandes ------------------------
   Flèches et pastilles sont posées à chaque rendu et masquées par défaut.
   Leur apparence est définie ICI, une seule fois ; les deux blocs qui suivent
   ne font que les révéler, chacun pour sa raison. */
/* `.tabs button` impose déjà `padding: 0 10px` et une bordure : il faut au
   moins autant de spécificité pour les reprendre, sinon le pictogramme est
   chassé hors de son bouton de 18 px et paraît collé à droite. */
.tabs button.tabs__nav { display: none; place-items: center; width: 15px; height: 20px;
  padding: 0; border: 0; flex: none; color: var(--text-5); border-radius: var(--r-pill); }
.tabs button.tabs__nav:hover { color: var(--accent-soft); background: rgba(255, 255, 255, .09); }
.tabs button.tabs__nav .ico { width: 11px; height: 11px; }
.tabs button.tabs__nav--prev .ico { transform: rotate(90deg); }
.tabs button.tabs__nav--next .ico { transform: rotate(-90deg); }
.tabs__dots { display: none; align-items: center; justify-content: center; gap: 2px;
  min-width: 0; overflow: hidden; }
/* Taille FIXE, et c'est délibéré : laisser les pastilles se comprimer les
   rendait illisibles bien avant qu'elles ne débordent. À taille fixe, soit
   elles tiennent, soit la mesure le voit et bascule sur le rang chiffré. */
.tabs__dot { width: 4px; height: 4px; flex: none;
  border-radius: var(--r-pill); background: rgba(255, 255, 255, .26); }
.tabs__dot.is-active { background: #fff; }
/* Rang chiffré : le repli des pastilles quand elles sont trop nombreuses. */
.tabs__count { display: none; font: 500 9.5px/1 var(--sans); color: var(--text-5);
  white-space: nowrap; letter-spacing: -.2px; }
.tabs__count b { font-weight: 700; color: #fff; }

/* ---- Révélateur 1 : les onglets ne tiennent plus en largeur -----------
   Seul l'actif reste, encadré des deux flèches. La classe est posée par mesure
   (ui-render.ajusterOnglets) car le débordement dépend aussi du nombre
   d'onglets et de la longueur de leurs noms — ce qu'une requête de conteneur
   ne sait pas exprimer. */
.tabs.is-compact { overflow: visible; }
.tabs.is-compact button.tabs__nav { display: grid; }
.tabs.is-compact button[role="tab"] { display: none; }
.tabs.is-compact button[role="tab"][aria-selected="true"] { display: block; min-width: 0;
  padding: 0 6px; overflow: hidden; text-overflow: ellipsis; }

/* ---- Révélateur 2 : la carte est trop étroite pour le moindre libellé --
   110 px de boîte de contenu : une carte d'une colonne en fait 63, une de deux
   colonnes en fait 174. Le seuil tombe donc franchement entre les deux plutôt
   qu'au bord de l'une d'elles.

   Ce bloc vient APRÈS le précédent à dessein : la règle sur l'onglet actif y
   est reprise à spécificité égale pour l'annuler. Une carte étroite n'affiche
   aucun libellé, même compactée. */
@container card (max-width: 110px) {
  .card__title, .card__icon, .card__dot { display: none; }
  /* Le bouton « Ajouter un lien » et celui « Ajouter un onglet » disparaissent
     aussi : à cette largeur l'en-tête est un indicateur, pas une barre
     d'outils, et 28 px de bouton feraient déborder les flèches. Les deux
     gestes restent dans le menu contextuel de la section. Les masquer règle
     du même coup un problème d'empilement — la prise étant en position
     absolue, elle recouvrirait un bouton resté dans le flux. */
  .card__sep, .card__spacer, .tabs .tabs__add, .card__head > .iconbtn { display: none; }
  .card__head { position: relative; }
  /* La prise passe SOUS toute la barre. Réduite à un reliquat de flex entre
     deux commandes, elle ne serait plus attrapable et la carte deviendrait
     indéplaçable — alors qu'elle n'a plus ni titre ni icône à saisir. */
  .card__grab { position: absolute; inset: 0; }
  /* La barre devient un petit boîtier qui occupe toute la largeur de l'en-tête
     — plutôt qu'un amas de commandes flottant au milieu du vide — avec les
     flèches aux deux bouts et les pastilles centrées entre elles. Réservé aux
     barres `--nav` : un boîtier vide serait pire que pas de boîtier. */
  .tabs { position: relative; z-index: 1; overflow: hidden; gap: 0; }
  .tabs--nav { flex: 1; height: 22px; padding: 0; border-radius: var(--r-pill);
    border: 1px solid rgba(255, 255, 255, .13); background: rgba(255, 255, 255, .05); }
  .tabs button.tabs__nav { display: grid; }
  .tabs .tabs__dots { display: flex; flex: 1; }
  .tabs.is-tally .tabs__dots { display: none; }
  .tabs.is-tally .tabs__count { display: block; flex: 1; text-align: center; }
  .tabs button[role="tab"],
  .tabs.is-compact button[role="tab"][aria-selected="true"] { display: none; }
}

/* Zone de prise de la carte (titre + pastille) : poignée hors édition. */
/* Étirée sur la hauteur de l'en-tête : c'est la seule prise de la carte, elle
   doit s'attraper sans viser la ligne de texte. Aucun effet visuel. */
.card__grab { display: flex; align-items: center; gap: 10px; min-width: 0; align-self: stretch; }
/* La carte se tire par son en-tête dans les deux modes. */
.card__grab { cursor: grab; }
/* Barre d'onglets « fantôme » : présente pour recevoir un onglet, révélée
   seulement pendant qu'on en glisse un. */
.tabs--ghost { display: none; }
body.is-dragging-tab .tabs--ghost { display: flex; }
body.is-dragging-tab .tabs { outline: 1px dashed rgba(var(--accent-rgb), .35); outline-offset: 3px; border-radius: var(--r-xs); }
/* Onglet visé pendant un glisser : le lien relâché ira dedans. */
.tabs button.is-drop-target { background: rgba(var(--accent-rgb), .3);
  border-color: rgba(var(--accent-rgb), .65); color: var(--text-strong); }

/* Poignées d'édition */
/* Cibles de clic généreuses : ce petit groupe est très sollicité en édition. */
.handles { display: flex; gap: 2px; padding: 4px; border-radius: var(--r-pill); flex: none;
  background: rgba(10, 12, 17, .55); border: 1px solid var(--glass-field-border); color: rgba(255, 255, 255, .62); }
.handles button { width: 27px; height: 27px; display: grid; place-items: center; font-size: 15px; border-radius: var(--r-pill); }
.handles button:hover { color: var(--text-strong); background: rgba(255, 255, 255, .12); }
.handles button.is-danger:hover { color: var(--danger); background: rgba(248, 113, 113, .16); }
.handles .ico { stroke-width: 1.8; }

/* ---------- Les 6 modes d'affichage des liens -------------------------
   (La numérotation des sous-titres saute le 3 : trace du mode « columns »
   retiré du catalogue et migré vers « detailed ».)
   Le mode, la taille, la densité et l'état des libellés sont pilotés par
   des attributs et des variables CSS posés sur .links par ui-render.js :
   data-mode, data-labels et --cell --iconbox --glyph --font --fav --tile
   --thumb --listcol --dgap --pad. Les valeurs sont des nombres nus :
   l'unité est ajoutée ici (calc(var(--x) * 1px)), ce qui permet les
   dérivées. */

.links { display: flex; flex-direction: column; }
.link { position: relative; min-width: 0; }
.link.sortable-ghost { opacity: .35; outline: 1px dashed rgba(var(--accent-rgb), .5); outline-offset: 1px; }

/* Libellés : affichés / au survol / jamais. S'applique au libellé sous
   l'icône ET au domaine des modes liste et tableau. */
.links[data-labels="hover"] [data-label],
.links[data-labels="hover"] [data-meta] { opacity: 0; transition: opacity .12s ease-out; }
.links[data-labels="hover"] .link:hover [data-label],
.links[data-labels="hover"] .link:hover [data-meta] { opacity: 1; }
.links[data-labels="never"] [data-label],
.links[data-labels="never"] [data-meta] { display: none; }

/* Outils par lien (mode édition, au survol) */
.link__tools { position: absolute; top: 50%; right: 4px; transform: translateY(-50%); display: none; gap: 1px;
  padding: 2px; border-radius: var(--r-pill); background: rgba(10, 12, 17, .72); border: 1px solid var(--glass-field-border); z-index: 2; }
.link__tools button { width: 20px; height: 20px; display: grid; place-items: center; font-size: 11px; border-radius: var(--r-pill); color: rgba(255, 255, 255, .6); }
.link__tools button:hover { color: var(--text-strong); }
.link__tools button.is-danger:hover { color: var(--danger); }
.is-editing .link:hover .link__tools { display: flex; }
.links[data-mode="icons"] .link__tools,
.links[data-mode="tiles"] .link__tools,
.links[data-mode="showcase"] .link__tools { top: 4px; right: 4px; transform: none; }

/* Les LIBELLÉS ne suivent pas l'échelle. « Taille » règle la dimension des
   vignettes, des tuiles et des colonnes — pas la lisibilité du texte : d'un
   réglage à l'autre, d'une section à l'autre, un nom de lien se lit toujours
   dans le même corps. Sans cette constante, deux sections voisines réglées
   différemment donnaient deux typographies, ce qui se voyait bien plus que la
   différence de taille voulue.
   Les valeurs sont celles du cran « Moyen », qui étaient déjà le point de
   référence du barème. */
.link__label { font: 400 var(--label-size)/1.2 var(--sans); color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.link__meta { font: 400 var(--label-mini)/1.2 var(--mono); color: var(--text-5);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.link__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.puce { width: 5px; height: 5px; flex: none; border-radius: var(--r-pill); background: rgba(var(--accent-rgb), .75); }

/* Modes en liste : le contenu se répartit tout seul en colonnes selon la
   largeur de la section. La taille fixe la largeur mini d'une colonne, le
   navigateur en met autant qu'il en tient.

   Une GRILLE, et non le multi-colonnes CSS. Ce dernier était le choix évident —
   c'est sa raison d'être — mais il est incompatible avec une hauteur imposée :
   dans une boîte de hauteur fixe, le trop-plein ne descend pas, il part dans des
   colonnes supplémentaires HORS CHAMP que rien ne rattrape. La liste mesure
   alors une hauteur de contenu égale à sa boîte, se croit complète, ne déclenche
   aucune barre de défilement, et cache le reste : relevé au rendu, 2 liens
   visibles sur 14, sans le moindre signe.

   La grille remplit ligne par ligne au lieu de colonne par colonne — l'ordre de
   lecture change — mais elle déborde vers le BAS, ce qui la rend compatible avec
   le défilement vertical, la cadence par lignes et le pas de la molette. Toute
   la machinerie du mur d'icônes s'y applique telle quelle.

   `align-content: start` pour la même raison qu'ailleurs : sans lui les lignes
   s'étirent pour remplir la carte et la zone cliquable enfle avec elles.

   Le `min(…, 100%)` autour de la largeur mini n'est pas une précaution en
   l'air : `minmax(200px, 1fr)` IMPOSE 200 px, même dans une carte qui n'en fait
   que 55. La piste déborde alors par la droite, se fait rogner, et le contenu
   centré dedans paraît décalé — voir le mur d'icônes juste après. */
.links[data-mode="detailed"],
.links[data-mode="compact"],
.links[data-mode="table"] {
  display: grid;
  align-content: start;
  grid-template-columns: repeat(auto-fill, minmax(min(calc(var(--listcol) * 1px), 100%), 1fr));
  gap: calc(max(0px, var(--pad) * 1px - 3px)) calc(var(--dgap) * 1px + 14px); }
/* Les marges d'antan sont devenues des gouttières de grille. */
.links[data-mode="detailed"] .link,
.links[data-mode="compact"] .link,
.links[data-mode="table"] .link { margin: 0; min-width: 0; }
/* L'ajout et l'en-tête traversent toutes les colonnes. */
.links[data-mode="detailed"] .add,
.links[data-mode="compact"] .add,
.links[data-mode="table"] .add,
.links[data-mode="table"] .thead { grid-column: 1 / -1; }
/* Mais l'en-tête « Libellé / Domaine » ne peut désigner qu'UNE colonne : à
   cheval sur plusieurs, ses deux intitulés se répartissent sur la largeur
   entière et « Domaine » se retrouve au-dessus des libellés de la colonne
   voisine. Un en-tête qui désigne la mauvaise colonne vaut moins que pas
   d'en-tête du tout : dès que la liste se répartit, il s'efface. Chaque ligne
   porte de toute façon ses deux champs, alignés. */
.links[data-mode="table"].is-multi .thead { display: none; }

/* 1. Liste détaillée */
.links[data-mode="detailed"] .link { display: flex; align-items: center; gap: calc(var(--font) * .8px);
  padding: calc(var(--pad) * 1px) 6px; border-radius: var(--r-md); }
.links[data-mode="detailed"] .link:hover { background: var(--hover-link); }
.favicon { width: calc(var(--fav) * 1px); height: calc(var(--fav) * 1px); flex: none;
  border-radius: calc(var(--fav) * .3px); display: grid; place-items: center; overflow: hidden;
  background: rgba(255, 255, 255, .1); border: 1px solid var(--glass-field-border);
  font: 500 calc(var(--fav) * .4px) var(--mono); color: rgba(255, 255, 255, .7); }
.favicon img { width: 66%; height: 66%; object-fit: contain; }
/* Vignette réduite : sert de marqueur de ligne en compact et en tableau. */
.favicon--sm { width: calc(var(--fav) * .62px); height: calc(var(--fav) * .62px);
  border-radius: calc(var(--fav) * .2px); font-size: calc(var(--fav) * .3px); }
/* « Sans cadre » : la favicon seule, sans vignette ni bordure derrière. */
.links[data-favicons="bare"] .favicon { background: none; border-color: transparent; }
.links[data-favicons="bare"] .favicon img { width: 100%; height: 100%; }
.favicon .ico { font-size: calc(var(--fav) * .55px); color: var(--accent-soft); }


/* 2. Liste compacte */
.links[data-mode="compact"] .link { display: flex; align-items: center; gap: 9px;
  padding: calc(var(--pad) * 1px) 6px; border-radius: var(--r-sm); }
.links[data-mode="compact"] .link:hover { background: var(--hover-link); }
.links[data-mode="compact"] .link__label { color: var(--text-2); }

/* 4bis. Mur d'icônes — colonnes automatiques : la taille fixe la largeur d'une
   cellule et il en rentre autant que la carte peut en tenir.

   `min(…, 100%)` autour de cette largeur, et c'est ce qui sauve les cartes très
   étroites : `minmax(90px, 1fr)` impose 90 px même dans une carte de 55, si bien
   que la piste dépassait de 35 px à droite. Rognée par le bord, elle donnait des
   icônes visiblement décalées — centrées dans une piste dont on ne voyait que la
   moitié gauche. Mesuré : centre à 45 px pour une zone de 55.

   `align-content: start` n'est PAS un détail. Une grille répartit par défaut
   ses rangées sur toute la hauteur disponible (`normal`, qui vaut `stretch`
   pour des rangées automatiques) : dès que la carte est plus haute que le
   contenu de l'onglet ouvert — parce qu'un autre onglet en a davantage, ou
   parce qu'on l'a tirée plus grande — chaque rangée gonfle, et la zone
   cliquable d'une icône devient bien plus grande qu'elle. On préfère des
   icônes à leur taille et du vide en dessous. */
.links[data-mode="icons"] { display: grid; align-content: start; gap: calc(var(--dgap) * 1px);
  grid-template-columns: repeat(auto-fill, minmax(min(calc(var(--cell) * 1px), 100%), 1fr)); }
.links[data-mode="icons"] .link { display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: calc(var(--pad) * 1px) 3px; border-radius: var(--r-lg); }
.links[data-mode="icons"] .link:hover { background: var(--hover-link); }
.tile-ico { width: calc(var(--iconbox) * 1px); height: calc(var(--iconbox) * 1px); flex: none;
  border-radius: calc(var(--iconbox) * .31px); display: grid; place-items: center; overflow: hidden;
  font: 500 calc(var(--glyph) * .8px) var(--mono);
  background: rgba(var(--accent-rgb), .16); border: 1px solid rgba(var(--accent-rgb), .28); color: var(--accent-soft); }
.tile-ico .ico { font-size: calc(var(--glyph) * 1px); }
.tile-ico img { width: 62%; height: 62%; object-fit: contain; }
/* La légende d'une icône garde son propre corps — plus petit, en chasse fixe —
   mais fixe lui aussi. */
.links[data-mode="icons"] .link__label { font: 400 var(--label-mini)/1 var(--mono);
  color: var(--text-4); max-width: 100%; }

/* 5. Vitrine et vitrine côte à côte */
/* Même raison qu'au mur d'icônes : les tuiles gardent leur hauteur, le vide
   reste en bas. */
.links[data-mode="tiles"] { display: grid; align-content: start; gap: calc(var(--dgap) * 1px);
  grid-template-columns: repeat(auto-fill, minmax(min(calc(var(--tile) * 1px), 100%), 1fr)); }
.links[data-mode="showcase"] { display: flex; flex-direction: row; gap: calc(var(--dgap) * 1px); overflow-x: auto;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .28) transparent; }
.links[data-mode="showcase"] .link { flex: 1; min-width: calc(var(--tile) * .7px); }
.links[data-mode="tiles"] .link,
.links[data-mode="showcase"] .link { display: flex; flex-direction: column; align-items: stretch; gap: 9px;
  padding: 9px; border-radius: var(--r-xl); background: var(--glass-inner); border: 1px solid var(--glass-inner-border); }
.links[data-mode="tiles"] .link:hover,
.links[data-mode="showcase"] .link:hover { background: rgba(255, 255, 255, .11); border-color: rgba(var(--accent-rgb), .4); }
.thumb { height: calc(var(--thumb) * 1px); border-radius: var(--r-md); display: grid; place-items: center;
  background-color: rgba(0, 0, 0, .28);
  background-image: repeating-linear-gradient(135deg, rgba(255, 255, 255, .14) 0 1px, transparent 1px 8px); }
.links[data-mode="showcase"] .thumb { height: calc(var(--thumb) * 1px + 26px); }
.thumb img { width: 34%; height: 34%; min-width: 24px; min-height: 24px; object-fit: contain; }
.thumb .thumb__letter { font: 500 calc(var(--font) * 1.3px) var(--mono); color: rgba(255, 255, 255, .55); }
.thumb .ico { font-size: calc(var(--font) * 1.6px); color: var(--accent-soft); }

/* 6. Tableau */
.links[data-mode="table"] .thead,
.links[data-mode="table"] .link { display: grid; grid-template-columns: 1fr 1fr; align-items: center; gap: 10px; }
.links[data-mode="table"] .thead { padding: 0 6px 5px; margin-bottom: 4px; border-bottom: 1px solid rgba(255, 255, 255, .09);
  font: 400 9px var(--mono); color: rgba(255, 255, 255, .34); letter-spacing: .1em; text-transform: uppercase; }
.links[data-mode="table"] .link { padding: calc(var(--pad) * 1px) 6px; border-radius: var(--r-sm); }
.links[data-mode="table"] .link:hover { background: var(--hover-link); }
.links[data-mode="table"] .cell1 { display: flex; align-items: center; gap: 9px; min-width: 0; }

/* Bandes d'ajout de section. Les placeholders d'ajout de LIEN ont disparu du
   corps des cartes : ils y occupaient une cellule et redimensionnaient la
   section rien qu'en passant en édition. Le bouton vit dans l'en-tête. */
.add { border: 1px dashed rgba(255, 255, 255, .16); color: var(--text-4); border-radius: var(--r-md); background: none;
  display: flex; align-items: center; justify-content: center; gap: 6px; font: 400 11px var(--sans); cursor: pointer; }
.add:hover { border-color: rgba(var(--accent-rgb), .5); color: var(--accent-soft); }
.add--card { grid-column: span 1; min-height: 140px; flex-direction: column; gap: 9px; border-radius: var(--r-2xl);
  background: rgba(var(--accent-rgb), .05); border-color: rgba(255, 255, 255, .18); font-size: 11px; }
.add--card:hover { background: rgba(var(--accent-rgb), .1); border-color: var(--accent); }
.add .ico { font-size: 14px; stroke-width: 1.8; }
.add--card .ico { font-size: 20px; }

/* ---------- Plein écran ---------------------------------------------- */

/* Le plein écran ne se sélectionne pas. C'est une vue de PROJECTION : on y
   clique sur des commandes, on n'y attrape pas du texte, et un glissement de
   souris pendant qu'on parle laissait un pâté bleu sur l'écran de la salle. Les
   champs de saisie gardent bien sûr leur sélection — sans quoi on ne pourrait
   plus y corriger un mot. */
.fs, .fs * { user-select: none; -webkit-user-select: none; }
.fs { position: fixed; inset: 0; z-index: 40; display: grid; place-items: center; }
/* Les champs de saisie gardent la leur : sans quoi on ne pourrait plus y
   corriger un mot — le filtre de la vue agrandie, par exemple. */
.fs input, .fs textarea { user-select: text; -webkit-user-select: text; }
.fs__scrim { position: absolute; inset: 0; background: rgba(8, 9, 13, .62); }
.fs__close { position: absolute; top: 22px; right: 26px; display: flex; gap: 8px; z-index: 2; }
.fs__close .iconbtn { width: 36px; height: 36px; background: rgba(255, 255, 255, .08); border-color: rgba(255, 255, 255, .16); color: rgba(255, 255, 255, .7); }
/* Surtout PAS de `filter` ici : appliqué à un ancêtre de cartes qui
   utilisent `backdrop-filter`, il fait clignoter et disparaître des
   sections au gré des recompositions. Le voile suffit à détacher la
   surcouche du fond. */

/* Section agrandie */
.secfull { position: relative; width: min(1200px, calc(100vw - 80px)); max-height: calc(100vh - 60px);
  padding: 22px 24px 18px; border-radius: var(--r-4xl);
  background: var(--glass-panel); border: 1px solid rgba(255, 255, 255, .15);
  backdrop-filter: blur(32px) saturate(1.35); -webkit-backdrop-filter: blur(32px) saturate(1.35);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), var(--sh-full); display: flex; flex-direction: column; gap: 20px; }
.secfull__head { display: flex; align-items: center; gap: 12px; }
.secfull__title { margin: 0; font: 500 19px/1 var(--sans); color: var(--text-strong); }
.pill { padding: 4px 9px; border-radius: var(--r-pill); background: rgba(255, 255, 255, .08);
  border: 1px solid var(--glass-card-border); font: 400 10px var(--mono); color: var(--text-3); }
.field-pill { display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 12px; border-radius: var(--r-pill);
  background: var(--glass-card); border: 1px solid var(--glass-card-border); color: var(--text-4); font: 400 11.5px var(--sans); }
input.field-pill { color: var(--text); min-width: 140px; }
input.field-pill::placeholder { color: var(--text-4); }
button.field-pill { cursor: pointer; }
button.field-pill:hover { color: var(--text-strong); border-color: rgba(var(--accent-rgb), .4); }
.secfull__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 26px; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .28) transparent; }
.group__title { font: 400 9.5px/1 var(--mono); color: rgba(255, 255, 255, .36); letter-spacing: .12em; text-transform: uppercase; margin-bottom: 9px; }
.secfull__foot { display: flex; align-items: center; gap: 12px; padding-top: 6px; border-top: 1px solid rgba(255, 255, 255, .08);
  font: 400 10.5px/1 var(--mono); color: var(--text-6); }

/* ---------- Modales (dans <dialog>) ----------------------------------- */

.modal { position: relative; width: 400px; max-width: calc(100vw - 40px); padding: 20px; border-radius: var(--r-3xl);
  background: var(--glass-modal); border: 1px solid var(--glass-field-border);
  backdrop-filter: blur(30px) saturate(1.3); -webkit-backdrop-filter: blur(30px) saturate(1.3);
  box-shadow: var(--sheen), var(--sh-modal); display: flex; flex-direction: column; gap: 16px; }
.modal--wide { width: 452px; }
.modal--danger { border-color: rgba(248, 113, 113, .28); padding: 22px; gap: 15px; }
.modal__head { display: flex; align-items: center; gap: 11px; }
.modal__badge { width: 30px; height: 30px; border-radius: 10px; display: grid; place-items: center; font-size: 15px; flex: none;
  background: rgba(var(--accent-rgb), .18); border: 1px solid rgba(var(--accent-rgb), .32); color: var(--accent-soft); }
.modal__badge--neutral { background: rgba(255, 255, 255, .09); border-color: var(--glass-field-border); color: rgba(255, 255, 255, .75); }
.modal__badge--danger { width: 40px; height: 40px; border-radius: var(--r-lg); font-size: 19px;
  background: rgba(248, 113, 113, .16); border-color: rgba(248, 113, 113, .36); color: var(--danger); }
.modal__title { margin: 0; font: 500 14.5px/1.2 var(--sans); color: var(--text-title); }
.modal__title--lg { font-size: 16px; line-height: 1.3; }
.modal__body { margin: 0; font: 400 12.5px/1.5 var(--sans); color: rgba(255, 255, 255, .55); text-wrap: pretty; }
.modal__foot { display: flex; align-items: center; gap: 9px; }
.modal__foot .btn { flex: 1; height: 38px; border-radius: var(--r-md); }
.btn--outline { border: 1px solid rgba(255, 255, 255, .18); color: rgba(255, 255, 255, .78); font-weight: 400; font-size: 12.5px; }
.btn--outline:hover { background: rgba(255, 255, 255, .08); color: var(--text-strong); }
.btn--danger { background: rgba(248, 113, 113, .9); color: var(--danger-on); }
.btn--danger:hover { background: var(--danger); }
.btn--reset { color: var(--text-4); font-weight: 400; flex: none !important; padding: 0 10px; }
.btn--reset:hover { color: var(--danger-text); }

.field { display: flex; flex-direction: column; gap: 6px; }
.field__label { font: 400 9.5px/1 var(--mono); color: rgba(255, 255, 255, .42); letter-spacing: .1em; text-transform: uppercase; }
.field__input { height: 38px; padding: 0 12px; border-radius: var(--r-md); background: var(--glass-field);
  border: 1px solid var(--glass-field-border); color: var(--text); font: 400 13px var(--sans); width: 100%; }
.field__input:focus { outline: none; border-color: rgba(var(--accent-rgb), .45); box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .12); }
.field-row { display: flex; gap: 12px; }
.field-row .field { flex: 1; min-width: 0; }
.field__note { font: 400 10.5px/1.4 var(--sans); color: var(--text-5); }

.switch { width: 38px; height: 22px; border-radius: var(--r-pill); background: rgba(255, 255, 255, .12); flex: none;
  border: 1px solid var(--glass-field-border); display: flex; align-items: center; padding: 0 3px; cursor: pointer; }
.switch > i { width: 16px; height: 16px; border-radius: var(--r-pill); background: #fff; }
.switch[aria-checked="true"] { background: rgba(var(--accent-rgb), .5); border-color: rgba(var(--accent-rgb), .7); justify-content: flex-end; }
.switch-row { display: flex; align-items: center; gap: 10px; font: 400 12.5px var(--sans); color: var(--text-2); }
.switch-row span { flex: 1; }

.segmented { display: flex; gap: 4px; padding: 4px; border-radius: 12px; background: var(--glass-card); border: 1px solid var(--glass-card-border); }
.segmented button { flex: 1; height: 34px; border-radius: var(--r-sm); display: flex; align-items: center; justify-content: center; gap: 7px;
  color: var(--text-3); font: 400 11px var(--sans); border: 1px solid transparent; }
.segmented button[aria-pressed="true"] { background: rgba(var(--accent-rgb), .2); border-color: rgba(var(--accent-rgb), .4); color: var(--accent-soft); font-weight: 500; }

/* Nuanciers (accents, fonds, pictos) */
.swatches { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.swatch { width: 30px; height: 30px; flex: none; border-radius: var(--r-pill); border: 1px solid rgba(255, 255, 255, .2); cursor: pointer; }
.swatch[aria-pressed="true"] { box-shadow: 0 0 0 2px rgba(255, 255, 255, .85); }
/* Grille régulière : les aperçus occupent toute la largeur du dialogue, donc
   le dernier s'aligne avec les autres contrôles. */
.swatches--bg { display: grid; grid-template-columns: repeat(6, 1fr); gap: 7px; }
.swatch--bg { width: 100%; height: 42px; border-radius: var(--r-sm); background-size: cover; background-position: center; }
.picto-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 4px; }
.picto-grid button { height: 32px; border-radius: var(--r-sm); display: grid; place-items: center; font-size: 15px;
  color: var(--text-3); border: 1px solid transparent; }
.picto-grid button:hover { color: var(--text-strong); background: rgba(255, 255, 255, .07); }
.picto-grid button[aria-pressed="true"] { background: rgba(var(--accent-rgb), .2); border-color: rgba(var(--accent-rgb), .4); color: var(--accent-soft); }

/* ---------- Sélecteur maison -------------------------------------------
   Remplace <select> : sous Firefox la liste déroulante native est rendue par
   l'OS et ignore les styles d'auteur (fond clair sur un thème sombre). */

.select { position: relative; }
.select__btn { width: 100%; height: 38px; padding: 0 10px 0 12px; border-radius: var(--r-md);
  background: var(--glass-field); border: 1px solid var(--glass-field-border); color: var(--text);
  font: 400 13px var(--sans); display: flex; align-items: center; gap: 8px; text-align: left; }
.select__btn:hover { border-color: rgba(var(--accent-rgb), .35); }
.select.is-open .select__btn { border-color: rgba(var(--accent-rgb), .45); box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .12); }
.select__text { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.select__chevron { font-size: 14px; color: var(--text-3); transition: transform .14s ease-out; }
.select.is-open .select__chevron { transform: rotate(180deg); }

.select__list { position: absolute; left: 0; right: 0; top: calc(100% + 5px); z-index: 5;
  max-height: 210px; overflow-y: auto; padding: 6px; border-radius: var(--r-md);
  background: rgba(18, 21, 28, .96); border: 1px solid var(--glass-field-border);
  backdrop-filter: blur(28px); -webkit-backdrop-filter: blur(28px); box-shadow: var(--sh-menu);
  display: flex; flex-direction: column; gap: 1px;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .28) transparent; }
.select__opt { display: flex; align-items: baseline; gap: 8px; padding: 8px 10px; border-radius: var(--r-sm);
  font: 400 12.5px var(--sans); color: var(--text-2); cursor: pointer; }
.select__opt small { margin-left: auto; font: 400 10px var(--mono); color: var(--text-5); white-space: nowrap; }
.select__opt:hover { background: rgba(255, 255, 255, .08); color: var(--text-strong); }
.select__opt[aria-selected="true"] { background: rgba(var(--accent-rgb), .2); color: var(--accent-soft); }
/* Ouverture vers le haut quand la place manque sous le contrôle. */
.select--up .select__list { top: auto; bottom: calc(100% + 5px); }

.select__preview { display: grid; place-items: center; width: 38px; height: 38px; flex: none;
  border-radius: var(--r-md); background: var(--glass-inner); border: 1px solid var(--glass-inner-border); }
.select__preview .favicon { --fav: 24; }

/* Champ avec suggestions (fichiers d'icônes déjà utilisés). */
.suggest-anchor { align-items: stretch; }
.suggest-wrap { position: relative; flex: 1; min-width: 0; }
.suggest-wrap .field__input { width: 100%; }
.suggest { top: calc(100% + 4px); max-height: 170px; }
.suggest-anchor .btn--outline { flex: none; height: 38px; border-radius: var(--r-md); padding: 0 13px; }

/* Choix de l'icône d'un lien : un panneau par famille. */
.icon-picker { display: flex; flex-direction: column; gap: 10px; }
.icon-panel { display: flex; flex-direction: column; gap: 6px; }

/* ---------- Menu contextuel ------------------------------------------- */

.menu { position: fixed; z-index: 70; width: 236px; padding: 7px; border-radius: var(--r-xl); background: rgba(18, 21, 28, .8);
  border: 1px solid var(--glass-field-border); backdrop-filter: blur(28px); -webkit-backdrop-filter: blur(28px);
  box-shadow: var(--sh-menu); display: flex; flex-direction: column; gap: 1px; }
/* Les entrées sont des <button>, ou des <a> quand elles ouvrent un lien. */
/* Ces règles ne visent QUE les entrées de menu : les boutons d'en-tête
   (retour, « … », cadenas) ont leur propre gabarit. */
.menu .item { display: flex; align-items: center; gap: 11px; padding: 8px 10px; border-radius: 10px;
  font: 400 12.5px var(--sans); color: var(--text-2); text-align: left; cursor: pointer; }
.menu .item .ico { font-size: 14px; color: rgba(255, 255, 255, .55); }
.menu .item:hover { background: rgba(255, 255, 255, .08); color: var(--text-strong); }
.menu .item.is-danger { color: var(--danger-text); }
.menu .item.is-danger .ico { color: var(--danger); }
.menu hr { height: 1px; border: 0; background: rgba(255, 255, 255, .1); margin: 4px 6px; }

/* En-tête du menu : le nom de la cible, et un retour quand on est dans un
   sous-menu. Ni filet ni pastille — le titre se lit comme une étiquette de
   groupe, pas comme un élément de plus à distinguer du reste. L'espace suffit
   à le séparer de la liste. */
.menu__head { display: flex; align-items: center; gap: 6px;
  padding: 5px 9px 7px; margin-bottom: 2px; }
.menu__back { flex: none; width: 22px; height: 22px; border-radius: 7px; display: grid; place-items: center;
  border: 1px solid var(--glass-field-border); color: var(--text-3); font-size: 12px; background: none; padding: 0; }
.menu__back:hover { color: var(--text-strong); background: rgba(255, 255, 255, .1); }

.crumbs { flex: 1; min-width: 0; display: flex; align-items: center; gap: 5px; flex-wrap: nowrap;
  font: 400 10px var(--mono); }
/* Seul contenu de l'en-tête : le nom de l'élément visé, en texte nu. */
.crumbs__target { flex: 0 1 auto; min-width: 46px; padding: 0; border: 0; background: none;
  color: var(--text-4); letter-spacing: .04em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.menu__body { display: flex; flex-direction: column; gap: 1px; }
.item__label { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.item__value { margin-left: auto; padding-left: 10px; font: 400 10px var(--mono); color: var(--text-5);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 45%; }
.item__chev { margin-left: auto; color: var(--text-4); font-size: 13px; display: grid; place-items: center; }
.item__chev .ico { transform: rotate(-90deg); }
.item__value + .item__chev { margin-left: 4px; }

/* ---------- Toasts et bandeau de synchro ------------------------------ */

/* En bas à GAUCHE : le panneau latéral d'édition occupe désormais tout le bord
   droit, et un message qui s'y glissait dessous passait inaperçu. */
.toasts { position: fixed; left: 26px; bottom: 26px; z-index: 60; display: flex; flex-direction: column; gap: 10px; width: 404px; max-width: calc(100vw - 40px); }
.toast { display: flex; align-items: flex-start; gap: 12px; padding: 14px; border-radius: var(--r-xl);
  background: rgba(18, 21, 28, .72); border: 1px solid var(--glass-field-border);
  backdrop-filter: blur(26px); -webkit-backdrop-filter: blur(26px); box-shadow: var(--sh-toast); }
.toast__ico { width: 28px; height: 28px; flex: none; border-radius: var(--r-pill); display: grid; place-items: center; font-size: 14px; }
.toast__text { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.toast__title { font: 500 12.5px/1.3 var(--sans); color: var(--text-title); }
.toast__sub { font: 400 11px/1.3 var(--sans); color: var(--text-3); }
.toast__actions { display: flex; flex-direction: column; gap: 5px; flex: none; align-self: center; }
.toast__action { height: 26px; padding: 0 10px; border-radius: 8px; border: 1px solid rgba(255, 255, 255, .16);
  color: rgba(255, 255, 255, .7); font: 400 11px var(--sans); flex: none; white-space: nowrap; }
.toast__action:hover { color: var(--text-strong); border-color: rgba(255, 255, 255, .35); }
.toast--success { border-color: rgba(125, 219, 163, .32); }
.toast--success .toast__ico { background: rgba(125, 219, 163, .16); border: 1px solid rgba(125, 219, 163, .4); color: var(--success); }
.toast--warning { border-color: rgba(251, 191, 36, .32); }
.toast--warning .toast__ico { background: rgba(251, 191, 36, .16); border: 1px solid rgba(251, 191, 36, .4); color: var(--warning); }
.toast--error { border-color: rgba(248, 113, 113, .34); }
.toast--error .toast__ico { background: rgba(248, 113, 113, .16); border: 1px solid rgba(248, 113, 113, .4); color: var(--danger); }
.toast--accent { border-color: rgba(var(--accent-rgb), .38); }
.toast--accent .toast__ico { background: rgba(var(--accent-rgb), .16); border: 1px solid rgba(var(--accent-rgb), .4); color: var(--accent-soft); }
.toast--accent .toast__action { border-color: rgba(var(--accent-rgb), .45); color: var(--accent-soft); }

/* ---------- Palette de commandes (Ctrl+K) ----------------------------- */

.palette { width: 560px; max-width: calc(100vw - 40px); padding: 12px; gap: 10px; }
.palette__input { height: 42px; font-size: 14px; }
.palette__list { display: flex; flex-direction: column; gap: 1px; max-height: min(420px, 60vh); overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .28) transparent; }
.palette__item { display: flex; align-items: center; gap: 11px; padding: 8px 10px; border-radius: 10px;
  font: 400 12.5px var(--sans); color: var(--text-2); text-align: left; cursor: pointer; }
.palette__item .ico { font-size: 14px; color: rgba(255, 255, 255, .55); }
.palette__item .favicon { width: 20px; height: 20px; font-size: 9px; }
.palette__item .favicon img { width: 13px; height: 13px; }
.palette__item small { font: 400 10px var(--mono); color: var(--text-5); margin-left: auto; padding-left: 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40%; }
.palette__item[aria-selected="true"] { background: rgba(var(--accent-rgb), .18); color: var(--accent-soft); }
.palette__item[aria-selected="true"] .ico { color: var(--accent-soft); }
.palette__empty { padding: 14px 10px; font: 400 12px var(--sans); color: var(--text-4); }

/* ---------- Emplacement des données (chemins, .reg) --------------------- */

.path-row { display: flex; gap: 8px; align-items: stretch; }
.path-row .field__input { font: 400 11.5px var(--mono); flex: 1; min-width: 0; }
.path-row .btn { flex: none; height: 38px; border-radius: var(--r-md); padding: 0 13px; }
.path-block { display: flex; flex-direction: column; gap: 10px; padding: 14px; border-radius: var(--r-xl);
  background: var(--glass-inner); border: 1px solid var(--glass-inner-border); }
.path-block__title { display: flex; align-items: center; gap: 9px; font: 500 12.5px var(--sans); color: var(--text-title); }
.path-block__title .ico { font-size: 15px; color: var(--accent-soft); }
.path-block__body { margin: 0; font: 400 11.5px/1.5 var(--sans); color: var(--text-3); text-wrap: pretty; }
.path-block__body ol { margin: 6px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 3px; }
.path-block__actions { display: flex; gap: 8px; flex-wrap: wrap; }
.path-block__actions .btn { flex: none; height: 32px; border-radius: var(--r-md); }
.path-block--warn { background: rgba(251, 191, 36, .1); border-color: rgba(251, 191, 36, .3); }
.path-block--warn .path-block__title .ico { color: var(--warning); }

/* ---------- Corbeille -------------------------------------------------- */

.trash-list { display: flex; flex-direction: column; gap: 4px; max-height: 320px; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .28) transparent; }
.trash-item { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--r-md);
  background: var(--glass-inner); border: 1px solid var(--glass-inner-border); }
.trash-item .ico { font-size: 14px; color: var(--text-4); }
.trash-item__label { flex: 1; min-width: 0; font: 400 12.5px var(--sans); color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trash-item__date { font: 400 9.5px var(--mono); color: var(--text-5); }

/* ---------- Aide (raccourcis clavier) ---------------------------------- */

.help-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 24px; }
.help-row { display: flex; align-items: center; gap: 10px; font: 400 12px var(--sans); color: var(--text-2); }
.help-row span { flex: 1; }
kbd { font: 500 10px var(--mono); color: var(--text-2); background: rgba(255, 255, 255, .09);
  border: 1px solid var(--glass-field-border); border-bottom-width: 2px; border-radius: 6px; padding: 3px 6px; white-space: nowrap; }

/* ---------- Panneau latéral de personnalisation ------------------------
   Il RÉTRÉCIT la scène au lieu de la recouvrir : .shell met la scène et le
   panneau côte à côte. La grille, elle, garde son nombre de colonnes : les
   cartes se resserrent mais ne changent pas de place, si bien qu'entrer en
   édition ne rebat plus la mise en page sous les yeux. */

.shell { flex: 1; min-height: 0; display: flex; position: relative; }
.shell > .stage { flex: 1; min-width: 0; }

/* Le panneau se POSE SUR la scène, il ne la rétrécit pas : ouvrir les réglages
   ne doit pas redistribuer les cartes sous les yeux de l'utilisateur, sans quoi
   on règle une mise en page qu'on ne voit jamais telle qu'elle sera. */
.panel { position: absolute; top: 0; right: 0; bottom: 0; z-index: 25;
  width: 320px; min-width: 0; overflow-y: auto; overflow-x: hidden;
  padding: 16px 18px 26px; display: flex; flex-direction: column; gap: 18px;
  background: rgba(14, 17, 23, .86); border-left: 1px solid rgba(255, 255, 255, .1);
  box-shadow: -18px 0 40px -20px rgba(0, 0, 0, .8);
  backdrop-filter: blur(28px) saturate(1.3); -webkit-backdrop-filter: blur(28px) saturate(1.3);
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .28) transparent; }
@media (max-width: 767px) {
  .panel { width: 100%; position: fixed; inset: var(--bar-h) 0 0 0; z-index: 30; border-left: none; }
}

.panel__head { display: flex; align-items: center; gap: 10px; }
.panel__badge { width: 28px; height: 28px; flex: none; border-radius: var(--r-sm); display: grid; place-items: center; font-size: 14px;
  background: rgba(var(--accent-rgb), .18); border: 1px solid rgba(var(--accent-rgb), .32); color: var(--accent-soft); }
.panel__id { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.panel__name { font: 500 13px/1 var(--sans); color: var(--text-title); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.panel__sub { font: 400 9.5px/1 var(--mono); color: var(--text-5); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.panel__close { width: 26px; height: 26px; flex: none; border-radius: var(--r-pill); border: 1px solid rgba(255, 255, 255, .12);
  color: var(--text-3); display: grid; place-items: center; font-size: 12px; }
.panel__close:hover { color: var(--text-strong); background: rgba(255, 255, 255, .1); }

.group { display: flex; flex-direction: column; gap: 9px; }
.group__title { font: 400 9.5px/1 var(--mono); color: rgba(255, 255, 255, .4); letter-spacing: .11em; text-transform: uppercase; }
.group__row { display: flex; align-items: baseline; gap: 8px; }
.group__value { font: 400 10px/1 var(--sans); color: var(--text-3); white-space: nowrap; }
.group__note { font: 400 9.5px/1.4 var(--mono); color: rgba(255, 255, 255, .3); }
.hr { height: 1px; background: rgba(255, 255, 255, .08); }
/* Dans le panneau le filet sépare deux natures de réglages — ce qui vaut pour
   la section, et ce qui se règle onglet par onglet. Il doit donc se voir. */
/* flex: none est INDISPENSABLE : le panneau est une colonne flex qui déborde,
   et un enfant de 1 px s'y laisse écraser à zéro. Le filet existait alors dans
   le DOM sans jamais se voir. */
.panel .hr { flex: none; margin: 3px 0; background: rgba(255, 255, 255, .15); }
.badge { white-space: nowrap; padding: 2px 7px; border-radius: var(--r-pill); background: rgba(var(--accent-rgb), .16);
  border: 1px solid rgba(var(--accent-rgb), .3); font: 400 8.5px var(--mono); color: var(--accent-soft); }

/* Piste segmentée */
.seg { display: flex; gap: 3px; padding: 3px; border-radius: 10px; background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .1); }
.seg button { flex: 1; min-width: 0; height: 28px; border-radius: 8px; font: 400 11px var(--sans); color: var(--text-3); border: 1px solid transparent; }
.seg button:hover { color: var(--text-strong); }
.seg--size button { height: 26px; border-radius: 7px; font: 500 10px var(--mono); color: rgba(255, 255, 255, .42); }
.seg button[aria-pressed="true"] { background: rgba(var(--accent-rgb), .22); border-color: rgba(var(--accent-rgb), .45); color: var(--text-strong); }

/* Catalogue des modes */
/* 6 modes sur 2 rangées de 3 : les pictogrammes peuvent être plus grands
   et les libellés tiennent en entier. */
.modes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; }
.modes button { min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  height: 68px; border-radius: var(--r-lg); font-size: 24px;
  background: var(--glass-inner); border: 1px solid var(--glass-inner-border); color: rgba(255, 255, 255, .6); }
.modes button:hover { background: rgba(255, 255, 255, .09); color: var(--text-strong); }
.modes button[aria-pressed="true"] { background: rgba(var(--accent-rgb), .18); border-color: rgba(var(--accent-rgb), .42); color: var(--text-strong); }
.modes span { font: 400 9.5px/1 var(--mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.modes--wide { grid-template-columns: repeat(6, 1fr); }
@media (max-width: 767px) { .modes--wide { grid-template-columns: repeat(3, 1fr); } }

/* Styles enregistrés */
/* Bouton de réinitialisation, en pied de panneau : au gabarit des boutons
   fantômes du reste de l'interface, pleine largeur. */
.panel__reset { width: 100%; height: 34px; border-radius: var(--r-md); justify-content: center; }
.panel__reset .ico { font-size: 13px; }

.iconbtn-sm { height: 28px; padding: 0 10px; border-radius: var(--r-sm); background: var(--glass-inner);
  border: 1px solid rgba(255, 255, 255, .1); color: rgba(255, 255, 255, .62);
  font: 400 10.5px var(--sans); display: flex; align-items: center; gap: 7px; flex: none; }
.iconbtn-sm:hover { color: var(--text-strong); background: rgba(255, 255, 255, .1); }

/* 12 accents : le nuancier passe à la ligne au lieu de déborder. */
.panel .swatches { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; justify-items: center; }
.panel .swatches button { width: 26px; height: 26px; border-radius: var(--r-pill); opacity: .55; border: none; }
.panel .swatches button:hover { opacity: .85; }
.panel .swatches button[aria-pressed="true"] { opacity: 1; box-shadow: 0 0 0 2px rgba(255, 255, 255, .85); }

/* Douzième pastille : pas de couleur propre, la section suit sa page. Une
   barre oblique la distingue d'une pastille sombre. */
.panel .swatches button.swatch--none { background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .22); opacity: .75; position: relative; }
.panel .swatches button.swatch--none::after { content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(to top right, transparent calc(50% - .8px), rgba(255, 255, 255, .5) calc(50% - .8px),
    rgba(255, 255, 255, .5) calc(50% + .8px), transparent calc(50% + .8px)); }
.panel .swatches button.swatch--none:hover { opacity: .95; }
.panel .swatches button.swatch--none[aria-pressed="true"] { opacity: 1; }

/* Le nuancier de FONDS reste une grille de vignettes rectangulaires : sans ça
   les règles rondes ci-dessus le réduiraient à des pastilles de 26 px. */
.panel .swatches--bg { grid-template-columns: repeat(4, 1fr); gap: 7px; justify-items: stretch; }
.panel .swatches--bg button { width: 100%; height: 40px; border-radius: var(--r-sm); opacity: .8; }
.panel .swatches--bg button[aria-pressed="true"] { opacity: 1; box-shadow: 0 0 0 2px rgba(var(--accent-rgb), .9); }
.panel .swatches--bg button.bgpick__add { background: rgba(255, 255, 255, .05);
  border: 1px dashed rgba(255, 255, 255, .22); display: grid; place-items: center; color: var(--text-4); }
.panel .swatches--bg button.bgpick__add:hover { color: var(--text-strong); border-color: var(--accent); }

/* ---- Liste des onglets d'une section -----------------------------------
   Un champ par onglet : on renomme sur place, et le champ actif ouvre son
   onglet dans la carte — ce qui rend visible que les réglages d'affichage
   portent sur l'onglet qu'on voit. */
.tablist { display: flex; flex-direction: column; gap: 6px; }
.tablist__row { display: flex; align-items: center; gap: 6px; }
.tablist__row .field__input { flex: 1; min-width: 0; height: 32px; font-size: 12.5px; }
/* Le bouton radio dit lequel est ouvert : le champ ne porte plus de filet
   d'accent, qui signalait la même chose deux fois et alourdissait la colonne. */
.tablist__pick { width: 14px; height: 14px; flex: none; margin: 0; cursor: pointer;
  appearance: none; border-radius: var(--r-pill); border: 1px solid rgba(255, 255, 255, .28);
  background: transparent; display: grid; place-items: center; }
.tablist__pick:hover { border-color: rgba(var(--accent-rgb), .7); }
.tablist__pick:checked { border-color: var(--accent); }
.tablist__pick:checked::after { content: ""; width: 6px; height: 6px;
  border-radius: var(--r-pill); background: var(--accent); }
.tablist__pick:focus-visible { outline: 2px solid rgba(var(--accent-rgb), .6); outline-offset: 2px; }
/* Place tenue par le radio absent de la ligne « nouvel onglet ». */
.tablist__pick--ghost { border-color: transparent; cursor: default; }
/* Place tenue par le bouton « supprimer » absent du premier onglet : sans lui
   son champ serait plus large que les autres. */
.tablist__spacer { width: 30px; height: 30px; flex: none; }
.tablist__del, .tablist__add { width: 30px; height: 30px; flex: none; border-radius: var(--r-sm);
  display: grid; place-items: center; font-size: 13px; color: var(--text-5);
  border: 1px solid transparent; }
.tablist__del:hover { color: var(--danger); background: rgba(248, 113, 113, .14); }
.tablist__add { border: 1px dashed rgba(255, 255, 255, .18); color: var(--text-4); }
.tablist__add:hover { color: var(--accent-soft); border-color: var(--accent); }
.tablist__row--new .field__input { border-style: dashed; }

/* Sélecteur d'icône d'un lien, dans un panneau de 320 px. */
.panel .icon-picker { gap: 8px; }
.panel .icon-picker .seg button { font-size: 10.5px; padding: 0 4px; }
.panel .icon-panel--image .path-row { flex-wrap: wrap; gap: 6px; }
.panel .icon-panel--image .btn { height: 30px; font-size: 11px; }

/* Nom et pictogramme sur une même ligne : le champ prend la place restante. */
.panel .field-row { display: flex; align-items: center; gap: 8px; }
.panel .field-row .field__input { flex: 1; min-width: 0; }
.panel .field-row .iconbtn-sm { width: 38px; height: 38px; padding: 0; flex: none;
  border-radius: var(--r-md); justify-content: center; }
.panel .field-row .iconbtn-sm .ico { font-size: 15px; }

/* Le bouton « Icône » occupe sa propre ligne : en flex il débordait du panneau. */
.panel .iconbtn-sm { width: 100%; justify-content: center; }

/* Carte sélectionnée : le panneau suit la carte */
.card.is-selected { background: rgba(255, 255, 255, .07); border-color: rgba(var(--accent-rgb), .45);
  box-shadow: var(--sheen), 0 0 0 3px rgba(var(--accent-rgb), .12), var(--sh-card); }

/* En-tête de carte : normal / compact / masqué */
.card__icon { font-size: 15px; color: var(--accent); flex: none; }
.card[data-header="compact"] .card__head { gap: 8px; min-height: 0; }
.card[data-header="compact"] .card__title { font-size: 11.5px; color: var(--text-3); }
/* « Masqué » retire l'IDENTITÉ de la carte — titre, icône, pastille — mais pas
   ses onglets : sans eux, une section à plusieurs onglets deviendrait
   inutilisable. Ce qui reste se pose au milieu, seul contenu de la ligne. */
.card[data-header="hidden"] .card__title,
.card[data-header="hidden"] .card__dot,
.card[data-header="hidden"] .card__icon,
.card[data-header="hidden"] .card__sep,
.card[data-header="hidden"] .card__spacer { display: none; }
/* La prise passe SOUS toute la ligne plutôt que de s'étirer à côté des
   onglets : un `flex: 1` sur elle mangerait l'espace libre et les pousserait à
   droite — le centrage ne tiendrait pas. En position absolue elle couvre
   l'en-tête entier, les onglets restent centrés, et la carte reste attrapable
   partout ailleurs sur la ligne. */
.card[data-header="hidden"] .card__head { justify-content: center; position: relative; }
.card[data-header="hidden"] .card__grab { position: absolute; inset: 0; }
.card[data-header="hidden"] .tabs { position: relative; z-index: 1; }
/* Sans onglets, l'en-tête n'a plus rien à montrer : il rend sa place au
   contenu, ce qui est tout l'intérêt du réglage. */
.card[data-header="hidden"][data-headtabs="0"] .card__head {
  min-height: 0; height: 0; overflow: hidden; }
/* En édition, l'en-tête masqué réapparaît en entier : sans lui, plus de prise,
   et plus moyen de reconnaître la section qu'on règle. */
.is-editing .card[data-header="hidden"] .card__head {
  height: auto; min-height: 26px; overflow: visible; justify-content: flex-start; }
.is-editing .card[data-header="hidden"] .card__dot,
.is-editing .card[data-header="hidden"] .card__icon,
.is-editing .card[data-header="hidden"] .card__spacer,
.is-editing .card[data-header="hidden"] .tabs { display: flex; }
.is-editing .card[data-header="hidden"] .card__grab { position: static; }
.is-editing .card[data-header="hidden"] .card__title { display: block; opacity: .45; }

/* ---------- Widgets ----------------------------------------------------
   Un widget est une SECTION : il hérite du cadre, du titre, de l'accent et de
   la place sur la grille. Ne restent ici que les styles de son CORPS, qui
   remplace la liste de liens. */
.widget { display: flex; flex-direction: column; gap: 10px; min-width: 0; min-height: 0; }
.page--free .grid-stack-item-content.card > .widget { flex: 1 1 auto; overflow-y: auto;
  overflow-x: hidden; scrollbar-width: thin; scrollbar-color: transparent transparent; }
.page--free .grid-stack-item:hover .grid-stack-item-content.card > .widget {
  scrollbar-color: rgba(255, 255, 255, .26) transparent; }
/* Un type inconnu ne perd rien : on le dit, et les données repartent intactes. */
.widget--unknown { flex-direction: row; align-items: center; gap: 9px;
  font: 400 11px/1.4 var(--mono); color: var(--text-5); }
.widget--unknown .ico { flex: none; color: var(--text-4); }
/* Les réglages d'un widget respirent comme les groupes du panneau : sans ce
   gabarit ils se collent au titre du groupe suivant. */
.wsettings { display: flex; flex-direction: column; gap: 18px; }

/* Le style des DEUX widgets livrés a quitté ce fichier : il vit
   désormais dans css/widgets/qr-link.css et css/widgets/horloges.css.
   Tout nouveau widget suit la même règle — voir la procédure du README. */


/* L'interrupteur dans le panneau : même gabarit que dans les modales. */
.switchrow--panel { padding: 0; background: none; border: 0; }

/* Une entrée de menu qu'on ne peut pas actionner : elle reste LISIBLE plutôt
   que d'être retirée. Son absence obligerait à se demander si l'option existe ;
   sa présence en gris dit qu'elle existe et pourquoi elle ne s'offre pas. */
.menu .item[disabled] { opacity: .38; cursor: default; pointer-events: none; }

/* ---------- Modale « Ajouter une section » ----------------------------- */

.modal--types { width: 600px; }
.types { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
@media (max-width: 767px) { .types { grid-template-columns: repeat(2, 1fr); } }
.types button { display: flex; flex-direction: column; gap: 9px; padding: 13px; border-radius: 15px; text-align: left;
  background: var(--glass-inner); border: 1px solid rgba(255, 255, 255, .1); }
.types button:hover { background: rgba(255, 255, 255, .1); border-color: rgba(var(--accent-rgb), .35); }
.types button[aria-pressed="true"] { background: rgba(var(--accent-rgb), .16); border-color: rgba(var(--accent-rgb), .4); }
.types .t-ico { width: 32px; height: 32px; border-radius: 10px; display: grid; place-items: center; font-size: 16px;
  background: rgba(255, 255, 255, .07); border: 1px solid rgba(255, 255, 255, .12); color: rgba(255, 255, 255, .7); }
.types button[aria-pressed="true"] .t-ico { background: rgba(var(--accent-rgb), .2); border-color: rgba(var(--accent-rgb), .35); color: var(--accent-soft); }
.types .t-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.types .t-name { font: 500 12.5px/1.2 var(--sans); color: var(--text); }
.types .t-sub { font: 400 10px/1.35 var(--sans); color: var(--text-4); }

.field--narrow { flex: none !important; width: 150px; }
.stepper { height: 38px; border-radius: var(--r-md); background: var(--glass-field); border: 1px solid var(--glass-field-border);
  display: flex; align-items: center; gap: 8px; padding: 0 6px; }
.stepper button { width: 26px; height: 26px; flex: none; border-radius: 8px; display: grid; place-items: center; color: var(--text-3); font-size: 12px; }
.stepper button:hover { color: var(--text-strong); background: rgba(255, 255, 255, .08); }
.stepper span { flex: 1; text-align: center; font: 500 11px var(--mono); color: rgba(255, 255, 255, .85); }

.switchrow { display: flex; align-items: center; gap: 12px; padding: 11px 13px; border-radius: 13px;
  background: rgba(255, 255, 255, .045); border: 1px solid rgba(255, 255, 255, .1); }
.switchrow.is-on { border-color: rgba(var(--accent-rgb), .35); background: rgba(var(--accent-rgb), .08); }
.switch-row__text { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 0; }
.switch-row__label { font: 400 12.5px/1 var(--sans); color: rgba(255, 255, 255, .88); }
.switch-row__sub { font: 400 10px/1.3 var(--mono); color: rgba(255, 255, 255, .36); }

/* ---------- Recherche instantanée (barre d'espace) ---------------------
   Surcouche modale : champ avec complétion en ligne, résultats groupés,
   pied de raccourcis. Le tableau reste visible derrière, sous un simple
   voile sombre — aucun filtre sur la page (voir la note du ::backdrop). */

#search { max-width: none; }
#search::backdrop { background: rgba(8, 9, 13, .66); }
/* Aucun filtre sur la page : voir la note du plein écran plus haut. */

.search { width: 600px; max-width: calc(100vw - 40px); border-radius: var(--r-3xl); overflow: hidden;
  background: rgba(20, 23, 30, .76); border: 1px solid rgba(255, 255, 255, .15);
  backdrop-filter: blur(32px) saturate(1.35); -webkit-backdrop-filter: blur(32px) saturate(1.35);
  box-shadow: var(--sheen), 0 44px 90px -30px rgba(0, 0, 0, .9); }

/* ---- Champ ---- */
/* La RANGÉE ne porte plus rien : ni cadre, ni fond. Elle aligne la loupe, la
   zone de saisie et le sélecteur de moteur, et se contente de les détacher des
   bords de la modale. C'est la zone où l'on TAPE qui est encadrée — voir
   `.qwrap` plus bas. Encadrer la rangée entière revenait à encadrer aussi la
   loupe et le moteur, qui ne sont pas des endroits où l'on écrit. */
.search__field { display: flex; align-items: center; gap: 11px;
  padding: 12px 12px 8px; }
.search__field > .ico { font-size: 19px; color: rgba(255, 255, 255, .45); flex: none; }
/* La loupe s'allume avec le focus, et reste allumée tant que le champ est
   rempli. (L'ancien « .qwrap.is-typing ~ .ico » ne pouvait jamais
   correspondre : la loupe PRÉCÈDE .qwrap dans le DOM et « ~ » ne regarde que
   les frères suivants — :has() sait, lui, regarder en avant.) */
.search__field:focus-within > .ico { color: var(--accent-soft); }
/* Règle SÉPARÉE : dans une liste commune, un navigateur sans :has() aurait
   jeté aussi la règle du focus. */
.search__field:has(.qwrap.is-typing) > .ico { color: var(--accent-soft); }

/* La saisie réelle est un <input> ; le fantôme de complétion est posé juste
   après, grâce à un miroir invisible qui reproduit la largeur du texte tapé. */
/* LA zone de saisie : c'est elle qui porte le cadre, l'arrondi et la couleur.

   Sa marge intérieure est répétée sur `.qshadow`, et ce n'est pas un oubli de
   factorisation : le fantôme de complétion est en `position: absolute` avec
   `inset: 0`, donc calé sur la boîte de REMPLISSAGE, tandis que la vraie saisie
   est dans le flux, donc calée sur la boîte de CONTENU. Sans la même marge des
   deux côtés, le fantôme se décale de la valeur du remplissage et la complétion
   ne prolonge plus le mot qu'on tape. */
.qwrap { position: relative; flex: 1; min-width: 0;
  padding: 9px 12px; border-radius: var(--r-lg);
  background: var(--glass-field); border: 1px solid var(--glass-field-border); }
.qwrap:focus-within { border-color: rgba(var(--accent-rgb), .5);
  background: rgba(var(--accent-rgb), .08); }
.qinput, .qshadow { font: 400 16px/22px var(--sans); white-space: nowrap; }
.qinput { width: 100%; height: 22px; padding: 0; border: none; background: none; color: var(--text-strong);
  outline: none; position: relative; z-index: 1; }
/* La règle générale de `:focus-visible` pose un halo de 3 px autour de
   l'élément focalisé. Sur une saisie sans arrondi, ce halo est un RECTANGLE
   collé au texte, et il doublait le cadre arrondi de la zone — deux traits
   concentriques pour dire une seule chose. La zone, elle, change déjà de
   bordure et de fond quand elle reçoit le focus : le signal est là, et il est
   meilleur. */
.qinput:focus-visible { box-shadow: none; }
.qinput::placeholder { color: var(--text-6); }
.qshadow { position: absolute; inset: 0; padding: 9px 12px; display: flex; align-items: center;
  pointer-events: none; overflow: hidden; box-sizing: border-box; }
.qmirror { visibility: hidden; flex: none; }
.qghost { flex: none; color: rgba(255, 255, 255, .3); }

.engine { flex: none; display: flex; align-items: center; gap: 7px; height: 26px; padding: 0 9px 0 7px;
  border-radius: 8px; background: rgba(255, 255, 255, .06); border: 1px solid var(--glass-field-border); }
.engine:hover { background: rgba(255, 255, 255, .11); }
.engine__fav { width: 14px; height: 14px; border-radius: 4px; background: rgba(255, 255, 255, .12);
  display: grid; place-items: center; font: 500 8px var(--mono); color: rgba(255, 255, 255, .75); }
.engine__name { font: 400 10.5px/1 var(--mono); color: var(--text-3); }
.engine .ico { font-size: 11px; color: rgba(255, 255, 255, .35); }

.search .clear { flex: none; width: 26px; height: 26px; border-radius: var(--r-pill);
  border: 1px solid var(--glass-field-border); color: rgba(255, 255, 255, .45);
  display: grid; place-items: center; font-size: 12px; }
.search .clear:hover { color: var(--text-strong); background: rgba(255, 255, 255, .1); }

/* ---- Résultats ---- */
.search .results { padding: 11px 9px 9px; max-height: 392px; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .28) transparent; }
.search .group__title { display: block; padding: 12px 9px 8px; font: 400 9px/1 var(--mono);
  color: rgba(255, 255, 255, .32); letter-spacing: .12em; text-transform: uppercase; }
.search .results > .group:first-child .group__title { padding-top: 4px; }

.search .row { display: flex; align-items: center; gap: 12px; padding: 9px; border-radius: 11px;
  border: 1px solid transparent; text-align: left; width: 100%; color: var(--text); cursor: pointer; }
.search .row:hover { background: rgba(255, 255, 255, .07); }
.search .row[aria-selected="true"] { background: rgba(var(--accent-rgb), .16); border-color: rgba(var(--accent-rgb), .3); }
.search .row .ico { font-size: 15px; color: var(--text-4); flex: none; }
.search .row[aria-selected="true"] .ico { color: var(--accent-soft); }
.search .row__label { flex: 1; min-width: 0; font: 400 13.5px/1 var(--sans);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search .row[aria-selected="true"] .row__label { color: var(--text-strong); }
.search .row__label .compl { color: rgba(255, 255, 255, .45); }
.search .row[aria-selected="true"] .row__label .compl { color: rgba(255, 255, 255, .55); }
.search .row__aside, .search .row__enter { flex: none; font: 400 9.5px/1 var(--mono); color: var(--text-4); }
/* Oubli d'une recherche : discret, révélé au survol ou à la sélection. */
.search .row__forget { flex: none; width: 22px; height: 22px; border-radius: var(--r-pill);
  display: grid; place-items: center; font-size: 11px; color: var(--text-4);
  opacity: 0; transition: opacity .12s ease-out; }
.search .row:hover .row__forget,
.search .row[aria-selected="true"] .row__forget { opacity: 1; }
.search .row__forget:hover { color: var(--danger); background: rgba(248, 113, 113, .16); }

/* Accès rapide : deux colonnes */
.search .quick { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px; }
.search .quick .row { gap: 11px; padding: 8px 9px; }
.search .quick .row__label { font-size: 12.5px; }

/* Liens du tableau de bord : vignette + libellé + chemin */
.search .row--link { gap: 11px; padding: 8px 9px; }
.search .fav { width: 24px; height: 24px; flex: none; border-radius: 7px; overflow: hidden;
  background: rgba(255, 255, 255, .1); border: 1px solid var(--glass-field-border);
  display: grid; place-items: center; font: 500 10px var(--mono); color: rgba(255, 255, 255, .7); }
.search .fav img { width: 16px; height: 16px; object-fit: contain; }
.search .fav .ico { font-size: 13px; color: var(--accent-soft); }
.search .quick .fav { width: 22px; height: 22px; font-size: 9px; }
.search .row__stack { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.search .row__title { font: 400 13px/1.2 var(--sans); color: rgba(255, 255, 255, .9);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search .row__title mark { background: none; color: var(--accent-soft); }
.search .row__path { font: 400 9.5px/1.2 var(--mono); color: var(--text-5);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Chercher ailleurs : pilules */
.search .elsewhere { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 9px 4px; }
.search .elsewhere .row { width: auto; gap: 7px; height: 28px; padding: 0 11px 0 9px;
  border-radius: var(--r-pill); background: rgba(255, 255, 255, .05); border-color: rgba(255, 255, 255, .1);
  font: 400 11.5px var(--sans); color: rgba(255, 255, 255, .7); }
.search .elsewhere .row .ico { font-size: 13px; color: rgba(255, 255, 255, .45); }
.search .elsewhere .row:hover { background: rgba(255, 255, 255, .11); color: var(--text-strong); }

.search .empty { padding: 26px 12px 30px; text-align: center; font: 400 12px/1.6 var(--sans); color: var(--text-4); }

/* ---- Pied de raccourcis ---- */
.search__foot { display: flex; align-items: center; gap: 16px; padding: 10px 14px;
  border-top: 1px solid rgba(255, 255, 255, .08); background: rgba(255, 255, 255, .02);
  font: 400 9.5px/1 var(--mono); color: rgba(255, 255, 255, .34); }
.search__foot > span { display: flex; align-items: center; gap: 6px; }
.search__foot .kbd { padding: 2px 5px; border-radius: 4px; background: rgba(255, 255, 255, .08);
  border: 1px solid var(--glass-field-border); color: rgba(255, 255, 255, .6); }

@media (max-width: 767px) {
  .search { width: calc(100vw - 24px); }
  .search .quick { grid-template-columns: 1fr; }
}

/* ---------- Mode édition : divers --------------------------------------

   Glisser-déposer : en mode « fallback » SortableJS suit le pointeur
   lui-même. Deux comportements natifs lui font concurrence et doivent être
   neutralisés, sans quoi le glisser avorte :
   - la sélection de texte, déclenchée par un appui-glissé sur du contenu ;
   - la gestuelle du navigateur sur la poignée.
   (Le troisième, le glisser natif des <a href>, est neutralisé côté JS par
   draggable="false" sur les liens en mode édition.) */
.is-editing .card,
.is-editing .link,
.is-editing .handles { user-select: none; -webkit-user-select: none; }
.card__grab { touch-action: none; }


.is-editing .card:focus-visible { outline: none; box-shadow: var(--sheen), var(--sh-card), 0 0 0 2px rgba(var(--accent-rgb), .5); }
