Dashboard and Admin Interfaces

Care Network Cohort Retention Dashboard

Complete a cohort retention panel in a care network scenario: include real content, actionable controls, clear status feedback, and responsive layout across sizes.

Dashboard and Admin InterfacesGrouped Retention PanelHTML TableCSSJavaScript
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>Care Network Cohort Retention Dashboard</title>
  <style>
    :root { --ink:#18332f; --paper:#f4efe4; --accent:#d45f3e; --secondary:#8fc4ad; --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:"Kaiti SC",STKaiti,"Songti SC",serif; background:radial-gradient(circle at 12% 18%,color-mix(in srgb,var(--accent) 12%,transparent) 0 1px,transparent 2px),var(--paper);background-size:19px 19px; }
    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(980px,calc(100% - 32px));margin:auto;padding:72px 0 92px}.mast{display:grid;grid-template-columns:1fr auto;transform:rotate(-.25deg);gap:32px;align-items:center;margin-bottom:46px}.mast h1{font-family:"Kaiti SC",STKaiti,serif;font-weight:700;font-size:clamp(40px,8vw,84px);letter-spacing:.02em;margin:0;line-height:1.12}.intro{max-width:650px;margin-top:18px;line-height:2}.scenario{padding:12px;border:2px solid var(--accent);color:var(--accent);transform:rotate(3deg)}.eyebrow{display:block;margin-bottom:9px;color:var(--accent);letter-spacing:.18em}.demo{border-radius:2px;transform:rotate(.12deg);box-shadow:0 30px 70px color-mix(in srgb,var(--ink) 18%,transparent);position:relative;min-height:430px;overflow:hidden;padding:clamp(28px,6vw,66px);background:color-mix(in srgb,var(--paper) 92%,#fff)}@media(max-width:700px){.page{width:calc(100% - 20px);padding:28px 0}.mast{grid-template-columns:1fr}.scenario{justify-self:start}.demo{padding:20px}}
    .panel{padding:26px;border:1px solid var(--line);border-radius:2px;background:var(--paper)}.stack{display:grid;gap:28px}.row{display:flex;gap:20px;flex-wrap:wrap}.action{padding:9px 2px;border:0;border-bottom:2px solid var(--line);background:transparent}.action.primary,.action.is-active{border-color:var(--accent);color:var(--accent)}.muted{font-size:14px;line-height:1.9}.status{min-height:20px;margin-top:28px;font-size:13px}.metric{font-size:clamp(40px,9vw,88px);font-weight:500;letter-spacing:-.06em}.meter{height:2px;background:var(--line)}.meter>i{display:block;height:100%;background:var(--accent)}.chip{font-size:11px;letter-spacing:.12em;text-transform:uppercase}
    .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}}
    .cohort-ribbon-studio{display:grid;gap:18px}.cohort-ribbon-studio header{display:flex;justify-content:space-between;gap:18px;align-items:end}.cohort-ribbon-studio h2{margin:.3em 0}.cohort-ribbon-grid{display:grid;grid-template-columns:minmax(0,1.3fr) 240px;gap:14px}.cohort-ribbon-cards{display:grid;gap:12px}.cohort-ribbon-cards article{display:grid;gap:12px;padding:16px;border:1px solid var(--line);border-radius:18px;background:var(--paper)}.cohort-ribbon-cards article header{display:flex;justify-content:space-between;gap:12px;align-items:center}.cohort-ribbon-cards ol{display:grid;gap:8px;padding:0;margin:0;list-style:none}.cohort-ribbon-cards li{display:grid;grid-template-columns:60px 58px 1fr;gap:10px;align-items:center}.cohort-ribbon-cards b{font-size:22px}.cohort-ribbon-cards i{display:block;height:12px;border-radius:999px;background:linear-gradient(90deg,var(--accent) calc(var(--fill)*1%),color-mix(in srgb,var(--line) 82%,transparent) 0)}.cohort-ribbon-grid aside{display:grid;align-content:start;gap:10px;padding:18px;border-left:4px solid var(--accent);background:color-mix(in srgb,var(--secondary) 10%,transparent)}.cohort-ribbon-grid aside ol{display:grid;gap:8px;padding-left:18px;margin:0}@media(max-width:760px){.cohort-ribbon-studio header{align-items:stretch;flex-direction:column}.cohort-ribbon-grid{grid-template-columns:1fr}}.workflow-session{display:grid;gap:14px}.session-command{display:grid;grid-template-columns:1fr auto minmax(170px,.45fr) auto;gap:16px;align-items:end;padding:18px;border-block:4px double var(--ink)}.session-command h2{margin:.2em 0}.session-command output{font:900 clamp(28px,5vw,54px)/1 ui-monospace,monospace}.session-command label{display:grid;grid-template-columns:1fr auto;gap:7px;font-size:12px}.session-command input{grid-column:1/-1;width:100%}#workflowSessionProgress{height:12px;overflow:hidden;border-radius:2px;background:var(--line)}#workflowSessionProgress i{display:block;width:0;height:100%;background:var(--accent)}.session-stage{min-width:0;transition:filter .25s,transform .25s}.session-stage[data-session-phase="running"]{transform:translateY(-3px)}.session-stage[data-session-phase="paused"]{filter:grayscale(.65)}.session-stage[data-session-phase="complete"]{filter:contrast(.78);opacity:.72}.session-log{display:grid;grid-template-columns:auto 1fr;gap:18px;align-items:start}.session-log ol{display:flex;flex-wrap:wrap;gap:7px;padding:0;margin:0;list-style:none}.session-log li{padding:5px 8px;border:1px solid var(--line);font-size:12px}@media(max-width:900px){.session-stage{order:-1}.session-command{grid-template-columns:1fr auto}.session-command label{grid-column:1/-1}.session-log{grid-template-columns:1fr}}
  </style>
</head>
<body data-aesthetic="paper" data-composition="split-note">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">paper / Cohort Retention Panel / INTERMEDIATE</span><h1>Care Network Cohort Retention Dashboard</h1><p class="intro">Complete a cohort retention panel in a care network scenario: include real content, actionable controls, clear status feedback, and responsive layout across sizes.</p></div><span class="scenario">Care Network</span></header>
    <div class="composition-split"><aside class="split-note"><b>CASE 02</b><span>Master the semantic structure, responsive arrangement, keyboard operation, and state synchronization of a cohort retention panel.</span></aside><section class="demo" aria-label="Care Network Cohort Retention Panel interaction area"><div class="workflow-session"><header class="session-command"><div><span class="eyebrow">Care Network SESSION</span><h2>Care Network Timing Board</h2></div><output id="workflowSessionClock">00:45</output><label>Round Duration<input id="workflowSessionLength" type="range" min="15" max="90" step="15" value="45"><span>sec</span></label><button id="workflowSessionToggle" class="action primary" type="button">Start applying the panel</button></header><div id="workflowSessionProgress" role="progressbar" aria-label="Care network progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><i></i></div><section id="workflowCore" class="workflow-core session-stage" data-session-phase="ready" tabindex="-1"><!-- 11DZ_CORE_START:dashboards-admin-cohort-panel --><div class="cohort-ribbon-studio"><header><div><span class="eyebrow">CARE COHORT RIBBONS</span><h2>Care Network Retention Corridor</h2></div><label>Show percentage <input id="cohortPercent" type="checkbox" checked data-core-bridge="dashboards-admin-cohort-panel"></label></header><div class="cohort-ribbon-grid"><section class="cohort-ribbon-cards"><article><header><strong>Joined this week</strong><span id="cohortLead0">Week 0 100%</span></header><ol><li><span>Week 0</span><b data-cohort="100" data-group="0" data-week="0">100%</b><i style="--fill:100"></i></li><li><span>Week 1</span><b data-cohort="84" data-group="0" data-week="1">84%</b><i style="--fill:84"></i></li><li><span>Week 2</span><b data-cohort="73" data-group="0" data-week="2">73%</b><i style="--fill:73"></i></li><li><span>Week 3</span><b data-cohort="68" data-group="0" data-week="3">68%</b><i style="--fill:68"></i></li></ol></article><article><header><strong>Joined Last Week</strong><span id="cohortLead1">Week 0 92%</span></header><ol><li><span>Week 0</span><b data-cohort="92" data-group="1" data-week="0">92%</b><i style="--fill:92"></i></li><li><span>Week 1</span><b data-cohort="78" data-group="1" data-week="1">78%</b><i style="--fill:78"></i></li><li><span>Week 2</span><b data-cohort="69" data-group="1" data-week="2">69%</b><i style="--fill:69"></i></li><li><span>Week 3</span><b data-cohort="58" data-group="1" data-week="3">58%</b><i style="--fill:58"></i></li></ol></article><article><header><strong>Joined two weeks ago</strong><span id="cohortLead2">Week 0 88%</span></header><ol><li><span>Week 0</span><b data-cohort="88" data-group="2" data-week="0">88%</b><i style="--fill:88"></i></li><li><span>Week 1</span><b data-cohort="71" data-group="2" data-week="1">71%</b><i style="--fill:71"></i></li><li><span>Week 2</span><b data-cohort="57" data-group="2" data-week="2">57%</b><i style="--fill:57"></i></li><li><span>Week 3</span><b data-cohort="44" data-group="2" data-week="3">44%</b><i style="--fill:44"></i></li></ol></article><article><header><strong>Joined three weeks ago</strong><span id="cohortLead3">Week 0 82%</span></header><ol><li><span>Week 0</span><b data-cohort="82" data-group="3" data-week="0">82%</b><i style="--fill:82"></i></li><li><span>Week 1</span><b data-cohort="63" data-group="3" data-week="1">63%</b><i style="--fill:63"></i></li><li><span>Week 2</span><b data-cohort="49" data-group="3" data-week="2">49%</b><i style="--fill:49"></i></li><li><span>Week 3</span><b data-cohort="39" data-group="3" data-week="3">39%</b><i style="--fill:39"></i></li></ol></article></section><aside><strong id="cohortTopWeek">Most stable group: joined this week</strong><p id="cohortModeHint">The current retention stickiness of the care network is being viewed as a percentage.</p><ol id="cohortSummaryList"></ol></aside></div></div><!-- 11DZ_CORE_END --></section><footer class="session-log"><strong id="workflowSessionScore">0 interaction checkpoints</strong><ol id="workflowSessionLaps" aria-label="Round Log"></ol></footer></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:dashboards-admin-cohort-panel */
const careCohortCells=[...document.querySelectorAll('[data-cohort]')];const careCohortCards=["Joined this week","Joined Last Week","Joined two weeks ago","Joined three weeks ago"];function renderCareCohort(asPercent){const grouped=careCohortCards.map((_,group)=>careCohortCells.filter(cell=>Number(cell.dataset.group)===group).map(cell=>Number(cell.dataset.cohort)));const peaks=grouped.map(values=>values.reduce((sum,value)=>sum+value,0));const topGroup=peaks.indexOf(Math.max(...peaks));document.querySelector('#cohortTopWeek').textContent='Best cohort group:'+careCohortCards[topGroup];document.querySelector('#cohortModeHint').textContent=asPercent?'The current retention stickiness of the care network is being viewed as a percentage.':'Currently observing follow-up coverage using estimated headcount.';document.querySelector('#cohortSummaryList').replaceChildren(...grouped.map((values,index)=>{const item=document.createElement('li');const tail=values.at(-1);item.textContent=careCohortCards[index]+' · Week 3 '+(asPercent?tail+'%':Math.round(tail*2.6)+' person');return item;}));careCohortCells.forEach(cell=>{const value=Number(cell.dataset.cohort);cell.textContent=asPercent?value+'%':Math.round(value*2.6)+' person';});grouped.forEach((values,index)=>{document.querySelector('#cohortLead'+index).textContent='Week 0 '+(asPercent?values[0]+'%':Math.round(values[0]*2.6)+' person');});}document.querySelector('#cohortPercent').addEventListener('change',event=>{renderCareCohort(event.currentTarget.checked);announce(event.currentTarget.checked?'Retention Percentage Shown':'Estimated audience shown');});renderCareCohort(true);
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"dashboards-admin-cohort-panel","selector":"[data-core-bridge=\"dashboards-admin-cohort-panel\"]","mode":"toggle","key":" "};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.setAttribute('aria-keyshortcuts',workflowBridgeSpec.key===' '?'Space':workflowBridgeSpec.key);const workflowBridgeToggleKeyMatches=event=>event.key===workflowBridgeSpec.key||event.key==='Spacebar'||event.code==='Space';workflowBridgeControl.addEventListener('keydown',event=>{if(!workflowBridgeToggleKeyMatches(event))return;event.preventDefault();});workflowBridgeControl.addEventListener('keyup',event=>{if(!workflowBridgeToggleKeyMatches(event))return;event.preventDefault();workflowBridgeControl.click();});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();workflowBridgeControl.click();const result=workflowBridgeCommit();setTimeout(workflowBridgeCommit,0);return result;}function workflowBridgeReset(){workflowBridgeCore.dataset.workflowVersion='0';workflowBridgeLastEffect=workflowBridgeSerialize();}
const workflowSessionCore=document.querySelector('#workflowCore');const workflowSessionToggle=document.querySelector('#workflowSessionToggle');const workflowSessionLength=document.querySelector('#workflowSessionLength');const workflowSessionState={phase:'ready',elapsed:0,limit:Number(workflowSessionLength.value),checkpoints:[],timer:null};function workflowSessionFormat(seconds){return String(Math.floor(seconds/60)).padStart(2,'0')+':'+String(seconds%60).padStart(2,'0');}function workflowSessionDrive(){const percent=Math.min(100,Math.round(workflowSessionState.elapsed/workflowSessionState.limit*100));document.querySelector('#workflowSessionClock').textContent=workflowSessionFormat(Math.max(0,workflowSessionState.limit-workflowSessionState.elapsed));const progress=document.querySelector('#workflowSessionProgress');progress.setAttribute('aria-valuenow',String(percent));progress.querySelector('i').style.width=percent+'%';workflowSessionCore.dataset.sessionPhase=workflowSessionState.phase;document.querySelector('#workflowSessionScore').textContent=workflowSessionState.checkpoints.length+' interactive checkpoints';}function workflowSessionLap(label){workflowSessionState.checkpoints.push({label,at:workflowSessionState.elapsed});const item=document.createElement('li');item.textContent=label+' · '+workflowSessionFormat(workflowSessionState.elapsed);document.querySelector('#workflowSessionLaps').append(item);workflowSessionDrive();}function workflowSessionStop(complete=false){clearInterval(workflowSessionState.timer);workflowSessionState.timer=null;workflowSessionState.phase=complete?'complete':'paused';workflowSessionToggle.textContent=complete?'Restart':'Continue round';workflowSessionToggle.setAttribute('aria-pressed','false');workflowSessionDrive();announce(complete?'Care Network Cycle Complete':'Round paused');}function workflowSessionStart(){if(workflowSessionState.phase==='complete'){workflowSessionState.elapsed=0;workflowSessionState.checkpoints=[];document.querySelector('#workflowSessionLaps').replaceChildren();}workflowSessionState.phase='running';workflowSessionToggle.textContent='Pause round';workflowSessionToggle.setAttribute('aria-pressed','true');const bridge=workflowBridgeActivate();workflowSessionLap(bridge.summary);clearInterval(workflowSessionState.timer);workflowSessionState.timer=setInterval(()=>{workflowSessionState.elapsed+=1;if(workflowSessionState.elapsed>=workflowSessionState.limit){workflowSessionStop(true);return;}workflowSessionDrive();},1000);workflowSessionDrive();announce('Care Network Round Started · '+bridge.summary);}workflowSessionToggle.addEventListener('click',()=>workflowSessionState.phase==='running'?workflowSessionStop():workflowSessionStart());workflowSessionLength.addEventListener('input',()=>{workflowSessionState.limit=Number(workflowSessionLength.value);workflowSessionState.elapsed=Math.min(workflowSessionState.elapsed,workflowSessionState.limit);workflowSessionDrive();});workflowSessionCore.addEventListener('keydown',event=>{if(event.key==='Enter'||event.key===' '){workflowSessionLap('Keyboard Interaction');}});workflowSessionCore.addEventListener('click',event=>{if(event.target.closest('[data-core-bridge]'))workflowSessionLap('Core action · '+workflowBridgeSummary());});document.addEventListener('visibilitychange',()=>{if(document.hidden&&workflowSessionState.phase==='running')workflowSessionStop();});workflowSessionDrive();
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