DOCS/claude design/sectionparcours-refonte-flux.html
Thomas Fransolet a5a8ecdb20 Documentation interne MyInfoMate / Unov
Import initial de la documentation : statut, roadmap, plans V1/V2,
specs verticales (creche, sport), audits securite, plan de test,
analyse concurrentielle et maquettes de design.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 11:17:01 +02:00

1394 lines
44 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html><html lang="fr"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<!-- Maquette rapatriee depuis l artifact c9d9a5c0-1ba4-4e50-a522-28a0cf2ecd15 le 2026-08-11. Source de verite du design : ce fichier. L artifact ne sert qu a la diffusion. -->
<title>Configurer un parcours — refonte du flux</title>
<style>
:root {
--ground: #F5F7F9;
--surface: #FFFFFF;
--surface-2: #ECF0F4;
--sunken: #E2E8EE;
--ink: #14202B;
--ink-2: #45596B;
--ink-3: #7A8B9B;
--line: #D3DCE4;
--line-soft: #E6ECF1;
--slate: #264863;
--slate-soft: #CBD7E1;
--brass: #A97B2E;
--brass-soft: #EFE2C8;
--moss: #4E7A46;
--clay: #A8322A;
--shadow-sm: 0 1px 2px rgba(20,32,43,.07);
--shadow-md: 0 2px 4px rgba(20,32,43,.06), 0 8px 22px rgba(20,32,43,.07);
--shadow-lg: 0 4px 10px rgba(20,32,43,.08), 0 20px 48px rgba(20,32,43,.12);
--prose: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, ui-serif, serif;
--ui: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--mono: ui-monospace, "Cascadia Mono", "SF Mono", Consolas, "Liberation Mono", monospace;
}
@media (prefers-color-scheme: dark) {
:root {
--ground: #0E151C;
--surface: #18222C;
--surface-2: #202C38;
--sunken: #131C25;
--ink: #E4EAF1;
--ink-2: #A6B5C3;
--ink-3: #74879A;
--line: #2B3945;
--line-soft: #222E3A;
--slate: #82AAC9;
--slate-soft: #33506A;
--brass: #D2A24C;
--brass-soft: #4A3A1C;
--moss: #7BB16E;
--clay: #E08078;
--shadow-sm: 0 1px 2px rgba(0,0,0,.35);
--shadow-md: 0 2px 4px rgba(0,0,0,.3), 0 8px 22px rgba(0,0,0,.28);
--shadow-lg: 0 4px 10px rgba(0,0,0,.35), 0 20px 48px rgba(0,0,0,.45);
}
}
:root[data-theme="dark"] {
--ground: #0E151C;
--surface: #18222C;
--surface-2: #202C38;
--sunken: #131C25;
--ink: #E4EAF1;
--ink-2: #A6B5C3;
--ink-3: #74879A;
--line: #2B3945;
--line-soft: #222E3A;
--slate: #82AAC9;
--slate-soft: #33506A;
--brass: #D2A24C;
--brass-soft: #4A3A1C;
--moss: #7BB16E;
--clay: #E08078;
--shadow-sm: 0 1px 2px rgba(0,0,0,.35);
--shadow-md: 0 2px 4px rgba(0,0,0,.3), 0 8px 22px rgba(0,0,0,.28);
--shadow-lg: 0 4px 10px rgba(0,0,0,.35), 0 20px 48px rgba(0,0,0,.45);
}
:root[data-theme="light"] {
--ground: #F5F7F9;
--surface: #FFFFFF;
--surface-2: #ECF0F4;
--sunken: #E2E8EE;
--ink: #14202B;
--ink-2: #45596B;
--ink-3: #7A8B9B;
--line: #D3DCE4;
--line-soft: #E6ECF1;
--slate: #264863;
--slate-soft: #CBD7E1;
--brass: #A97B2E;
--brass-soft: #EFE2C8;
--moss: #4E7A46;
--clay: #A8322A;
--shadow-sm: 0 1px 2px rgba(20,32,43,.07);
--shadow-md: 0 2px 4px rgba(20,32,43,.06), 0 8px 22px rgba(20,32,43,.07);
--shadow-lg: 0 4px 10px rgba(20,32,43,.08), 0 20px 48px rgba(20,32,43,.12);
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--ground);
color: var(--ink);
font-family: var(--prose);
font-size: 17px;
line-height: 1.62;
-webkit-font-smoothing: antialiased;
}
.page {
max-width: 1180px;
margin: 0 auto;
padding: 56px 28px 96px;
display: flex;
flex-direction: column;
gap: 60px;
}
.prose { max-width: 68ch; }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
a { color: var(--slate); text-decoration-thickness: 1px; text-underline-offset: 2px; }
code {
font-family: var(--mono);
font-size: .84em;
background: var(--surface-2);
border-radius: 3px;
padding: 1px 5px;
}
:focus-visible {
outline: 2px solid var(--brass);
outline-offset: 2px;
border-radius: 3px;
}
/* ---------- masthead ---------- */
.masthead {
display: flex;
flex-direction: column;
gap: 14px;
padding-bottom: 26px;
border-bottom: 1px solid var(--line);
}
.eyebrow {
font-family: var(--mono);
font-size: 11.5px;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--ink-3);
}
.masthead h1 {
font-size: clamp(31px, 4.6vw, 47px);
line-height: 1.08;
letter-spacing: -0.02em;
font-weight: 600;
margin: 0;
text-wrap: balance;
}
.standfirst {
font-size: 19.5px;
line-height: 1.55;
color: var(--ink-2);
max-width: 60ch;
margin: 0;
}
/* ---------- section headings ---------- */
.sec { display: flex; flex-direction: column; gap: 26px; }
.sec-head { display: flex; flex-direction: column; gap: 10px; max-width: 68ch; }
.sec-head h2 {
font-size: clamp(23px, 2.7vw, 30px);
line-height: 1.18;
letter-spacing: -0.014em;
font-weight: 600;
margin: 0;
text-wrap: balance;
}
.sec-head h3 {
font-size: 20px;
font-weight: 600;
letter-spacing: -0.01em;
margin: 0;
}
/* ---------- depth meter ---------- */
.depth {
display: flex;
flex-direction: column;
gap: 3px;
font-family: var(--ui);
}
.depth-row {
display: grid;
grid-template-columns: 30px minmax(0, 1fr);
align-items: stretch;
gap: 12px;
}
.depth-n {
font-family: var(--mono);
font-size: 11px;
color: var(--ink-3);
display: flex;
align-items: center;
justify-content: flex-end;
font-variant-numeric: tabular-nums;
}
.depth-bar {
background: var(--surface);
border: 1px solid var(--line-soft);
border-left: 3px solid var(--stripe, var(--slate-soft));
border-radius: 4px;
padding: 9px 13px;
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: 4px 10px;
box-shadow: var(--shadow-sm);
}
.depth-bar strong { font-size: 14px; font-weight: 600; letter-spacing: -.005em; }
.depth-bar span { font-size: 13px; color: var(--ink-2); }
.depth-bar em {
font-family: var(--mono);
font-style: normal;
font-size: 11px;
color: var(--ink-3);
margin-left: auto;
white-space: nowrap;
}
.d1 { --stripe: #B9C6D2; margin-left: 0; }
.d2 { --stripe: #93A9BC; }
.d3 { --stripe: #6E8CA6; }
.d4 { --stripe: #4A6E90; }
.d5 { --stripe: var(--clay); }
.depth-row.i2 { padding-left: 26px; }
.depth-row.i3 { padding-left: 52px; }
.depth-row.i4 { padding-left: 78px; }
.depth-row.i5 { padding-left: 104px; }
.depth-note {
font-family: var(--ui);
font-size: 13px;
color: var(--ink-3);
margin: 8px 0 0 42px;
}
/* ---------- findings ---------- */
.findings {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
gap: 14px;
font-family: var(--ui);
}
.finding {
background: var(--surface);
border: 1px solid var(--line-soft);
border-radius: 6px;
padding: 16px 17px 17px;
box-shadow: var(--shadow-sm);
display: flex;
flex-direction: column;
gap: 7px;
}
.finding h4 {
margin: 0;
font-size: 14.5px;
font-weight: 650;
letter-spacing: -.005em;
}
.finding p { font-size: 13.5px; line-height: 1.52; color: var(--ink-2); margin: 0; }
.finding .tagline {
font-family: var(--mono);
font-size: 10.5px;
letter-spacing: .07em;
text-transform: uppercase;
color: var(--clay);
}
/* ---------- mockup frame ---------- */
.demo { display: flex; flex-direction: column; gap: 12px; }
.demo-scroll { overflow-x: auto; padding-bottom: 4px; }
.frame {
min-width: 780px;
background: var(--surface);
border: 1px solid var(--line);
border-radius: 12px;
box-shadow: var(--shadow-lg);
overflow: hidden;
font-family: var(--ui);
font-size: 14px;
line-height: 1.45;
}
.frame-bar {
display: flex;
align-items: center;
gap: 10px;
padding: 13px 18px;
border-bottom: 1px solid var(--line-soft);
background: var(--surface-2);
}
.crumbs {
display: flex;
align-items: center;
gap: 7px;
flex-wrap: wrap;
font-size: 13px;
color: var(--ink-3);
min-width: 0;
}
.crumbs b { color: var(--ink); font-weight: 600; }
.crumbs i { font-style: normal; color: var(--ink-3); }
.frame-title {
margin-left: auto;
font-family: var(--mono);
font-size: 11px;
letter-spacing: .06em;
text-transform: uppercase;
color: var(--ink-3);
}
.frame-body { display: grid; grid-template-columns: 280px minmax(0, 1fr); }
.rail {
border-right: 1px solid var(--line-soft);
background: var(--sunken);
padding: 16px 14px 18px;
display: flex;
flex-direction: column;
gap: 14px;
}
.rail-head {
display: flex;
flex-direction: column;
gap: 3px;
padding: 0 4px;
}
.rail-head .k {
font-family: var(--mono);
font-size: 10.5px;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--ink-3);
}
.rail-head .v { font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.steplist {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
position: relative;
}
/* the trail spine */
.steplist::before {
content: "";
position: absolute;
left: 17px;
top: 20px;
bottom: 20px;
width: 1px;
background: var(--line);
}
.step-btn {
position: relative;
width: 100%;
display: grid;
grid-template-columns: 26px minmax(0, 1fr);
gap: 10px;
align-items: center;
background: none;
border: none;
border-radius: 6px;
padding: 8px 8px 8px 4px;
text-align: left;
cursor: pointer;
font: inherit;
color: var(--ink-2);
transition: background .12s ease, color .12s ease;
}
.step-btn:hover { background: var(--surface-2); color: var(--ink); }
.pin {
position: relative;
z-index: 1;
width: 26px;
height: 26px;
border-radius: 50%;
display: grid;
place-items: center;
background: var(--surface);
border: 1px solid var(--line);
font-family: var(--mono);
font-size: 11.5px;
font-variant-numeric: tabular-nums;
color: var(--ink-3);
flex: none;
}
.step-lab { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.step-lab .t { font-size: 13.5px; font-weight: 550; letter-spacing: -.004em; }
.step-lab .s { font-size: 11.5px; color: var(--ink-3); }
.step-btn[aria-current="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }
.step-btn[aria-current="true"] .pin {
background: var(--brass);
border-color: var(--brass);
color: #fff;
font-weight: 600;
}
:root[data-theme="dark"] .step-btn[aria-current="true"] .pin,
.step-btn[aria-current="true"] .pin { color: #fff; }
@media (prefers-color-scheme: dark) { .step-btn[aria-current="true"] .pin { color: #14202B; } }
:root[data-theme="dark"] .step-btn[aria-current="true"] .pin { color: #14202B; }
:root[data-theme="light"] .step-btn[aria-current="true"] .pin { color: #fff; }
.step-btn.is-root { grid-template-columns: 26px minmax(0, 1fr); }
.step-btn.is-root .pin { border-radius: 5px; }
.rail-add {
margin-left: 36px;
background: none;
border: 1px dashed var(--line);
border-radius: 6px;
padding: 7px 10px;
font: inherit;
font-size: 12.5px;
color: var(--ink-3);
cursor: pointer;
text-align: left;
}
.rail-add:hover { border-color: var(--slate); color: var(--slate); }
/* ---------- detail panel ---------- */
.panel { padding: 20px 22px 22px; display: none; flex-direction: column; gap: 16px; min-width: 0; }
.panel.is-active { display: flex; }
@media (prefers-reduced-motion: no-preference) {
.panel.is-active { animation: slidein .22s cubic-bezier(.2,.7,.35,1); }
@keyframes slidein {
from { opacity: 0; transform: translateX(9px); }
to { opacity: 1; transform: none; }
}
}
.panel-head { display: flex; align-items: flex-start; gap: 12px; }
.panel-head h4 { margin: 0; font-size: 17px; font-weight: 650; letter-spacing: -.012em; }
.panel-head p { margin: 2px 0 0; font-size: 12.5px; color: var(--ink-3); }
.block {
border: 1px solid var(--line-soft);
border-radius: 9px;
padding: 14px 15px 15px;
display: flex;
flex-direction: column;
gap: 12px;
}
.block-title {
display: flex;
align-items: center;
gap: 8px;
font-size: 13px;
font-weight: 650;
letter-spacing: .002em;
}
.block-title .glyph {
width: 20px; height: 20px;
display: grid; place-items: center;
border-radius: 5px;
background: var(--surface-2);
color: var(--slate);
font-size: 11px;
flex: none;
}
.block-title .hint { margin-left: auto; font-weight: 400; font-size: 11.5px; color: var(--ink-3); }
.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }
.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field > label {
font-size: 11.5px;
font-weight: 600;
letter-spacing: .02em;
color: var(--ink-2);
}
.input {
border: 1px solid var(--line);
border-radius: 6px;
background: var(--surface);
padding: 8px 10px;
font-size: 13.5px;
color: var(--ink);
min-height: 35px;
display: flex;
align-items: center;
gap: 8px;
}
.input.ghost { color: var(--ink-3); }
.input .lang {
margin-left: auto;
font-family: var(--mono);
font-size: 10px;
letter-spacing: .05em;
color: var(--slate);
background: var(--surface-2);
border-radius: 3px;
padding: 2px 5px;
flex: none;
}
.choice { display: flex; flex-direction: column; gap: 6px; }
.opt {
display: grid;
grid-template-columns: 16px minmax(0, 1fr);
gap: 9px;
align-items: start;
border: 1px solid var(--line-soft);
border-radius: 7px;
padding: 9px 11px;
background: var(--surface);
}
.opt .dot {
width: 15px; height: 15px;
border-radius: 50%;
border: 1.5px solid var(--line);
margin-top: 2px;
}
.opt.on { border-color: var(--slate); background: color-mix(in srgb, var(--slate) 6%, transparent); }
.opt.on .dot { border-color: var(--slate); border-width: 4.5px; }
.opt .t { font-size: 13px; font-weight: 550; }
.opt .s { font-size: 11.5px; color: var(--ink-3); line-height: 1.42; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
font-size: 11.5px;
border: 1px solid var(--line);
border-radius: 999px;
padding: 3px 10px;
color: var(--ink-2);
background: var(--surface);
}
.chip.media { border-color: var(--slate-soft); color: var(--slate); }
.qrow {
display: grid;
grid-template-columns: 22px minmax(0, 1fr) auto;
gap: 10px;
align-items: center;
border: 1px solid var(--line-soft);
border-radius: 7px;
padding: 9px 11px;
background: var(--surface);
}
.qrow .qn {
font-family: var(--mono);
font-size: 11px;
color: var(--ink-3);
font-variant-numeric: tabular-nums;
}
.qrow .qt { font-size: 13px; min-width: 0; }
.qrow .qm { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); }
.qrow.expand { border-color: var(--brass); background: color-mix(in srgb, var(--brass) 7%, transparent); }
.qbody {
grid-column: 1 / -1;
border-top: 1px dashed var(--line);
padding-top: 11px;
margin-top: 2px;
display: flex;
flex-direction: column;
gap: 11px;
}
.frame-foot {
display: flex;
align-items: center;
gap: 12px;
padding: 11px 18px;
border-top: 1px solid var(--line-soft);
background: var(--surface-2);
font-size: 12.5px;
color: var(--ink-3);
}
.saved { display: inline-flex; align-items: center; gap: 6px; color: var(--moss); font-weight: 550; }
.saved::before {
content: "";
width: 7px; height: 7px;
border-radius: 50%;
background: var(--moss);
}
.btn {
border-radius: 999px;
padding: 7px 16px;
font: inherit;
font-size: 13px;
font-weight: 550;
border: 1px solid var(--line);
background: var(--surface);
color: var(--ink-2);
cursor: pointer;
}
.btn.primary { background: var(--slate); border-color: var(--slate); color: #fff; }
@media (prefers-color-scheme: dark) { .btn.primary { color: #0E151C; } }
:root[data-theme="dark"] .btn.primary { color: #0E151C; }
:root[data-theme="light"] .btn.primary { color: #fff; }
.foot-actions { margin-left: auto; display: flex; gap: 9px; }
.caption {
font-family: var(--ui);
font-size: 12.5px;
color: var(--ink-3);
max-width: 76ch;
line-height: 1.5;
}
.caption b { color: var(--ink-2); font-weight: 600; }
/* ---------- option B sketch ---------- */
.sketch {
min-width: 780px;
display: grid;
grid-template-columns: 236px 300px minmax(0, 1fr);
gap: 1px;
background: var(--line);
border: 1px solid var(--line);
border-radius: 10px;
overflow: hidden;
font-family: var(--ui);
box-shadow: var(--shadow-md);
}
.sk-col { background: var(--surface); padding: 15px 15px 18px; display: flex; flex-direction: column; gap: 10px; }
.sk-col.muted { background: var(--sunken); }
.sk-h {
font-family: var(--mono);
font-size: 10.5px;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--ink-3);
padding-bottom: 8px;
border-bottom: 1px solid var(--line-soft);
}
.sk-item {
font-size: 13px;
color: var(--ink-2);
padding: 7px 9px;
border-radius: 5px;
border: 1px solid transparent;
}
.sk-item.on { background: var(--surface); border-color: var(--slate-soft); color: var(--ink); font-weight: 550; box-shadow: var(--shadow-sm); }
.sk-item.dim { color: var(--ink-3); }
.sk-ph {
border: 1px dashed var(--line);
border-radius: 6px;
padding: 10px 11px;
font-size: 12.5px;
color: var(--ink-3);
}
/* ---------- verdict table ---------- */
.tbl-wrap { overflow-x: auto; }
table {
width: 100%;
min-width: 640px;
border-collapse: collapse;
font-family: var(--ui);
font-size: 13.5px;
}
th, td { text-align: left; padding: 11px 14px; vertical-align: top; border-bottom: 1px solid var(--line-soft); }
thead th {
font-family: var(--mono);
font-size: 10.5px;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--ink-3);
border-bottom: 1px solid var(--line);
font-weight: 400;
}
tbody th { font-weight: 600; color: var(--ink); width: 30%; }
td { color: var(--ink-2); }
.yes { color: var(--moss); font-weight: 600; }
.no { color: var(--clay); font-weight: 600; }
/* ---------- verdict + resume ---------- */
.verdict {
border: 1px solid var(--slate-soft);
border-left: 4px solid var(--slate);
border-radius: 9px;
background: var(--surface);
padding: 22px 24px;
box-shadow: var(--shadow-sm);
max-width: 72ch;
}
.verdict h3 { margin: 0 0 10px; font-size: 20px; font-weight: 600; letter-spacing: -.012em; }
.resume {
border: 1px solid var(--line);
border-radius: 9px;
background: var(--surface);
padding: 20px 22px 22px;
font-family: var(--ui);
display: flex;
flex-direction: column;
gap: 12px;
}
.resume h3 {
margin: 0;
font-family: var(--mono);
font-size: 11.5px;
letter-spacing: .09em;
text-transform: uppercase;
color: var(--ink-3);
font-weight: 400;
}
.resume ol { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 8px; }
.resume li { font-size: 14px; color: var(--ink-2); line-height: 1.5; }
.resume li b { color: var(--ink); font-weight: 600; }
.foot {
border-top: 1px solid var(--line);
padding-top: 20px;
font-family: var(--ui);
font-size: 12.5px;
color: var(--ink-3);
display: flex;
flex-wrap: wrap;
gap: 6px 24px;
}
@media (max-width: 720px) {
.page { padding: 34px 16px 64px; gap: 46px; }
body { font-size: 16px; }
.depth-row.i2 { padding-left: 14px; }
.depth-row.i3 { padding-left: 28px; }
.depth-row.i4 { padding-left: 42px; }
.depth-row.i5 { padding-left: 56px; }
}
</style>
<div class="page">
<header class="masthead">
<span class="eyebrow">manager-app · SectionParcours · 9 août 2026</span>
<h1>Configurer un parcours sans empiler quatre fenêtres</h1>
<p class="standfirst">
La refonte du 6 août a réglé le <em>vocabulaire</em> : trois questions en français à la place de neuf
booléens. Elle n'a pas touché à la <em>forme</em> — et la forme, c'est une popup qui en ouvre une, qui
en ouvre une. Voici la mesure du problème et deux façons d'en sortir.
</p>
</header>
<!-- ============ 1. ÉTAT DES LIEUX ============ -->
<section class="sec">
<div class="sec-head">
<h2>Ce que traverse le client aujourd'hui</h2>
<p class="prose">
Pour poser une question sur la deuxième étape d'un parcours, et l'écrire en néerlandais,
il faut ouvrir cinq surfaces l'une par-dessus l'autre. Chacune existe pour de bonnes raisons ;
c'est leur empilement qui n'a été décidé par personne.
</p>
</div>
<div class="depth">
<div class="depth-row i1">
<span class="depth-n">1</span>
<div class="depth-bar d1">
<strong>Écran de configuration</strong>
<span>où se déroule le parcours · carte de base · liste des parcours</span>
<em>en place</em>
</div>
</div>
<div class="depth-row i2">
<span class="depth-n">2</span>
<div class="depth-bar d2">
<strong>Popup « Modifier le Parcours »</strong>
<span>8 contrôles + la liste des étapes</span>
<em>popup</em>
</div>
</div>
<div class="depth-row i3">
<span class="depth-n">3</span>
<div class="depth-bar d3">
<strong>Popup « Modifier l'Étape »</strong>
<span>10 contrôles + la liste des questions</span>
<em>popup sur popup</em>
</div>
</div>
<div class="depth-row i4">
<span class="depth-n">4</span>
<div class="depth-bar d4">
<strong>Popup « Modifier la Question »</strong>
<span>3 à 6 contrôles selon le type</span>
<em>popup sur popup sur popup</em>
</div>
</div>
<div class="depth-row i5">
<span class="depth-n">5</span>
<div class="depth-bar d5">
<strong>Popup de traduction</strong>
<span>jusqu'à 10 langues, un éditeur riche par langue</span>
<em>et une de plus</em>
</div>
</div>
</div>
<p class="depth-note">
Chaque niveau fait <code>screenWidth × 0,82</code> puis <code>0,75</code> puis <code>0,65</code> — les
fenêtres rétrécissent à mesure qu'on descend, ce qui est le seul repère visuel de profondeur.
</p>
<div class="findings">
<article class="finding">
<span class="tagline">Empilement</span>
<h4>Rien ne dit où l'on est</h4>
<p>
Quatre dialogues au même endroit de l'écran, mêmes coins arrondis, même bouton « Sauvegarder » en
bas à droite. Le seul indice de niveau est une largeur qui diminue de 7 %.
</p>
</article>
<article class="finding">
<span class="tagline">Sauvegarde</span>
<h4>Rien n'est écrit avant d'avoir tout refermé</h4>
<p>
Chaque popup travaille sur une copie JSON profonde et ne remonte qu'à la fermeture. Fermer la
fenêtre du parcours par la croix jette les trois questions saisies dessous, sans avertissement.
</p>
</article>
<article class="finding">
<span class="tagline">Contexte</span>
<h4>Le parcours disparaît quand on édite l'étape</h4>
<p>
Impossible de voir la liste des étapes pendant qu'on en configure une. Comparer l'étape 2 et
l'étape 3, c'est fermer, rouvrir, refermer, rouvrir.
</p>
</article>
</div>
</section>
<!-- ============ 2. OPTION A ============ -->
<section class="sec">
<div class="sec-head">
<h2>Option A — une seule fenêtre, un rail d'étapes</h2>
<p class="prose">
La popup reste : le client sait qu'il « entre » configurer un parcours et qu'il en ressort. Ce qui
disparaît, c'est l'empilement. Les étapes deviennent un rail à gauche, toujours visible ; le détail
s'affiche à droite ; la question s'ouvre dans le flux, sans nouvelle fenêtre.
<strong>C'est cliquable — essayez le rail.</strong>
</p>
</div>
<div class="demo">
<div class="demo-scroll">
<div class="frame">
<div class="frame-bar">
<div class="crumbs">
<b>Le fort souterrain</b>
<i></i>
<span id="crumb-tail">Le parcours</span>
</div>
<span class="frame-title">Fort de Saint-Héribert</span>
</div>
<div class="frame-body">
<aside class="rail">
<div class="rail-head">
<span class="k">Parcours</span>
<span class="v">Le fort souterrain</span>
</div>
<ul class="steplist" role="list">
<li>
<button class="step-btn is-root" type="button" data-panel="p-root" aria-current="true">
<span class="pin"></span>
<span class="step-lab">
<span class="t">Le parcours</span>
<span class="s">Titre, ambiance, progression</span>
</span>
</button>
</li>
<li>
<button class="step-btn" type="button" data-panel="p-s1">
<span class="pin">1</span>
<span class="step-lab">
<span class="t">La poterne d'entrée</span>
<span class="s">2 médias</span>
</span>
</button>
</li>
<li>
<button class="step-btn" type="button" data-panel="p-s2">
<span class="pin">2</span>
<span class="step-lab">
<span class="t">Le couloir de contrescarpe</span>
<span class="s">1 média · 1 question</span>
</span>
</button>
</li>
<li>
<button class="step-btn" type="button" data-panel="p-s3">
<span class="pin">3</span>
<span class="step-lab">
<span class="t">La chambre de tir</span>
<span class="s">Aucun contenu</span>
</span>
</button>
</li>
</ul>
<button class="rail-add" type="button"> Ajouter une étape</button>
</aside>
<!-- panel : parcours -->
<section class="panel is-active" id="p-root">
<div class="panel-head">
<div>
<h4>Le parcours</h4>
<p>Ce que le visiteur voit avant de commencer.</p>
</div>
</div>
<div class="grid2">
<div class="field">
<label for="a-titre">Titre</label>
<div class="input" id="a-titre">Le fort souterrain <span class="lang">FR +3</span></div>
</div>
<div class="field">
<label for="a-desc">Description</label>
<div class="input" id="a-desc">Une heure sous la colline… <span class="lang">FR +3</span></div>
</div>
</div>
<div class="block">
<div class="block-title"><span class="glyph"></span> Quelle ambiance ?</div>
<div class="choice">
<div class="opt on"><span class="dot"></span><span><span class="t">Visite</span><br><span class="s">Parcours de découverte : le visiteur avance à son rythme.</span></span></div>
<div class="opt"><span class="dot"></span><span><span class="t">Jeu</span><br><span class="s">Escape game ou chasse au trésor : messages de début et de fin.</span></span></div>
</div>
</div>
<div class="block">
<div class="block-title"><span class="glyph"></span> Comment le visiteur progresse-t-il ?<span class="hint">durée estimée : 55 min</span></div>
<div class="choice">
<div class="opt"><span class="dot"></span><span><span class="t">Libre</span><br><span class="s">Il choisit ses étapes dans l'ordre qu'il veut.</span></span></div>
<div class="opt on"><span class="dot"></span><span><span class="t">Dans l'ordre</span><br><span class="s">Il suit la séquence ; il peut revenir sur une étape déjà vue.</span></span></div>
<div class="opt"><span class="dot"></span><span><span class="t">Étape par étape</span><br><span class="s">Chaque étape se débloque en réussissant le défi de la précédente.</span></span></div>
</div>
</div>
</section>
<!-- panel : étape 1 -->
<section class="panel" id="p-s1">
<div class="panel-head">
<div>
<h4>Étape 1 — La poterne d'entrée</h4>
<p>Le rail reste à gauche : passer à l'étape 2 est un clic, plus un aller-retour.</p>
</div>
</div>
<div class="grid2">
<div class="field">
<label for="b-titre">Titre</label>
<div class="input" id="b-titre">La poterne d'entrée <span class="lang">FR +3</span></div>
</div>
<div class="field">
<label for="b-desc">Description</label>
<div class="input" id="b-desc">Le seul accès d'origine… <span class="lang">FR +3</span></div>
</div>
</div>
<div class="block">
<div class="block-title"><span class="glyph"></span> Emplacement<span class="hint">parcours sur le terrain</span></div>
<div class="grid2">
<div class="field">
<label for="b-geo">Position</label>
<div class="input" id="b-geo">50.4283, 4.8091</div>
</div>
<div class="field">
<label for="b-ray">Déclenchement dans un rayon de</label>
<div class="input" id="b-ray">15 m</div>
</div>
</div>
</div>
<div class="block">
<div class="block-title"><span class="glyph"></span> Contenu riche</div>
<div class="field">
<label>Médias</label>
<div class="chips">
<span class="chip media">Image · poterne-1900.jpg</span>
<span class="chip media">Vidéo · ouverture-grille.mp4</span>
<span class="chip"> ajouter</span>
</div>
</div>
<div class="field">
<label for="b-audio">Audio guide</label>
<div class="input ghost" id="b-audio">Aucun audio <span class="lang">FR +3</span></div>
</div>
</div>
<div class="block">
<div class="block-title"><span class="glyph">?</span> Questions<span class="hint">aucune — facultatif</span></div>
<button class="btn" type="button"> Ajouter une question</button>
</div>
</section>
<!-- panel : étape 2 -->
<section class="panel" id="p-s2">
<div class="panel-head">
<div>
<h4>Étape 2 — Le couloir de contrescarpe</h4>
<p>La question s'ouvre ici, pas dans une quatrième fenêtre.</p>
</div>
</div>
<div class="grid2">
<div class="field">
<label for="c-titre">Titre</label>
<div class="input" id="c-titre">Le couloir de contrescarpe <span class="lang">FR +3</span></div>
</div>
<div class="field">
<label for="c-desc">Description</label>
<div class="input" id="c-desc">Quatre-vingts mètres de galerie… <span class="lang">FR +3</span></div>
</div>
</div>
<div class="block">
<div class="block-title"><span class="glyph">?</span> Questions<span class="hint">1 question · sans chrono</span></div>
<div class="qrow expand">
<span class="qn">01</span>
<span class="qt">Combien de meurtrières comptez-vous dans le couloir ?</span>
<span class="qm">réponse attendue</span>
<div class="qbody">
<div class="grid2">
<div class="field">
<label for="d-type">Type de validation</label>
<div class="input" id="d-type">Réponse attendue</div>
</div>
<div class="field">
<label for="d-rep">Réponse</label>
<div class="input" id="d-rep">14 <span class="lang">FR +3</span></div>
</div>
</div>
<p class="caption">
⌨ La réponse ne contient que des chiffres : le visiteur verra un pavé numérique façon
cadenas. Rien à configurer.
</p>
</div>
</div>
<button class="btn" type="button"> Ajouter une question</button>
</div>
</section>
<!-- panel : étape 3 -->
<section class="panel" id="p-s3">
<div class="panel-head">
<div>
<h4>Étape 3 — La chambre de tir</h4>
<p>Une étape vierge : les trois blocs attendent, rien n'est obligatoire.</p>
</div>
</div>
<div class="grid2">
<div class="field">
<label for="e-titre">Titre</label>
<div class="input" id="e-titre">La chambre de tir <span class="lang">FR +3</span></div>
</div>
<div class="field">
<label for="e-desc">Description</label>
<div class="input ghost" id="e-desc">À rédiger <span class="lang">FR</span></div>
</div>
</div>
<div class="block">
<div class="block-title"><span class="glyph"></span> Emplacement</div>
<div class="input ghost">Placer sur la carte</div>
</div>
<div class="block">
<div class="block-title"><span class="glyph"></span> Contenu riche</div>
<div class="chips"><span class="chip"> ajouter un média</span></div>
</div>
<div class="block">
<div class="block-title"><span class="glyph">?</span> Questions</div>
<button class="btn" type="button"> Ajouter une question</button>
</div>
</section>
</div>
<div class="frame-foot">
<span class="saved">Enregistré</span>
<span>il y a 3 s</span>
<div class="foot-actions">
<button class="btn" type="button">Fermer</button>
<button class="btn primary" type="button">Voir dans l'app</button>
</div>
</div>
</div>
</div>
<p class="caption">
Trois changements portent tout le reste. <b>Le rail</b> — la liste des étapes ne disparaît jamais.
<b>Le fil</b> en haut à gauche — on sait où on est sans compter les fenêtres. <b>« Enregistré »</b> en
bas à gauche remplace « Sauvegarder » : chaque champ part au serveur en sortant du champ, il n'y a
plus rien à perdre en fermant.
</p>
</div>
</section>
<!-- ============ 3. OPTION B ============ -->
<section class="sec">
<div class="sec-head">
<h2>Option B — l'atelier plein écran</h2>
<p class="prose">
Le parcours quitte la popup et devient un écran à part entière, sur le modèle des éditeurs de
contenu. Trois colonnes : les parcours de la section, les étapes du parcours choisi, le détail de
l'étape choisie. Rien n'est jamais recouvert.
</p>
</div>
<div class="demo">
<div class="demo-scroll">
<div class="sketch" role="img" aria-label="Maquette schématique : trois colonnes — liste des parcours, liste des étapes, détail de l'étape sélectionnée.">
<div class="sk-col muted">
<span class="sk-h">Parcours de la section</span>
<div class="sk-item on">Le fort souterrain</div>
<div class="sk-item">Les jardins de la contrescarpe</div>
<div class="sk-item dim"> Nouveau parcours</div>
</div>
<div class="sk-col muted">
<span class="sk-h">Étapes · 3</span>
<div class="sk-item">1 · La poterne d'entrée</div>
<div class="sk-item on">2 · Le couloir de contrescarpe</div>
<div class="sk-item">3 · La chambre de tir</div>
<div class="sk-item dim"> Ajouter une étape</div>
</div>
<div class="sk-col">
<span class="sk-h">Étape 2 — Le couloir de contrescarpe</span>
<div class="sk-ph">Titre · Description · Emplacement</div>
<div class="sk-ph">Contenu riche — 1 média</div>
<div class="sk-ph">Questions — 1, dépliée sur place</div>
<div class="sk-ph">Aperçu côté visiteur, en direct</div>
</div>
</div>
</div>
<p class="caption">
Le gain réel de B n'est pas la place : c'est la <b>troisième colonne libre</b>, où loger un aperçu
visiteur en direct. Le coût réel n'est pas le code de l'écran — c'est que le parcours devient le seul
type de section à ne pas se configurer comme les douze autres.
</p>
</div>
</section>
<!-- ============ 4. VERDICT ============ -->
<section class="sec">
<div class="sec-head">
<h2>Ce qui les sépare</h2>
</div>
<div class="tbl-wrap">
<table>
<thead>
<tr>
<th scope="col">Critère</th>
<th scope="col">A — fenêtre unique + rail</th>
<th scope="col">B — atelier plein écran</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Profondeur maximale</th>
<td><span class="yes">2</span> — la fenêtre, puis la traduction</td>
<td><span class="yes">1</span> — plus la traduction</td>
</tr>
<tr>
<th scope="row">Cohérence avec les 12 autres sections</th>
<td><span class="yes">Intacte</span> — même geste : j'ouvre, je règle, je ferme</td>
<td><span class="no">Rompue</span> — le parcours devient l'exception</td>
</tr>
<tr>
<th scope="row">Ce qu'il faut réécrire</th>
<td>Les trois <code>show…</code> fusionnés en un widget à panneaux. Les blocs de champs se déplacent sans changer</td>
<td>Idem, plus une route, un écran, et sa place dans le menu latéral</td>
</tr>
<tr>
<th scope="row">Aperçu visiteur en direct</th>
<td>À l'étroit — il faudrait un troisième volet dans une fenêtre déjà large</td>
<td><span class="yes">Naturel</span> — la colonne est libre</td>
</tr>
<tr>
<th scope="row">Sauvegarde au fil de l'eau</th>
<td colspan="2">Nécessaire dans les deux cas, et indépendante du choix — c'est le vrai chantier</td>
</tr>
</tbody>
</table>
</div>
<div class="verdict">
<h3>Je recommande A</h3>
<p>
Non pas parce que la popup serait meilleure en soi, mais parce que le client a déjà appris le geste
sur douze autres types de section. Faire du parcours le seul écran plein cadre lui demande d'apprendre
une deuxième grammaire pour le type le plus compliqué du produit — le pire endroit où placer la
nouveauté.
</p>
<p>
Et surtout : ce qui fait mal aujourd'hui n'est pas <em>la popup</em>, c'est <em>l'empilement</em> et
<em>la sauvegarde en cascade</em>. A traite les deux. B traite les deux aussi, pour plus cher, en
ajoutant un risque d'incohérence. Si l'aperçu en direct devient un jour prioritaire, B redevient le
bon choix — et le travail fait pour A (un widget à panneaux, indépendant du <code>Dialog</code> qui
l'entoure) se déplace tel quel dans un écran plein.
</p>
</div>
</section>
<!-- ============ 5. CE QUI NE BOUGE PAS ============ -->
<section class="sec">
<div class="sec-head">
<h3>Ce qui ne change pas, quel que soit le choix</h3>
</div>
<div class="findings">
<article class="finding">
<h4>La popup de traduction reste une popup</h4>
<p>
Écrire dix langues est une tâche à part, avec son éditeur riche et son bouton IA. Un niveau de
profondeur pour ça est justifié. Les langues restent listées verticalement — pas d'onglets.
</p>
</article>
<article class="finding">
<h4>Les composants de champ restent</h4>
<p>
Ce qui casse les alignements, ce n'est pas leur conception : c'est
<code>size.width × 0.2</code> dans <code>NumberInputContainer</code> et des tailles de label qui
vont de 16 à 25 px selon le composant. Deux corrections, pas une bibliothèque à refaire.
</p>
</article>
<article class="finding">
<h4>Les trois questions restent les trois questions</h4>
<p>
Où se déroule le parcours, quelle ambiance, comment on progresse. Le vocabulaire du 6 août est
bon ; c'est son contenant qu'on change.
</p>
</article>
</div>
</section>
<!-- ============ 6. REPRISE ============ -->
<section class="sec">
<div class="resume">
<h3>Pour reprendre plus tard</h3>
<ol>
<li><b>Trancher A ou B.</b> Rien ne se code avant. Tout le reste en découle.</li>
<li>
<b>Sauvegarde au fil de l'eau d'abord</b>, avant la refonte visuelle : c'est le seul point qui fait
perdre du travail au client aujourd'hui, et il se traite indépendamment de la forme retenue.
Aujourd'hui les trois popups travaillent sur une copie <code>jsonEncode/jsonDecode</code> et ne
remontent qu'à la fermeture.
</li>
<li>
<b>Extraire les blocs de champs</b> des trois <code>show…</code> en widgets autonomes
(<code>ParcoursFields</code>, <code>EtapeFields</code>, <code>QuestionFields</code>). Cette étape
sert A et B à l'identique — c'est le travail à faire en premier une fois le choix posé.
</li>
<li>
<b>Puis le contenant</b> : rail + panneaux dans un <code>Dialog</code> pour A, un écran routé pour B.
</li>
<li>
<b>Rejouer</b> le plan de test <code>§19.13 cas 0</code> — les 7 lignes ajoutées le 9 août couvrent
déjà cet écran.
</li>
</ol>
</div>
</section>
<footer class="foot">
<span>Fichiers concernés : <code>manager-app/lib/Screens/Configurations/Section/SubSection/Parcours/</code></span>
<span>Suivi : <code>DOCS/todo-features.md</code> · <code>DOCS/test-plan.md §19.13</code></span>
</footer>
</div>
<script>
(function () {
var buttons = Array.prototype.slice.call(document.querySelectorAll('.step-btn'));
var panels = Array.prototype.slice.call(document.querySelectorAll('.panel'));
var tail = document.getElementById('crumb-tail');
buttons.forEach(function (btn) {
btn.addEventListener('click', function () {
var id = btn.getAttribute('data-panel');
buttons.forEach(function (b) {
b.setAttribute('aria-current', String(b === btn));
});
panels.forEach(function (p) {
p.classList.toggle('is-active', p.id === id);
});
var label = btn.querySelector('.step-lab .t');
var pin = btn.querySelector('.pin').textContent.trim();
if (tail && label) {
tail.textContent = pin === '◆' ? label.textContent : 'Étape ' + pin + ' · ' + label.textContent;
}
});
});
})();
</script>
</body></html>