<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Reply controls · three approaches</title>
<style>
*{box-sizing:border-box}body{margin:0;background:#f3f2ee;color:#252a28;font:15px system-ui,sans-serif}main{max-width:1320px;margin:auto;padding:36px 24px}h1{font-size:32px;letter-spacing:-1px;margin:8px 0}p{line-height:1.5;color:#59635f}.eyebrow{font-size:12px;letter-spacing:2px;text-transform:uppercase;color:#46725f}.controls{display:flex;gap:16px;flex-wrap:wrap;align-items:center;padding:16px 0 24px}button,select{font:inherit;cursor:pointer;border:1px solid #bac5be;border-radius:8px;background:white;padding:10px 14px;color:inherit}button:focus-visible,select:focus-visible,textarea:focus-visible{outline:3px solid #4a8872;outline-offset:2px}.grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:28px}.label{display:flex;align-items:center;gap:10px}.letter{background:#dce7df;color:#315443;border-radius:50%;padding:7px 12px}h2{font-size:18px}.description{min-height:46px;font-size:14px}.phone{height:640px;border:7px solid #303a35;border-radius:32px;overflow:hidden;background:#fafbf9;display:flex;flex-direction:column;box-shadow:0 14px 30px #20352816}.status{padding:10px 18px 5px;display:flex;justify-content:space-between;font-size:12px;font-weight:650;background:#edf1ec}.browser{padding:8px 14px;background:#edf1ec;border-bottom:1px solid #d8e0d9;font-size:12px;color:#607267;text-align:center}.viewport{flex:1;min-height:0;position:relative;display:flex;flex-direction:column}.scroll{overflow:auto;flex:1;min-height:0;padding:16px}.brand{font-size:20px;font-weight:750;color:#315443;border-bottom:1px solid #dde3db;padding-bottom:12px}.context{padding:18px 0;color:#536159;line-height:1.5}.context h3{color:#243f31;margin:0 0 8px;font-size:18px}.context small{font-size:11px}.card{border:1px solid #d8e0d8;border-radius:12px;background:white;padding:12px;position:relative}.actions{display:flex;gap:8px;padding:8px 0;background:white;z-index:2}.post{background:#315f49;color:white;flex:1;border-color:#315f49}.more{font-size:19px;padding:6px 14px}textarea{font:15px/1.65 system-ui;width:100%;height:330px;resize:none;padding:12px;border:1px solid #ccd6cd;border-radius:8px;color:#304137;background:#fcfdfb;display:block}.tail{height:85px;padding-top:16px;font-size:12px;color:#748178}.dock{flex-shrink:0;padding:4px 14px;background:white;border-top:1px solid #d2dcd3}.keyboard{background:#d1d5d9;padding:9px 5px 14px;flex-shrink:0}.keyboard[hidden]{display:none}.keys{display:flex;justify-content:center;gap:4px;margin:5px 0}.key{background:#fafafa;border-radius:4px;box-shadow:0 1px 1px #7777;flex:1;text-align:center;padding:7px 0;font-size:14px}.key.space{flex:5}.keyboard footer{height:5px;width:110px;background:#343b38;border-radius:4px;margin:16px auto 0}.c .card{position:sticky;top:0}.c textarea{height:220px}.phone.landscape{height:410px;border-radius:24px}.phone.landscape .keyboard .keys{margin:2px 0}.phone.landscape .key{padding:2px 0}.phone.landscape .keyboard{padding:3px}.phone.landscape .keyboard footer{margin:5px auto 0}.phone.landscape .status{padding:4px 18px}.phone.landscape .browser{padding:3px}.result{font-size:13px;color:#315f49;margin:0}.note{font-size:13px;margin-top:24px;max-width:850px}.menu{padding:8px;background:#edf3ee;border-radius:6px}.menu[hidden]{display:none}.menu button{display:block;width:100%;margin:4px 0;text-align:left}.error{color:#9a342e;font-size:13px;margin:8px 0}.error[hidden]{display:none}@media(max-width:1000px){.grid{grid-template-columns:1fr;max-width:420px;margin:auto}.description{min-height:0}main{padding:24px 16px}}
</style>
<main><div class="eyebrow">Zenmemes · Step 1 exploration</div><h1>A reply, within reach.</h1><p>Try the same draft in three layouts. Scroll inside each phone to compare where Post goes.</p>
<div class="controls"><label><input type="checkbox" id="keyboard" checked> Simulated keyboard</label><label><input type="checkbox" id="landscape"> Reduced-height / landscape simulation</label><label>Entry <select id="entry"><option value="inline">Inline reply</option><option value="dedicated">Dedicated reply page</option></select></label><button id="long">Load long draft</button><button id="reset">Reset</button></div>
<div class="grid" id="grid"></div><p class="note">Concept mockups with a simulated keyboard, not the application or an iPhone browser test. The reduced-height mode illustrates limited space; it does not reproduce device rotation. Post simulates a retryable failure on its first press, then success. Drafts stay local to this page.</p></main>
<script>
const shortDraft='Thank you for sharing this.\n\nI think the most useful change is making it easier to reply while reading the conversation.';
const longDraft=Array.from({length:10},(_,i)=>`${i+1}. A little more context makes this a longer reply. I want to keep writing without losing the conversation or having to hunt for Post.`).join('\n\n');
const options=[['a','Above the editor','The action row scrolls with the page. Simple, but it can leave the visible area.'],['b','At the visible edge','The action row stays above the simulated keyboard while editing.'],['c','A persistent editor header','The header stays with the editor. Scroll the draft inside the writing area.']];
for(const [id,title,description] of options){
const section=document.createElement('section');section.innerHTML=`<div class="label"><span class="letter">${id.toUpperCase()}</span><h2>${title}</h2></div><p class="description">${description}</p><div class="phone ${id}"><div class="status"><span>9:41</span><span>● ▰</span></div><div class="browser">zenmemes.com</div><div class="viewport"><div class="scroll"><div class="brand">Zenmemes</div><div class="context"><small>GENERAL · A MOMENT AGO</small><h3>A quieter place to write</h3><span class="context-copy">What would make it easier to join the conversation from your phone?</span></div><form class="card"><div class="actions"><button class="post" type="submit">Post reply</button><button type="button" class="more" aria-label="Reply actions" aria-expanded="false">⋯</button></div><div class="menu" hidden><button type="button" class="clear">Clear fields</button><button type="button" class="save">Save reply to Outbox</button></div><textarea aria-label="Option ${id.toUpperCase()} reply draft" inputmode="none"></textarea><p class="error" role="alert" hidden>Couldn’t post. Your draft is still here. Try Post reply again.</p><p class="result" role="status"></p></form><div class="tail">End of conversation</div></div><div class="dock" hidden></div></div><div class="keyboard" aria-hidden="true"><div class="keys">${'qwertyuiop'.split('').map(k=>`<span class="key">${k}</span>`).join('')}</div><div class="keys">${'asdfghjkl'.split('').map(k=>`<span class="key">${k}</span>`).join('')}</div><div class="keys">${'⇧zxcvbnm⌫'.split('').map(k=>`<span class="key">${k}</span>`).join('')}</div><div class="keys"><span class="key">123</span><span class="key space">space</span><span class="key">return</span></div><footer></footer></div></div>`;
document.querySelector('#grid').append(section);
const form=section.querySelector('form'),ta=section.querySelector('textarea'),actions=section.querySelector('.actions'),dock=section.querySelector('.dock');ta.value=shortDraft;
if(id==='b'){form.id='reply-b';actions.querySelector('.post').setAttribute('form',form.id)}
section.querySelector('.more').onclick=e=>{const menu=section.querySelector('.menu');menu.hidden=!menu.hidden;e.currentTarget.setAttribute('aria-expanded',String(!menu.hidden))};
section.querySelector('.clear').onclick=()=>{ta.value='';ta.focus()};section.querySelector('.save').onclick=()=>{section.querySelector('.result').textContent='Saved in this mockup.'};
let attempt=0;form.onsubmit=e=>{e.preventDefault();const error=section.querySelector('.error'),result=section.querySelector('.result');if(!ta.value.trim()){error.textContent='Write a reply before posting.';error.hidden=false;return}attempt++;error.hidden=attempt%2===0;error.textContent='Couldn’t post. Your draft is still here. Try Post reply again.';result.textContent=attempt%2===0?'Reply posted in this mockup.':''};
section.update=()=>{const keyboard=document.querySelector('#keyboard').checked;section.querySelector('.keyboard').hidden=!keyboard;section.querySelector('.phone').classList.toggle('landscape',document.querySelector('#landscape').checked);if(id==='b'){dock.hidden=!keyboard;if(keyboard)dock.append(actions);else form.append(actions)}section.querySelector('.context-copy').textContent=document.querySelector('#entry').value==='dedicated'?'Replying to: What would make it easier to join the conversation from your phone?':'What would make it easier to join the conversation from your phone?'};
section.reset=()=>{ta.value=shortDraft;attempt=0;section.querySelector('.error').hidden=true;section.querySelector('.result').textContent='';section.querySelector('.menu').hidden=true;section.querySelector('.more').setAttribute('aria-expanded','false');section.querySelector('.scroll').scrollTop=0;ta.scrollTop=0};
}
const sections=[...document.querySelectorAll('.grid>section')];const update=()=>sections.forEach(s=>s.update());document.querySelectorAll('.controls input,.controls select').forEach(el=>el.onchange=update);document.querySelector('#long').onclick=()=>document.querySelectorAll('textarea').forEach(t=>t.value=longDraft);document.querySelector('#reset').onclick=()=>{sections.forEach(s=>s.reset());update()};update();
</script></html>