Forms and input

Course enrollment budget setup sheet

Complete the budget configuration form in a course enrollment scenario: includes real content, interactive controls, clear status feedback, and responsive layouts.

Forms and inputBudget allocation sheetHTMLCSSJavaScript
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>Course enrollment budget setup sheet</title>
  <style>
    :root { --ink:#111111; --paper:#f8f8f4; --accent:#111111; --secondary:#8d8d88; --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:Helvetica,"PingFang SC",sans-serif; background:repeating-linear-gradient(0deg,transparent 0 31px,color-mix(in srgb,var(--ink) 7%,transparent) 32px),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(1120px,calc(100% - 30px));margin:auto;padding:48px 0 80px}.mast{display:grid;grid-template-columns:1fr auto;border-top:10px solid var(--ink);padding-top:20px;gap:20px;align-items:end;margin-bottom:26px}.mast h1{font-family:Helvetica,"PingFang SC",sans-serif;font-weight:900;font-size:clamp(44px,10vw,106px);letter-spacing:-.075em;margin:0;line-height:.82}.eyebrow{display:inline-block;margin-bottom:12px;padding:5px 8px;color:var(--paper);background:var(--ink);font:900 10px/1 ui-monospace,monospace;letter-spacing:.14em}.intro{max-width:700px;line-height:1.55}.scenario{padding:9px 12px;border:3px solid var(--ink);font-weight:900}.demo{border:3px solid var(--ink);border-radius:0;box-shadow:12px 12px 0 var(--ink);position:relative;min-height:410px;overflow:hidden;padding:clamp(22px,4vw,46px);background:var(--paper)}@media(max-width:700px){.page{width:calc(100% - 18px);padding:20px 0}.mast{grid-template-columns:1fr}.demo{padding:15px}}
    .panel{padding:30px;border:0;border-radius:42px 12px;background:color-mix(in srgb,var(--secondary) 18%,var(--paper))}.row{display:flex;flex-wrap:wrap;gap:14px;align-items:center}.stack{display:flex;flex-direction:column;gap:20px}.action{min-height:48px;padding:12px 22px;border:0;border-radius:50% 50% 18px 18px;background:color-mix(in srgb,var(--secondary) 42%,transparent);font-weight:800}.action.primary,.action.is-active{color:var(--paper);background:var(--accent)}.muted{color:color-mix(in srgb,var(--ink) 64%,transparent);line-height:1.7}.status{min-height:25px;margin-top:16px;color:var(--accent)}.metric{font-size:clamp(32px,7vw,66px);font-weight:800}.meter{height:11px;border-radius:50%;background:color-mix(in srgb,var(--ink) 10%,transparent)}.meter>i{display:block;height:100%;border-radius:inherit;background:var(--accent)}.chip{padding:8px 12px;border-radius:50%;background:var(--paper)}
    .composition-index{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:18px}.index-mark{display:grid;align-content:space-between;width:76px;padding:16px 10px;border:1px solid var(--line);color:var(--accent);background:color-mix(in srgb,var(--paper) 82%,transparent);text-align:center}.index-mark strong{font:900 34px/1 ui-monospace,monospace}.index-mark span{writing-mode:vertical-rl;font:800 10px/1.2 ui-monospace,monospace;letter-spacing:.18em}.composition-index .demo{grid-column:1;grid-row:1}.composition-index::before{content:"";position:absolute;left:-12px;top:38px;width:5px;height:45%;background:linear-gradient(var(--accent),var(--secondary))}@media(max-width:700px){.composition-index{grid-template-columns:1fr}.index-mark{grid-row:1;width:auto;grid-template-columns:auto 1fr}.index-mark span{writing-mode:horizontal-tb}.composition-index .demo{grid-row:2}}
    .budget-builder{display:grid;grid-template-columns:1fr minmax(220px,.55fr);gap:18px}.budget-builder header,.budget-limit{grid-column:1/-1}.budget-builder h2{margin:.3em 0}.budget-lines{display:grid;gap:9px}.budget-lines label{display:grid;grid-template-columns:1fr 120px 80px;gap:10px;align-items:center}.budget-lines input,.budget-limit input{width:100%;padding:10px;border:1px solid var(--line);border-radius:8px;background:var(--paper)}.budget-builder aside{display:grid;align-content:center;padding:22px;border-radius:18px;background:var(--ink);color:var(--paper)}@media(max-width:650px){.budget-builder{grid-template-columns:1fr}.budget-builder>*{grid-column:auto}.budget-lines label{grid-template-columns:1fr 100px}.budget-lines output{grid-column:1/-1}}.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="monochrome" data-composition="field-index">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">monochrome / Budget Allocation Form / BEGINNER</span><h1>Course enrollment budget setup sheet</h1><p class="intro">Complete the budget configuration form in a course enrollment scenario: includes real content, interactive controls, clear status feedback, and responsive layouts.</p></div><span class="scenario">Course registration</span></header>
    <div class="composition-index"><section class="demo" aria-label="Course registration budget configuration table interactive area"><div class="workflow-session"><header class="session-command"><div><span class="eyebrow">Course enrollment SESSION</span><h2>Course Planning Timeline</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 course enrollment submission</button></header><div id="workflowSessionProgress" role="progressbar" aria-label="Course enrollment plan 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:forms-input-budget-builder --><div class="budget-builder panel"><header><span class="eyebrow">BUDGET BUILDER</span><h2>Course Registration Budget</h2></header><div class="budget-lines"><label><span>Venue</span><input data-budget-line type="number" min="0" step="10" value="80" data-core-bridge="forms-input-budget-builder"><output>¥80</output></label><label><span>Materials</span><input data-budget-line type="number" min="0" step="10" value="115"><output>¥115</output></label><label><span>Transportation</span><input data-budget-line type="number" min="0" step="10" value="150"><output>¥150</output></label><label><span>Catering</span><input data-budget-line type="number" min="0" step="10" value="185"><output>¥185</output></label></div><label class="budget-limit">Budget cap <input id="budgetLimit" type="number" min="0" value="700"></label><aside><span>Current total</span><strong id="budgetTotal" class="metric">¥0</strong><p id="budgetBalance"></p></aside></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><aside class="index-mark" aria-hidden="true"><strong>05</strong><span>Course Registration FIELD INDEX</span></aside></div>
  </main>
  <script>
    'use strict';
    const statusOutput = document.querySelector('#status');
    const announce = message => { statusOutput.textContent = message; };
    /* 11DZ_CORE_SCRIPT_START:forms-input-budget-builder */
const budgetInputs=[...document.querySelectorAll('[data-budget-line]')];function renderBudget(){let total=0;budgetInputs.forEach(input=>{const value=Math.max(0,Number(input.value)||0);total+=value;input.nextElementSibling.textContent='¥'+value;});const limit=Math.max(0,Number(document.querySelector('#budgetLimit').value)||0);const balance=limit-total;document.querySelector('#budgetTotal').textContent='¥'+total;document.querySelector('#budgetBalance').textContent=balance>=0?'Still available to allocate ¥'+balance:'Over budget ¥'+Math.abs(balance);announce('Total Budget '+total+' yuan');}budgetInputs.forEach(input=>input.addEventListener('input',renderBudget));document.querySelector('#budgetLimit').addEventListener('input',renderBudget);renderBudget();
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"forms-input-budget-builder","selector":"[data-core-bridge=\"forms-input-budget-builder\"]","mode":"number","key":"ArrowUp"};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("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 step=Number(workflowBridgeControl.step)||1;const min=workflowBridgeControl.min===''?-Infinity:Number(workflowBridgeControl.min);const max=workflowBridgeControl.max===''?Infinity:Number(workflowBridgeControl.max);let next=Math.min(max,Math.max(min,(Number(workflowBridgeControl.value)||0)+step));if(next===Number(workflowBridgeControl.value))next=Math.max(min,Number(workflowBridgeControl.value)-step);workflowBridgeControl.value=String(next);workflowBridgeControl.dispatchEvent(new Event('input',{bubbles:true}));workflowBridgeControl.dispatchEvent(new Event('change',{bubbles:true}));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?'Course selection plan round 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('Course Enrollment Round has 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