- utils/echelles.ts : texte des slides 15 à 18, mot pour mot, source unique (la future nav S / M / XL lira ce fichier). - EchelleTete.vue : badge d'échelle, titre, sept mots, phrase, ligne « Chaque section est ouverte aux contributions » vers /proposer. - Placée en tête du texte existant, sans le remplacer : Outils (S), popup Écosystème Entraide (M), page Codev (M), popup média (XL). Réseaux AEP et Jobs attendent les arbitrages n° 1 et 2 (table R §6). - /proposer?categorie=<id> présélectionne l'onglet. - Menu mobile : « recherche-média » pointait sur /rag (301), pointe sur /media, état actif comme les autres liens. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
187 lines
5.9 KiB
Vue
187 lines
5.9 KiB
Vue
<template>
|
|
<Teleport to="body">
|
|
<Transition name="backdrop">
|
|
<div
|
|
v-if="modelValue"
|
|
class="fixed inset-0 z-[1500]"
|
|
style="background: rgba(26,34,56,0.55);"
|
|
@click="close"
|
|
aria-hidden="true"
|
|
/>
|
|
</Transition>
|
|
|
|
<Transition name="modal">
|
|
<div
|
|
v-if="modelValue"
|
|
class="mission-modal"
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-labelledby="mission-title"
|
|
@keydown.esc="close"
|
|
>
|
|
<button
|
|
class="mission-close"
|
|
type="button"
|
|
@click="close"
|
|
aria-label="Fermer"
|
|
>
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true">
|
|
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
|
|
</svg>
|
|
</button>
|
|
|
|
<div class="mission-body">
|
|
<h2 id="mission-title" class="mission-title">{{ title }}</h2>
|
|
<EchelleTete v-if="echelle" :echelle="echelle" compact @navigate="close" />
|
|
<slot>
|
|
<p class="mission-text">
|
|
L'architecture est l'une des professions les plus complexes qui soit ; elle croise droit, technique, esthétique, économie, social, écologie — tout à la fois, tout simultanément, souvent sans filet. Paradoxalement, c'est aussi l'une des moins structurées sur le plan de l'entraide : peu de transmission horizontale, beaucoup d'isolement, une culture du chacun-pour-soi héritée d'une formation qui prépare à la compétition plus qu'à la coopération. On sort de l'école seul·e. On s'installe seul·e. On réinvente ce que d'autres ont déjà traversé.
|
|
</p>
|
|
<p class="mission-text">
|
|
Cette carte est née de cette frustration — et de cette conviction : les ressources existent, les gens qui ont réussi à sortir la tête de l'eau aussi. L'enjeu, c'est de les documenter, de les rendre accessibles, de les ajuster en temps réel grâce aux retours de la communauté. Pas un catalogue figé ; un commun vivant, au service de ceux et celles qui cherchent à faire évoluer leur pratique vers quelque chose de plus épanouissant, mieux rémunéré, au service de la société — et qui prend soin de la santé, la nôtre et celle des gens pour qui nous construisons.
|
|
</p>
|
|
</slot>
|
|
|
|
<div class="mission-cta-wrap">
|
|
<button class="btn-explorer" type="button" @click="close">{{ ctaLabel }}</button>
|
|
<NuxtLink to="/manifeste" class="link-manifeste" @click="close">Lire le manifeste →</NuxtLink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Transition>
|
|
</Teleport>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { EchelleId } from '~/utils/echelles'
|
|
|
|
const props = withDefaults(defineProps<{
|
|
modelValue: boolean
|
|
title?: string
|
|
ctaLabel?: string
|
|
storageKey?: string
|
|
/** Tête d'échelle du deck (S / M / XL) affichée sous le titre. Absente sur /agences tant que l'arbitrage n° 1 n'est pas rendu. */
|
|
echelle?: EchelleId
|
|
}>(), {
|
|
title: "L'écosystème d'entraide architecte",
|
|
ctaLabel: 'Explorer la carte',
|
|
storageKey: 'aep_mission_seen',
|
|
})
|
|
|
|
const emit = defineEmits<{ 'update:modelValue': [value: boolean] }>()
|
|
|
|
function close() {
|
|
emit('update:modelValue', false)
|
|
if (typeof window !== 'undefined') {
|
|
try { localStorage.setItem(props.storageKey, '1') } catch {}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.mission-modal {
|
|
position: fixed;
|
|
z-index: 1501;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
width: min(560px, 92vw);
|
|
max-height: calc(100dvh - 80px);
|
|
background: var(--nav-bg);
|
|
border-radius: 16px;
|
|
box-shadow: 0 16px 64px rgba(26,34,56,0.28);
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.mission-close {
|
|
position: absolute;
|
|
top: 12px;
|
|
right: 12px;
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 8px;
|
|
border: none;
|
|
background: var(--nav-bg-alt);
|
|
color: var(--nav-text-muted);
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: background 0.15s;
|
|
z-index: 1;
|
|
}
|
|
.mission-close:hover { background: var(--nav-surface); }
|
|
|
|
.mission-body {
|
|
padding: 1.75rem 1.5rem 1.5rem;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.mission-title {
|
|
font-size: 1.25rem;
|
|
font-weight: 700;
|
|
color: var(--nav-text);
|
|
margin: 0 0 1rem;
|
|
line-height: 1.25;
|
|
padding-right: 2rem;
|
|
}
|
|
|
|
.mission-text,
|
|
:slotted(.mission-text) {
|
|
font-size: 0.95rem;
|
|
line-height: 1.65;
|
|
color: var(--nav-text);
|
|
margin: 0 0 1rem;
|
|
}
|
|
:slotted(.mission-text strong) { font-weight: 700; }
|
|
:slotted(.mission-text a) { color: var(--nav-primary-solid); text-decoration: underline; }
|
|
|
|
.mission-cta-wrap {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
margin-top: 1.5rem;
|
|
}
|
|
|
|
.btn-explorer {
|
|
padding: 0.65rem 1.25rem;
|
|
background: var(--nav-primary);
|
|
color: var(--nav-text-on-primary);
|
|
border: none;
|
|
border-radius: 8px;
|
|
font-size: 0.9rem;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: opacity 0.15s;
|
|
}
|
|
.btn-explorer:hover { opacity: 0.88; }
|
|
|
|
.link-manifeste {
|
|
font-size: 0.875rem;
|
|
color: var(--nav-primary-solid);
|
|
text-decoration: underline;
|
|
text-underline-offset: 2px;
|
|
}
|
|
.link-manifeste:hover { opacity: 0.75; }
|
|
|
|
.backdrop-enter-active, .backdrop-leave-active { transition: opacity 0.2s ease; }
|
|
.backdrop-enter-from, .backdrop-leave-to { opacity: 0; }
|
|
|
|
.modal-enter-active, .modal-leave-active { transition: opacity 0.2s ease, transform 0.2s ease; }
|
|
.modal-enter-from, .modal-leave-to { opacity: 0; transform: translate(-50%, -48%); }
|
|
|
|
@media (max-width: 480px) {
|
|
.mission-body { padding: 1.5rem 1.1rem 1.25rem; }
|
|
.mission-title { font-size: 1.1rem; }
|
|
.mission-text { font-size: 0.9rem; }
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.modal-enter-active, .modal-leave-active { transition: none; }
|
|
.backdrop-enter-active, .backdrop-leave-active { transition: none; }
|
|
}
|
|
</style>
|