Navigation par fil d’Ariane de la salle de services externes
Réalisez une navigation par fil d’Ariane dans un contexte de hall de services cliniques : contenu réel, contrôles interactifs, retours d’état clairs et mise en page adaptative à toutes les tailles.
Après activation de JavaScript, ce cas peut être modifié, exécuté et enregistré. Code source fixe ci-dessous :
<!doctype html>
<html lang="fr" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Navigation par fil d’Ariane de la salle de services externes</title>
<style>
:root { --ink:#252525; --paper:#f7f2e8; --accent:#247ba0; --secondary:#f4b942; --line:color-mix(in srgb, var(--ink) 18%, transparent); --shadow:0 24px 60px color-mix(in srgb, var(--ink) 16%, transparent); color-scheme:light; }
* { box-sizing:border-box; }
html { min-width:320px; background:var(--paper); }
body { min-height:100vh; margin:0; overflow-x:hidden; color:var(--ink); font-family:"Hiragino Maru Gothic ProN","PingFang SC",sans-serif; background:radial-gradient(circle at 15% 10%,color-mix(in srgb,var(--secondary) 35%,transparent) 0 9%,transparent 10%),radial-gradient(circle at 90% 75%,color-mix(in srgb,var(--accent) 18%,transparent) 0 12%,transparent 13%),var(--paper); }
button,input,select,textarea { color:inherit; font:inherit; }
button,[role="button"],input,select,textarea { accent-color:var(--accent); }
button { cursor:pointer; }
button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible { outline:3px solid var(--accent); outline-offset:3px; }
[hidden] { display:none !important; }
@media (max-width:700px) { .mast h1 { line-height:1.08 !important; letter-spacing:-.035em !important; overflow-wrap:anywhere; } }
@media (prefers-reduced-motion:reduce) { *,*::before,*::after { scroll-behavior:auto !important; animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; } }
.page{width:min(1140px,calc(100% - 28px));margin:auto;padding:54px 0}.mast{display:flex;justify-content:space-between;align-items:center;gap:24px;margin:0 12px 28px}.mast h1{font-family:"Hiragino Maru Gothic ProN","PingFang SC",sans-serif;font-weight:900;font-size:clamp(38px,8vw,82px);letter-spacing:-.035em;margin:0;line-height:.98}.eyebrow{display:inline-flex;padding:7px 12px;border-radius:999px;color:var(--paper);background:var(--accent);font-weight:900}.intro{max-width:620px;line-height:1.65}.scenario{padding:12px 18px;border-radius:999px;background:var(--secondary);box-shadow:0 7px 0 color-mix(in srgb,var(--ink) 18%,transparent);font-weight:900}.demo{border-radius:46px 18px 46px 18px;box-shadow:0 18px 0 color-mix(in srgb,var(--secondary) 45%,transparent);position:relative;min-height:390px;overflow:hidden;padding:clamp(22px,5vw,54px);background:color-mix(in srgb,var(--paper) 90%,#fff)}@media(max-width:700px){.mast{display:grid}.page{width:calc(100% - 16px);padding:18px 0}.demo{padding:17px}}
.stack{display:flex;flex-direction:column;gap:18px}.panel{padding:28px;border-left:7px solid var(--accent);background:color-mix(in srgb,var(--secondary) 12%,var(--paper))}.action{min-height:46px;padding:11px 18px;border:0;border-bottom:3px solid var(--ink);background:transparent;font-weight:900}.action.primary,.action.is-active{color:var(--paper);background:var(--ink)}.row{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px}.metric{font:900 clamp(32px,7vw,64px)/1 ui-monospace,monospace}.status{min-height:22px;padding-top:12px;border-top:1px dashed var(--line)}.muted{color:color-mix(in srgb,var(--ink) 62%,transparent)}.chip{display:inline-block;padding:5px 8px;background:var(--secondary)}.meter{height:12px;border:1px solid var(--ink)}.meter>i{display:block;height:100%;background:var(--ink)}
.composition-split{display:grid;grid-template-columns:150px minmax(0,1fr);gap:18px;align-items:start}.split-note{position:sticky;top:20px;display:grid;gap:14px;padding:18px 12px;border-block:3px double var(--accent);font-size:13px;line-height:1.65}.split-note b{font:900 12px/1 ui-monospace,monospace;letter-spacing:.12em}.split-note span{writing-mode:vertical-rl;min-height:120px;color:color-mix(in srgb,var(--ink) 60%,transparent)}.composition-split .demo{min-width:0}@media(max-width:900px){.composition-split{grid-template-columns:1fr}.split-note{position:static;grid-template-columns:auto 1fr}.split-note span{writing-mode:horizontal-tb;min-height:0}}
.breadcrumb-studio{display:grid;gap:20px;max-width:920px;margin:auto}.breadcrumb-studio header{display:flex;justify-content:space-between;gap:18px;align-items:end}.breadcrumb-studio h2{margin:.35em 0}.crumb-trail{display:flex;flex-wrap:wrap;gap:9px;align-items:center;padding:18px;margin:0;border:1px solid var(--line);border-radius:18px;list-style:none;background:var(--paper)}.crumb-trail li{display:flex;gap:9px;align-items:center}.crumb-trail li:not(:last-child)::after{content:"/";color:var(--accent)}.crumb-trail a{color:inherit;text-underline-offset:4px}.crumb-trail [aria-current="page"]{font-weight:900}.crumb-builder{display:grid;grid-template-columns:minmax(200px,.8fr) auto;gap:14px;align-items:end}.crumb-builder label{display:grid;gap:8px;font-weight:800}.crumb-builder select{width:100%;padding:11px;border:1px solid var(--line);border-radius:10px;background:var(--paper)}.crumb-preview{display:grid;gap:8px;padding:18px;border-left:5px solid var(--accent);background:color-mix(in srgb,var(--secondary) 12%,transparent)}.breadcrumb-studio code{padding:3px 6px;background:color-mix(in srgb,var(--secondary) 20%,transparent)}@media(max-width:680px){.breadcrumb-studio header,.crumb-builder{align-items:stretch;flex-direction:column;display:flex}}.workflow-guide{display:grid;grid-template-columns:190px minmax(0,1fr);grid-template-areas:"rail core" "rail evidence";gap:14px 18px}.guide-rail{grid-area:rail;display:grid;align-content:start;gap:15px;padding:18px;border-right:1px solid var(--line)}.guide-rail ol{display:grid;gap:8px;padding:0;margin:0;list-style:none}.guide-rail li{display:grid;grid-template-columns:30px 1fr;gap:8px;align-items:center;padding:9px;opacity:.5}.guide-rail li[aria-current="step"]{opacity:1;color:var(--paper);background:var(--ink)}.guide-rail li.is-complete{opacity:1;color:var(--accent)}.guide-actions{display:grid;grid-template-columns:1fr 1fr;gap:7px}.guide-actions .action{padding-inline:8px}#workflowGuideProgress{height:6px;background:var(--line)}#workflowGuideProgress i{display:block;width:0;height:100%;background:var(--accent)}.guide-core{grid-area:core;min-width:0;padding:16px;border:1px solid var(--line)}.guide-core>p{margin:0 0 14px;padding:10px;border-left:4px solid var(--accent);background:color-mix(in srgb,var(--secondary) 12%,transparent)}.guide-core[data-guide-step="1"]{border-radius:28px}.guide-core[data-guide-step="2"]{box-shadow:inset 0 0 0 4px color-mix(in srgb,var(--accent) 35%,transparent)}.guide-evidence{grid-area:evidence;display:grid;grid-template-columns:1fr 1fr auto;gap:12px;align-items:start}.guide-evidence details,.guide-evidence form{padding:12px;border:1px solid var(--line)}.guide-evidence label{display:grid;gap:7px}.guide-evidence textarea{width:100%;padding:9px;border:1px solid var(--line);background:var(--paper)}@media(max-width:900px){.workflow-guide{grid-template-columns:1fr;grid-template-areas:"core" "rail" "evidence"}.guide-rail{border-right:0;border-bottom:1px solid var(--line)}.guide-rail ol{grid-template-columns:repeat(3,1fr)}.guide-evidence{grid-template-columns:1fr}}
</style>
</head>
<body data-aesthetic="playful" data-composition="split-note">
<main class="page">
<header class="mast"><div><span class="eyebrow">playful / navigation en fil d’Ariane / INTERMEDIATE</span><h1>Navigation par fil d’Ariane de la salle de services externes</h1><p class="intro">Réalisez une navigation par fil d’Ariane dans un contexte de hall de services cliniques : contenu réel, contrôles interactifs, retours d’état clairs et mise en page adaptative à toutes les tailles.</p></div><span class="scenario">Salle de consultation externe</span></header>
<div class="composition-split"><aside class="split-note"><b>CASE 02</b><span>Maîtriser la structure sémantique de la navigation en fil d’Ariane, l’organisation responsive, l’utilisation du clavier et la synchronisation des états.</span></aside><section class="demo" aria-label="Zone interactive de navigation par fil d’Ariane du hall de service ambulatoire"><div class="workflow-guide"><nav class="guide-rail" aria-label="Guide du hall de services ambulatoires"><span class="eyebrow">Hall de services ambulatoires GUIDE</span><ol><li data-workflow-guide-step="0" aria-current="step"><b>1</b><span>Navigation d’entrée du hall de services ambulatoires</span></li><li data-workflow-guide-step="1"><b>2</b><span>Navigation par fil d’Ariane du hall de services ambulatoires</span></li><li data-workflow-guide-step="2"><b>3</b><span>Navigation terminée pour le hall des services ambulatoires</span></li></ol><div class="guide-actions"><button id="workflowGuideBack" class="action" type="button" disabled>Étape précédente</button><button id="workflowGuideNext" class="action primary" type="button">Terminer cette étape</button></div><div id="workflowGuideProgress" role="progressbar" aria-label="avancement du hall des services de consultation externe" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><i></i></div></nav><section id="workflowCore" class="workflow-core guide-core" data-guide-step="0" aria-describedby="workflowGuideInstruction"><p id="workflowGuideInstruction">Veuillez effectuer, dans l’exemple principal, les opérations liées à « Navigation d’entrée de la salle de service de clinique ».</p><!-- 11DZ_CORE_START:navigation-menus-breadcrumb-builder --><div class="breadcrumb-studio panel"><header><div><span class="eyebrow">BREADCRUMB BUILDER</span><h2>Atelier de parcours pour le hall des services de consultation externe</h2><p class="muted">Lors de l’ajout d’un niveau, synchronisez la mise à jour du chemin, de l’emplacement actuel et du résumé de niveau.</p></div><output id="crumbDepthStatus">3 chemin de niveau</output></header><nav aria-label="Fil d’Ariane"><ol id="crumbTrail" class="crumb-trail"></ol></nav><div class="crumb-builder"><label>Nom du niveau suivant <select id="crumbChoice"><option>Progression du hall des services de consultation externe</option><option>Rappel du hall des services de consultations externes</option><option>Favoris du hall de services ambulatoires</option><option>Aperçu du hall de services de la consultation</option><option>plan du hall des services de clinique</option><option>Inspiration pour le hall des services de consultation</option></select></label><div class="row"><button id="addCrumb" class="action primary" type="button" data-core-bridge="navigation-menus-breadcrumb-builder">Approfondir d’un niveau</button><button id="removeCrumb" class="action" type="button">Retour au niveau supérieur</button></div></div><aside id="crumbPreview" class="crumb-preview"><strong>Emplacement actuel</strong><p id="crumbPreviewText">En attente de sélection du chemin</p></aside></div><!-- 11DZ_CORE_END --></section><aside class="guide-evidence"><details id="workflowGuideDetails"><summary>Voir les exigences d’acceptation</summary><ul><li>La navigation d’entrée du hall de services ambulatoires nécessite un changement d’état visible une seule fois</li><li>La navigation du hall des services ambulatoires nécessite un changement d’état visible en une seule étape</li><li>Le hall de services ambulatoires nécessite un changement d’état visible pour achever la navigation</li></ul></details><form id="workflowGuideEvidenceForm"><label>Preuve de cette étape<textarea id="workflowGuideEvidence" rows="3" placeholder="Enregistrer l’état observé"></textarea></label><input class="action" type="submit" value="Enregistrer la preuve"></form><output id="workflowGuideSummary">0 / 3 étapes terminées</output></aside></div><p id="status" class="status" role="status" aria-live="polite"></p></section></div>
</main>
<script>
'use strict';
const statusOutput = document.querySelector('#status');
const announce = message => { statusOutput.textContent = message; };
/* 11DZ_CORE_SCRIPT_START:navigation-menus-breadcrumb-builder */
const crumbChoices=["Progression du hall des services de consultation externe","Rappel du hall des services de consultations externes","Favoris du hall de services ambulatoires","Aperçu du hall de services de la consultation","plan du hall des services de clinique","Inspiration pour le hall des services de consultation"];const crumbTrail=document.querySelector('#crumbTrail');const crumbChoice=document.querySelector('#crumbChoice');const crumbState=crumbChoices.slice(0,3);function renderCrumbs(){crumbTrail.replaceChildren();crumbState.forEach((label,index)=>{const item=document.createElement('li');if(index===crumbState.length-1){const current=document.createElement('span');current.textContent=label;current.setAttribute('aria-current','page');item.append(current);}else{const link=document.createElement('a');link.href='#crumb-'+index;link.textContent=label;link.addEventListener('click',event=>{event.preventDefault();crumbState.splice(index+1);renderCrumbs();});item.append(link);}crumbTrail.append(item);});document.querySelector('#crumbDepthStatus').textContent=crumbState.length+' chemin de niveau';document.querySelector('#crumbPreviewText').textContent=crumbState.join(' / ');announce('Nombre total de chemins actuels '+crumbState.length+' niveau');}document.querySelector('#addCrumb').addEventListener('click',()=>{const next=crumbChoice.value;if(crumbState.at(-1)===next)return announce('Déjà à '+next);crumbState.push(next);renderCrumbs();});document.querySelector('#removeCrumb').addEventListener('click',()=>{if(crumbState.length===1)return;crumbState.pop();renderCrumbs();});renderCrumbs();
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"navigation-menus-breadcrumb-builder","selector":"[data-core-bridge=\"navigation-menus-breadcrumb-builder\"]","mode":"click","key":"Enter"};const workflowBridgeCore=document.querySelector('#workflowCore');const workflowBridgeControl=workflowBridgeCore.querySelector(workflowBridgeSpec.selector);if(!workflowBridgeControl)throw new Error('Missing core bridge: '+workflowBridgeSpec.name);const workflowBridgeControlledId=workflowBridgeControl.getAttribute('aria-controls');const workflowBridgeControlled=workflowBridgeControlledId?document.getElementById(workflowBridgeControlledId):null;workflowBridgeCore.dataset.workflowBridge=workflowBridgeSpec.name;workflowBridgeCore.dataset.workflowVersion='0';function workflowBridgeSerialize(){const visualNode=workflowBridgeCore.firstElementChild||workflowBridgeCore;const visual=getComputedStyle(visualNode);const outputs=[...workflowBridgeCore.querySelectorAll('output,[role="status"],[aria-live],meter,progress')].map(node=>node.textContent.trim()+'|'+node.getAttribute('aria-valuenow')+'|'+node.getAttribute('value'));const canvas=[...workflowBridgeCore.querySelectorAll('canvas')].map(node=>{try{return node.toDataURL().slice(-160);}catch{return 'canvas-unavailable';}});return JSON.stringify({html:workflowBridgeCore.innerHTML,status:statusOutput.textContent,outputs,canvas,visual:[visual.display,visual.visibility,visual.opacity,visual.transform,visual.filter,visual.backgroundColor,visual.width,visual.height],scroll:workflowBridgeSpec.mode==='scroll'?workflowBridgeControl.scrollTop:null});}let workflowBridgeLastEffect=workflowBridgeSerialize();function workflowBridgeSummary(){const label=(workflowBridgeControl.getAttribute('aria-label')||workflowBridgeControl.textContent||workflowBridgeControl.value||workflowBridgeSpec.name).trim().replace(/\s+/g,' ').slice(0,72);return label+' · Version de base '+workflowBridgeCore.dataset.workflowVersion;}function workflowBridgeCommit(){const effect=workflowBridgeSerialize();if(effect===workflowBridgeLastEffect)return {changed:false,summary:workflowBridgeSummary()};workflowBridgeLastEffect=effect;workflowBridgeCore.dataset.workflowVersion=String(Number(workflowBridgeCore.dataset.workflowVersion||0)+1);return {changed:true,summary:workflowBridgeSummary()};}function workflowBridgeScheduleCommit(){queueMicrotask(workflowBridgeCommit);setTimeout(workflowBridgeCommit,0);}workflowBridgeControl.addEventListener("click",workflowBridgeScheduleCommit);const workflowBridgeStateTargets=new Set(workflowBridgeCore.querySelectorAll('dialog'));if(workflowBridgeControlled&&workflowBridgeCore.contains(workflowBridgeControlled))workflowBridgeStateTargets.add(workflowBridgeControlled);workflowBridgeStateTargets.forEach(target=>['close','cancel','toggle'].forEach(eventName=>target.addEventListener(eventName,workflowBridgeScheduleCommit)));function workflowBridgeActivate(){workflowBridgeControl.focus();workflowBridgeControl.click();const result=workflowBridgeCommit();setTimeout(workflowBridgeCommit,0);return result;}function workflowBridgeReset(){workflowBridgeCore.dataset.workflowVersion='0';workflowBridgeLastEffect=workflowBridgeSerialize();}
const workflowGuideCore=document.querySelector('#workflowCore');const workflowGuideStages=["Navigation d’entrée du hall de services ambulatoires","Navigation par fil d’Ariane du hall de services ambulatoires","Navigation terminée pour le hall des services ambulatoires"];const workflowGuideState={step:0,completed:new Set(),evidence:new Map(),consumedVersion:0};function workflowGuideDrive(){const step=workflowGuideState.step;workflowGuideCore.dataset.guideStep=String(step);document.querySelector('#workflowGuideInstruction').textContent='Veuillez terminer «'+workflowGuideStages[step]+'Opérations associées à « ».';document.querySelectorAll('[data-workflow-guide-step]').forEach((item,index)=>{item.classList.toggle('is-complete',workflowGuideState.completed.has(index));if(index===step)item.setAttribute('aria-current','step');else item.removeAttribute('aria-current');});document.querySelector('#workflowGuideBack').disabled=step===0;document.querySelector('#workflowGuideNext').textContent=step===workflowGuideStages.length-1?'Accéder au chemin':'Terminer cette étape';const percent=Math.round(workflowGuideState.completed.size/workflowGuideStages.length*100);const progress=document.querySelector('#workflowGuideProgress');progress.setAttribute('aria-valuenow',String(percent));progress.querySelector('i').style.width=percent+'%';document.querySelector('#workflowGuideSummary').textContent=workflowGuideState.completed.size+' / '+workflowGuideStages.length+' Étapes complétées · '+workflowBridgeSummary();announce('Étape actuelle du hall de service ambulatoire :'+workflowGuideStages[step]);}function workflowGuideAdvance(direction){if(direction>0){const bridge=workflowBridgeActivate();const version=Number(workflowGuideCore.dataset.workflowVersion||0);if(version<=workflowGuideState.consumedVersion){announce('Veuillez d’abord effectuer la modification d’état visible du cas principal');return;}workflowGuideState.consumedVersion=version;workflowGuideState.completed.add(workflowGuideState.step);announce('Variation du cas principal enregistrée · '+bridge.summary);}workflowGuideState.step=Math.max(0,Math.min(workflowGuideStages.length-1,workflowGuideState.step+direction));workflowGuideDrive();}document.querySelector('#workflowGuideBack').addEventListener('click',()=>workflowGuideAdvance(-1));document.querySelector('#workflowGuideNext').addEventListener('click',()=>workflowGuideAdvance(1));document.querySelector('#workflowGuideEvidenceForm').addEventListener('submit',event=>{event.preventDefault();const version=Number(workflowGuideCore.dataset.workflowVersion||0);if(version<=workflowGuideState.consumedVersion){announce('La preuve n’a pas été enregistrée : le cas principal n’a encore subi aucun changement nouveau');return;}const text=document.querySelector('#workflowGuideEvidence').value.trim();workflowGuideState.evidence.set(workflowGuideState.step,text||'Vérification de l’état visible terminée');workflowGuideState.completed.add(workflowGuideState.step);workflowGuideState.consumedVersion=version;workflowGuideDrive();announce('Les preuves de cette étape ont été enregistrées · '+workflowBridgeSummary());});document.querySelector('#workflowGuideDetails').addEventListener('toggle',event=>announce(event.currentTarget.open?'Exigences d’acceptation développées':'Exigences d’acceptation repliées'));workflowGuideDrive();
workflowBridgeReset();
</script>
</body>
</html>