/*
 * LA COLONNE DE DROITE DE /catalogue — feuille de la surface EGMtheme (lot A, session 352).
 *
 * 🔗 **DEPUIS LA 378, CE FICHIER SERT DEUX SURFACES, ET C'EST DIT ICI.** Le dock « Mes connexions »
 *    est aussi servi dans la colonne de droite de l'ACCUEIL (le Tiz). Ses 53 regles sont donc
 *    prefixees `.tz-dock-scope` — une classe portee par les DEUX colonnes — et son socle de balises
 *    nues est borne a `.tz-dock` (voir le bloc 2 bis). ⛔ Le reste du fichier (la grille a deux
 *    colonnes, la carte Premium, la publicite, les cellules du rail) reste ancre sur
 *    `.egmtheme-catalogue-rail` : il n'a QU'UNE surface, et rien de tout cela n'existe sur
 *    l'accueil. ⭐ *Ce qui est deplace doit etre DIT — un deplacement silencieux est une
 *    suppression pour qui cherche.*
 *
 * 🏠 D'OU VIENT CE FICHIER. Il recolte `themes/egmtheme-v2/assets/css/rail.css` (182 l.) et
 *    `connections.css` (494 l.). Le V2 garde ses copies : il reste banc de mesure et reserve de
 *    composants (decision porteur du 2026-09-03), ⛔ il n'est plus la cible de livraison. Les deux
 *    copies vivent donc separement — ⭐ *ce qui est recolte est DIT*, et c'est dit ici.
 *
 * 🎨 LES JETONS SONT SCOPES SUR `.egmtheme-catalogue-rail`, ⛔ JAMAIS SUR `:root`.
 *    🚨 Raison mesuree (audit 351 §3.5) : EGMtheme porte deja 22 couleurs et 46 proprietes
 *    `--egmtheme-*`, et les NOMS SE CROISENT — `radius-lg` vaut 16px ici et 7px dans le contrat
 *    V2 (x 2,3), `radius-2xl` 32px contre 9px (x 3,6). Poser ces valeurs sur `:root` ou les
 *    rebaptiser `--egmtheme-*` multiplierait chaque arrondi du reste du theme, EN SILENCE.
 *    ⇒ prefixe `--tz-` conserve, portee close, zero fuite.
 *
 * 🧮 COMBIEN DE JETONS, ET POURQUOI CEUX-LA (audit 351 §3.4, corrige en 352).
 *    L'audit comptait 37 gardes sur 100. La cloture qui l'a produit lisait le CSS ; elle ne
 *    voyait donc ni ce que le SCRIPT lit, ni ce que le PRODUCTEUR emet :
 *      · 33 cites >= 2 fois en CSS ......... gardes (c'est la definition d'un jeton)
 *      ·  4 lus par `getComputedStyle` ..... gardes — ⛔ ininlinables, c'est leur seul mode de
 *                                            lecture (`catalogue-dock.js`, fonction `jeton()`)
 *      · 10 emis par le PRODUCTEUR ......... gardes — `EGM_Tizofun_Connections::PALETTE` rend
 *                                            `var(--tz-subject-*-cold|tint)` dans un attribut
 *                                            `style` : AUCUN CSS ne les cite, et sans eux les
 *                                            5 pastilles d'avatar tombent en `inherit` /
 *                                            `transparent`. 🪤 Le defaut serait SILENCIEUX.
 *      ·  1 propre a CETTE surface ........ `catalogue-rail-sticky-top` (voir plus bas)
 *      · 16 de plus au lot B .............. gardes — les 8 familles de matiere que le dock ne
 *                                            pouvait pas atteindre (voir leur encadre plus bas)
 *      ⇒ 64 declarations `--tz-*`, et 63 valeurs INLINEES ci-dessous.
 *    ⭐ Chaque valeur inlinee porte en commentaire le jeton V2 qu'elle remplace : *ce qui n'est
 *    plus nomme doit rester RE-MESURABLE* — c'est la contrepartie de l'inlining, et c'est ce qui
 *    permet a la loi porteur du 2026-09-01 (« chaque composant se re-mesure contre la maquette »)
 *    de continuer a s'appliquer. Modele : `IA/Galerie Tizofun trois designs/app.dc.html`,
 *    colonne l. 168-191, dock l. 447-528.
 *
 * 🔤 AUCUNE `font-family` N'EST INTRODUITE. Consigne porteur : on ne touche pas a la police de
 *    /catalogue. Elle est tenue PAR CONSTRUCTION — la seule occurrence de ce fichier est
 *    `font-family: inherit` sur le bouton Premium.
 *
 * 🚸 SG-A (351) : LE PREFLIGHT TAILWIND S'APPLIQUE A CE MARKUP. La feuille de l'app catalogue est
 *    injectee en `<style>` par le bundle, donc APRES toute feuille enqueuee. Elle reinitialise
 *    `button`, `input`, `svg`, `ul` et les bordures. Deux consequences tenues ici :
 *      1. toutes nos regles sont ancrees sur `.egmtheme-catalogue-rail` (specificite >= 0-1-1) ;
 *         le preflight selectionne par element (0-0-1) et par `*` (0-0-0) : ⭐ il ne gagne jamais ;
 *      2. le vrai risque n'est pas la surcharge, c'est le SILENCE — ce que le preflight retire aux
 *         balises nues quand il est la, et ce que l'agent utilisateur leur remet quand il n'est
 *         pas la (page servie sans JS). ⇒ le bloc « SOCLE DES BALISES NUES » plus bas pose
 *         EXPLICITEMENT les deux etats, pour que le composant soit identique dans les deux cas.
 */

/* ═══════════════════════════ 1. LES 64 JETONS, SCOPES ═══════════════════════════════════ */

/*
 * 🧬 UNE SEULE DECLARATION, DEUX LECTEURS (session 361).
 *
 * La colonne PHP n'est plus seule a lire la palette des matieres : les pastilles de matiere du
 * bloc d'en-tete sont peintes par l'app REACT, qui vit dans `.egmtheme-catalogue-shell__main` —
 * un FRERE de la colonne, ⛔ pas un descendant. Depuis `.egmtheme-catalogue-rail`, aucune
 * variable ne peut l'atteindre : les 5 pastilles seraient tombees en `inherit`, EN SILENCE
 * (c'est exactement le defaut de la 352, 0 juge rouge).
 *
 * ⭐ *Recopier 13 hexadecimaux dans le TypeScript aurait fabrique un second foyer pour un meme
 * fait.* Le porteur du fait reste CE bloc ; on elargit sa PORTEE au conteneur commun.
 * 🪤 Les deux selecteurs sont necessaires : `[egmtheme_catalogue_rail]` est aussi servi hors de
 * la coque (les fiches, cf. `verify_fiches_ad_rail`), ou aucun `.egmtheme-catalogue-shell`
 * n'existe. Garder le second, c'est garder la colonne peinte partout ou elle se pose.
 * 🚨 Toujours ⛔ JAMAIS sur `:root` : la raison de l'encadre ci-dessus n'a pas bouge.
 */
/*
 * 🔗 SESSION 378 — `.tz-dock-scope` REJOINT LES DEUX AUTRES, ET C'EST TOUT CE QUI CHANGE ICI.
 *
 * Le dock « Mes connexions » est desormais servi sur DEUX surfaces : la colonne de /catalogue et
 * la colonne de droite de l'accueil (le Tiz). ⭐ *On BRANCHE, ⛔ on ne reconstruit pas* : les 53
 * regles du dock ont quitte le prefixe `.egmtheme-catalogue-rail` pour `.tz-dock-scope`, une
 * classe que les DEUX colonnes portent. ⛔ Aucune valeur n'a bouge (delta mesure : 530 octets,
 * soit 53 x 10 caracteres de prefixe).
 * 🪤 Les jetons doivent suivre le composant : sans cette ligne, le dock de l'accueil tomberait en
 * `inherit` / `transparent` — EN SILENCE, puisqu'aucune regle ne manquerait, seulement leurs
 * valeurs. ⭐ *Un juge de presences ne voit pas de valeur.*
 * 🚸 Portee close : `community.css` ne cite AUCUN `--tz-*` (mesure : 0 occurrence), il n'y a donc
 * aucun croisement de noms avec l'accueil.
 */
/*
 * 🎠 SESSION 1050 — `.egm-gsc-promo` (l'encart de la vitrine des communautes, sur le Tiz) REJOINT
 * LA PORTEE, POUR LA MEME RAISON QUE `.tz-dock-scope` EN 378 : sa tete reprend la carte de la
 * colonne (`.tz-railcard`), et 1049 en avait RECOPIE les valeurs. Elle cite maintenant ces jetons
 * (`var(--tz-warm-*, <repli>)`) : la colonne change de couleur ⇒ l'encart suit.
 * 🪤 Cette feuille ne se charge sur l'accueil que si le dock y est servi : sans elle, l'encart
 * tombe sur ses replis (memes valeurs, ecrites a cote de chaque `var()`). ⛔ Toujours pas `:root`.
 * Le premier selecteur est ajoute EN TETE : le juge 378 (E3) lit `.egmtheme-catalogue-rail,`
 * puis `.tz-dock-scope {` colles.
 */
.egm-gsc-promo,
.egmtheme-catalogue-shell,
.egmtheme-catalogue-rail,
.tz-dock-scope {
	/* — 14 couleurs citees >= 2 fois (1050 : + `--tz-warm-highlight`, cite par l'encart) — */
	--tz-surface-page: #FFFFFF;        /* x10 */
	--tz-warm-ink: #3D2A12;            /* x5  — l'encre chaude du modele */
	--tz-warm-rail: #FAF2E2;           /* x3  — le creme de la colonne */
	--tz-warm-rail-border: #EFE1C4;    /* x3  */
	--tz-warm-surface: #F7EFE0;        /* x3  */
	--tz-surface-soft: #F0F2F8;        /* x3  */
	--tz-ink-body: #3A4056;            /* x3  */
	--tz-ink-faint: #636A7E;           /* x3  — 🔠 1291 : ex-#8B91A4 (3,14:1) ⇒ gris du barème (5,4:1) */
	--tz-warm-surface-dim: #F0E3CB;    /* x2  */
	--tz-warm-gold: #B4690E;           /* x2  — fonds et contours seulement */
	--tz-warm-gold-ink: #A35500;       /* x2  — ♿ 1294 : sourcils du dock ; #B4690E = 4,23:1 sur le creme ⇒ 4,67:1 */
	--tz-warm-highlight-dim: #E2C89B;  /* x2  */
	--tz-warm-highlight: #FFE7B8;      /* x2  — 1050 : etiquette de tete de la colonne ET de l'encart */
	--tz-ink-muted: #5A6076;           /* x2  */
	--tz-ink-strong: #0D1024;          /* x2  */

	/* — 5 de typographie citees >= 2 fois — */
	/* 🔠 1291/TYPO3 — barème de lecture (TYPO_LECTURE_S1284 §0) : méta 12 ⇒ 14 (plancher), pastille
	   11 ⇒ 12,5 (sourcils MAJ), base 13,5 ⇒ 14. Le foyer, ⛔ 23 retouches locales. */
	--tz-text-meta: 0.875rem;          /* x7  — plancher du barème (ex-0,75rem, plancher D16) */
	--tz-text-pill: 0.78125rem;        /* x4  — role PASTILLE, ⛔ pas du texte courant (ex-0,6875rem) */
	--tz-text-base: 0.875rem;          /* x3  — ex-0,84375rem */
	--tz-weight-bold: 700;             /* x5  */
	--tz-weight-semibold: 600;         /* x5  */

	/* — 6 rayons cites >= 2 fois — 🚨 valeurs du contrat V2, ⛔ SANS RAPPORT avec les
	     `--egmtheme-radius-*` du theme (16px/32px/24px) : ne jamais les confondre. — */
	--tz-radius-4xl: 12px;             /* x4  */
	--tz-radius-pill: 999px;           /* x4  */
	--tz-radius-3xl: 10px;             /* x2  */
	--tz-radius-lg: 7px;               /* x2  */
	--tz-radius-md: 6px;               /* x2  */
	--tz-radius-xl: 8px;               /* x2  */

	/* — 9 de gabarit citees >= 2 fois — */
	--tz-layout-dock-close: 26px;
	--tz-layout-dock-filter-arrow: 22px;
	--tz-layout-dock-filters-gap: 4px;
	--tz-layout-dock-row-action: 28px;
	--tz-layout-dock-row-avatar: 30px;
	--tz-layout-dock-row-padding: 10px 14px;
	--tz-layout-dock-top-avatar: 38px;
	--tz-layout-library-card-dot: 7px;
	--tz-layout-rail-gap: 12px;

	/*
	 * — 4 LUES PAR LE SCRIPT, ⛔ JAMAIS PAR LE CSS (audit 351 §3.3) —
	 * 🪤 Leur repli ecrit dans `catalogue-dock.js` vaut EXACTEMENT leur valeur servie : si on les
	 * oublie, le dock se comporte pareil et tout juge reste VERT — jusqu'au jour ou la maquette
	 * bouge un de ces quatre nombres. ⇒ le juge du lot lit la propriete CALCULEE et exige une
	 * valeur non vide, ⛔ il ne se contente pas d'un comportement correct.
	 */
	--tz-layout-dock-footer-clearance: 10px;
	--tz-layout-dock-panel-min: 280px;
	--tz-layout-dock-top-step: 130px;
	--tz-layout-dock-filters-step: 120px;

	/*
	 * — 10 EMISES PAR LE PRODUCTEUR, ⛔ CITEES PAR AUCUN CSS —
	 * `EGM_Tizofun_Connections::PALETTE` rend `--tz-dock-avatar-ink: var(--tz-subject-X-cold)` et
	 * `--tz-dock-avatar-bg: var(--tz-subject-X-tint)` dans l'attribut `style` de chaque pastille
	 * (rang = identifiant EGM modulo 5, regle ECRITE et deterministe). ⭐ Ce sont les couleurs de
	 * la palette des MATIERES, ⛔ pas une sixieme palette.
	 */
	--tz-subject-arts-cold: #B0397A;
	--tz-subject-arts-tint: #FBEEF4;
	--tz-subject-maths-cold: #1B63C4;
	--tz-subject-maths-tint: #EAF1FC;
	--tz-subject-lecture-cold: #1E7A52;
	--tz-subject-lecture-tint: #E8F4EE;
	--tz-subject-monde-cold: #0E7490;
	--tz-subject-monde-tint: #E6F3F7;
	--tz-subject-langue-cold: #6D3FD4;
	--tz-subject-langue-tint: #F3EFFE;

	/*
	 * — 16 DE PLUS, EMISES PAR LE PRODUCTEUR DE LA CARTE DE ROLE (lot B, session 353) —
	 * 🚨 **LES FAMILLES SONT TREIZE, LA MAQUETTE N'EN MONTRE QUE CINQ.**
	 * `EGM_Tizofun_Appearance::FAMILLES` en compte 13 (`neutre` compris, qui DIT l'absence de
	 * classement) et `EGM_Tizofun_Subjects::matiere_du_contenu()` peut rendre n'importe laquelle.
	 * Le dock, lui, n'en tirait que 5 parce que sa regle est `identifiant % 5` — une regle CLOSE.
	 * ⭐ *Une palette servie par une regle close n'a pas la meme cloture qu'une palette servie par
	 * la DONNEE.* Ne declarer que les cinq d'en haut ferait tomber les huit autres en `inherit` :
	 * c'est exactement le defaut silencieux de la 352 (5 pastilles incolores, 0 juge rouge).
	 * ⛔ Aucune valeur inventee : les 16 sont copiees du contrat V2 (`tokens.generated.css`), et
	 * le juge du lot mesure cette egalite.
	 */
	--tz-subject-rouge-cold: #C2362F;
	--tz-subject-rouge-tint: #FBEDEC;
	--tz-subject-ambre-cold: #A64B06;
	--tz-subject-ambre-tint: #FBF1E5;
	--tz-subject-or-cold: #7A5C06;
	--tz-subject-or-tint: #F8F3E2;
	--tz-subject-olive-cold: #4E6410;
	--tz-subject-olive-tint: #F1F5E4;
	--tz-subject-sapin-cold: #2E7D32;
	--tz-subject-sapin-tint: #E9F4EA;
	--tz-subject-indigo-cold: #3B3FA8;
	--tz-subject-indigo-tint: #EDEEFA;
	--tz-subject-prune-cold: #7B2D8E;
	--tz-subject-prune-tint: #F6EBF9;
	--tz-subject-neutre-cold: #5A6076;
	--tz-subject-neutre-tint: #F0F2F8;

	/*
	 * — 1 PROPRE A CETTE SURFACE —
	 * 📐 Le V2 collait ses cartes sous SON en-tete (`93px`). L'en-tete d'EGMtheme est un autre
	 * composant : mesure du 2026-09-03 dans `assets/dist/header/assets/header.js` —
	 * `.egmtheme-site-header{position:sticky;top:0}`, hauteur = contenu + `padding:16px 24px`,
	 * ⛔ non fixee par une regle qu'on puisse lire statiquement.
	 * ⇒ Cette valeur est un REPLI DECLARE, et `catalogue-dock.js` la RE-MESURE au chargement
	 *   (`.egmtheme-site-header` reel). ⭐ *Mesurer plutot que deviner* : sans script la colonne
	 *   colle a peu pres, avec script elle colle juste. 🪤 ⛔ Ne pas aligner ce repli sur la valeur
	 *   mesuree : un repli qui vaut la valeur servie ne se distingue plus d'elle (lecon SG-E).
	 */
	--tz-layout-catalogue-rail-sticky-top: 80px;
}

/* ═══════════════════════════ 2. LE SOCLE DES BALISES NUES (SG-A) ════════════════════════ */

/*
 * ⭐ CE BLOC EST LA POUR QUE LE COMPOSANT SOIT IDENTIQUE AVEC ET SANS LE PREFLIGHT TAILWIND.
 * Il vient EN PREMIER : toutes les regles de composant qui suivent ont la meme specificite
 * (0-1-1) et gagnent donc par l'ordre. ⛔ Ne pas le deplacer plus bas.
 */
.egmtheme-catalogue-rail *,
.egmtheme-catalogue-rail *::before,
.egmtheme-catalogue-rail *::after {
	box-sizing: border-box;
	border: 0 solid;
}

.egmtheme-catalogue-rail button,
.egmtheme-catalogue-rail input {
	margin: 0;
	padding: 0;
	font: inherit;
	color: inherit;
	background: transparent;
}

.egmtheme-catalogue-rail button {
	text-transform: none;
	appearance: button;
}

/* 🔎 Le champ de recherche natif : pas de chrome WebKit, et notre croix reste la seule. */
.egmtheme-catalogue-rail input[type='search'] {
	appearance: textfield;
	outline-offset: -2px;
}

.egmtheme-catalogue-rail input[type='search']::-webkit-search-cancel-button,
.egmtheme-catalogue-rail input[type='search']::-webkit-search-decoration {
	-webkit-appearance: none;
}

/* 🚸 `svg{display:block}` est une regle du preflight. On la pose nous-memes pour que le dessin
   ne devienne pas une boite en ligne (donc decalee) quand le bundle n'a pas tourne. */
.egmtheme-catalogue-rail svg {
	display: block;
	vertical-align: middle;
}

.egmtheme-catalogue-rail ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.egmtheme-catalogue-rail h2,
.egmtheme-catalogue-rail p {
	margin: 0;
}

/*
 * 🚨 **UN `hidden` SERVI N'EST PAS UN PIXEL CACHE.** `[hidden]{display:none}` est une regle de
 *    l'AGENT UTILISATEUR : n'importe quelle regle d'auteur qui pose `display` la bat, quelle que
 *    soit sa specificite. Or ce composant en pose une sur presque tout. Sans cette ligne, les
 *    16 controles qui portent `hidden` dans le HTML servi (contrat « sans script ») seraient
 *    peints avant que le script ne tourne, et le filtre de groupe ne cacherait aucune ligne.
 *    ⭐ Le `!important` est ici la SEULE forme correcte : il rend a `hidden` le pouvoir que la
 *    cascade lui retire des qu'on ecrit `display` quelque part dans le sous-arbre. (Lecon 345.)
 */
.egmtheme-catalogue-rail [hidden] {
	display: none !important;
}

/*
 * ── 🔗 SESSION 378 — LE MEME SOCLE, MAIS PORTE PAR LE COMPOSANT LUI-MEME ──────────────────────
 *
 * 🚨 **CE BLOC N'EST PAS UN DOUBLON : IL EST LA CONDITION POUR QUE LE DOCK SOIT PORTABLE.** Le
 *    socle ci-dessus est ancre sur `.egmtheme-catalogue-rail`, c'est-a-dire sur UNE surface. Le
 *    dock en sert deux depuis la 378, et la seconde (la colonne de droite de l'accueil) porte
 *    d'autres composants — des cartes, des boutons « Suivre », des titres — qui ont leur propre
 *    style. Etendre le socle a `.tz-dock-scope` aurait donc reinitialise les VOISINS du dock.
 * ⭐ *Ce qui protege un composant se porte sur le composant, ⛔ pas sur la piece ou il est pose.*
 *    ⇒ ces regles sont bornees a `.tz-dock` et a son sous-arbre : elles n'atteignent rien d'autre,
 *    sur aucune des deux surfaces.
 * ⚠️ Elles sont la copie EXACTE des valeurs du socle d'au-dessus. Toute divergence de valeur entre
 *    les deux se verrait a l'oeil et dans aucun test de presence.
 */
.tz-dock,
.tz-dock *,
.tz-dock *::before,
.tz-dock *::after {
	box-sizing: border-box;
	border: 0 solid;
}

.tz-dock button,
.tz-dock input {
	margin: 0;
	padding: 0;
	font: inherit;
	color: inherit;
	background: transparent;
}

.tz-dock button {
	text-transform: none;
	appearance: button;
}

.tz-dock input[type='search'] {
	appearance: textfield;
	outline-offset: -2px;
}

.tz-dock input[type='search']::-webkit-search-cancel-button,
.tz-dock input[type='search']::-webkit-search-decoration {
	-webkit-appearance: none;
}

.tz-dock svg {
	display: block;
	vertical-align: middle;
}

.tz-dock ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.tz-dock h2,
.tz-dock p {
	margin: 0;
}

/* 🚨 Meme raison, meme forme, meme `!important` que ci-dessus (lecon 345) : les 16 controles qui
   portent `hidden` dans le HTML servi doivent le rester tant que le script n'a pas tourne. */
.tz-dock [hidden] {
	display: none !important;
}

/* ═══════════════════════════ 3. LA MISE EN PAGE A DEUX COLONNES ═════════════════════════ */

/*
 * 📐 Le gabarit `page-catalogue.html` sert desormais [racine React] + [colonne PHP] dans une
 * meme ligne. ⭐ La largeur maximale et le fond appartiennent au CONTENANT COMMUN, ⛔ plus a la
 * colonne principale : une colonne voisine ne peut pas s'aligner sur un frere qui reclame toute
 * la largeur (`max-w-7xl mx-auto`) ni toute la hauteur du viewport (`min-h-screen`).
 * ⇒ Les deux classes sont retirees d'`App.tsx` (lot A5), et leurs effets reprennent ici.
 */
.egmtheme-catalogue-shell {
	display: flex;
	align-items: stretch;
	gap: 16px;                    /* meme respiration que `--tz-layout-rail-gap` + 4 */
	width: 100%;
	/* 📐 539 — la coque du catalogue rejoint la colonne unique du site (`--egm-page-max`).
	   Elle portait `80rem` (1280), heritage du `max-w-7xl` retire d'`App.tsx` au lot A5.
	   📢 Le rail a droite ne bouge pas : il reste a `max-width: 330px` avec ses 14 px de
	   gouttiere interne ⇒ la pub y dispose de 330 − 2×14 = **302 px** de boite de contenu,
	   au-dessus du plancher de 300 px (consigne porteur du 15-09). Les 80 px gagnes par la
	   coque vont donc tous a la colonne de cartes, ⛔ aucun a la colonne de pub. */
	max-width: var(--egm-page-max, 1360px);
	margin: 0 auto;
	padding: 24px 16px;           /* = `py-6 px-4` retire d'App.tsx */
	box-sizing: border-box;       /* 📐 539 — sans lui la coque rend 1360 + 32 = 1392 */
}

/* La colonne principale (la racine React) : elle prend ce qui reste, et elle peut retrecir.
   ⭐ `min-width:0` est obligatoire — sans lui, une grille de cartes refuse de se comprimer et
   pousse la colonne creme hors de l'ecran. */
.egmtheme-catalogue-shell__main {
	flex: 1 1 0;
	min-width: 0;
}

/*
 * Le fond de la page reste PLEINE LARGEUR, comme avant le lot A (`bg-gray-50` d'App.tsx).
 *
 * 🎨 SESSION 361 — LA COULEUR VIENT DU MODELE, ⛔ PLUS DE TAILWIND. `#F9FAFB` etait le
 * `bg-gray-50` de l'app : un gris BLEUTE. Le modele pose `body{background:#faf9f5}`
 * (`app.dc.html` l. 16) : un blanc CASSE, chaud, de la meme famille que le creme de la colonne
 * (`#FAF2E2`) et que la banniere d'appel (`#FDF6EA`). ⭐ *Un fond froid sous des surfaces
 * chaudes ne se lit pas comme une nuance : il se lit comme une erreur d'assemblage.*
 *
 * 📐 ET LA BANDE VIDE SOUS LE MENU (demande porteur du 2026-09-04). Meme cause qu'en 257 sur la
 * page d'un jeu, meme remede, meme foyer : le `--wp--style--block-gap` (24px) que la mise en
 * page des blocs applique a tout enfant de `.wp-site-blocks`. Ce n'est ni une marge de l'app,
 * ni un rembourrage de la coque — la coque garde SON `padding: 24px 16px`, qui est la
 * respiration INTERIEURE du contenu et n'a jamais ete en cause.
 * 🪤 Portee : `/catalogue` SEULE. ⛔ Aucune autre page ne perd son gap.
 * Specificite (0,1,1) contre le `:where()` de WordPress (0,0,0) : la regle gagne sans `!important`.
 */
main.egmtheme-catalogue {
	background: #FAF9F5;
	margin-block-start: 0;
}

/*
 * 🪤 SOUS 900px, LA COLONNE PASSE SOUS LE CONTENU. C'est le meme seuil que celui du script
 * (`window.innerWidth < 900`), et ce n'est pas une coincidence : au-dessous, le dock cesse d'etre
 * ancre — un panneau fixe de 330px sur un telephone recouvrirait la page. ⭐ Les deux moities
 * doivent basculer au MEME nombre, sinon il existe une largeur ou la colonne est en flux et le
 * dock encore fixe.
 */
@media (max-width: 899px) {
	.egmtheme-catalogue-shell {
		flex-direction: column;
	}

	.egmtheme-catalogue-rail {
		max-width: none;
	}
}

/* ═══════════════════════════ 4. LA COLONNE ══════════════════════════════════════════════ */

/* 📐 MESURE MAQUETTE (app.dc.html l. 168) : la colonne est un CONTENANT creme borde, ⛔ pas une
   simple pile de cartes. `align-self:stretch` lui fait epouser la hauteur de la colonne
   principale — c'est ce qui donne le bandeau creme continu jusqu'au pied de page. */
.egmtheme-catalogue-rail {
	display: flex;
	flex: 1 1 264px;                        /* --tz-layout-rail-basis */
	flex-direction: column;
	align-self: stretch;
	gap: var(--tz-layout-rail-gap);
	min-width: 0;
	max-width: var(--egm-page-rail, 330px); /* --tz-layout-rail-max · 📐 890 : foyer `front.css` */
	padding: 14px;                          /* --tz-layout-rail-padding */
	border: 1px solid var(--tz-warm-rail-border);
	border-radius: 16px;                    /* --tz-radius-panel */
	background: var(--tz-warm-rail);
}

/* 📐 MESURE MAQUETTE (l. 191) : les DEUX dernieres cartes de la colonne sont collantes sous
   l'en-tete, ⛔ pas la colonne entiere. */
.egmtheme-catalogue-rail .tz-rail__sticky {
	position: sticky;
	top: var(--tz-layout-catalogue-rail-sticky-top);
	display: flex;
	flex-direction: column;
	gap: var(--tz-layout-rail-gap);
}

/* 📱 750/R10 — LE REPLI DE LA COLONNE. Au bureau, `tz-rail__more` n'existe pas pour la mise en
   page (`display: contents` : ses cartes restent des enfants flex du conteneur collant, au meme
   ecart) et le bouton ne se montre pas. Il ne vit que sous 900px (le `@media` juste dessous) ;
   seul le script pose `aria-expanded="false"`, donc sans script tout reste deplie. */
.egmtheme-catalogue-rail .tz-rail__more {
	display: contents;
}

.egmtheme-catalogue-rail .tz-rail__fold {
	display: none;
}

@media (max-width: 899px) {
	/* La colonne est sous le contenu : plus rien ne colle (la page parcours le faisait deja, l. 1664). */
	.egmtheme-catalogue-rail .tz-rail__sticky {
		position: static;
	}

	.egmtheme-catalogue-rail .tz-rail__fold:not([hidden]) {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 6px;
		width: 100%;
		min-height: 38px;                   /* loi 484 — ⚖️ D1 tranché 25-09 : 44 au doigt, bloc R9-bis plus bas */
		padding: 8px 14px;
		border: 1px solid var(--tz-warm-rail-border);
		border-radius: var(--tz-radius-xl);
		background: var(--tz-surface-page);
		color: var(--tz-warm-ink);
		font: inherit;
		font-size: var(--tz-text-base);
		font-weight: 600;
		cursor: pointer;
	}

	.egmtheme-catalogue-rail .tz-rail__fold:focus-visible {
		outline: 2px solid var(--tz-warm-gold);
		outline-offset: 2px;
	}

	.egmtheme-catalogue-rail .tz-rail__fold svg {
		transition: transform .2s ease;
		transform: rotate(-90deg);
	}

	.egmtheme-catalogue-rail .tz-rail__fold[aria-expanded="false"] svg {
		transform: rotate(90deg);
	}

	.egmtheme-catalogue-rail .tz-rail__fold[aria-expanded="false"] + .tz-rail__more {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.egmtheme-catalogue-rail .tz-rail__fold svg {
		transition: none;
	}
}

/* ═══════════════════════════ 5. LA CARTE A TETE SOMBRE ═════════════════════════════════ */

/* 📐 MESURE MAQUETTE : c'est LA forme des cartes de la colonne — publicite, tendances,
   collections, createurs. Une seule regle, ⛔ pas une par cellule. */
.egmtheme-catalogue-rail .tz-railcard {
	overflow: hidden;
	border: 1px solid var(--tz-warm-surface-dim);
	border-radius: 13px;                    /* --tz-radius-5xl */
	background: var(--tz-surface-page);
	/* --tz-shadow-rail-card */
	box-shadow: 0 1px 1px rgba(122, 74, 15, .05), 0 3px 7px -3px rgba(122, 74, 15, .10);
}

.egmtheme-catalogue-rail .tz-railcard__head {
	display: flex;
	align-items: center;
	gap: 9px;                               /* --tz-layout-library-card-head-gap */
	padding: 13px 16px;                     /* --tz-layout-library-card-head-padding */
	background: var(--tz-warm-ink);
}

.egmtheme-catalogue-rail .tz-railcard__dot {
	flex: none;
	width: var(--tz-layout-library-card-dot);
	height: var(--tz-layout-library-card-dot);
	border-radius: var(--tz-radius-pill);
	background: var(--tz-warm-gold);
}

/* 🔤 ECART D16 DECLARE : la maquette ecrit 10,5px ; le plancher d'accessibilite du chantier
   releve a 12px (`text-meta`). L'ecart est DIT ici, il ne se decouvre pas dans un diff. */
/* 🏷️ 1529 (porteur) — TOUS les en-tetes de widget prennent la valeur des en-tetes de pub (1528) :
   11 px, graisse normale (ex-`text-meta` gras). ECART D16 DECLARE, comme pour la pub. */
.egmtheme-catalogue-rail .tz-railcard__label {
	font-size: 0.6875rem;
	font-weight: 400;
	letter-spacing: .11em;
	text-transform: uppercase;
	color: var(--tz-warm-highlight);
}

/* 🏷️ 1528 (porteur) — l'en-tete d'une PUB s'ecrit plus petit et en graisse normale (ex-14 px gras),
   meme valeur que le Hub (`.ah-ad-card__label`) et la communaute. ECART D16 DECLARE : 11 px, sous le
   plancher du bareme, voulu par le porteur pour une mention, ⛔ pour un texte a lire. */
.egmtheme-catalogue-rail .tz-ad .tz-railcard__label {
	font-size: 0.6875rem;
	font-weight: 400;
}

.egmtheme-catalogue-rail .tz-railcard__note {
	margin-left: auto;
	font-size: var(--tz-text-meta);
	color: var(--tz-warm-highlight-dim);
	text-decoration: none;
}

/* 👆 R9-bis (831 ; ⚖️ D1 : 44 px au doigt, la souris garde sa densité) — mesuré à 390 tactile sur
   `/catalogue/` : note de carte 18 px, bouton de repli de la colonne 38 px. `--egm-tap-min` : jeton
   public de la cible tactile (repli 44 = la valeur servie). */
@media (pointer: coarse) {
	.egmtheme-catalogue-rail .tz-railcard__note {
		display: inline-flex;
		align-items: center;
		min-height: var(--egm-tap-min, 44px);
	}

	/* Même sélecteur que la règle de 38 (`:not([hidden])`, 0-3-0) : à spécificité égale, la
	   dernière déclarée gagne — celle-ci. */
	.egmtheme-catalogue-rail .tz-rail__fold:not([hidden]) {
		min-height: var(--egm-tap-min, 44px);
	}
}

.egmtheme-catalogue-rail .tz-railcard__body {
	padding: 12px;                          /* --tz-layout-library-card-body-padding */
}

/* ═══════════════════════════ 6. L'EMPLACEMENT PUBLICITAIRE ═════════════════════════════ */

/* La creative vient de la regie, qui l'a deja bornee et porte la garde E6. Cette feuille ne fait
   que lui reserver sa place — ⛔ elle ne decide rien de ce qui s'y affiche.
   `--tz-ad-w` / `--tz-ad-h` sont poses EN LIGNE par le producteur (300x250 par defaut).

   🚨 ECART DECLARE vs MAQUETTE — ET C'EST LA MAQUETTE QUI SE CONTREDIT (signalement porteur du
   2026-09-04, session 360). Le modele (`app.dc.html` l. 198) laisse `padding:12px` au corps de
   la carte pub et y pose un gabarit pointille qui annonce lui-meme « 300 × 250 » — dans une
   boite qui n'en fait que 276. Le code en heritait, via la regle generique
   `.tz-railcard__body`. La chaine mesuree : colonne 330px (`tz-rail` max-width) − 2×14px de
   gouttiere = 302px de carte − 2×1px de bordure = 300px de corps. C'est EXACTEMENT le format
   que le producteur annonce (`width => 300`). Les 12px volaient donc 24px a une creative de
   300px, et `overflow:hidden` la coupait ensuite SANS UN MOT.
   ⭐ *Une gouttiere heritee d'une regle generique devient une amputation quand le contenu a un
   format impose.* ⇒ le corps de la carte PUB — et lui seul — n'a pas de gouttiere. */
.egmtheme-catalogue-rail .tz-ad .tz-railcard__body {
	padding: 0;
}

.egmtheme-catalogue-rail .tz-ad__slot {
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--tz-ad-w, 300px);           /* --tz-layout-ad-width */
	max-width: 100%;
	min-height: var(--tz-ad-h, 250px);      /* --tz-layout-ad-height */
	margin: 0 auto;
	overflow: hidden;
	/* Une creative a format fixe (une image 300x250) reste centree DANS l'enveloppe etiree. */
	text-align: center;
	/* ⛔ Plus d'arrondi propre au slot : sans gouttiere, il touche les bords de la carte, et
	   c'est `overflow:hidden` + `border-radius:13px` de `.tz-railcard` qui arrondit les deux
	   coins bas. Un second arrondi ici creuserait un liston clair entre les deux. */
	border-radius: 0;
}

/* 🚨 LA VRAIE CAUSE DES BANDES BLANCHES — ET LA GOUTTIERE N'EN ETAIT QUE LA MOITIE
   (2e signalement porteur du 2026-09-04, DOM servi a l'appui).

   La regie n'insere pas la creative en direct : elle l'enveloppe dans
   `<div class="egmam-ad eam-ad-34987">`. Cette enveloppe est donc **l'unique enfant** du slot,
   donc **un item flex**, donc `flex: 0 1 auto` — sa largeur est celle de son CONTENU, ⛔ pas
   celle du slot. Et la creative, elle, demande `width: 100%`... de cette enveloppe retrecie.
   La chaine se referme sur elle-meme : la largeur finale est celle du texte le plus long de
   la creative (« ESPACE PUBLICITAIRE », ~190px), ⛔ pas les 300px du slot.

   ⭐ *Un `width: 100%` ne vaut que ce que vaut le parent : dans un conteneur flex, le parent
   est un item qui RETRECIT sur son contenu, et 100 % d'une largeur devinee ne remplit rien.*
   🪤 Le defaut est doublement silencieux : la creative se croit responsive, le slot se croit a
   300px, et aucun des deux ne ment — c'est l'enveloppe intercalee, invisible dans les deux
   feuilles, qui decide. Elle n'appartient a personne : ni au theme, ni a la creative.

   ⇒ On etire explicitement ce que la regie intercale. `flex-basis: 100%` (⛔ pas `width`) pour
   que la regle reste juste si la regie ajoute un jour un 2e enfant, et `min-width: 0` pour que
   le contenu long ne repousse pas la boite au-dela de la carte. */
.egmtheme-catalogue-rail .tz-ad__slot > * {
	flex: 1 1 100%;
	min-width: 0;
}

/* ═══════════════════════════ 7. LE BLOC PREMIUM ════════════════════════════════════════ */

/* 📐 MESURE MAQUETTE (l. 169-174) : le bloc est peint en ambre PLEIN et porte l'ombre haute
   (8px/22px), ⛔ pas celle du bouton du hero (4px/12px). */
.egmtheme-catalogue-rail .tz-premium {
	padding: 20px;                          /* --tz-layout-library-premium-padding */
	border-radius: var(--tz-radius-4xl);
	/* ♿ 1291/TYPO3 — décision porteur 06-10 « orange foncé + blanc » : sur `#E07A00` le blanc ne
	   valait que 3,02:1 et le crème 2,59:1 ⇒ `#A35500` (blanc 5,45:1, crème 4,67:1).
	   🎨 2843 — consigne porteur 10-27 « plus clair, autour de #bd6e00 » ⇒ `#BD6E00` (blanc 3,9:1) :
	   le texte passe du crème au blanc pour garder la meilleure lecture possible sur ce fond.
	   ♿ 2856 — porteur 10-28 « applique la reco du collège » ⇒ `#AE6500` : même teinte, −8 %, le plus
	   clair qui tient AA partout (blanc 4,51:1 ; titre 18 px et texte 14 px sont du texte COURANT). */
	background: #AE6500;                    /* ex-#BD6E00 (2843, 3,89:1), ex-#A35500 (1291) */
	box-shadow: 0 8px 22px rgba(196, 106, 0, .32); /* --tz-shadow-cta-amber-high */
}

.egmtheme-catalogue-rail .tz-premium__badge {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 10px;                      /* --tz-layout-library-premium-badge-padding */
	border-radius: var(--tz-radius-pill);
	background: rgba(255, 255, 255, .12);   /* --tz-surface-glass-chip */
	font-size: var(--tz-text-pill);
	font-weight: var(--tz-weight-semibold);
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--tz-surface-page);
}

.egmtheme-catalogue-rail .tz-premium__title {
	margin: 12px 0 8px;                     /* --tz-layout-library-premium-title-margin */
	font-size: 1.125rem;                    /* --tz-text-2xl */
	font-weight: var(--tz-weight-semibold);
	letter-spacing: -.015em;
	color: var(--tz-surface-page);
}

.egmtheme-catalogue-rail .tz-premium__text {
	margin: 0 0 18px;                       /* --tz-layout-library-premium-text-margin */
	font-size: var(--tz-text-base);
	line-height: 1.6;                       /* --tz-layout-library-premium-text-lh */
	color: #FFFFFF;                         /* 2843 : ex-#FFEBCE ; 2856 : blanc 4,51:1 sur #AE6500 */
	text-wrap: pretty;
}

/* 📐 La hauteur plancher de 46px suffit a en faire une cible sure — meme mesure que le bouton
   pose sur le visuel du slider (334). */
.egmtheme-catalogue-rail .tz-premium__cta {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 46px;                       /* --tz-layout-library-premium-cta-height */
	padding: 0 14px;
	border: 0;
	border-radius: 9px;                     /* --tz-radius-2xl */
	background: var(--tz-surface-page);
	font-family: inherit;
	font-size: 0.875rem;                    /* --tz-text-md */
	font-weight: var(--tz-weight-semibold);
	color: #AE6500;                         /* 2856 : suit le fond, 4,51:1 sur blanc ; 2843 : #BD6E00 */
	text-decoration: none;
	cursor: pointer;
}

.egmtheme-catalogue-rail .tz-premium__cta:hover,
.egmtheme-catalogue-rail .tz-premium__cta:focus-visible {
	color: var(--tz-warm-ink);
}

/* ═══════════════════════════ 8. LE DOCK — LE CONTENANT ═════════════════════════════════ */

/* 📐 MESURE MAQUETTE (l. 447) : le dock est `position:fixed`, colle en bas, MAIS sa `left` et sa
   `width` sont recopiees depuis la colonne laterale en flux. Sans script, il reste en bas de la
   colonne : c'est un repli LISIBLE, ⛔ pas une mise en page cassee. */
.tz-dock-scope .tz-dock {
	position: relative;
	z-index: 40;
	margin-top: auto;
}

/*
 * 🚨 **LA CEINTURE DU PLANCHER** (defaut porteur du 2026-09-03). La geometrie du script borne
 * desormais le panneau SOUS l'en-tete, donc ce `z-index` ne devrait jamais servir — sauf dans un
 * cas, ecrit et assume : quand la fenetre est si basse que le plancher de 280px
 * (`--tz-layout-dock-panel-min`) l'emporte sur la place disponible. La, le panneau MORD sur la
 * barre de menu, et il vaut mieux qu'il la couvre que d'etre avale par elle.
 * 📏 MESURE : `.egmtheme-site-header{z-index:1000}` (`assets/dist/header/assets/header.js`).
 * ⭐ Le V2 avait recolte `z-index:40` — il vivait sous un AUTRE en-tete. ⛔ Un nombre recolte n'est
 *   pas un nombre mesure : il ne vaut que dans la pile ou il a ete releve.
 * 🚸 La surcharge ne vaut QUE pour l'etat ancre (le dock fixe). En flux, le dock garde le 40 de la
 *   maquette : il n'a alors aucun voisin a depasser.
 */
.tz-dock-scope .tz-dock[data-tz-dock-anchored] {
	position: fixed;
	z-index: 1001;
	bottom: 0;
	margin-top: 0;
}

/* ⛔ Le marqueur natif du `<summary>` : la maquette n'en a pas. Les deux selecteurs sont
   necessaires (WebKit garde le sien hors du `::marker`). */
.tz-dock-scope .tz-dock__toggle::-webkit-details-marker {
	display: none;
}

.tz-dock-scope .tz-dock__toggle::marker {
	content: '';
}

/* ═══════════════════════════ 9. LE SOCLE ET SON BOUTON ═════════════════════════════════ */

/* 📐 MESURE MAQUETTE (l. 448) : le socle est du papier creme borde, et son ombre MONTE. */
.tz-dock-scope .tz-dock__toggle {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	gap: 10px;                              /* --tz-layout-dock-toggle-gap */
	padding: 12px 14px;                     /* --tz-layout-dock-toggle-padding */
	margin: 12px 12px 14px;                 /* --tz-layout-dock-wrap-padding */
	border-radius: var(--tz-radius-4xl);
	background: var(--tz-warm-ink);
	box-shadow: 0 8px 20px rgba(13, 16, 36, .18); /* --tz-shadow-dock-toggle */
	color: var(--tz-surface-page);
	cursor: pointer;
	list-style: none;
	font-size: var(--tz-text-base);
	font-weight: var(--tz-weight-semibold);
}

/* Le socle creme lui-meme : un calque derriere le bouton, aux mesures du wrap de la maquette. */
.tz-dock-scope .tz-dock::before {
	content: '';
	position: absolute;
	inset: 0;
	border: 1px solid var(--tz-warm-rail-border);
	border-bottom: none;
	border-radius: 16px 16px 0 0;           /* --tz-layout-dock-wrap-radius */
	background: var(--tz-warm-rail);
	box-shadow: 0 -6px 16px rgba(61, 42, 18, .08); /* --tz-shadow-dock-base */
	pointer-events: none;
}

/* 📐 MESURE MAQUETTE (l. 449) : OUVERT, le bouton perd ses deux coins hauts — il « sort » du
   panneau. C'est la seule difference visuelle du socle entre les deux etats. */
.tz-dock-scope .tz-dock[open] > .tz-dock__toggle {
	border-radius: 0 0 var(--tz-radius-4xl) var(--tz-radius-4xl);
}

/*
 * 📐 DEMANDE PORTEUR (session 345) : **le socle inverse son dehors avec le bouton**. FERME, il
 *    coiffe le dock (`16px 16px 0 0`) et sa bordure basse n'existe pas. OUVERT, le panneau vient
 *    se poser DESSUS : ⭐ *deux coins arrondis entre deux surfaces jointives dessinent une fente*,
 *    donc les coins hauts s'effacent et ce sont les coins bas qui s'arrondissent.
 * ⭐ La bordure suit le rayon, ⛔ elle ne reste pas en haut : un filet horizontal la ou le panneau
 *    et le socle se touchent ferait deux boites au lieu d'une.
 */
.tz-dock-scope .tz-dock[open]::before {
	border-top: none;
	border-bottom: 1px solid var(--tz-warm-rail-border);
	border-radius: 0 0 16px 16px;           /* --tz-layout-dock-wrap-radius-open */
}

.tz-dock-scope .tz-dock__label {
	flex: 1;
	min-width: 0;
	text-align: left;
}

/* 🔤 Maquette 11,5px ⇒ `text-meta` (12px) par D16. */
.tz-dock-scope .tz-dock__count {
	color: var(--tz-warm-highlight-dim);
	font-size: var(--tz-text-meta);
	font-weight: 400;                       /* --tz-weight-regular */
}

.tz-dock-scope .tz-dock__chevron {
	flex: none;
	transition: transform .18s ease;        /* --tz-motion-card */
}

.tz-dock-scope .tz-dock[open] .tz-dock__chevron {
	transform: rotate(180deg);
}

/*
 * 📐 **DEMANDE PORTEUR (session 355) : OUVERT, LE SOCLE S'EFFACE.** Il repetait l'icone, le titre
 *    et le compteur que la tete du panneau porte desormais, et il coutait ~62px de haut — sur un
 *    telephone en paysage, c'est un tiers de la liste des contacts.
 * 🏠 **LA GARDE EST `[data-tz-dock-enhanced]`, ⛔ PAS `[open]` SEUL.** Cet attribut n'existe que
 *    si le script tourne. Sans script, la croix de fermeture reste `hidden` : le `<summary>` est
 *    alors le SEUL controle qui referme le dock, et le retirer enfermerait la personne dans un
 *    panneau ouvert. ⭐ *Ce qui remplace un controle doit exister avant qu'on retire celui qu'il
 *    remplace* — meme loi que les `hidden data-tz-dock-enhance` du markup servi.
 * 🪤 `display:none` sur le `<summary>`, ⛔ pas `visibility` ni une hauteur nulle : c'est la
 *    HAUTEUR du dock que le script soustrait (`dock.offsetHeight` dans `ancrer()`), et un element
 *    invisible mais mesurable rendrait au panneau exactement les pixels qu'on vient de lui gagner.
 * 🧱 Le socle creme (`::before`) suit : `inset:0` sur une boite devenue plate laisserait un filet
 *    d'1px de bordure sous le panneau.
 */
.tz-dock-scope .tz-dock[data-tz-dock-enhanced][open] > .tz-dock__toggle,
.tz-dock-scope .tz-dock[data-tz-dock-enhanced][open]::before {
	display: none;
}

/* ═══════════════════════════ 10. LE PANNEAU ════════════════════════════════════════════ */

/* 📐 MESURE MAQUETTE (l. 457) : le panneau sort PAR LE HAUT du dock (`bottom:100%`), il est blanc,
   borde chaud, sans bordure basse, et son ombre monte elle aussi. */
.tz-dock-scope .tz-dock__panel {
	display: flex;
	flex-direction: column;
	max-height: 440px;                      /* --tz-layout-dock-panel-max */
	overflow: hidden;
	border: 1px solid var(--tz-warm-surface-dim);
	border-bottom: none;
	border-radius: 14px 14px 0 0;           /* --tz-layout-dock-panel-radius */
	background: var(--tz-surface-page);
	box-shadow: 0 -8px 30px rgba(13, 16, 36, .14); /* --tz-shadow-dock-panel */
}

/*
 * 📐 SESSION 355 — EN FLUX (sous 900px, ou script absent d'ancrage), le panneau n'a plus de socle
 *    sous lui : sans bordure basse il se lirait comme une boite COUPEE. ⭐ *Un bord manquant se
 *    lit comme une troncature, ⛔ pas comme un choix.*
 */
.tz-dock-scope .tz-dock[data-tz-dock-enhanced][open] .tz-dock__panel {
	border-bottom: 1px solid var(--tz-warm-surface-dim);
	border-radius: 14px;                    /* --tz-layout-dock-panel-radius */
}

/* Ancre : quand le script tient la geometrie, le panneau devient absolu au-dessus du socle. */
.tz-dock-scope .tz-dock[data-tz-dock-anchored] .tz-dock__panel {
	position: absolute;
	right: 0;
	bottom: 100%;
	left: 0;
	z-index: 60;
}

/* 🪤 ANCRE : la, le panneau touche le bas de la fenetre — un bord bas arrondi y dessinerait une
   fente sur le vide. Il reprend donc la forme de la maquette (l. 457). ⚠️ Cette regle DOIT rester
   APRES celle du flux : les deux ont la meme specificite, c'est l'ordre qui tranche. */
.tz-dock-scope .tz-dock[data-tz-dock-enhanced][data-tz-dock-anchored][open] .tz-dock__panel {
	border-bottom: none;
	border-radius: 14px 14px 0 0;           /* --tz-layout-dock-panel-radius */
}

.tz-dock-scope .tz-dock__head {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 13px 16px;                     /* --tz-layout-dock-head-padding */
	background: var(--tz-warm-ink);
}

/* 📐 SESSION 355 : la tete porte desormais l'identite du dock — l'icone, le titre, le compteur,
   la croix. L'icone et le compteur sont ceux du socle, ⛔ pas des jumeaux : meme balise, meme
   classe, meme methode PHP. */
.tz-dock-scope .tz-dock__head > .tz-icon {
	flex: none;
	color: var(--tz-surface-page);
}

.tz-dock-scope .tz-dock__headcount {
	flex: none;
}

.tz-dock-scope .tz-dock__title {
	flex: 1;
	min-width: 0;
	color: var(--tz-surface-page);
	font-size: var(--tz-text-base);
	font-weight: var(--tz-weight-bold);
}

.tz-dock-scope .tz-dock__close {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: var(--tz-layout-dock-close);
	height: var(--tz-layout-dock-close);
	border: none;
	border-radius: var(--tz-radius-lg);
	background: #8FA6FF;                    /* --tz-action-on-dark */
	color: var(--tz-surface-page);
	cursor: pointer;
}

/* ═══════════════════════════ 11. LA RECHERCHE ══════════════════════════════════════════ */

.tz-dock-scope .tz-dock__searchwrap {
	padding: 12px 14px 0;                   /* --tz-layout-dock-search-padding */
}

.tz-dock-scope .tz-dock__search {
	display: flex;
	align-items: center;
	gap: 8px;
	height: 36px;                           /* --tz-layout-dock-search-height */
	padding: 0 12px;                        /* --tz-layout-dock-search-inset */
	border: 1px solid #DCDFEA;              /* --tz-border-strong */
	border-radius: var(--tz-radius-xl);
	background: var(--tz-surface-page);
}

.tz-dock-scope .tz-dock__searchicon {
	flex: none;
	color: var(--tz-ink-faint);
}

.tz-dock-scope .tz-dock__searchinput {
	flex: 1;
	min-width: 0;
	border: none;
	outline: none;
	background: none;
	color: var(--tz-ink-strong);
	font: inherit;
	font-size: 0.78125rem;                  /* --tz-text-small */
}

/* ═══════════════════════════ 12. « LES PLUS CONSULTES » ════════════════════════════════ */

.tz-dock-scope .tz-dock__top {
	padding: 12px 14px 4px;                 /* --tz-layout-dock-top-padding */
}

/* 🔤 Maquette 10,5px ⇒ `text-pill` (11px) par D16 — et c'est bien une PASTILLE (un sur-titre),
   pas une phrase : E10 tient (le sens n'est jamais porte par la seule couleur). */
.tz-dock-scope .tz-dock__kicker {
	color: var(--tz-warm-gold-ink);
	font-size: var(--tz-text-pill);
	font-weight: var(--tz-weight-bold);
	letter-spacing: .09em;
	text-transform: uppercase;
}

.tz-dock-scope .tz-dock__toprow {
	display: flex;
	align-items: center;
	gap: var(--tz-layout-dock-filters-gap);
	margin: 9px 0 0;                        /* --tz-layout-dock-top-margin */
}

.tz-dock-scope .tz-dock__topscroll {
	display: flex;
	flex: 1;
	gap: 10px;                              /* --tz-layout-dock-top-gap */
	min-width: 0;
	overflow-x: auto;
	scrollbar-width: none;
}

/* 📐 MESURE MAQUETTE : la barre de defilement des DEUX rangees est masquee. */
.tz-dock-scope .tz-dock__topscroll::-webkit-scrollbar,
.tz-dock-scope .tz-dock__filterscroll::-webkit-scrollbar {
	display: none;
}

.tz-dock-scope .tz-dock__toparrow {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 20px;                            /* --tz-layout-dock-top-arrow-w */
	height: 38px;                           /* --tz-layout-dock-top-arrow-h */
	border: none;
	border-radius: var(--tz-radius-md);
	background: var(--tz-surface-soft);
	color: var(--tz-ink-muted);
	cursor: pointer;
}

.tz-dock-scope .tz-dock__topitem {
	display: flex;
	flex: none;
	flex-direction: column;
	align-items: center;
	gap: 5px;
	width: 52px;                            /* --tz-layout-dock-top-item */
	padding: 0;
	border: none;
	background: none;
	cursor: pointer;
}

.tz-dock-scope .tz-dock__topavatar {
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--tz-layout-dock-top-avatar);
	height: var(--tz-layout-dock-top-avatar);
	border-radius: var(--tz-radius-pill);
	background: var(--tz-dock-avatar-bg);
	color: var(--tz-dock-avatar-ink);
	font-size: var(--tz-text-meta);
	font-weight: var(--tz-weight-bold);
}

.tz-dock-scope .tz-dock__topname {
	overflow: hidden;
	max-width: 100%;
	color: var(--tz-ink-body);
	font-size: var(--tz-text-meta);         /* 🔠 1294 : un nom, pas une pastille ⇒ plancher 14 */
	line-height: 1.2;
	text-align: center;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* ═══════════════════════════ 13. LES FILTRES DE GROUPE ═════════════════════════════════ */

.tz-dock-scope .tz-dock__filters {
	display: flex;
	align-items: center;
	gap: var(--tz-layout-dock-filters-gap);
	padding: 10px 14px;                     /* --tz-layout-dock-filters-padding */
	border-top: 1px solid var(--tz-warm-surface);
}

.tz-dock-scope .tz-dock__filterarrow {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: var(--tz-layout-dock-filter-arrow);
	height: var(--tz-layout-dock-filter-arrow);
	border: none;
	border-radius: var(--tz-radius-md);
	background: var(--tz-surface-soft);
	color: var(--tz-ink-muted);
	cursor: pointer;
}

.tz-dock-scope .tz-dock__filterscroll {
	display: flex;
	flex: 1;
	flex-wrap: nowrap;
	gap: var(--tz-layout-dock-filters-gap);
	min-width: 0;
	padding: 4px;                           /* --tz-layout-dock-filters-inset */
	border-radius: var(--tz-radius-3xl);
	background: var(--tz-warm-rail);
	overflow-x: auto;
	scrollbar-width: none;
}

.tz-dock-scope .tz-dock__filter {
	flex: none;
	padding: 6px 12px;                      /* --tz-layout-dock-filter-padding */
	border: none;
	border-radius: var(--tz-radius-lg);
	background: none;
	color: var(--tz-ink-body);
	cursor: pointer;
	font-size: var(--tz-text-meta);
	font-weight: 500;                       /* --tz-weight-medium */
	white-space: nowrap;
}

/* 📐 MESURE MAQUETTE : le filtre ACTIF est une pastille blanche posee sur le creme, avec l'ombre
   d'onglet du contrat. ⭐ Et il ne se dit pas QUE par la couleur : `aria-pressed` le porte. */
.tz-dock-scope .tz-dock__filter[aria-pressed='true'] {
	background: var(--tz-surface-page);
	box-shadow: 0 1px 2px rgba(13, 16, 36, .12); /* --tz-shadow-tab-active */
	color: var(--tz-ink-strong);
}

/* ═══════════════════════════ 14. LA LISTE DE PERSONNES ═════════════════════════════════ */

.tz-dock-scope .tz-dock__list {
	display: flex;
	flex: 1;
	flex-direction: column;
	min-height: 0;
	margin: 0;
	padding: 0;
	list-style: none;
	overflow-y: auto;
}

.tz-dock-scope .tz-dock__row {
	display: flex;
	align-items: center;
	gap: 10px;                              /* --tz-layout-dock-row-gap */
	padding: var(--tz-layout-dock-row-padding);
	border-top: 1px solid var(--tz-warm-surface);
}

.tz-dock-scope .tz-dock__avatar {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: var(--tz-layout-dock-row-avatar);
	height: var(--tz-layout-dock-row-avatar);
	border-radius: var(--tz-radius-pill);
	background: var(--tz-dock-avatar-bg);
	color: var(--tz-dock-avatar-ink);
	font-size: var(--tz-text-meta);
	font-weight: var(--tz-weight-bold);
}

.tz-dock-scope .tz-dock__who {
	flex: 1;
	min-width: 0;
}

.tz-dock-scope .tz-dock__name {
	display: block;
	overflow: hidden;
	color: var(--tz-warm-ink);
	font-size: var(--tz-text-meta);         /* 🔠 1294 : ex-13 (--tz-text-sm) ⇒ plancher 14 */
	font-weight: var(--tz-weight-semibold);
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* 🔤 Maquette 11px ⇒ `text-pill`. ⭐ Le statut ne s'ecrit QUE s'il existe (D36 Q2 ④) : un pair
   n'a pas de ligne ici, et cela se mesure dans le HTML servi. */
.tz-dock-scope .tz-dock__status {
	display: block;
	margin-top: 1px;                        /* --tz-layout-dock-row-status-top */
	color: var(--tz-ink-faint);
	font-size: var(--tz-text-meta);         /* 🔠 1294 : statut en minuscules ⇒ plancher 14 */
}

.tz-dock-scope .tz-dock__status.is-online {
	color: #0F7B4F;                         /* --tz-state-success-ink */
}

.tz-dock-scope .tz-dock__action {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: var(--tz-layout-dock-row-action);
	height: var(--tz-layout-dock-row-action);
	border: none;
	border-radius: var(--tz-radius-xl);
	background: var(--tz-surface-soft);
	color: var(--tz-ink-body);
	cursor: pointer;
}

/* 🚸 MESURE MAQUETTE : la sourdine ACTIVE bascule vers le registre « danger » du contrat. ⭐ Mais
   le LIBELLE, lui, ne dit jamais « bloquer » (D36 Q3 ②) — un enfant qui coupe le son croit
   souvent avoir bloque, et la couleur ne doit pas le lui laisser croire toute seule. */
.tz-dock-scope .tz-dock__mute[aria-pressed='true'] {
	background: #FBE7E7;                    /* --tz-state-danger-bg */
	color: #C2334D;                         /* --tz-state-danger-ink */
}

.tz-dock-scope .tz-dock__empty {
	margin: 0;
	padding: var(--tz-layout-dock-row-padding);
	border-top: 1px solid var(--tz-warm-surface);
	color: var(--tz-ink-faint);
	font-size: var(--tz-text-meta);
}

/* ═══════════════════════════ 15. LA CARTE DE ROLE (lot B, S353) ════════════════════════ */

/*
 * 🎭 UNE FENTE, TROIS NATURES — et DEUX formes seulement, parce que la maquette n'en dessine que
 * deux : une LISTE (« Tendances de la semaine » l. 176, « Mes classes » l. 1171) et un DIAPORAMA
 * (« En cours » l. 394). ⭐ Ecrire trois blocs de style pour trois cartes ferait diverger deux
 * d'entre elles a la premiere retouche : ce sont les MEMES rangees.
 *
 * 🎨 `--tz-cell-ink` et `--tz-cell-bg` ne sont PAS declares ici : ils sont poses en attribut
 * `style` par l'afficheur, avec la couleur de la MATIERE du contenu (ou de la classe). Meme
 * mecanique que `--tz-dock-avatar-*` du dock — et meme piege : les 26 jetons qu'ils designent
 * sont declares en section 1, ⛔ aucune feuille ne les cite.
 */
.egmtheme-catalogue-rail .tz-cell__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

/* 📐 MESURE MAQUETTE (l. 179, 1174) : la rangee, son filet creme, ses 12px de gouttiere. */
.egmtheme-catalogue-rail .tz-cell__link {
	display: flex;
	align-items: flex-start;
	gap: 12px;                              /* --tz-layout-cell-row-gap */
	padding: 13px 18px;                     /* --tz-layout-cell-row-padding */
	border-bottom: 1px solid var(--tz-warm-surface);
	color: var(--tz-warm-ink);
	text-decoration: none;
}

.egmtheme-catalogue-rail .tz-cell__row:last-child .tz-cell__link {
	border-bottom: none;
}

.egmtheme-catalogue-rail a.tz-cell__link:hover,
.egmtheme-catalogue-rail a.tz-cell__link:focus-visible {
	background: var(--tz-warm-surface);
}

/* 📐 MESURE MAQUETTE (l. 180) : 26px pour le rang des tendances ; (l. 1175) 30px pour l'initiale
   d'une classe. ⭐ La pastille est CARREE-ARRONDIE, ⛔ pas ronde : le rond est l'avatar du dock. */
.egmtheme-catalogue-rail .tz-cell__badge {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 26px;                            /* --tz-layout-cell-badge */
	height: 26px;
	border-radius: var(--tz-radius-lg);
	background: var(--tz-cell-bg);
	color: var(--tz-cell-ink);
	font-size: var(--tz-text-meta);
	font-weight: var(--tz-weight-semibold);
}

/* 🗂️ 357 : « Collections » partage la garniture de « Mes classes » (initiale + nom + compteur,
   voir class-egmtheme-collections.php) — même badge 30px mesuré maquette (l. 206), ⛔ pas les
   26px de « Tendances ». Un seul jeu de règles pour une seule forme, ⛔ une classe dupliquée. */
.egmtheme-catalogue-rail .tz-cell--classes .tz-cell__badge,
.egmtheme-catalogue-rail .tz-cell--collections .tz-cell__badge {
	width: 30px;                            /* --tz-layout-cell-badge-lg */
	height: 30px;
	border-radius: var(--tz-radius-xl);
}

.egmtheme-catalogue-rail .tz-cell__body {
	flex: 1;
	min-width: 0;
}

/* 📐 MESURE MAQUETTE (l. 182) : 13,5px ⇒ `text-base`, interligne 1,4, cesure douce. */
.egmtheme-catalogue-rail .tz-cell__title {
	display: block;
	font-size: var(--tz-text-base);
	font-weight: var(--tz-weight-semibold);
	line-height: 1.4;                       /* --tz-leading-snug */
	text-wrap: pretty;
}

/* 🔤 Maquette 12px ⇒ `text-meta` (12px) — la seule taille ou la maquette et le plancher D16
   coincident. */
.egmtheme-catalogue-rail .tz-cell__meta {
	display: block;
	margin-top: 4px;                        /* --tz-layout-cell-meta-gap */
	color: var(--tz-ink-faint);
	font-size: var(--tz-text-meta);
}

/* 📐 MESURE MAQUETTE (l. 1176) : le nom d'une classe est plus gros que le titre d'une tendance. */
.egmtheme-catalogue-rail .tz-cell__name {
	flex: 1;
	min-width: 0;
	font-size: 0.875rem;                    /* 14px — --tz-text-sm */
	font-weight: var(--tz-weight-semibold);
}

/* 🔤 Maquette 12,5px ⇒ `text-meta` (12px) par D16 : ⛔ on ne descend pas sous le plancher a11y
   pour gagner un demi-pixel de fidelite. */
.egmtheme-catalogue-rail .tz-cell__count {
	flex: none;
	align-self: center;
	color: #7A5A28;                         /* --tz-warm-ink-dim */
	font-size: var(--tz-text-meta);
}

/* 📐 MESURE MAQUETTE (l. 187-188) : le pied de la carte « Tendances » porte l'invitation. */
.egmtheme-catalogue-rail .tz-cell__foot {
	padding: 12px 14px;                     /* --tz-layout-cell-foot-padding */
}

.egmtheme-catalogue-rail .tz-cell__cta {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 42px;                       /* --tz-layout-cell-cta-height */
	border: 1px solid #DCDFEA;              /* --tz-border-cool */
	border-radius: 9px;                     /* --tz-radius-2xl */
	color: var(--tz-ink-strong);
	text-decoration: none;
	font-size: var(--tz-text-base);
	font-weight: var(--tz-weight-semibold);
}

.egmtheme-catalogue-rail .tz-cell__cta:hover,
.egmtheme-catalogue-rail .tz-cell__cta:focus-visible {
	background: var(--tz-surface-soft);
}

/* ── LE DIAPORAMA « EN COURS » ─────────────────────────────────────────────────────────── */

/* 📐 MESURE MAQUETTE (l. 397) : la position vit dans l'en-tete sombre, avec les deux fleches. */
.egmtheme-catalogue-rail .tz-cell__position {
	flex: none;
	color: var(--tz-warm-highlight-dim);
	font-size: var(--tz-text-meta);
	font-weight: var(--tz-weight-semibold);
}

/* 📐 MESURE MAQUETTE (l. 398) : 28px, coins 8px, un filet blanc a 20 % sur un fond blanc a 10 %. */
.egmtheme-catalogue-rail .tz-cell__nav {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 28px;                            /* --tz-layout-cell-nav */
	height: 28px;
	border: 1px solid rgba(255, 255, 255, .2);
	border-radius: var(--tz-radius-xl);
	background: rgba(255, 255, 255, .1);
	color: var(--tz-surface-page);
	cursor: pointer;
}

.egmtheme-catalogue-rail .tz-cell__nav:hover,
.egmtheme-catalogue-rail .tz-cell__nav:focus-visible {
	background: rgba(255, 255, 255, .2);
}

.egmtheme-catalogue-rail .tz-cell__slide {
	padding: 14px;                          /* --tz-layout-cell-slide-padding */
}

/* 📐 MESURE MAQUETTE (l. 406) : 16/9, coins 9px, fond froid — c'est le CADRE qui tient le ratio,
   ⛔ pas l'image : une couverture absente ne doit pas faire sauter la hauteur de la carte. */
.egmtheme-catalogue-rail .tz-cell__cover {
	position: relative;
	overflow: hidden;
	aspect-ratio: 16 / 9;
	border: 1px solid #E9EBF2;              /* --tz-border-cool-dim */
	border-radius: 9px;                     /* --tz-radius-2xl */
	background: var(--tz-surface-soft);
}

.egmtheme-catalogue-rail .tz-cell__cover img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* 🔤 Maquette 14,5px : au-dessus du plancher, on la sert telle quelle. */
.egmtheme-catalogue-rail .tz-cell__slidetitle {
	margin: 12px 0 0;                       /* --tz-layout-cell-slide-gap */
	font-size: 0.90625rem;                  /* 14,5px — --tz-text-md */
	font-weight: var(--tz-weight-semibold);
	line-height: 1.4;                       /* --tz-leading-snug */
	letter-spacing: -.01em;
	text-wrap: pretty;
}

.egmtheme-catalogue-rail .tz-cell__progress {
	display: flex;
	align-items: center;
	gap: 10px;                              /* --tz-layout-cell-progress-gap */
	margin-top: 11px;                       /* --tz-layout-cell-progress-top */
}

/* 📐 MESURE MAQUETTE (l. 411) : 5px de haut, coins 3px, rail froid. */
.egmtheme-catalogue-rail .tz-cell__bar {
	flex: 1;
	overflow: hidden;
	min-width: 50px;                        /* --tz-layout-cell-bar-min */
	height: 5px;                            /* --tz-layout-cell-bar */
	border-radius: 3px;                     /* --tz-radius-xs */
	background: #EDEFF5;                    /* --tz-surface-cool-dim */
}

.egmtheme-catalogue-rail .tz-cell__bar > span {
	display: block;
	height: 100%;
	border-radius: 3px;                     /* --tz-radius-xs */
}

.egmtheme-catalogue-rail .tz-cell__pct {
	flex: none;
	color: var(--tz-ink-muted);
	font-size: var(--tz-text-meta);
	font-weight: var(--tz-weight-semibold);
}

/* 📐 MESURE MAQUETTE (l. 414) : le bouton « Reprendre » est le seul accent FRAMBOISE de la
   colonne. ⭐ Il est plein largeur : c'est l'action principale de la carte. */
.egmtheme-catalogue-rail .tz-cell__resume {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 42px;                       /* --tz-layout-cell-cta-height */
	margin-top: 12px;                       /* --tz-layout-cell-slide-gap */
	border-radius: 9px;                     /* --tz-radius-2xl */
	background: #C4265E;                    /* --tz-accent-resume */
	color: var(--tz-surface-page);
	text-decoration: none;
	font-size: var(--tz-text-base);
	font-weight: var(--tz-weight-semibold);
}

.egmtheme-catalogue-rail .tz-cell__resume:hover,
.egmtheme-catalogue-rail .tz-cell__resume:focus-visible {
	background: #A81F4F;                    /* --tz-accent-resume-hover */
}

/* ═══════════════════════════ 16. LE MOUVEMENT REDUIT ═══════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
	.tz-dock-scope .tz-dock__chevron {
		transition: none;
	}
}

/* ═══════════════════════════ 17. LE VOLET DE CHAT DU DOCK (session 519) ════════════════
 * Consigne porteur du 2026-09-13 : le clic sur « Discuter » ouvre DANS le dock la section de chat
 * de l'outil de chat. Le volet (`rendre_volet_chat()`) remplace la liste tant qu'un fil est ouvert
 * (`.tz-dock__panel.is-chatting`) : sa tete (retour · nom · porte vers la messagerie), la rangee
 * des conversations ouvertes (une puce par personne, non-lus dits par le cadre), et les cadres —
 * un `<iframe>` par personne, seul l'actif est visible. ⭐ Le cadre prend TOUTE la place qui reste :
 * c'est le Hub encastre qui fait defiler le fil et garde le composeur au pied.
 * ⛔ Aucun libelle ici ni dans le script : ils viennent du producteur, par PHP. */

.tz-dock-scope .tz-dock__panel.is-chatting > :not(.tz-dock__head):not(.tz-dock__chat) {
	display: none;
}

.tz-dock-scope .tz-dock__chat {
	display: flex;
	flex: 1;
	flex-direction: column;
	min-height: 0;
}

.tz-dock-scope .tz-dock__chat[hidden] {
	display: none;
}

.tz-dock-scope .tz-dock__chathead {
	display: flex;
	flex: none;
	align-items: center;
	gap: 8px;
	padding: 8px 10px;
	border-bottom: 1px solid var(--tz-warm-surface-dim);
	background: var(--tz-surface-soft);
}

.tz-dock-scope .tz-dock__chatback,
.tz-dock-scope .tz-dock__chatopen {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: var(--tz-layout-dock-row-action);
	height: var(--tz-layout-dock-row-action);
	border: none;
	border-radius: var(--tz-radius-xl);
	background: var(--tz-surface-page);
	color: var(--tz-ink-body);
	cursor: pointer;
	text-decoration: none;
}

.tz-dock-scope .tz-dock__chatback:hover,
.tz-dock-scope .tz-dock__chatback:focus-visible,
.tz-dock-scope .tz-dock__chatopen:hover,
.tz-dock-scope .tz-dock__chatopen:focus-visible {
	background: var(--tz-warm-surface-dim);
}

.tz-dock-scope .tz-dock__chatwho {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	color: var(--tz-ink-body);
	font-size: var(--tz-text-base);
	font-weight: var(--tz-weight-bold);
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* La rangee des conversations ouvertes : des puces, la puce active en creme (comme un filtre). */
.tz-dock-scope .tz-dock__chatthreads {
	display: flex;
	flex: none;
	gap: 4px;
	padding: 6px 10px;
	overflow-x: auto;
	scrollbar-width: none;
	border-bottom: 1px solid var(--tz-warm-surface-dim);
}

.tz-dock-scope .tz-dock__chatthreads[hidden] {
	display: none;
}

.tz-dock-scope .tz-dock__chatthreads::-webkit-scrollbar {
	display: none;
}

.tz-dock-scope .tz-dock__thread {
	display: inline-flex;
	flex: none;
	align-items: center;
	gap: 6px;
	height: 28px;
	padding: 0 6px 0 10px;
	border: 1px solid transparent;
	border-radius: var(--tz-radius-xl);
	background: transparent;
	color: var(--tz-ink-body);
	font-size: var(--tz-text-meta);
	font-weight: var(--tz-weight-semibold);
	cursor: pointer;
	white-space: nowrap;
}

.tz-dock-scope .tz-dock__thread[aria-selected="true"] {
	border-color: var(--tz-warm-surface-dim);
	background: var(--tz-surface-page);
	box-shadow: 0 1px 2px rgba(13, 16, 36, .08);
}

.tz-dock-scope .tz-dock__thread:hover,
.tz-dock-scope .tz-dock__thread:focus-visible {
	background: var(--tz-surface-soft);
}

/* Le nombre de non-lus, tel que le cadre le DIT ; absent = 0. */
.tz-dock-scope .tz-dock__threadunread,
.tz-dock-scope .tz-dock__rowunread {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 18px;
	height: 18px;
	padding: 0 5px;
	border-radius: 9px;
	background: #C4265E;                    /* --tz-accent-resume */
	color: var(--tz-surface-page);
	font-size: 11px;
	font-weight: var(--tz-weight-bold);
	line-height: 1;
}

.tz-dock-scope .tz-dock__threadunread[hidden],
.tz-dock-scope .tz-dock__rowunread[hidden] {
	display: none;
}

.tz-dock-scope .tz-dock__threadclose {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	margin-left: 2px;
	border: none;
	border-radius: 9px;
	background: transparent;
	color: var(--tz-ink-faint);
	cursor: pointer;
}

.tz-dock-scope .tz-dock__threadclose:hover,
.tz-dock-scope .tz-dock__threadclose:focus-visible {
	background: var(--tz-warm-surface-dim);
	color: var(--tz-ink-body);
}

/* Les cadres : la place qui reste ; un seul visible. */
.tz-dock-scope .tz-dock__chatframes {
	position: relative;
	flex: 1;
	min-height: 0;
	background: var(--tz-surface-page);
}

.tz-dock-scope .tz-dock__chatframe {
	display: block;
	width: 100%;
	height: 100%;
	border: none;
	background: transparent;
}

.tz-dock-scope .tz-dock__chatframe[hidden] {
	display: none;
}

.tz-dock-scope .tz-dock__chatloading {
	position: absolute;
	top: 50%;
	left: 0;
	right: 0;
	margin: 0;
	padding: 0 16px;
	transform: translateY(-50%);
	color: var(--tz-ink-faint);
	font-size: var(--tz-text-meta);
	text-align: center;
	pointer-events: none;
}

.tz-dock-scope .tz-dock__chatloading[hidden] {
	display: none;
}

/* En flux (sous 900px, ou sans ancrage), le panneau borne a 440px serait trop court pour un fil :
   tant qu'on y parle, il prend jusqu'a 70 % de la fenetre. Ancre, le script pose la hauteur. */
.tz-dock-scope .tz-dock:not([data-tz-dock-anchored]) .tz-dock__panel.is-chatting {
	max-height: 70vh;
	max-height: 70dvh; /* 📱 807 — manquait à 797/R13 : le clavier du téléphone réduit la fenêtre, `vh` non */
	min-height: 420px;
}

/* Sur la ligne, la personne dont le fil a du nouveau porte son nombre, a cote de « Discuter ». */
.tz-dock-scope .tz-dock__action.has-unread {
	position: relative;
}

.tz-dock-scope .tz-dock__action .tz-dock__rowunread {
	position: absolute;
	top: -6px;
	right: -6px;
}

/* ═══════════════════════════ 18. LES ESPACES DU DOCK (session 523) ══════════════════════
 * Consigne porteur du 2026-09-13 : « un fil des classes doit aussi s'ouvrir dans le Fil du Tiz
 * pour les groupes de l'utilisateur connecte ». La section (`rendre_espaces()`) vit entre les
 * filtres et les personnes : un sur-titre derive (« Mes classes » / « Mes groupes », le meme
 * dessin que le kicker de la rangee haute) et une ligne par espace — l'embleme du groupe servi
 * par le serveur (photo, sinon l'emoji du type), le nom, le type en sous-ligne, et le meme bouton
 * « Discuter » que les personnes. ⭐ La ligne EST une `.tz-dock__row` : memes hauteurs, memes
 * espacements — rien n'est redessine. La section ne defile pas elle-meme : c'est la liste des
 * personnes qui garde le defilement, les espaces restent en tete (peu nombreux). */

.tz-dock-scope .tz-dock__spaces {
	flex: none;
	padding: 6px 0 0;
}

.tz-dock-scope .tz-dock__spaces[hidden] {
	display: none;
}

.tz-dock-scope .tz-dock__sectitle {
	margin: 0;
	padding: 4px 14px 2px;
	color: var(--tz-warm-gold-ink);
	font-size: var(--tz-text-pill);
	font-weight: var(--tz-weight-bold);
	letter-spacing: .09em;
	text-transform: uppercase;
}

.tz-dock-scope .tz-dock__list--spaces {
	flex: none;
	overflow: visible;
}

/* L'embleme : le rond des personnes, sur le fond doux du dock ; l'emoji au centre, la photo pleine. */
.tz-dock-scope .tz-dock__avatar--space {
	overflow: hidden;
	background: var(--tz-warm-surface-dim);
	color: var(--tz-ink-body);
	font-size: 16px;
}

.tz-dock-scope .tz-dock__avatarimg {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* ═══════════════ 10. LA PAGE /parcours REPREND CETTE COQUILLE (session 545) ═══════════════
 *
 * ⭐ **LA CLASSE EST LE CONTRAT DU COMPOSANT, ⛔ PAS LE NOM D'UNE PAGE.**
 * `.egmtheme-catalogue-shell` / `.egmtheme-catalogue-rail` / `.tz-dock-scope` decrivent « la
 * colonne creme du site » ; `/parcours` les reutilise telles quelles (`EGMLP_Front` pose la
 * coquille, `EGMtheme_Paths_Page` remplit la colonne). Recopier ces 1 631 lignes sous un prefixe
 * `egmlp-*` aurait fabrique un second foyer, qui aurait diverge au premier reglage de palette.
 * ⇒ Les 4 regles ci-dessous sont TOUT ce que la page ajoute.
 */

/* Le fond chaud de la page — meme valeur et meme raison que `main.egmtheme-catalogue` (l. 388) :
   un fond froid sous des surfaces chaudes ne se lit pas comme une nuance, mais comme une erreur
   d'assemblage. 🪤 Le `margin-block-start: 0` retire la bande vide que la mise en page des blocs
   (`--wp--style--block-gap`) pose sous le menu — meme cause qu'en 257, meme remede.
   Portee : la page des parcours SEULE (la classe vient de `EGMLP_Front::body_class()`). */
body.egmlp-page main.egmtheme-content {
	background: #FAF9F5;
	margin-block-start: 0;
}

/* Dans la coquille, la largeur et la respiration appartiennent au CONTENANT COMMUN : l'app garde
   son `max-width` pour le cas ou la colonne est eteinte (elle est alors seule sur la page).
   ⭐ Une colonne voisine ne peut pas s'aligner sur un frere qui reclame toute la largeur. */
.egmtheme-catalogue-shell .egm-lp-front {
	max-width: none;
	margin: 0;
	padding: 0;
}

/* Sous 900px la colonne passe sous le contenu (regle l. 412) : la carte des vedettes et la pub
   ne doivent plus coller, sinon elles suivent le defilement d'une page qu'elles ne bordent plus. */
@media (max-width: 899px) {
	.egmlp-rail .tz-rail__sticky {
		position: static;
	}
}

/* 👆 R9-ter (838 ; ⚖️ D1 : 44 px au doigt, la souris garde la densité de la maquette) — le dock
   « Mes connexions » (connecté : accueil, catalogue, parcours). Mesuré à 390 tactile, dock ouvert :
   fermer 26 · recherche 20 (dans une enveloppe de 36) · flèches 20 × 38 et 22 · filtres 31 ·
   actions de ligne 28. Les trois cotes-jetons du dock basculent d'un coup ; le champ remplit son
   enveloppe (toucher l'enveloppe = toucher le champ) et passe à 16 px (iOS zoome en deçà — R5).
   Les rangées défilent déjà au doigt ; leurs flèches restent (elles disent « il y en a d'autres »),
   à 44. */
@media (pointer: coarse) {
	.tz-dock-scope {
		--tz-layout-dock-close: var(--egm-tap-min, 44px);
		--tz-layout-dock-filter-arrow: var(--egm-tap-min, 44px);
		--tz-layout-dock-row-action: var(--egm-tap-min, 44px);
	}

	.tz-dock-scope .tz-dock__search {
		height: 46px;
	}

	.tz-dock-scope .tz-dock__searchinput {
		align-self: stretch;
		font-size: 16px;
	}

	.tz-dock-scope .tz-dock__toparrow {
		width: var(--egm-tap-min, 44px);
		height: var(--egm-tap-min, 44px);
	}

	/* Un filtre court (« CE1 ») faisait 41 de large : la largeur aussi. */
	.tz-dock-scope .tz-dock__filter {
		min-width: var(--egm-tap-min, 44px);
		min-height: var(--egm-tap-min, 44px);
	}
}

/* ═══════════════════════ 1128. LES PRODUITS DE LA PAGE DES RESULTATS ════════════════════════ */

/* 🛍️ La carte « Dans la boutique » (colonne de `/?s=`, comptes gratuits) : la MEME carte a tete
   sombre que la publicite et les tendances (section 5) ; seules la rangee produit et son prix
   sont neufs. L'en-tete est un `<h2>` (la carte est une `<section>` nommee) : il garde l'allure
   du libelle des autres cartes. Les cartes sont peintes par l'app `search-picks`. */
.egmtheme-catalogue-rail .tz-picks .tz-railcard__label {
	margin: 0;
	font-family: inherit;
	line-height: inherit;
}

.egmtheme-catalogue-rail .tz-picks__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.egmtheme-catalogue-rail .tz-picks__link {
	display: flex;
	align-items: flex-start;
	gap: 12px;                              /* --tz-layout-cell-row-gap */
	padding: 13px 16px;
	border-bottom: 1px solid var(--tz-warm-surface);
	color: var(--tz-warm-ink);
	text-decoration: none;
}

.egmtheme-catalogue-rail .tz-picks__item:last-child .tz-picks__link {
	border-bottom: none;
}

.egmtheme-catalogue-rail .tz-picks__link:hover,
.egmtheme-catalogue-rail .tz-picks__link:focus-visible {
	background: var(--tz-warm-surface);
}

.egmtheme-catalogue-rail .tz-picks__thumb {
	display: block;
	flex: none;
	overflow: hidden;
	width: 72px;
	height: 72px;
	border-radius: var(--tz-radius-xl);
	background: var(--tz-warm-surface);
}

.egmtheme-catalogue-rail .tz-picks__thumb img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.egmtheme-catalogue-rail .tz-picks__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 6px;
	min-width: 0;
}

/* 3 lignes au plus : un titre de produit long ne doit pas allonger la colonne collante. */
.egmtheme-catalogue-rail .tz-picks__name {
	display: -webkit-box;
	overflow: hidden;
	font-size: var(--tz-text-base);
	font-weight: var(--tz-weight-semibold);
	line-height: 1.35;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	line-clamp: 3;
}

.egmtheme-catalogue-rail .tz-picks__price {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 6px;
	font-size: var(--tz-text-meta);
}

.egmtheme-catalogue-rail .tz-picks__now {
	color: var(--tz-ink-strong);
	font-size: var(--tz-text-base);
	font-weight: var(--tz-weight-bold);
}

.egmtheme-catalogue-rail .tz-picks__was {
	color: var(--tz-ink-faint);
	text-decoration: line-through;
}

.egmtheme-catalogue-rail .tz-picks__badge {
	padding: 1px 7px;
	border-radius: var(--tz-radius-pill);
	background: var(--tz-warm-gold);
	color: var(--tz-warm-ink);
	font-weight: var(--tz-weight-bold);
}

/* ⏳ La place des deux rangees, tenue avant le script : la colonne collante ne saute pas. */
.egmtheme-catalogue-rail .tz-picks__skeleton {
	display: grid;
	gap: 1px;
}

.egmtheme-catalogue-rail .tz-picks__skeleton span {
	display: block;
	height: 98px;
	background: var(--tz-warm-surface);
	opacity: .55;
}

@media (pointer: coarse) {
	.egmtheme-catalogue-rail .tz-picks__link {
		min-height: var(--egm-tap-min, 44px);
	}
}
