/** * Les trois échelles du deck du 23/09/2026 (conférence AEP), slides 15 à 18. * Texte repris mot pour mot : c'est la tête de chaque onglet (directive Jules du 25/09, point 2). * Source unique : la nav S / M / XL (B10 : NavEchelles, NavTiroir, FilEchelle) lit aussi ce fichier. * Aucun libellé d'échelle ni d'onglet ne se recopie ailleurs. */ export type EchelleId = 'S' | 'M' | 'XL' /** Ce que la nav lit d'une route : compatible avec `useRoute()` sans en dépendre (testable en node). */ export interface RouteNav { path: string query?: Record } export interface OngletNav { libelle: string to: string actif: (route: RouteNav) => boolean } export interface Echelle { id: EchelleId titre: string sousTitre?: string mots: string[] phrase: string /** Catégorie de /proposer présélectionnée par le lien de contribution. */ categorieProposer: 'ecosysteme' | 'reseau' | 'jobs' | 'outils' | 'references' /** Onglets du groupe, dans l'ordre de la barre, du menu et du fil d'échelle (B10, directive Jules du 29/09 + arbitrage 1A du 26/09). */ onglets: OngletNav[] } const sousChemin = (base: string) => (r: RouteNav) => r.path === base || r.path.startsWith(`${base}/`) const surPublications = (r: RouteNav) => r.query?.tab === 'projets' export const ECHELLES: Record = { S: { id: 'S', titre: 'Partir de soi', sousTitre: "pour s'émanciper", mots: [ 'quête de sens', 'où habiter, avec qui', 'gagner sa vie', 'santé mentale', 'mener ses projets', 'naviguer avec soi', 'les compétences psychosociales', ], phrase: 'Des ressources, des méthodes, des pairs : matériel et mutualisé.', categorieProposer: 'outils', onglets: [ { libelle: 'Jobs', to: '/trouver-du-taf', actif: sousChemin('/trouver-du-taf') }, { libelle: 'Outils', to: '/outils', actif: sousChemin('/outils') }, ], }, M: { id: 'M', titre: 'La communauté', mots: [ 'entraide', 'mutualisation', 'appartenance', 'être vu, soutenu', 'traverser les creux', 'accomplissement', 'le codev', ], phrase: "C'est le groupe qui remet un individu debout. L'affinité fait tenir, la confrontation fait avancer.", categorieProposer: 'ecosysteme', onglets: [ { libelle: "Écosystème d'entraide", to: '/', actif: (r) => r.path === '/' }, { libelle: 'Réseaux AEP', to: '/agences', actif: sousChemin('/agences') }, { libelle: 'Codev', to: '/codev', actif: sousChemin('/codev') }, ], }, XL: { id: 'XL', titre: 'Contribuer', mots: [ 'contribution', 'affiliation, filiation', 'identité', 'sens', 'de nouveaux récits', 'un nouveau contrat social', 'la médecine du corps social', ], phrase: 'La bibliothèque, les récits, la filiation entre projets.', categorieProposer: 'references', onglets: [ { libelle: 'Recherche média', to: '/media', actif: (r) => sousChemin('/media')(r) && !surPublications(r) }, { libelle: 'Publications', to: '/media?tab=projets', actif: (r) => sousChemin('/media')(r) && surPublications(r) }, ], }, } /** Ordre des groupes dans la barre et le menu. */ export const ORDRE_ECHELLES: EchelleId[] = ['S', 'M', 'XL'] /** Slide 15, commune aux trois échelles. */ export const ECHELLES_CADRE = "Trois échelles, imbriquées. Pas un escalier : ça circule dans les deux sens. Entrez par celle qui presse." /** Version courte de la slide 15 (tête du menu) : première et dernière phrase, tirées du texte ci-dessus. */ export const ECHELLES_CADRE_COURT = (() => { const phrases = ECHELLES_CADRE.match(/[^.]+\./g) ?? [ECHELLES_CADRE] return phrases.length > 1 ? `${phrases[0].trim()} ${phrases[phrases.length - 1].trim()}` : ECHELLES_CADRE })() /** Groupe de la page courante et son onglet actif, ou null hors groupe (Manifeste, À propos, Proposer, fiche…). */ export function echelleDeRoute(route: RouteNav): { echelle: EchelleId; onglet: OngletNav } | null { for (const id of ORDRE_ECHELLES) { const onglet = ECHELLES[id].onglets.find((o) => o.actif(route)) if (onglet) return { echelle: id, onglet } } return null }