Mini Apps and Mini Games

Portable Team Ritual Calculator

Create a portable calculator in the team ritual scenario: includes real content, actionable controls, clear state feedback, and responsive layouts across sizes.

Mini Apps and Mini GamesPortable calculatorHTMLCSSJavaScript
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>Portable Team Ritual Calculator</title>
  <style>
    :root { --ink:#17241d; --paper:#f3f0e7; --accent:#af4f45; --secondary:#9eb49f; --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:22px;border:1px solid var(--line);background:color-mix(in srgb,#fff 58%,transparent)}.stack{display:grid;gap:15px}.row{display:flex;flex-wrap:wrap;gap:10px;align-items:center}.action{min-height:44px;padding:10px 17px;border:1px solid var(--ink);border-radius:999px;background:transparent}.action.primary,.action.is-active{color:var(--paper);background:var(--accent)}.muted{opacity:.68}.status{min-height:24px;margin-top:15px;color:var(--accent);font-weight:800}.metric{font-size:clamp(30px,6vw,58px);font-weight:900}.meter{height:9px;overflow:hidden;border-radius:999px;background:color-mix(in srgb,var(--ink) 12%,transparent)}.meter>i{display:block;height:100%;background:var(--accent)}.chip{padding:6px 9px;border:1px solid var(--line);border-radius:999px;font-size:12px}
    .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}
    .calc-workbench{display:grid;grid-template-columns:minmax(280px,520px) minmax(220px,.7fr);gap:18px;justify-content:center}.mini{padding:22px;border:1px solid var(--line);border-radius:24px;background:var(--ink);color:var(--paper)}.calculator output{display:block;min-height:90px;padding:22px;text-align:right;font:800 clamp(34px,8vw,62px)/1 ui-monospace,monospace}.calc-keys{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}.calc-keys button{min-height:58px;border:1px solid rgba(255,255,255,.16);border-radius:14px;color:inherit;background:rgba(255,255,255,.08);font-size:20px}.calculator>.action{width:100%;margin-top:10px;color:inherit;border-color:rgba(255,255,255,.3)}.calc-ledger{padding:24px;border-block:3px double var(--accent)}.calc-ledger h2{margin:.5em 0}.calc-ledger ul{display:grid;gap:7px;padding-left:20px}.calc-ledger p{line-height:1.7}@media(max-width:720px){.calc-workbench{grid-template-columns:1fr}.calc-ledger{order:-1}}.workflow-compare{display:grid;grid-template-columns:minmax(230px,.55fr) minmax(0,1.45fr);gap:18px}.compare-stage{display:grid;gap:12px;min-width:0}.compare-stage>header{display:flex;justify-content:space-between;gap:16px;align-items:end}.compare-stage h2{margin:.2em 0}.compare-core{--compare-split:50%;min-width:0;padding:14px;clip-path:inset(0 calc(100% - var(--compare-split)) 0 0);outline:1px dashed var(--accent);outline-offset:-8px;transition:clip-path .25s,filter .25s}.compare-core[data-compare-channel="B"]{filter:hue-rotate(32deg) saturate(1.15)}.compare-controls{display:grid;align-content:start;gap:16px;padding:20px;border:1px solid var(--line);border-radius:24px 4px 24px 4px;background:var(--paper)}.compare-controls fieldset,.compare-controls>label{display:grid;gap:8px}.compare-controls input[type="range"]{width:100%}#workflowCompareShelf{display:grid;gap:6px;padding:0;margin:0;list-style:none}#workflowCompareShelf li{display:grid;grid-template-columns:auto 1fr auto;gap:8px;padding:9px;border-top:1px solid var(--line);font-size:12px}@media(max-width:900px){.workflow-compare{grid-template-columns:1fr}.compare-stage{order:-1}.compare-core{clip-path:none;border-left:8px solid var(--accent)}}
  </style>
</head>
<body data-aesthetic="paper" data-composition="gallery-frame">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">paper / portable calculator / INTERMEDIATE</span><h1>Portable Team Ritual Calculator</h1><p class="intro">Create a portable calculator in the team ritual scenario: includes real content, actionable controls, clear state feedback, and responsive layouts across sizes.</p></div><span class="scenario">Team Ritual</span></header>
    <figure class="composition-gallery"><section class="demo" aria-label="Team ritual portable calculator interactive area"><div class="workflow-compare"><form id="workflowCompareControls" class="compare-controls"><fieldset><legend>Reference Channel</legend><label><input type="radio" name="workflowChannel" value="A" checked>A · Icebreaker Round</label><label><input type="radio" name="workflowChannel" value="B">B · Collaborative Round</label></fieldset><label>Team score weighting<input id="workflowCompareWeight" type="range" min="10" max="90" value="50"><output id="workflowCompareWeightValue">50 pt</output></label><label><input id="workflowCompareFreeze" type="checkbox">Freeze current version</label><button id="workflowCompareCapture" class="action primary" type="button">Sample and record results</button><ol id="workflowCompareShelf" aria-label="Version Sampling Record"></ol></form><section class="compare-stage"><header><span class="eyebrow">Team ritual COMPARE</span><h2>Team Side-by-Side Dual-Version Comparison</h2><output id="workflowCompareLive">Version A waiting for sampling</output></header><section id="workflowCore" class="workflow-core compare-core" data-compare-channel="A" style="--compare-split:50%"><!-- 11DZ_CORE_START:mini-apps-games-calculator-pad --><div class="calc-workbench"><div class="mini calculator"><output id="calcDisplay" aria-live="polite">0</output><div class="calc-keys"><button type="button" data-key="7" data-core-bridge="mini-apps-games-calculator-pad">7</button><button type="button" data-key="8">8</button><button type="button" data-key="9">9</button><button type="button" data-key="÷">÷</button><button type="button" data-key="4">4</button><button type="button" data-key="5">5</button><button type="button" data-key="6">6</button><button type="button" data-key="×">×</button><button type="button" data-key="1">1</button><button type="button" data-key="2">2</button><button type="button" data-key="3">3</button><button type="button" data-key="−">−</button><button type="button" data-key="0">0</button><button type="button" data-key=".">.</button><button type="button" data-key="=">=</button><button type="button" data-key="+">+</button></div><button id="calcClear" class="action" type="button">Clear</button></div><aside class="calc-ledger"><span class="eyebrow">Team Ritual MEMO</span><h2>Team Ritual Calculation Notes</h2><ul><li>Team Ritual Collaboration</li><li>Team Ritual Progress</li><li>Team ritual reminder</li><li>Team ritual favorites</li><li>Team ritual overview</li><li>Team Ritual Plan</li></ul><p>The number keys, operators, and equals sign are handled by an explicit state machine.</p></aside></div><!-- 11DZ_CORE_END --></section></section></div><p id="status" class="status" role="status" aria-live="polite"></p></section><figcaption class="gallery-caption"><strong>Team Ritual / GALLERY 03</strong></figcaption></figure>
  </main>
  <script>
    'use strict';
    const statusOutput = document.querySelector('#status');
    const announce = message => { statusOutput.textContent = message; };
    /* 11DZ_CORE_SCRIPT_START:mini-apps-games-calculator-pad */
let current='0';let accumulator=null;let pendingOperator=null;let replaceCurrent=false;const display=document.querySelector('#calcDisplay');const calculator=document.querySelector('.calculator');const operations={'+':(left,right)=>left+right,'−':(left,right)=>left-right,'×':(left,right)=>left*right,'÷':(left,right)=>right===0?NaN:left/right};function renderCalculator(){display.textContent=current;}function resetCalculator(){current='0';accumulator=null;pendingOperator=null;replaceCurrent=false;renderCalculator();}function calculatePending(){if(pendingOperator===null||accumulator===null)return Number(current);const result=operations[pendingOperator](accumulator,Number(current));if(!Number.isFinite(result)){current='Error';accumulator=null;pendingOperator=null;replaceCurrent=true;return null;}current=String(Number(result.toFixed(10)));accumulator=Number(current);return accumulator;}function pressCalculatorKey(key){if(/^\d$/.test(key)){if(current==='Error'||replaceCurrent){current=key;replaceCurrent=false;}else if(current==='0')current=key;else current+=key;}else if(key==='.'){if(current==='Error'||replaceCurrent){current='0.';replaceCurrent=false;}else if(!current.includes('.'))current+='.';}else if(key in operations){if(current==='Error')resetCalculator();if(pendingOperator!==null&&!replaceCurrent)calculatePending();accumulator=Number(current);pendingOperator=key;replaceCurrent=true;}else if(key==='='){if(pendingOperator!==null&&calculatePending()!==null){pendingOperator=null;replaceCurrent=true;}}renderCalculator();announce(current==='Error'?'Unable to complete the calculation':'Calculation Result '+current);}document.querySelectorAll('[data-key]').forEach(button=>button.addEventListener('click',()=>pressCalculatorKey(button.dataset.key)));document.querySelector('#calcClear').addEventListener('click',()=>{resetCalculator();announce('Cleared');});document.addEventListener('keydown',event=>{if(!calculator.contains(document.activeElement))return;const keyboardMap={Enter:'=',Escape:'Clear','+':'+','-':'−','*':'×','/':'÷'};const key=keyboardMap[event.key]||event.key;if(key==='Clear'){event.preventDefault();resetCalculator();announce('Cleared');return;}if(/^\d$/.test(key)||['.','=','+','−','×','÷'].includes(key)){event.preventDefault();pressCalculatorKey(key);}});
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"mini-apps-games-calculator-pad","selector":"[data-core-bridge=\"mini-apps-games-calculator-pad\"]","mode":"press","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.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 workflowCompareCore=document.querySelector('#workflowCore');const workflowCompareWeight=document.querySelector('#workflowCompareWeight');const workflowCompareState={channel:'A',weight:50,frozen:false,snapshots:[]};function workflowCompareFingerprint(){const controls=[...workflowCompareCore.querySelectorAll('input,select,textarea')];const outputs=[...workflowCompareCore.querySelectorAll('output,[role="status"],strong')].map(node=>node.textContent.trim()).filter(Boolean);return {controlValues:controls.map(control=>control.type==='checkbox'||control.type==='radio'?control.checked:control.value),summary:outputs.slice(0,4).join(' / '),nodes:workflowCompareCore.querySelectorAll('*').length};}function workflowCompareDrive(){workflowCompareCore.dataset.compareChannel=workflowCompareState.channel;workflowCompareCore.style.setProperty('--compare-split',workflowCompareState.weight+'%');document.querySelector('#workflowCompareWeightValue').textContent=workflowCompareState.weight+' pt';document.querySelector('#workflowCompareLive').textContent=workflowCompareState.channel+' Version · '+workflowCompareState.weight+' pt'+(workflowCompareState.frozen?' · Frozen':'');announce('Team Comparison Under Review '+workflowCompareState.channel+' Version');}function workflowCompareCapture(source){const bridge=workflowBridgeActivate();const snapshot={...workflowCompareFingerprint(),channel:workflowCompareState.channel,weight:workflowCompareState.weight,source,bridge:bridge.summary};workflowCompareState.snapshots.push(snapshot);const item=document.createElement('li');item.innerHTML='<b>'+snapshot.channel+'</b><span>'+(snapshot.summary||snapshot.bridge)+'</span><small>'+snapshot.weight+' pt · '+snapshot.bridge+'</small>';document.querySelector('#workflowCompareShelf').prepend(item);announce('sampled '+snapshot.channel+' Version and record results · '+bridge.summary);}document.querySelectorAll('[name="workflowChannel"]').forEach(input=>input.addEventListener('change',()=>{workflowCompareState.channel=input.value;workflowCompareDrive();}));workflowCompareWeight.addEventListener('input',()=>{workflowCompareState.weight=Number(workflowCompareWeight.value);workflowCompareDrive();});document.querySelector('#workflowCompareFreeze').addEventListener('change',event=>{workflowCompareState.frozen=event.currentTarget.checked;workflowCompareDrive();});document.querySelector('#workflowCompareCapture').addEventListener('click',()=>workflowCompareCapture('Button Sampling'));workflowCompareCore.addEventListener('dblclick',()=>workflowCompareCapture('Main view double-click'));workflowCompareDrive();
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