Files
decision/frontend/app/pages/textes/formules.vue
T
YvvandClaude Fable 5 e164b5f6c1 v2 : les 14 écrans — le tour complet de la démocratie d'exercice
- Aujourd'hui (Fil 13 sections + capture sticky) + Le chemin (tunnel 2 gestes,
  Q0 inline, 3 chips, dérogation asymétrique, alternatives réglage/consignation)
- Registre + fiche décision (timeline, périmètre premier/second lieu auditable,
  affluence non-ignorable, S'instruire condensé, éléments + cartographie de
  clôture, épreuve du réel, Remettre en question, PV A4, gravure)
- Salle de vote 5 modalités (consentement, nuancé+histogramme, binaire hérité
  avec jauge inertielle, Réglage collectif complet — faisceau, médiane basse,
  Pour moi, Explorer, cristallisation-geste —, élection à départage humain)
- Textes (Pacte en clair, document vivant, diff, vue projetée, Atelier des
  formules porté du v1 sur le moteur unique) + Mandats (faits comptés, feux
  de la rampe, wizard 3 étapes) + Observatoire (consigner→observer→protocoliser)
- Onboarding 7 gabarits + Données locales (export/import, attributs, atelier)
- voting→framing gardé (Reformuler d'un réglage figé non cristallisé)
- Pages v1 supprimées (login, documents, mandates, protocols, sanctuary,
  tools, decisions/new) — 342 tests verts, build zéro erreur

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 13:47:20 +02:00

160 lines
5.2 KiB
Vue

<script setup lang="ts">
/**
* /textes/formules — l'Atelier des formules : la pédagogie du seuil,
* seule maison des lettres W/T/M/B/G/C. Query params ?W=&T=&M=&B=&G=&C=(&S=)
* pré-règlent l'établi — les liens « comprendre ce seuil » arrivent ici.
*/
import { BINARY_DESCRIPTION, BINARY_COST, METHOD_LABELS } from '~/lexicon'
import type { AtelierInit } from '~/components/texts/textsModel'
const route = useRoute()
function numParam(name: string): number | undefined {
const raw = route.query[name]
const value = Number(Array.isArray(raw) ? raw[0] : raw)
return Number.isFinite(value) ? value : undefined
}
const initial = computed((): AtelierInit => {
const init: AtelierInit = {}
const W = numParam('W')
const T = numParam('T')
const M = numParam('M')
const B = numParam('B')
const G = numParam('G')
const C = numParam('C')
const S = numParam('S')
if (W !== undefined) init.W = W
if (T !== undefined) init.T = T
if (M !== undefined) init.M = M
if (B !== undefined) init.B = B
if (G !== undefined) init.G = G
if (C !== undefined) init.C = C
if (S !== undefined) init.S = S
return init
})
</script>
<template>
<!-- ld-v2 -->
<div class="atelier">
<NuxtLink to="/textes" class="ld-btn ld-btn--quiet atelier__back">
<UIcon name="i-lucide-arrow-left" />
Tous les textes
</NuxtLink>
<header class="atelier__header">
<h1 class="atelier__title">L'Atelier des formules</h1>
<p class="atelier__subtitle">
La pédagogie du seuil — c'est ici, et seulement ici, que vivent les lettres.
Partout ailleurs, l'outil parle français.
</p>
</header>
<!-- L'établi -->
<AtelierFormulaLab :key="JSON.stringify(initial)" :initial="initial" />
<!-- Le pour/contre, présenté pour ce qu'il est -->
<section class="atelier__card ld-card">
<div class="atelier__card-head">
<span class="atelier__card-icon atelier__card-icon--binary">
<UIcon name="i-lucide-scale" />
</span>
<div>
<h2 class="atelier__card-title">{{ METHOD_LABELS.binary }}</h2>
<p class="atelier__card-sub">{{ BINARY_DESCRIPTION }}</p>
</div>
</div>
<p class="atelier__prose">
Cette formule inertielle est un héritage de la Toile de Confiance Ğ1 : quand
des milliers de membres sont éligibles et que peu s'expriment, elle exige
presque l'unanimité ; quand la participation monte, le seuil descend vers la
majorité cible. C'est une protection remarquable pour les très grands corps
et un outil d'exception : son coût reste « {{ BINARY_COST }} ».
Pour la vie courante d'un collectif, le consentement, le vote nuancé et le
réglage collectif font mieux vivre le désaccord.
</p>
</section>
<!-- Le Réglage collectif : la médiane basse expliquée -->
<section class="atelier__card ld-card">
<div class="atelier__card-head">
<span class="atelier__card-icon atelier__card-icon--parametric">
<UIcon name="i-lucide-sliders-horizontal" />
</span>
<div>
<h2 class="atelier__card-title">{{ METHOD_LABELS.parametric }}</h2>
<p class="atelier__card-sub">décider au curseur la médiane basse, expliquée en jouant</p>
</div>
</div>
<p class="atelier__prose">
Quand la question est un nombre un montant, un taux, une répartition
voter pour ou contre appauvrit la question. Chacun pose son curseur, et le
collectif retient la médiane basse. Bouge les cinq curseurs-votes ci-dessous :
tire un vote vers l'extrême, la médiane bouge à peine.
</p>
<AtelierMedianDemo />
</section>
</div>
</template>
<style scoped>
.atelier {
display: flex;
flex-direction: column;
gap: clamp(1rem, 3vw, 1.5rem);
max-width: 56rem;
margin: 0 auto;
padding-bottom: 4rem;
}
.atelier__back { align-self: flex-start; font-size: 0.8125rem; text-decoration: none; }
.atelier__header { display: flex; flex-direction: column; gap: 0.35rem; }
.atelier__title {
font-size: clamp(1.5rem, 5vw, 1.9rem);
font-weight: 800;
letter-spacing: -0.02em;
color: var(--mood-text);
}
.atelier__subtitle {
font-size: 0.875rem;
color: var(--mood-text-muted);
line-height: 1.55;
max-width: 38rem;
}
.atelier__card {
padding: clamp(1rem, 3vw, 1.4rem);
display: flex;
flex-direction: column;
gap: 0.9rem;
}
.atelier__card-head { display: flex; align-items: center; gap: 0.8rem; }
.atelier__card-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2.75rem;
height: 2.75rem;
border-radius: var(--r-icon);
font-size: 1.3rem;
flex-shrink: 0;
}
.atelier__card-icon--binary {
background: color-mix(in srgb, var(--mood-secondary) 12%, transparent);
color: var(--mood-secondary);
}
.atelier__card-icon--parametric {
background: color-mix(in srgb, var(--mood-tertiary) 12%, transparent);
color: var(--mood-tertiary);
}
.atelier__card-title { font-size: 1.05rem; font-weight: 800; color: var(--mood-text); }
.atelier__card-sub { font-size: 0.8125rem; color: var(--mood-text-muted); }
.atelier__prose {
font-size: 0.875rem;
line-height: 1.65;
color: var(--mood-text);
}
</style>