[ADD] interface: colour tokens, two themes, checked palette, marks
The plan's colours carry meaning — a conflict, a reservation, a mode — so
they must stay readable for every reader and in both themes. jetons.css
defines the tokens for the light and dark themes, set by data-theme on the
root; palette.js reads them from the stylesheet text and checks, by
computation, contrast to WCAG and separation under the three
dichromacies, keeping the conflict hue reserved. The theme follows the
system at each start and the operator's choice lasts the session.
Checked: 1709 node and 43 browser tests.
--- FR ---
[ADD] interface : jetons de couleur, deux thèmes, palette, marques
Les couleurs du plan portent un sens — un conflit, une réservation, un mode
— et doivent rester lisibles pour tout lecteur et dans les deux thèmes.
jetons.css définit les jetons des thèmes clair et sombre, posés par
data-theme sur la racine ; palette.js les lit dans le texte de la feuille
et contrôle, par calcul, le contraste au sens des WCAG et la séparation
sous les trois dichromaties, la teinte du conflit restant réservée. Le
thème suit le système à chaque démarrage ; le choix de l'opérateur vaut
pour la séance.
Vérifié : 1709 node et 43 navigateur.
Assisted-by: Claude Opus 5.5
2026-10-07 02:33:12 -04:00
// © 2026 TechnoLibre (http://www.technolibre.ca)
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
// Le registre des marques porteuses d'information et des textes (§ 14.5,
// § 7.5, § 7.6, § 7.7), et la palette de jetons.css validée par calcul sur
// lui (§ 12.7) : chaque entrée tient son seuil sur chacun de ses fonds, dans
// les deux thèmes, en couleurs d'origine puis sous les trois dichromaties.
import assert from 'node:assert/strict' ;
import { readFileSync } from 'node:fs' ;
import { describe , test } from '../../test/lanceur.js' ;
[ADD] plan: one hue and pattern per conflict rule, legend, appartenance
The plan drew every conflict in one hue, so a table that seats colleagues
together looked like one where people meet again. Each active rule now has
its own reserved hue and pattern: same appartenance hatched one way, met
again hatched the other, back at a table dotted; rules on one table
overlap, the badge keeps the total. A legend from the view bar shows each
active rule's sample. A table's tooltip names the appartenance that brings
a pair together. The hues are validated by computation in both themes and
the spec (7.5, 12.7) follows. Checked: 2848 node, 580 browser tests.
--- FR ---
[ADD] plan : une teinte et une trame par règle, légende, appartenance
Le plan dessinait tout conflit d'une seule teinte : une table qui réunit
des collègues ressemblait à une table où des gens se revoient. Chaque
règle active a sa teinte réservée et sa trame : même appartenance hachurée
dans un sens, voisins revus dans l'autre, table revue en pointillé ; les
règles d'une table se superposent, la pastille garde le total. Une légende
dans la barre de vue montre l'échantillon de chaque règle active.
L'infobulle nomme l'appartenance qui réunit une paire. Teintes validées
par calcul dans les deux thèmes ; spec § 7.5, § 12.7. Vérifié : 2848, 580.
Assisted-by: Claude Opus 5.5
2026-10-08 04:33:43 -04:00
import { CONFLITS , JETONS _CONFLIT , MARQUES , SEPARATIONS , TEXTES } from './marques.js' ;
import { lireBlocs , lireJetons , verifierPalette , verifierSeparation } from './palette.js' ;
[ADD] interface: colour tokens, two themes, checked palette, marks
The plan's colours carry meaning — a conflict, a reservation, a mode — so
they must stay readable for every reader and in both themes. jetons.css
defines the tokens for the light and dark themes, set by data-theme on the
root; palette.js reads them from the stylesheet text and checks, by
computation, contrast to WCAG and separation under the three
dichromacies, keeping the conflict hue reserved. The theme follows the
system at each start and the operator's choice lasts the session.
Checked: 1709 node and 43 browser tests.
--- FR ---
[ADD] interface : jetons de couleur, deux thèmes, palette, marques
Les couleurs du plan portent un sens — un conflit, une réservation, un mode
— et doivent rester lisibles pour tout lecteur et dans les deux thèmes.
jetons.css définit les jetons des thèmes clair et sombre, posés par
data-theme sur la racine ; palette.js les lit dans le texte de la feuille
et contrôle, par calcul, le contraste au sens des WCAG et la séparation
sous les trois dichromaties, la teinte du conflit restant réservée. Le
thème suit le système à chaque démarrage ; le choix de l'opérateur vaut
pour la séance.
Vérifié : 1709 node et 43 navigateur.
Assisted-by: Claude Opus 5.5
2026-10-07 02:33:12 -04:00
const JETONS = readFileSync ( new URL ( './jetons.css' , import . meta . url ) , 'utf8' ) ;
const THEMES = [ 'clair' , 'sombre' ] ;
const NOMS _MARQUES = [
'cadenasFerme' , 'cadenasOuvert' , 'anneau' , 'hachure' , 'remplissagePlein' ,
[ADD] plan: one hue and pattern per conflict rule, legend, appartenance
The plan drew every conflict in one hue, so a table that seats colleagues
together looked like one where people meet again. Each active rule now has
its own reserved hue and pattern: same appartenance hatched one way, met
again hatched the other, back at a table dotted; rules on one table
overlap, the badge keeps the total. A legend from the view bar shows each
active rule's sample. A table's tooltip names the appartenance that brings
a pair together. The hues are validated by computation in both themes and
the spec (7.5, 12.7) follows. Checked: 2848 node, 580 browser tests.
--- FR ---
[ADD] plan : une teinte et une trame par règle, légende, appartenance
Le plan dessinait tout conflit d'une seule teinte : une table qui réunit
des collègues ressemblait à une table où des gens se revoient. Chaque
règle active a sa teinte réservée et sa trame : même appartenance hachurée
dans un sens, voisins revus dans l'autre, table revue en pointillé ; les
règles d'une table se superposent, la pastille garde le total. Une légende
dans la barre de vue montre l'échantillon de chaque règle active.
L'infobulle nomme l'appartenance qui réunit une paire. Teintes validées
par calcul dans les deux thèmes ; spec § 7.5, § 12.7. Vérifié : 2848, 580.
Assisted-by: Claude Opus 5.5
2026-10-08 04:33:43 -04:00
'contourConflit' , 'trameAppartenance' , 'trameVoisins' , 'trameTable' , 'pastille' , 'poignee' , 'gel' , 'miseEnEvidence' ,
[ADD] interface: colour tokens, two themes, checked palette, marks
The plan's colours carry meaning — a conflict, a reservation, a mode — so
they must stay readable for every reader and in both themes. jetons.css
defines the tokens for the light and dark themes, set by data-theme on the
root; palette.js reads them from the stylesheet text and checks, by
computation, contrast to WCAG and separation under the three
dichromacies, keeping the conflict hue reserved. The theme follows the
system at each start and the operator's choice lasts the session.
Checked: 1709 node and 43 browser tests.
--- FR ---
[ADD] interface : jetons de couleur, deux thèmes, palette, marques
Les couleurs du plan portent un sens — un conflit, une réservation, un mode
— et doivent rester lisibles pour tout lecteur et dans les deux thèmes.
jetons.css définit les jetons des thèmes clair et sombre, posés par
data-theme sur la racine ; palette.js les lit dans le texte de la feuille
et contrôle, par calcul, le contraste au sens des WCAG et la séparation
sous les trois dichromaties, la teinte du conflit restant réservée. Le
thème suit le système à chaque démarrage ; le choix de l'opérateur vaut
pour la séance.
Vérifié : 1709 node et 43 navigateur.
Assisted-by: Claude Opus 5.5
2026-10-07 02:33:12 -04:00
'selection' , 'cadreLecture' , 'cadreEcriture' , 'cadreBloque' , 'focus' ,
'contourTable' , 'contourChaise' , 'echelle' , 'fantome' ,
] ;
// Les remplissages d'une chaise : fond, pleine, et les deux couleurs de la
// hachure — ses traits sur le fond de la chaise.
const REMPLISSAGES _CHAISE = [ '--couleur-chaise-fond' , '--couleur-chaise-pleine' , '--couleur-hachure' ] ;
// Fonds minimaux des marques de désignation et du fantôme. « chaise » vaut
// chacun des remplissages d'une chaise : la marque se pose sur une chaise
// vide, pourvue ou à pourvoir.
const c = ( nom ) => ` --couleur- ${ nom } ` ;
const FONDS _REQUIS = {
focus : [ ... [ 'page-fond' , 'bandeau-fond' , 'sol' , 'table-fond' ] . map ( c ) , ... REMPLISSAGES _CHAISE ] ,
selection : [ ... [ 'page-fond' , 'sol' , 'table-fond' ] . map ( c ) , ... REMPLISSAGES _CHAISE ] ,
miseEnEvidence : [ ... [ 'page-fond' , 'sol' , 'table-fond' ] . map ( c ) , ... REMPLISSAGES _CHAISE ] ,
fantome : [ ... [ 'sol' , 'table-fond' ] . map ( c ) , ... REMPLISSAGES _CHAISE ] ,
} ;
const parNom = ( registre , nom ) => registre . find ( ( e ) => e . nom === nom ) ;
describe ( 'registre des marques' , ( ) => {
[ADD] plan: one hue and pattern per conflict rule, legend, appartenance
The plan drew every conflict in one hue, so a table that seats colleagues
together looked like one where people meet again. Each active rule now has
its own reserved hue and pattern: same appartenance hatched one way, met
again hatched the other, back at a table dotted; rules on one table
overlap, the badge keeps the total. A legend from the view bar shows each
active rule's sample. A table's tooltip names the appartenance that brings
a pair together. The hues are validated by computation in both themes and
the spec (7.5, 12.7) follows. Checked: 2848 node, 580 browser tests.
--- FR ---
[ADD] plan : une teinte et une trame par règle, légende, appartenance
Le plan dessinait tout conflit d'une seule teinte : une table qui réunit
des collègues ressemblait à une table où des gens se revoient. Chaque
règle active a sa teinte réservée et sa trame : même appartenance hachurée
dans un sens, voisins revus dans l'autre, table revue en pointillé ; les
règles d'une table se superposent, la pastille garde le total. Une légende
dans la barre de vue montre l'échantillon de chaque règle active.
L'infobulle nomme l'appartenance qui réunit une paire. Teintes validées
par calcul dans les deux thèmes ; spec § 7.5, § 12.7. Vérifié : 2848, 580.
Assisted-by: Claude Opus 5.5
2026-10-08 04:33:43 -04:00
test ( 'les vingt-deux marques du contrat, noms uniques, seuil 3, au moins un fond chacune' , ( ) => {
[ADD] interface: colour tokens, two themes, checked palette, marks
The plan's colours carry meaning — a conflict, a reservation, a mode — so
they must stay readable for every reader and in both themes. jetons.css
defines the tokens for the light and dark themes, set by data-theme on the
root; palette.js reads them from the stylesheet text and checks, by
computation, contrast to WCAG and separation under the three
dichromacies, keeping the conflict hue reserved. The theme follows the
system at each start and the operator's choice lasts the session.
Checked: 1709 node and 43 browser tests.
--- FR ---
[ADD] interface : jetons de couleur, deux thèmes, palette, marques
Les couleurs du plan portent un sens — un conflit, une réservation, un mode
— et doivent rester lisibles pour tout lecteur et dans les deux thèmes.
jetons.css définit les jetons des thèmes clair et sombre, posés par
data-theme sur la racine ; palette.js les lit dans le texte de la feuille
et contrôle, par calcul, le contraste au sens des WCAG et la séparation
sous les trois dichromaties, la teinte du conflit restant réservée. Le
thème suit le système à chaque démarrage ; le choix de l'opérateur vaut
pour la séance.
Vérifié : 1709 node et 43 navigateur.
Assisted-by: Claude Opus 5.5
2026-10-07 02:33:12 -04:00
assert . equal ( MARQUES . length , NOMS _MARQUES . length ) ;
assert . deepEqual ( MARQUES . map ( ( m ) => m . nom ) , NOMS _MARQUES ) ;
assert . equal ( new Set ( MARQUES . map ( ( m ) => m . nom ) ) . size , MARQUES . length ) ;
for ( const marque of MARQUES ) {
assert . deepEqual ( Object . keys ( marque ) . sort ( ) , [ 'fonds' , 'jeton' , 'nom' , 'seuil' ] , marque . nom ) ;
assert . equal ( marque . seuil , 3 , marque . nom ) ;
assert . ok ( marque . fonds . length > 0 , marque . nom ) ;
assert . equal ( new Set ( marque . fonds ) . size , marque . fonds . length , ` ${ marque . nom } : fond en double ` ) ;
}
} ) ;
test ( 'le registre est figé' , ( ) => {
assert . ok ( Object . isFrozen ( MARQUES ) && Object . isFrozen ( TEXTES ) ) ;
assert . ok ( MARQUES . every ( ( m ) => Object . isFrozen ( m ) && Object . isFrozen ( m . fonds ) ) ) ;
assert . ok ( TEXTES . every ( ( m ) => Object . isFrozen ( m ) && Object . isFrozen ( m . fonds ) ) ) ;
} ) ;
test ( 'le focus, la sélection, la mise en évidence et le fantôme se mesurent sur chaque fond où ils se peignent, chaque remplissage de chaise compris' , ( ) => {
for ( const nom of [ 'focus' , 'selection' , 'miseEnEvidence' , 'fantome' ] ) {
const marque = parNom ( MARQUES , nom ) ;
assert . notEqual ( marque , undefined , nom ) ;
for ( const fond of FONDS _REQUIS [ nom ] ) {
assert . ok ( marque . fonds . includes ( fond ) , ` ${ nom } : ${ fond } ` ) ;
}
}
} ) ;
test ( 'une marque posée sur une chaise se mesure sur chacun de ses remplissages' , ( ) => {
const surChaise = [ 'cadenasFerme' , 'cadenasOuvert' , 'anneau' ] ;
for ( const nom of surChaise ) {
for ( const fond of REMPLISSAGES _CHAISE ) {
assert . ok ( parNom ( MARQUES , nom ) . fonds . includes ( fond ) , ` ${ nom } : ${ fond } ` ) ;
}
}
assert . deepEqual ( parNom ( MARQUES , 'hachure' ) . fonds , [ '--couleur-chaise-fond' ] ) ;
} ) ;
test ( 'chaque jeton et chaque fond du registre existe dans les deux thèmes' , ( ) => {
const entrees = [ ... MARQUES , ... TEXTES ] ;
assert . ok ( entrees . length > 20 ) ;
for ( const theme of THEMES ) {
const jetons = lireJetons ( JETONS , theme ) ;
for ( const entree of entrees ) {
for ( const nom of [ entree . jeton , ... entree . fonds ] ) {
assert . ok ( jetons . has ( nom ) , ` ${ theme } : ${ entree . nom } → ${ nom } ` ) ;
}
}
}
} ) ;
} ) ;
[ADD] plan: one hue and pattern per conflict rule, legend, appartenance
The plan drew every conflict in one hue, so a table that seats colleagues
together looked like one where people meet again. Each active rule now has
its own reserved hue and pattern: same appartenance hatched one way, met
again hatched the other, back at a table dotted; rules on one table
overlap, the badge keeps the total. A legend from the view bar shows each
active rule's sample. A table's tooltip names the appartenance that brings
a pair together. The hues are validated by computation in both themes and
the spec (7.5, 12.7) follows. Checked: 2848 node, 580 browser tests.
--- FR ---
[ADD] plan : une teinte et une trame par règle, légende, appartenance
Le plan dessinait tout conflit d'une seule teinte : une table qui réunit
des collègues ressemblait à une table où des gens se revoient. Chaque
règle active a sa teinte réservée et sa trame : même appartenance hachurée
dans un sens, voisins revus dans l'autre, table revue en pointillé ; les
règles d'une table se superposent, la pastille garde le total. Une légende
dans la barre de vue montre l'échantillon de chaque règle active.
L'infobulle nomme l'appartenance qui réunit une paire. Teintes validées
par calcul dans les deux thèmes ; spec § 7.5, § 12.7. Vérifié : 2848, 580.
Assisted-by: Claude Opus 5.5
2026-10-08 04:33:43 -04:00
describe ( 'les trois sortes de conflit (§ 7.5, § 12.7)' , ( ) => {
test ( 'une par règle localisable, dans l’ ordre du moteur : sa règle, la marque de sa trame, le jeton de sa teinte, la forme de son motif' , ( ) => {
assert . deepEqual (
CONFLITS . map ( ( c ) => [ c . regle , c . marque , c . jeton , c . forme ] ) ,
[
[ 'separerAppartenances' , 'trameAppartenance' , '--couleur-conflit-appartenance' , 'hachuresDescendantes' ] ,
[ 'nouveauxVoisins' , 'trameVoisins' , '--couleur-conflit-voisins' , 'hachuresMontantes' ] ,
[ 'nouvelleTable' , 'trameTable' , '--couleur-conflit-table' , 'points' ] ,
] ,
) ;
assert . ok ( CONFLITS . every ( ( c ) => Object . keys ( c ) . sort ( ) . join ( ) === 'forme,jeton,marque,regle' ) ) ;
assert . ok ( Object . isFrozen ( CONFLITS ) && CONFLITS . every ( ( c ) => Object . isFrozen ( c ) ) ) ;
assert . deepEqual ( JETONS _CONFLIT , CONFLITS . map ( ( { jeton } ) => jeton ) ) ;
assert . ok ( Object . isFrozen ( JETONS _CONFLIT ) ) ;
// Les seuils d'écart perçu : entre deux teintes de conflit, et d'une
// teinte de conflit à une autre marque du plan.
assert . deepEqual ( SEPARATIONS , { entreConflits : 12 , autresMarques : 5 } ) ;
assert . ok ( Object . isFrozen ( SEPARATIONS ) ) ;
} ) ;
test ( 'chaque trame est au registre, peinte de son jeton sur le fond du plateau' , ( ) => {
for ( const { marque , jeton } of CONFLITS ) {
const entree = parNom ( MARQUES , marque ) ;
assert . notEqual ( entree , undefined , marque ) ;
assert . equal ( entree . jeton , jeton , marque ) ;
assert . deepEqual ( entree . fonds , [ '--couleur-table-fond' ] , marque ) ;
}
} ) ;
test ( 'teinte réservée au registre : une teinte de conflit ne peint que sa trame, aucune autre marque ni aucun texte' , ( ) => {
const peintes = [ ... MARQUES , ... TEXTES ] . filter ( ( e ) => JETONS _CONFLIT . includes ( e . jeton ) || e . fonds . some ( ( f ) => JETONS _CONFLIT . includes ( f ) ) ) ;
assert . deepEqual ( peintes . map ( ( e ) => e . nom ) , CONFLITS . map ( ( { marque } ) => marque ) ) ;
// Le contour épaissi d'une table en conflit est commun aux trois règles :
// il ne porte aucune de leurs teintes.
assert . ok ( ! JETONS _CONFLIT . includes ( parNom ( MARQUES , 'contourConflit' ) . jeton ) ) ;
} ) ;
} ) ;
[ADD] interface: colour tokens, two themes, checked palette, marks
The plan's colours carry meaning — a conflict, a reservation, a mode — so
they must stay readable for every reader and in both themes. jetons.css
defines the tokens for the light and dark themes, set by data-theme on the
root; palette.js reads them from the stylesheet text and checks, by
computation, contrast to WCAG and separation under the three
dichromacies, keeping the conflict hue reserved. The theme follows the
system at each start and the operator's choice lasts the session.
Checked: 1709 node and 43 browser tests.
--- FR ---
[ADD] interface : jetons de couleur, deux thèmes, palette, marques
Les couleurs du plan portent un sens — un conflit, une réservation, un mode
— et doivent rester lisibles pour tout lecteur et dans les deux thèmes.
jetons.css définit les jetons des thèmes clair et sombre, posés par
data-theme sur la racine ; palette.js les lit dans le texte de la feuille
et contrôle, par calcul, le contraste au sens des WCAG et la séparation
sous les trois dichromaties, la teinte du conflit restant réservée. Le
thème suit le système à chaque démarrage ; le choix de l'opérateur vaut
pour la séance.
Vérifié : 1709 node et 43 navigateur.
Assisted-by: Claude Opus 5.5
2026-10-07 02:33:12 -04:00
describe ( 'registre des textes' , ( ) => {
test ( 'page, secondaire, bandeau, refus, avis, listes du plan, pastille ; seuil 4,5' , ( ) => {
assert . deepEqual ( TEXTES . map ( ( t ) => t . nom ) , [ 'page' , 'secondaire' , 'bandeau' , 'refus' , 'avis' , 'listes' , 'pastille' ] ) ;
assert . ok ( TEXTES . every ( ( t ) => t . seuil === 4.5 && t . fonds . length > 0 ) ) ;
assert . deepEqual ( parNom ( TEXTES , 'listes' ) . fonds , [ '--couleur-sol' ] ) ;
assert . deepEqual ( parNom ( TEXTES , 'pastille' ) . fonds , [ '--couleur-pastille-fond' ] ) ;
} ) ;
} ) ;
describe ( 'palette de jetons.css validée par calcul (§ 12.7, § 14.5)' , ( ) => {
test ( 'aucun jeton de texte ou de marque, ni aucun de leurs fonds, n’ a de canal alpha' , ( ) => {
const noms = new Set ( [ ... MARQUES , ... TEXTES ] . flatMap ( ( e ) => [ e . jeton , ... e . fonds ] ) ) ;
assert . ok ( noms . size > 20 ) ;
const blocs = lireBlocs ( JETONS ) ;
for ( const theme of THEMES ) {
const selecteur = ` :root[data-theme=' ${ theme } '] ` ;
const brutes = new Map (
blocs . filter ( ( b ) => b . selecteurs . includes ( selecteur ) ) . flatMap ( ( b ) => [ ... b . declarations ] ) ,
) ;
const jetons = lireJetons ( JETONS , theme ) ;
for ( const nom of noms ) {
assert . equal ( jetons . get ( nom ) [ 3 ] , 1 , ` ${ theme } : ${ nom } ` ) ;
assert . doesNotMatch (
brutes . get ( nom ) ,
/rgba|hsla|transparent|#[0-9a-f]{8}\b|#[0-9a-f]{4}\b|\/\s*[\d.]+%?\s*\)/i ,
` ${ theme } : ${ nom } ` ,
) ;
}
}
} ) ;
test ( 'chaque marque tient 3:1 sur chacun de ses fonds, dans les deux thèmes, sous les trois simulations' , ( ) => {
assert . deepEqual ( verifierPalette ( JETONS , MARQUES ) , [ ] ) ;
} ) ;
test ( 'chaque texte tient 4,5:1 sur chacun de ses fonds, dans les deux thèmes, sous les trois simulations' , ( ) => {
assert . deepEqual ( verifierPalette ( JETONS , TEXTES ) , [ ] ) ;
} ) ;
[ADD] plan: one hue and pattern per conflict rule, legend, appartenance
The plan drew every conflict in one hue, so a table that seats colleagues
together looked like one where people meet again. Each active rule now has
its own reserved hue and pattern: same appartenance hatched one way, met
again hatched the other, back at a table dotted; rules on one table
overlap, the badge keeps the total. A legend from the view bar shows each
active rule's sample. A table's tooltip names the appartenance that brings
a pair together. The hues are validated by computation in both themes and
the spec (7.5, 12.7) follows. Checked: 2848 node, 580 browser tests.
--- FR ---
[ADD] plan : une teinte et une trame par règle, légende, appartenance
Le plan dessinait tout conflit d'une seule teinte : une table qui réunit
des collègues ressemblait à une table où des gens se revoient. Chaque
règle active a sa teinte réservée et sa trame : même appartenance hachurée
dans un sens, voisins revus dans l'autre, table revue en pointillé ; les
règles d'une table se superposent, la pastille garde le total. Une légende
dans la barre de vue montre l'échantillon de chaque règle active.
L'infobulle nomme l'appartenance qui réunit une paire. Teintes validées
par calcul dans les deux thèmes ; spec § 7.5, § 12.7. Vérifié : 2848, 580.
Assisted-by: Claude Opus 5.5
2026-10-08 04:33:43 -04:00
// Les autres marques du plan : celles qui se peignent sur le sol, le
// plateau ou une chaise, trames de conflit exceptées, chaque jeton une fois.
const FONDS _DU _PLAN = new Set ( [ '--couleur-sol' , '--couleur-table-fond' , ... REMPLISSAGES _CHAISE ] ) ;
const autresMarquesDuPlan = ( ) => [
... new Set ( MARQUES . filter ( ( m ) => ! JETONS _CONFLIT . includes ( m . jeton ) && m . fonds . some ( ( f ) => FONDS _DU _PLAN . has ( f ) ) ) . map ( ( m ) => m . jeton ) ) ,
] ;
test ( ` les trois teintes de conflit se séparent deux à deux de ${ SEPARATIONS . entreConflits } au moins (OKLab × 100), dans les deux thèmes, en couleurs d’ origine et sous les trois simulations ` , ( ) => {
assert . equal ( JETONS _CONFLIT . length , 3 ) ;
assert . deepEqual ( verifierSeparation ( JETONS , JETONS _CONFLIT , [ ] , SEPARATIONS . entreConflits ) , [ ] ) ;
} ) ;
test ( ` chaque teinte de conflit se sépare de ${ SEPARATIONS . autresMarques } au moins de chaque autre marque du plan, dans les deux thèmes, sous les trois simulations ` , ( ) => {
const autres = autresMarquesDuPlan ( ) ;
assert . ok ( autres . length >= 10 , ` ${ autres . length } autres marques ` ) ;
for ( const jeton of [ '--couleur-gel' , '--couleur-mise-en-evidence' , '--couleur-selection' , '--couleur-focus' , '--couleur-fantome' , '--couleur-pastille-fond' ] ) {
assert . ok ( autres . includes ( jeton ) , jeton ) ;
}
assert . deepEqual ( verifierSeparation ( JETONS , JETONS _CONFLIT , autres , SEPARATIONS . autresMarques ) , [ ] ) ;
} ) ;
[ADD] interface: colour tokens, two themes, checked palette, marks
The plan's colours carry meaning — a conflict, a reservation, a mode — so
they must stay readable for every reader and in both themes. jetons.css
defines the tokens for the light and dark themes, set by data-theme on the
root; palette.js reads them from the stylesheet text and checks, by
computation, contrast to WCAG and separation under the three
dichromacies, keeping the conflict hue reserved. The theme follows the
system at each start and the operator's choice lasts the session.
Checked: 1709 node and 43 browser tests.
--- FR ---
[ADD] interface : jetons de couleur, deux thèmes, palette, marques
Les couleurs du plan portent un sens — un conflit, une réservation, un mode
— et doivent rester lisibles pour tout lecteur et dans les deux thèmes.
jetons.css définit les jetons des thèmes clair et sombre, posés par
data-theme sur la racine ; palette.js les lit dans le texte de la feuille
et contrôle, par calcul, le contraste au sens des WCAG et la séparation
sous les trois dichromaties, la teinte du conflit restant réservée. Le
thème suit le système à chaque démarrage ; le choix de l'opérateur vaut
pour la séance.
Vérifié : 1709 node et 43 navigateur.
Assisted-by: Claude Opus 5.5
2026-10-07 02:33:12 -04:00
} ) ;