Business and Service Flows

Flower shop service reservation flow

Complete a service booking flow in a flower shop scenario: includes real content, actionable controls, clear status feedback, and responsive layout.

Business and Service FlowsService reservation flowHTMLCSSJavaScript
With JavaScript enabled, you can edit, run, and save this example. The fixed source is as follows:
<!doctype html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Flower shop service reservation flow</title>
  <style>
    :root { --ink:#24213a; --paper:#f6f1e8; --accent:#e6a23c; --secondary:#a8a1d8; --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:Avenir,"PingFang SC",sans-serif; background: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(1320px,calc(100% - 56px));margin:auto;padding:10vh 0}.mast{display:grid;grid-template-columns:minmax(0,1fr) 160px;gap:10vw;margin-block:6vh;align-items:start;margin-bottom:10vh}.mast h1{font-family:Avenir,"PingFang SC",sans-serif;font-weight:500;font-size:clamp(38px,8vw,88px);letter-spacing:-.055em;margin:0;line-height:.96}.eyebrow{display:block;margin-bottom:24px;font:600 10px/1 ui-monospace,monospace;letter-spacing:.22em}.intro{max-width:52ch;margin-top:28px;line-height:1.8}.scenario{font-size:13px;text-align:right}.demo{border-radius:1px;border-color:color-mix(in srgb,var(--ink) 35%,transparent);box-shadow:none;position:relative;min-height:420px;padding:clamp(28px,5vw,70px);background:transparent}@media(max-width:700px){.page{width:calc(100% - 24px);padding:36px 0}.mast{grid-template-columns:1fr;margin-bottom:30px}.scenario{text-align:left}.demo{padding:18px}}
    .panel{padding:24px;border-block:1px solid var(--ink);background:transparent}.stack{display:grid;gap:22px}.row{display:flex;flex-wrap:wrap;gap:16px}.action{padding:8px 0;border:0;border-bottom:1px solid currentColor;background:transparent;letter-spacing:.08em}.action.primary,.action.is-active{color:var(--accent);border-bottom-width:4px}.status{min-height:28px;margin-top:20px;font-style:italic}.metric{font-family:Didot,serif;font-size:clamp(38px,8vw,76px)}.muted{max-width:54ch;line-height:1.8}.meter{position:relative;height:3px;background:var(--line)}.meter>i{position:absolute;inset:0 auto 0 0;background:var(--accent)}.chip{padding-bottom:3px;border-bottom:1px solid var(--ink);font-size:13px}
    .composition-deck{display:grid;grid-template-rows:auto 1fr;border:1px solid var(--line);border-radius:24px;overflow:hidden;background:color-mix(in srgb,var(--ink) 4%,var(--paper))}.deck-bar{display:flex;justify-content:space-between;gap:18px;align-items:center;padding:12px 18px;color:var(--paper);background:var(--ink);font:700 12px/1 ui-monospace,monospace}.deck-lights{display:flex;gap:7px}.deck-lights i{width:10px;height:10px;border-radius:50%;background:var(--accent)}.deck-lights i:nth-child(2){background:var(--secondary)}.deck-lights i:nth-child(3){background:color-mix(in srgb,var(--paper) 55%,transparent)}.composition-deck .demo{border:0;border-radius:0;box-shadow:none}
    .reservation-demo{display:grid;grid-template-columns:1fr minmax(240px,.6fr);gap:16px}.reservation-demo section,.reservation-demo aside{display:grid;align-content:start;gap:16px;min-width:0}.reservation-demo h2{margin:.3em 0}.reservation-demo fieldset{min-width:0;border:0;padding:0}.reservation-dates,.reservation-slots{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}.reservation-slots{grid-template-columns:repeat(4,minmax(0,1fr))}.reservation-demo fieldset input{position:absolute;opacity:0}.reservation-demo fieldset span{display:block;padding:12px;border:1px solid var(--line);border-radius:10px;text-align:center}.reservation-demo fieldset input:checked+span{color:var(--paper);background:var(--accent)}.reservation-demo fieldset input:focus-visible+span{outline:3px solid var(--accent);outline-offset:2px}.reservation-demo section>label{display:grid;gap:7px}.reservation-demo input[type="number"]{min-width:0;padding:10px;border:1px solid var(--line);border-radius:8px}.reservation-demo dl div{display:flex;justify-content:space-between;gap:14px}.reservation-demo dd{margin:0;font-weight:900}@media(max-width:900px){.reservation-demo{grid-template-columns:1fr}.reservation-dates,.reservation-slots{grid-template-columns:repeat(2,minmax(0,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="minimal" data-composition="control-deck">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">minimal / Service Booking Flow / ADVANCED</span><h1>Flower shop service reservation flow</h1><p class="intro">Complete a service booking flow in a flower shop scenario: includes real content, actionable controls, clear status feedback, and responsive layout.</p></div><span class="scenario">Flower shop</span></header>
    <div class="composition-deck"><div class="deck-bar"><span>CONTROL DECK · 04</span><span>Service reservation flow</span><span class="deck-lights" aria-hidden="true"><i></i><i></i><i></i></span></div><section class="demo" aria-label="Flower Shop Service Reservation Flow Interaction Area"><div class="workflow-dispatch"><aside class="dispatch-console"><span class="eyebrow">Flower Shop DISPATCH</span><h2>Bouquet order dispatch console</h2><form id="workflowDispatchForm"><label>Task Type<select id="workflowDispatchKind"><option>Daily Bouquet</option><option>Seasonal bouquet</option><option>Custom Bouquet</option></select></label><label>Floral quantity<input id="workflowDispatchAmount" type="number" min="1" max="9999" value="27"><span>Branch</span></label><fieldset><legend>Processing priority</legend><label><input type="radio" name="workflowPriority" value="normal" checked>Regular</label><label><input type="radio" name="workflowPriority" value="urgent">Urgent</label></fieldset><button class="action primary" type="submit">Accept orders</button></form><label>Current task<select id="workflowDispatchActive" aria-label="Switch current task"><option value="1">Daily Bouquet</option><option value="2">Seasonal bouquet</option></select></label><output id="workflowDispatchSummary">Waiting for Dispatch</output></aside><section id="workflowCore" class="workflow-core dispatch-workbench" data-dispatch-priority="normal"><!-- 11DZ_CORE_START:commerce-service-flows-reservation-flow --><form id="reservationForm" class="reservation-demo"><section class="panel"><span class="eyebrow">RESERVATION</span><h2>Flower Shop Reservation</h2><fieldset><legend>Select Date</legend><div class="reservation-dates"><label><input type="radio" name="date" value="7 16" checked data-core-bridge="commerce-service-flows-reservation-flow"><span>7 16</span></label><label><input type="radio" name="date" value="7 month 17 day"><span>7 month 17 day</span></label><label><input type="radio" name="date" value="7 month 18 day"><span>7 month 18 day</span></label></div></fieldset><fieldset><legend>Select time</legend><div class="reservation-slots"><label><input type="radio" name="slot" value="09:30"><span>09:30</span></label><label><input type="radio" name="slot" value="11:00" checked><span>11:00</span></label><label><input type="radio" name="slot" value="14:30"><span>14:30</span></label><label><input type="radio" name="slot" value="16:00"><span>16:00</span></label></div></fieldset><label>Number of people <input name="people" type="number" min="1" max="8" value="2"></label></section><aside class="panel"><h3>Reservation Summary</h3><dl><div><dt>Date</dt><dd id="reservationDate"></dd></div><div><dt>Time</dt><dd id="reservationSlot"></dd></div><div><dt>Number of people</dt><dd id="reservationPeople"></dd></div></dl><button class="action primary" type="submit">Confirm Reservation</button><small>This demo will not submit a real reservation.</small></aside></form><!-- 11DZ_CORE_END --></section></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:commerce-service-flows-reservation-flow */
const reservationForm=document.querySelector('#reservationForm');function renderReservation(){const data=new FormData(reservationForm);document.querySelector('#reservationDate').textContent=data.get('date');document.querySelector('#reservationSlot').textContent=data.get('slot');document.querySelector('#reservationPeople').textContent=data.get('people')+' person';announce('Reservation summary updated');}reservationForm.querySelectorAll('input').forEach(input=>input.addEventListener('change',renderReservation));reservationForm.addEventListener('submit',event=>{event.preventDefault();renderReservation();announce('Flower shop reservation confirmed locally');});renderReservation();
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"commerce-service-flows-reservation-flow","selector":"[data-core-bridge=\"commerce-service-flows-reservation-flow\"]","mode":"radio","key":"ArrowRight"};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+' · Core Version '+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("keydown",workflowBridgeScheduleCommit);workflowBridgeControl.addEventListener('input',workflowBridgeScheduleCommit);workflowBridgeControl.addEventListener('change',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();const radios=[...workflowBridgeCore.querySelectorAll('input[type="radio"]')].filter(input=>input.name===workflowBridgeControl.name&&!input.disabled);const current=Math.max(0,radios.findIndex(input=>input.checked));radios[(current+1)%radios.length].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":"Daily Bouquet","amount":12,"priority":"normal","touches":0}],["2",{"label":"Seasonal bouquet","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+' Branch · '+bridge.summary;announce('Current flower order task:'+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+' Branch · '+workflowBridgeSummary();});workflowDispatchRender('1',false);
workflowBridgeReset();
  </script>
</body>
</html>
Page feedbackFound an issue or have suggestions for improvement?
Feedback features need to be used in the online version

Please enable JavaScript in the online version before submitting; local features of the current tool or example are not affected.

Go to the online version for feedback