Recueil de poèmes des montagnes et des plaines, texte en défilement rythmé
Réalisez une composition de texte défilant rythmée pour le scénario du recueil de poésie des montagnes : comprend du contenu réel, des contrôles interactifs, un retour d’état clair et une mise en page adaptée à 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>Recueil de poèmes des montagnes et des plaines, texte en défilement rythmé</title>
<style>
:root { --ink:#18314f; --paper:#f7f8f2; --accent:#ff6b5e; --secondary:#71c9b5; --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}}
.panel{padding:16px;border:3px double var(--accent);background:var(--paper)}.stack{display:grid;gap:14px}.row{display:grid;grid-auto-flow:column;grid-auto-columns:max-content;gap:10px;overflow:auto}.action{padding:10px 15px;border:1px solid var(--accent);background:transparent;font-family:Didot,serif;letter-spacing:.06em}.action.primary,.action.is-active{color:var(--paper);background:var(--ink)}.metric{font-family:Didot,serif;font-size:clamp(36px,8vw,74px);letter-spacing:.04em}.status{min-height:24px;padding:9px;border-inline:1px solid var(--accent);text-align:center}.muted{line-height:1.8}.chip{padding:5px 14px;border-inline:1px solid var(--accent);letter-spacing:.1em}.meter{height:5px;background:var(--line)}.meter>i{display:block;height:100%;background:linear-gradient(90deg,var(--accent),var(--secondary))}
.composition-gallery{margin:0;padding:clamp(8px,2vw,18px);border:1px solid var(--ink);background:color-mix(in srgb,var(--paper) 78%,transparent)}.gallery-caption{display:grid;grid-template-columns:auto 1fr auto;gap:16px;align-items:center;padding:15px 4px 2px;font-size:12px}.gallery-caption::before,.gallery-caption::after{content:"";height:1px;background:var(--line)}.gallery-caption strong{font:800 11px/1.2 ui-monospace,monospace;letter-spacing:.16em;text-transform:uppercase}.composition-gallery .demo{box-shadow:none}.composition-gallery .demo::before{content:"";position:absolute;inset:10px;border:1px dashed color-mix(in srgb,var(--accent) 36%,transparent);pointer-events:none}
.marquee-lab{display:grid;gap:18px}.marquee-controls{display:grid;grid-template-columns:1fr minmax(210px,.7fr) auto;gap:18px;align-items:end}.marquee-controls h2{margin:.3em 0 0}.marquee-controls label{display:grid;grid-template-columns:1fr auto;gap:8px;font-weight:800}.marquee-controls input{grid-column:1/-1}.marquee-stage{--marquee-duration:14s;overflow:hidden;padding-block:24px;border:1px solid var(--line);background:var(--ink);color:var(--paper)}.marquee-line{display:flex;width:max-content;padding-block:10px;transform:rotate(-2deg);font-size:clamp(30px,7vw,78px);font-weight:950;white-space:nowrap}.marquee-line>div{display:flex;animation:marqueeMove var(--marquee-duration) linear infinite}.marquee-line span{display:inline-flex;align-items:center}.marquee-line span::after{content:"✦";margin-inline:.35em;color:var(--secondary)}.marquee-line.line-1{margin-left:-20%;transform:rotate(1deg);color:var(--secondary)}.marquee-line.line-1>div{animation-direction:reverse}.marquee-line.line-2{margin-left:-8%;font-size:clamp(22px,5vw,58px)}.marquee-stage.is-reversed .marquee-line>div{animation-direction:reverse}.marquee-stage.is-reversed .line-1>div{animation-direction:normal}.marquee-stage.is-paused .marquee-line>div{animation-play-state:paused}.marquee-visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}@keyframes marqueeMove{to{transform:translateX(-50%)}}@media(max-width:760px){.marquee-controls{grid-template-columns:1fr}}.workflow-dispatch{display:grid;grid-template-columns:minmax(210px,.48fr) minmax(0,1.52fr);gap:18px}.dispatch-console{display:grid;align-content:start;gap:16px;padding:22px;border:1px solid var(--line);border-radius:18px;background:color-mix(in srgb,var(--secondary) 12%,var(--paper))}.dispatch-console h2{margin:.2em 0}.dispatch-console form,.dispatch-console label{display:grid;gap:7px}.dispatch-console input,.dispatch-console select{min-width:0;width:100%;padding:10px;border:1px solid var(--line);border-radius:8px;background:var(--paper)}.dispatch-console fieldset{display:flex;gap:12px;border:1px solid var(--line);border-radius:10px}.dispatch-console fieldset label{display:flex;align-items:center}.dispatch-workbench{--dispatch-load:.22;min-width:0;padding:14px;border-left:8px solid color-mix(in srgb,var(--accent) calc(var(--dispatch-load)*100%),var(--line));background:linear-gradient(90deg,color-mix(in srgb,var(--accent) 8%,transparent),transparent 28%)}.dispatch-workbench[data-dispatch-priority="urgent"]{box-shadow:inset 0 0 0 2px var(--accent)}@media(max-width:900px){.workflow-dispatch{grid-template-columns:1fr}.dispatch-console{order:2}}
</style>
</head>
<body data-aesthetic="playful" data-composition="gallery-frame">
<main class="page">
<header class="mast"><div><span class="eyebrow">playful / texte défilant rythmique / BEGINNER</span><h1>Recueil de poèmes des montagnes et des plaines, texte en défilement rythmé</h1><p class="intro">Réalisez une composition de texte défilant rythmée pour le scénario du recueil de poésie des montagnes : comprend du contenu réel, des contrôles interactifs, un retour d’état clair et une mise en page adaptée à toutes les tailles.</p></div><span class="scenario">Recueil de poèmes de montagne</span></header>
<figure class="composition-gallery"><section class="demo" aria-label="zone interactive de texte défilant au rythme du recueil de poèmes de montagne"><div class="workflow-dispatch"><aside class="dispatch-console"><span class="eyebrow">Recueil de poèmes de montagne DISPATCH</span><h2>Table de mise en ordre des manuscrits poétiques</h2><form id="workflowDispatchForm"><label>Type de tâche<select id="workflowDispatchKind"><option>Poème du sentier de montagne</option><option>Chapitre de la vallée</option><option>Nuit au gîte</option></select></label><label>Nombre de vers<input id="workflowDispatchAmount" type="number" min="1" max="9999" value="36"><span>ligne</span></label><fieldset><legend>Priorité de traitement</legend><label><input type="radio" name="workflowPriority" value="normal" checked>Standard</label><label><input type="radio" name="workflowPriority" value="urgent">Urgent</label></fieldset><button class="action primary" type="submit">Inclure dans un recueil</button></form><label>Tâche en cours<select id="workflowDispatchActive" aria-label="Basculer la tâche en cours"><option value="1">Poème du sentier de montagne</option><option value="2">Chapitre de la vallée</option></select></label><output id="workflowDispatchSummary">En attente de planification</output></aside><section id="workflowCore" class="workflow-core dispatch-workbench" data-dispatch-priority="normal"><!-- 11DZ_CORE_START:typography-text-marquee-lines --><div class="marquee-lab"><header class="marquee-controls panel"><div><span class="eyebrow">MARQUEE LINES</span><h2>texte à défilement rythmé</h2></div><label>Vitesse de défilement <input id="marqueeSpeed" type="range" min="6" max="24" value="14"><output id="marqueeSpeedValue">14 s</output></label><div class="row"><button id="marqueeDirection" class="action" type="button" data-core-bridge="typography-text-marquee-lines">Inverse</button><button id="marqueePause" class="action" type="button" aria-pressed="false">Pause</button></div></header><section id="marqueeStage" class="marquee-stage" aria-labelledby="marqueeAccessible"><h3 id="marqueeAccessible" class="marquee-visually-hidden">Collection de poèmes des montagnes et des champs, aperçu de la collection de poèmes des montagnes et des champs, plan de la collection de poèmes des montagnes et des champs, inspiration de la collection de poèmes des montagnes et des champs, notes de la collection de poèmes des montagnes et des champs</h3><div class="marquee-line line-0" aria-hidden="true"><div><span>Recueil de poèmes de montagne</span><span>Aperçu du recueil de poèmes des montagnes et des champs</span><span>Projet de recueil de poèmes des montagnes et des champs</span><span>Inspiration du recueil de poésie des montagnes et des champs</span><span>Carnet de poésie des montagnes</span><span>Recueil de poèmes de montagne</span><span>Aperçu du recueil de poèmes des montagnes et des champs</span><span>Projet de recueil de poèmes des montagnes et des champs</span><span>Inspiration du recueil de poésie des montagnes et des champs</span><span>Carnet de poésie des montagnes</span></div></div><div class="marquee-line line-1" aria-hidden="true"><div><span>Recueil de poèmes de montagne</span><span>Aperçu du recueil de poèmes des montagnes et des champs</span><span>Projet de recueil de poèmes des montagnes et des champs</span><span>Inspiration du recueil de poésie des montagnes et des champs</span><span>Carnet de poésie des montagnes</span><span>Recueil de poèmes de montagne</span><span>Aperçu du recueil de poèmes des montagnes et des champs</span><span>Projet de recueil de poèmes des montagnes et des champs</span><span>Inspiration du recueil de poésie des montagnes et des champs</span><span>Carnet de poésie des montagnes</span></div></div><div class="marquee-line line-2" aria-hidden="true"><div><span>Recueil de poèmes de montagne</span><span>Aperçu du recueil de poèmes des montagnes et des champs</span><span>Projet de recueil de poèmes des montagnes et des champs</span><span>Inspiration du recueil de poésie des montagnes et des champs</span><span>Carnet de poésie des montagnes</span><span>Recueil de poèmes de montagne</span><span>Aperçu du recueil de poèmes des montagnes et des champs</span><span>Projet de recueil de poèmes des montagnes et des champs</span><span>Inspiration du recueil de poésie des montagnes et des champs</span><span>Carnet de poésie des montagnes</span></div></div></section></div><!-- 11DZ_CORE_END --></section></div><p id="status" class="status" role="status" aria-live="polite"></p></section><figcaption class="gallery-caption"><strong>Recueil de poèmes des montagnes et des champs / GALLERY 03</strong></figcaption></figure>
</main>
<script>
'use strict';
const statusOutput = document.querySelector('#status');
const announce = message => { statusOutput.textContent = message; };
/* 11DZ_CORE_SCRIPT_START:typography-text-marquee-lines */
const marqueeStage=document.querySelector('#marqueeStage');const marqueeSpeed=document.querySelector('#marqueeSpeed');function renderMarqueeSpeed(){marqueeStage.style.setProperty('--marquee-duration',marqueeSpeed.value+'s');document.querySelector('#marqueeSpeedValue').textContent=marqueeSpeed.value+' s';announce('cycle de vitesse du défilement '+marqueeSpeed.value+' s');}marqueeSpeed.addEventListener('input',renderMarqueeSpeed);document.querySelector('#marqueeDirection').addEventListener('click',()=>{const reversed=marqueeStage.classList.toggle('is-reversed');announce(reversed?'La direction du défilement a été inversée':'Le sens du défilement a été rétabli');});document.querySelector('#marqueePause').addEventListener('click',event=>{const paused=marqueeStage.classList.toggle('is-paused');event.currentTarget.textContent=paused?'Continuer':'Pause';event.currentTarget.setAttribute('aria-pressed',String(paused));announce(paused?'Texte défilant en pause':'Texte défilant en mouvement continu');});renderMarqueeSpeed();
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"typography-text-marquee-lines","selector":"[data-core-bridge=\"typography-text-marquee-lines\"]","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 workflowDispatchCore=document.querySelector('#workflowCore');const workflowDispatchForm=document.querySelector('#workflowDispatchForm');const workflowDispatchSelect=document.querySelector('#workflowDispatchActive');const workflowDispatchJobs=new Map([["1",{"label":"Poème du sentier de montagne","amount":12,"priority":"normal","touches":0}],["2",{"label":"Chapitre de la vallée","amount":21,"priority":"urgent","touches":0}]]);let workflowDispatchSerial=workflowDispatchJobs.size;function workflowDispatchDrive(job,activate=false){workflowDispatchCore.dataset.dispatchPriority=job.priority;workflowDispatchCore.style.setProperty('--dispatch-load',Math.min(.95,.16+job.amount/120));const bridge=activate?workflowBridgeActivate():{changed:false,summary:workflowBridgeSummary()};document.querySelector('#workflowDispatchSummary').textContent=job.label+' · '+job.amount+' Ligne · '+bridge.summary;announce('Tâche de composition du poème en cours :'+job.label);}function workflowDispatchRender(activeId,activate=false){workflowDispatchSelect.replaceChildren(...[...workflowDispatchJobs].map(([id,job])=>{const option=document.createElement('option');option.value=id;option.textContent=job.label+(job.priority==='urgent'?' · Urgent':'');return option;}));workflowDispatchSelect.value=activeId;workflowDispatchDrive(workflowDispatchJobs.get(activeId),activate);}workflowDispatchForm.addEventListener('submit',event=>{event.preventDefault();const data=new FormData(workflowDispatchForm);const id=String(++workflowDispatchSerial);workflowDispatchJobs.set(id,{label:document.querySelector('#workflowDispatchKind').value,amount:Math.max(1,Number(document.querySelector('#workflowDispatchAmount').value)||1),priority:data.get('workflowPriority'),touches:0});workflowDispatchRender(id,true);});workflowDispatchSelect.addEventListener('change',()=>workflowDispatchDrive(workflowDispatchJobs.get(workflowDispatchSelect.value),true));workflowDispatchCore.addEventListener('focusin',()=>{const job=workflowDispatchJobs.get(workflowDispatchSelect.value);if(!job)return;job.touches+=1;document.querySelector('#workflowDispatchSummary').textContent=job.label+' · '+job.amount+' Ligne · '+workflowBridgeSummary();});workflowDispatchRender('1',false);
workflowBridgeReset();
</script>
</body>
</html>