Screens need colour that separates information without ever carrying it alone. Tokens gain state, membership and status tints whose marks hold 3:1 and texts 4.5:1 in both themes and under three dichromacies, and every hue stays 30 degrees from the reserved conflict hues. Commands get three levels; Pastille, Carte and an icon module join the primitives; memberships map to six stable tints over sorted names. A pill label wraps and never truncates, and keeps one line beside a nowrap neighbour. Checked: node 3949; browser 767, only the walkthrough captures differ. --- FR --- [ADD] interface : fondations, pastilles, cartes, icônes, bandeau marine Les écrans ont besoin d'une couleur qui distingue l'information sans jamais la porter seule. Les jetons gagnent des teintes d'état, d'appartenance et de statut dont les marques tiennent 3:1 et les textes 4,5:1 dans les deux thèmes et sous trois dichromaties, chaque teinte à 30 degrés des teintes de conflit réservées. Les commandes ont trois niveaux ; Pastille, Carte et un module d'icônes rejoignent les primitives ; les appartenances reçoivent six teintes stables sur les noms triés. Un libellé de pastille se replie, jamais tronqué. Vérifié : node 3949 ; navigateur 767, seules les captures du parcours. Assisted-by: Claude Opus 5.5
92 lines
3.3 KiB
Svelte
92 lines
3.3 KiB
Svelte
<!-- © 2026 TechnoLibre (http://www.technolibre.ca)
|
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -->
|
|
|
|
<script>
|
|
// Un refus posé là où le geste a eu lieu (§ 2.1, § 5.9, § 14.6) : son
|
|
// texte, celui de t sur son code et ses détails, puis son remède en
|
|
// Commande, puis chacun de details.autres dans leur ordre, de même. Une
|
|
// région role="status", jamais une fenêtre.
|
|
//
|
|
// refus : {code, details}, le remède dans details.remede. Le remède
|
|
// s'exécute par actionRemede (commande.js), sur la séance et l'état de
|
|
// navigation du contexte, ou par gestes, ceux que l'écran fournit — le
|
|
// choix d'une place sur le plan. Un remède que rien ne sait exécuter ne
|
|
// pose aucune commande ; le texte du refus reste. Le remède abouti — tout
|
|
// rendu autre que null, qui dit une désignation annulée —, lever(refus),
|
|
// quand il est donné, reçoit le refus affiché au départ du remède, celui
|
|
// qu'il levait : le porteur ne retire que lui, même remplacé entre-temps.
|
|
// Un refus de details.autres rend à lever le refus qui le porte.
|
|
//
|
|
// Le refus se peint sur son propre fond, --couleur-refus-fond, bordé de son
|
|
// filet et d'un trait de gauche de la teinte du refus, une icône devant son
|
|
// texte : il se lit de même sur la page, une carte ou une fenêtre.
|
|
import { getContext } from 'svelte';
|
|
import { actionRemede } from './commande.js';
|
|
import Commande from './Commande.svelte';
|
|
import Icone from './Icone.svelte';
|
|
import Refus from './Refus.svelte';
|
|
|
|
let { refus, lever = null, gestes = {}, id = undefined } = $props();
|
|
|
|
const t = getContext('t');
|
|
const seance = getContext('seance');
|
|
const ui = getContext('ui') ?? null;
|
|
|
|
const message = $derived(t(refus.code, refus.details));
|
|
const action = $derived(actionRemede(refus.details?.remede ?? null, { seance, ui, gestes }));
|
|
const autres = $derived(refus.details?.autres ?? []);
|
|
|
|
async function executerRemede() {
|
|
const affiche = refus;
|
|
const rendu = await action.executer();
|
|
if (rendu !== null) lever?.(affiche);
|
|
return rendu;
|
|
}
|
|
|
|
// Le lever d'un refus de details.autres : celui du refus qui le porte.
|
|
const leverPorteur = $derived(lever === null ? null : () => lever(refus));
|
|
</script>
|
|
|
|
<div class="refus" role="status" data-refus={refus.code} {id}>
|
|
<p><span class="signe"><Icone nom="interdit" /></span>{message}</p>
|
|
{#if action !== null}
|
|
{#key action}
|
|
<Commande
|
|
cle={action.cle}
|
|
details={action.details}
|
|
nom={action.nom}
|
|
confirmer={action.confirmer}
|
|
executer={executerRemede}
|
|
{gestes}
|
|
/>
|
|
{/key}
|
|
{/if}
|
|
{#each autres as autre, rang (rang)}
|
|
<Refus refus={autre} lever={leverPorteur} {gestes} />
|
|
{/each}
|
|
</div>
|
|
|
|
<style>
|
|
.refus {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: var(--espace-1);
|
|
padding: var(--espace-1) var(--espace-2);
|
|
border: 1px solid var(--couleur-refus-filet);
|
|
border-left: 3px solid var(--couleur-refus);
|
|
border-radius: var(--rayon-2);
|
|
background-color: var(--couleur-refus-fond);
|
|
color: var(--couleur-refus);
|
|
font-size: var(--taille-texte);
|
|
}
|
|
|
|
p {
|
|
margin: 0;
|
|
}
|
|
|
|
.signe {
|
|
margin-right: var(--espace-1);
|
|
color: var(--couleur-refus-marque);
|
|
}
|
|
</style>
|