Floating layers and status feedback

Document Review Context Actions

Complete a contextual actions form for a document review scenario: include real content, interactive controls, clear status feedback, and responsive layouts across sizes.

Floating layers and status feedbackContext ActionsHTMLCSSJavaScript
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>Document Review Context Actions</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:Optima,"Songti SC",serif; background:radial-gradient(ellipse at top left,color-mix(in srgb,var(--secondary) 32%,transparent),transparent 42%),radial-gradient(ellipse at bottom right,color-mix(in srgb,var(--accent) 18%,transparent),transparent 45%),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(1100px,calc(100% - 34px));margin:auto;padding:68px 0}.mast{display:grid;grid-template-columns:1fr auto;align-items:center;gap:40px;margin:0 4vw 36px}.mast h1{font-family:Optima,"Songti SC",serif;font-weight:700;font-size:clamp(40px,8vw,86px);letter-spacing:-.025em;margin:0;line-height:1.02}.eyebrow{display:block;margin-bottom:12px;color:var(--accent);font-size:12px;letter-spacing:.2em}.intro{max-width:60ch;line-height:1.9}.scenario{display:grid;width:108px;height:108px;place-items:center;padding:12px;border:1px solid var(--line);border-radius:50%;text-align:center}.demo{border-radius:72px 18px 72px 18px;box-shadow:0 28px 80px color-mix(in srgb,var(--ink) 14%,transparent);position:relative;min-height:430px;overflow:hidden;padding:clamp(28px,5vw,58px);background:color-mix(in srgb,var(--paper) 84%,transparent)}@media(max-width:700px){.page{width:calc(100% - 18px);padding:24px 0}.mast{grid-template-columns:1fr;margin-inline:12px}.scenario{width:auto;height:auto;border-radius:999px}.demo{padding:18px}}
    .panel{padding:20px;border:1px solid color-mix(in srgb,var(--accent) 50%,transparent);border-radius:18px;background:color-mix(in srgb,var(--paper) 88%,transparent);box-shadow:inset 0 0 24px color-mix(in srgb,var(--accent) 7%,transparent)}.stack{display:grid;gap:16px}.row{display:flex;flex-wrap:wrap;gap:9px}.action{padding:11px 16px;border:1px solid var(--accent);border-radius:6px;color:var(--accent);background:transparent;box-shadow:0 0 14px color-mix(in srgb,var(--accent) 10%,transparent)}.action.primary,.action.is-active{color:var(--paper);background:var(--accent)}.status{min-height:24px;color:var(--secondary);text-shadow:0 0 10px currentColor}.metric{font-size:clamp(30px,7vw,64px);font-weight:900;text-shadow:0 0 18px color-mix(in srgb,var(--accent) 40%,transparent)}.muted{opacity:.7}.chip{padding:6px 9px;border:1px solid var(--secondary);border-radius:4px}.meter{height:7px;background:color-mix(in srgb,var(--accent) 15%,transparent)}.meter>i{display:block;height:100%;box-shadow:0 0 12px var(--accent);background:var(--accent)}
    .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}
    .context-actions-demo{display:grid;gap:18px}.context-actions-demo header{max-width:680px}.context-actions-demo h2{margin:.2em 0}.context-surface{position:relative;display:grid;align-content:center;justify-items:start;min-height:320px;padding:clamp(28px,7vw,76px);border:2px dashed var(--line);border-radius:28px;background:color-mix(in srgb,var(--secondary) 10%,var(--paper))}.context-surface>span{font:800 10px/1 ui-monospace,monospace;letter-spacing:.18em}.context-surface>strong{margin-top:12px;font-size:clamp(34px,7vw,70px)}.context-surface>button{padding:11px 15px;border:1px solid var(--ink);border-radius:10px;background:var(--paper)}.context-menu{position:absolute;z-index:5;display:grid;width:210px;padding:7px;border:1px solid var(--line);border-radius:14px;background:var(--paper);box-shadow:0 18px 48px #0004}.context-menu button{display:grid;grid-template-columns:28px 1fr;gap:8px;padding:11px;border:0;border-radius:8px;background:transparent;text-align:left}.context-menu button:hover,.context-menu button:focus-visible{background:color-mix(in srgb,var(--secondary) 22%,transparent)}.context-menu hr{width:100%;margin:5px 0;border:0;border-top:1px solid var(--line)}.context-menu .context-danger{color:#a8322a}.context-actions-demo>output{padding:12px 16px;border-left:5px solid var(--accent);font-weight:900}.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="organic" data-composition="control-deck">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">organic / Context Actions Sheet / INTERMEDIATE</span><h1>Document Review Context Actions</h1><p class="intro">Complete a contextual actions form for a document review scenario: include real content, interactive controls, clear status feedback, and responsive layouts across sizes.</p></div><span class="scenario">Document Review</span></header>
    <div class="composition-deck"><div class="deck-bar"><span>CONTROL DECK · 04</span><span>Context Actions</span><span class="deck-lights" aria-hidden="true"><i></i><i></i><i></i></span></div><section class="demo" aria-label="Document Review Context Actions Interaction Area"><div class="workflow-dispatch"><aside class="dispatch-console"><span class="eyebrow">Document Review DISPATCH</span><h2>Review Queue Control Center</h2><form id="workflowDispatchForm"><label>Task Type<select id="workflowDispatchKind"><option>Text Editing</option><option>Structural Suggestions</option><option>Publish Confirmation</option></select></label><label>Pending reviews<input id="workflowDispatchAmount" type="number" min="1" max="9999" value="39"><span>item</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">Submit for Review</button></form><label>Current task<select id="workflowDispatchActive" aria-label="Switch current task"><option value="1">Text Editing</option><option value="2">Structural Suggestions</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:overlays-feedback-context-actions --><section class="context-actions-demo"><header><span class="eyebrow">CONTEXT ACTIONS</span><h2>Document Review Quick Actions</h2><p>Right-click, Shift + F10 or the button to open the same set of context actions.</p></header><div id="contextSurface" class="context-surface" tabindex="0" aria-label="Document review progress action area"><span>SELECTED ITEM</span><strong>Document Review Progress</strong><p>Right-click here or press Shift + F10</p><button id="contextOpen" type="button" aria-haspopup="menu" aria-expanded="false" data-core-bridge="overlays-feedback-context-actions">Open actions menu</button><div id="contextMenu" class="context-menu" role="menu" hidden><button type="button" role="menuitem"><span aria-hidden="true">✎</span><span class="context-action-copy">Rename</span></button><button type="button" role="menuitem"><span aria-hidden="true">□</span><span class="context-action-copy">Create Copy</span></button><button type="button" role="menuitem"><span aria-hidden="true">→</span><span class="context-action-copy">Move to…</span></button><hr><button type="button" role="menuitem" class="context-danger"><span aria-hidden="true">×</span><span class="context-action-copy">Archive</span></button></div></div><output id="contextResult">No action taken yet</output></section><!-- 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:overlays-feedback-context-actions */
const contextSurface=document.querySelector('#contextSurface');const contextOpen=document.querySelector('#contextOpen');const contextMenu=document.querySelector('#contextMenu');const contextItems=[...contextMenu.querySelectorAll('[role="menuitem"]')];function contextActionLabel(item){return item.querySelector('.context-action-copy').textContent;}function openContextMenu(x,y){const maximumX=Math.max(8,contextSurface.clientWidth-225);const maximumY=Math.max(8,contextSurface.clientHeight-230);contextMenu.style.left=Math.min(Math.max(8,x),maximumX)+'px';contextMenu.style.top=Math.min(Math.max(8,y),maximumY)+'px';contextMenu.hidden=false;contextOpen.setAttribute('aria-expanded','true');contextItems[0].focus();announce('Context actions menu is open');}function closeContextMenu(restore=false){contextMenu.hidden=true;contextOpen.setAttribute('aria-expanded','false');if(restore)contextOpen.focus();}contextOpen.addEventListener('click',event=>{event.stopPropagation();openContextMenu(contextOpen.offsetLeft,contextOpen.offsetTop+contextOpen.offsetHeight+6);});contextSurface.addEventListener('contextmenu',event=>{event.preventDefault();const rect=contextSurface.getBoundingClientRect();openContextMenu(event.clientX-rect.left,event.clientY-rect.top);});contextSurface.addEventListener('keydown',event=>{if(event.shiftKey&&event.key==='F10'){event.preventDefault();openContextMenu(24,80);}});contextMenu.addEventListener('keydown',event=>{const index=contextItems.indexOf(document.activeElement);if(event.key==='ArrowDown'||event.key==='ArrowUp'){event.preventDefault();const offset=event.key==='ArrowDown'?1:-1;contextItems[(index+offset+contextItems.length)%contextItems.length].focus();}if(event.key==='Escape'){event.preventDefault();closeContextMenu(true);}});contextItems.forEach(item=>item.addEventListener('click',()=>{const label=contextActionLabel(item);document.querySelector('#contextResult').textContent='Executed:'+label;announce('Executed '+label);closeContextMenu(true);}));document.addEventListener('click',event=>{if(!contextMenu.hidden&&!contextMenu.contains(event.target))closeContextMenu(false);});
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"overlays-feedback-context-actions","selector":"[data-core-bridge=\"overlays-feedback-context-actions\"]","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+' · 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("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":"Text Editing","amount":12,"priority":"normal","touches":0}],["2",{"label":"Structural Suggestions","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+' item · '+bridge.summary;announce('Current task in the review queue:'+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+' item · '+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