Ada Form — small interactions, longer attention
Build an original minimal portfolio for a fictional interaction designer, Ada Form. The portfolio is about the moments around a task: arriving, pausing, leaving and returning. It should be quieter than a product marketing site and more concrete than a list of abstract design values. The work consists of three independent interaction studies with original interface artwork and complete case essays. Do not invent clients, employment, awards, research results or shipped-product claims. The designer and all project situations are fictional. Explain that on the About page and retain the independent-study language throughout the cases.
The selected research reference is nelson.co, found in the DesEngs minimum directory. Its direct personal introduction and simple separation of work from explorations demonstrate that a portfolio can remain useful without a marketing funnel. Borrow that restraint, not its identity, employer information, projects, imagery or exact layout. Ada uses a left identity rail and a separate wider stream of interface studies. The first screen is a small introduction followed by real work. It is not a giant hero over a dashboard screenshot, and it has no call-to-action button promising a service.
Deliverable
Create five complete pages: index.html, return.html, soft-close.html, nearby.html and about.html. Each study has a stable relative URL and can be loaded directly. Use ordinary static HTML, one local CSS file, one short local script, locally hosted Geist and original SVG/WebP artwork. Include the font license and reference credits. Every project link works, next-project navigation cycles through the three cases, and the footer Collection link leads two directory levels upward. Do not add a client-side router, authentication, storage system, analytics or external image service.
Composition and typography
The desktop shell is approximately 1090 pixels wide, centered, with 30-pixel horizontal padding and 70 pixels above the content. Inside, use a 190-pixel identity column, an 85-pixel gap and a flexible work column. The identity rail has Ada Form at 17 pixels, Interaction designer below at 14 pixels, and two vertically arranged links: Studies and About. The rail may remain sticky at a modest top offset while the work scrolls. It must not become a full-height colored sidebar or contain a large logo. Its purpose is orientation, not branding spectacle.
Use white as the page surface and #282b28 for body text. Secondary copy is #616760. Use Geist at 16 pixels with a 1.65 line height. The introduction heading is around 25 pixels, regular weight, with a 1.45 line height. Case titles can reach 30 pixels, but do not use giant uppercase typography. Section headings are 18 pixels. Captions and metadata remain 14 pixels. The design should feel precise through alignment and spacing rather than through decorative borders. On phones under about 750 pixels, stack the identity above the work and make the two navigation links horizontal.
The homepage introduction reads Small interactions. Longer attention. Follow with a short explanation of the three original studies. Below it, show a vertical sequence of work entries. Each has a title and description on the left, a year and arrow on the right, and an original wide interface illustration below. There are no cards around the entries. The image itself provides a pale field that distinguishes the study. Leave about 43 pixels between entries. Every image links to its case, and the accessible name identifies which study will open.
Original study content
Return asks what it means to resume interrupted work. The problem is that a saved form preserves values but may lose the reason someone paused. The proposal is a return note attached to the relevant section, with a Continue here action. The case must distinguish a timestamp from an intention and acknowledge that merely reopening a section does not resolve the unfinished question. The prototype confirmation returns the person to Delivery details and reminds them to check the date. This is local demonstration text, not a real form submission.
Soft close asks what closing a document should mean. The proposal separates saved from finished and lets a person leave an optional short note. It does not require a status choice every time they leave. The case must discuss how an exit prompt can become annoying and why the pattern should appear only when appropriate. Its local action is Leave document, followed by a precise confirmation that the draft is saved but not approved. Do not implement a browser before-unload trap or actual navigation interception; the demonstration illustrates the wording in place.
Nearby studies a contextual action placed near the selected passage rather than in a distant toolbar. The action is Keep this passage, and the result names the source and preserves context. Explain why a saved excerpt without surrounding information can mislead. The case should discuss discovery and occlusion as tradeoffs of contextual controls. The visual sketch uses an ordinary surface and a single action, not a crowded editor. The local prototype only displays the confirmation and a reset option; it does not collect documents or access a real reading library.
Case structure
Every case starts with independent-study metadata, title, subtitle and a short lead. A large original interface figure follows with a useful caption. The essay contains The question, The interaction, A detail that matters, The tradeoff and What remains open. Preserve the exact original narratives supplied below. The text measure is about 590 pixels, with enough space between sections to support reading. Do not replace the prose with bullet-point feature claims or invented outcome metrics. A reader should learn why the control behaves as it does and which uncertainty remains.
Place Try the moment between the design detail and tradeoff sections. It has a thin top and bottom rule, a short explanation, one action button and Reset. The action updates a polite status region and disables itself to avoid suggesting repeated work. Reset restores the initial text and re-enables the action. The result is a local simulated state change. Keep its meaning explicit and do not show a network spinner, fake progress bar or claim that a remote document was changed. Both controls must work with keyboard and touch input.
Artwork and material
Use three original interface drawings, each at 1200 by 720. Return has a warm gray field, Soft close a pale blue-gray field and Nearby a muted green-gray field. Inside is a quiet white document surface with a title, separator, question, specific contextual sentence and one small action. Typography is readable in the large figure. The image is a visual sketch, while the live confirmation sits below as HTML. Do not use reference screenshots or a decorative laptop frame. Keep source SVG and optimized WebP files in the package, with a hero.webp preview copied from Return for the library.
About and honesty
The About page introduces Ada as a fictional designer and explains the interest in continuity. It names three habits: describe the state, design exits and recovery, and keep the language as precise as the control. It explains which parts of the cases are functional and that no documents are saved or collaborators contacted. Use [email protected] as a plain example address with a note to replace it when adapting the template. No contact form, newsletter subscription, mail sending or false availability claim is needed.
Accessibility and implementation
Use a single h1 on every page, ordinary heading order, semantic navigation and figures, a skip link and visible focus outlines. The status region uses role=status. Buttons have descriptive text and native disabled behavior. Body copy is never reduced below a readable size to make the layout fit. At mobile widths, the identity rail returns to normal flow, the case title reduces to 27 pixels and the result area has enough height for wrapped confirmation text. No horizontal document overflow is acceptable. Respect reduced-motion preference by removing image transitions.
Keep the script scoped to each data-demo region. Use textContent for all result changes. There is no reason to parse user HTML or retain state across visits. The build source below is a precise reference for the shell, data, artwork and behavior. It is included so a reconstruction preserves the actual interaction and original content, not merely the visual idea. A suitable implementation can reorganize the source while preserving the semantics, routes and outputs. Do not import a general UI framework for this small portfolio.
Verification
Inspect the homepage and a case on desktop. At an actual 390-pixel viewport, visit all five routes and measure document width, not only the screenshot dimensions. Check the identity navigation, image sizing, section text and footer. Click the case action and verify the exact confirmation, disabled state and reset behavior. Follow next-project and all-studies links. Check every local link and font/image file. Report actual evidence and distinguish a working local demonstration from a real product action. Do not claim research validation, Lighthouse scores or deployment unless those were independently completed.
Exact content and implementation reference
The following original data and source form the complete reconstruction reference. The project narratives are part of the content brief. The source specifies the exact routes, art geometry, responsive rules and state transitions; it is not an instruction to add unrelated infrastructure.
data.mjs
export const studies=[{id:'return',title:'Return',subtitle:'A way back into interrupted work.',year:'2026',color:'#edece6',lead:'An interaction study about resuming a task without reconstructing the last ten minutes.',question:'Where was I?',context:'A long form can be technically saved while still feeling lost. The fields remain, but the person no longer remembers which part was uncertain or what they planned to do next. Return explores a small marker for that moment of interruption.',decision:'The interface lets someone leave a short return note attached to a section. It is not another task or reminder. When they reopen the document, the note appears with the relevant section and a direct Continue here action. The rest of the document remains available, but it does not compete for attention.',detail:'The note is written in the first person: “Check the delivery date before continuing.” The wording preserves the reason for pausing. A generic Last edited label would preserve a timestamp but lose the intention. The control is close to the section heading so it can be found without searching a global menu.',tradeoff:'A return note can become stale. The study clears the marker only when the person explicitly dismisses it, rather than assuming that opening the section means the question is resolved. In a real product, this behavior would need testing across several days of interrupted work.',reflection:'I would evaluate whether the marker helps people resume accurately, not whether it makes them finish faster. Some pauses are useful. A good interface should preserve the pause without turning it into a warning.',action:'Continue here',result:'You are back at Delivery details. Check the date, then continue.'},
{id:'soft-close',title:'Soft close',subtitle:'Leaving without losing the thread.',year:'2025',color:'#e5e9ed',lead:'A study of the moment between finishing an edit and leaving a document.',question:'What should closing mean?',context:'A close button is usually treated as a simple exit. In a collaborative document, leaving may mean the work is ready, unfinished, or waiting for someone else. Soft close examines how to ask for the right amount of context without turning every departure into a form.',decision:'The prototype offers a short optional exit note and a clear statement of what has been saved. The default action remains Leave document. It does not require a status selection. A person can add “The introduction is ready; the examples need another pass” when that distinction matters.',detail:'The confirmation separates local action from social implication. It says the draft was saved, not that the work was approved. The note sits beside the latest revision for the next visit. A small undo link returns to the document while preserving the note, so an accidental exit is recoverable.',tradeoff:'An exit prompt can become annoying if it appears too often. I would show this pattern only after meaningful edits or when a person chooses to leave a note. The study is not an argument for intercepting every navigation event with a modal.',reflection:'The key design distinction is between saved and finished. A system can know the former and should be careful about inferring the latter. The interaction language should preserve that difference.',action:'Leave document',result:'Draft saved. Your note stays with the revision; leaving does not mark it approved.'},
{id:'nearby',title:'Nearby',subtitle:'Finding an action where the question begins.',year:'2025',color:'#e7eadf',lead:'A small study of contextual navigation inside a personal document collection.',question:'Can an action stay near its meaning?',context:'A document library often places every command in the same toolbar, even when the useful action depends on the item being read. Nearby explores a restrained contextual action that appears beside the relevant sentence rather than in a distant control strip.',decision:'The selected excerpt receives one action: Keep this passage. A secondary disclosure explains where it will go. The prototype does not expose a dozen formatting and sharing options at once. It keeps the action connected to the reason the person selected the text.',detail:'The saved passage includes a link back to its source and a few surrounding words. A clipped sentence without context can be misleading. The confirmation therefore names the source and offers View saved passage, instead of a generic success toast that disappears before it can be read.',tradeoff:'Contextual controls can be difficult to discover and can cover the text they act upon. I placed the action below the excerpt in the reading flow and retained a keyboard-accessible button. This sacrifices some compactness for predictability.',reflection:'The next question is whether people recognize the relationship between the excerpt and its source after returning later. The study does not claim a measured improvement; it provides a concrete interaction to investigate.',action:'Keep this passage',result:'Passage kept with its source: Notes on ordinary attention. The surrounding context remains attached.'}];
site.css
@font-face{font-family:Geist;src:url('assets/geist-variable.woff2') format('woff2');font-weight:100 900;font-display:swap}*{box-sizing:border-box}body{margin:0;color:#282b28;background:#fff;font:16px/1.65 Geist,Arial,sans-serif}a{color:inherit;text-underline-offset:4px}button,input{font:inherit}button{cursor:pointer}h1,h2,p{margin:0}h1,h2{font-weight:450}h1{font-size:25px;line-height:1.45}h2{font-size:18px;margin-bottom:15px}a:focus-visible,button:focus-visible{outline:2px solid #596c7b;outline-offset:5px}.layout{max-width:1090px;margin:auto;padding:70px 30px;display:grid;grid-template-columns:190px minmax(0,1fr);gap:85px}.identity{font-size:14px;position:sticky;top:60px;align-self:start}.identity .name{font-size:17px;text-decoration:none}.identity p{color:#616760;margin-top:6px}.identity nav{display:flex;flex-direction:column;gap:13px;margin-top:40px}.identity nav a{text-decoration:none}.identity nav a:hover{text-decoration:underline}.intro{max-width:570px;margin-bottom:55px}.intro p{margin-top:20px;color:#616760}.study-row{margin-bottom:43px}.study-row>a{display:flex;justify-content:space-between;text-decoration:none;align-items:baseline;gap:20px}.study-row h2{font-size:18px;margin:0}.study-row p,.study-row time{font-size:14px;color:#616760}.study-row p{margin-top:5px}.study-row img{display:block;width:100%;height:auto;margin-top:18px;transition:filter .2s}.study-row a:hover img{filter:contrast(1.03)}.case-head{margin-bottom:30px}.case-head .meta{font-size:14px;color:#616760;margin-bottom:18px}.case-head h1{font-size:30px;margin-bottom:18px}.case-head>p:last-child{font-size:18px}.figure{margin:30px 0 40px}.figure img{display:block;width:100%;height:auto}.figure figcaption{font-size:14px;color:#616760;margin-top:12px}.prose{max-width:590px}.prose section{margin-bottom:35px}.try{padding:26px 0;border-top:1px solid #d8dcd7;border-bottom:1px solid #d8dcd7;margin:40px 0}.try>p{font-size:14px;color:#616760;margin-bottom:20px}.try button{border:1px solid #c2c9c0;border-radius:5px;background:#f3f5f1;padding:10px 17px;color:#282b28}.try button:hover{background:#e8ece5}.try .reset{border:0;background:none;text-decoration:underline;padding-left:0;margin-left:20px;font-size:14px}.result{min-height:80px;margin-top:20px;font-size:16px}.next{border-top:1px solid #d8dcd7;padding-top:24px;display:flex;justify-content:space-between;gap:24px}.about p{margin-bottom:25px}.about h2{margin-top:38px}.about ul{padding-left:20px}.about li{margin-bottom:12px}footer{font-size:14px;color:#616760;margin-top:65px;display:flex;gap:22px;flex-wrap:wrap}.skip{position:absolute;top:-90px;padding:12px;background:white}.skip:focus{top:10px}@media(max-width:750px){.layout{display:block;padding:30px 22px}.identity{position:static;margin-bottom:45px}.identity nav{flex-direction:row;margin-top:22px;gap:25px}.intro{margin-bottom:35px}.case-head h1{font-size:27px}.study-row{margin-bottom:34px}.try{padding:22px 0}.try button{max-width:100%}.next{font-size:14px}.result{min-height:100px}}@media(prefers-reduced-motion:reduce){*{transition:none!important}}
site.js
(()=>{document.querySelectorAll('[data-demo]').forEach(demo=>{const result=demo.querySelector('[role=status]');demo.querySelector('[data-act]').addEventListener('click',()=>{result.textContent=demo.dataset.result;demo.querySelector('[data-act]').disabled=true;});demo.querySelector('[data-reset]').addEventListener('click',()=>{result.textContent='Ready to try. This is a local interaction study.';demo.querySelector('[data-act]').disabled=false;});});})();
build.mjs
import fs from'node:fs';import sharp from'sharp';import{studies}from'./data.mjs';const out='public/demos/ada-form',src='scripts/ada-form';const e=s=>s.replaceAll('&','&').replaceAll('"','"');function art(s){return`<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="720"><rect width="1200" height="720" fill="${s.color}"/><rect x="245" y="120" width="710" height="480" rx="10" fill="#fff"/><g font-family="Arial,sans-serif" fill="#30372f"><text x="290" y="190" font-size="20">${s.title} / an interaction study</text><line x1="290" y1="220" x2="910" y2="220" stroke="#d4d9d1"/><text x="290" y="290" font-size="32">${s.question}</text><text x="290" y="350" font-size="18">${s.id==='return'?'Check the delivery date before continuing.':s.id==='soft-close'?'The introduction is ready. Examples need another pass.':'A passage worth keeping, with its source.'}</text><rect x="290" y="420" width="310" height="65" rx="5" fill="#e4e9e0"/><text x="320" y="461" font-size="22">${s.action}</text><text x="290" y="550" font-size="16" fill="#64705e">Local concept / no remote action</text></g></svg>`;}function shell(title,body){return`<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${title} — Ada Form</title><meta name="description" content="Ada Form, original interaction-design studies in continuity, context and attention."><link rel="stylesheet" href="site.css"></head><body><a class="skip" href="#main">Skip to content</a><div class="layout"><header class="identity"><a class="name" href="index.html">Ada Form</a><p>Interaction designer</p><nav aria-label="Main"><a href="index.html">Studies</a><a href="about.html">About</a></nav></header><div><main id="main">${body}</main><footer><span>Independent concepts, 2025–26</span><a href="assets/CREDITS.txt">Credits</a><a href="../../">Collection ↗</a></footer></div></div><script src="site.js"></script></body></html>`;}export async function buildAdaForm(){fs.mkdirSync(`${out}/assets`,{recursive:true});for(const f of['site.css','site.js'])fs.copyFileSync(`${src}/${f}`,`${out}/${f}`);for(const s of studies){const svg=art(s);fs.writeFileSync(`${out}/assets/${s.id}.svg`,svg);await sharp(Buffer.from(svg)).webp({quality:93}).toFile(`${out}/assets/${s.id}.webp`);}fs.copyFileSync(`${out}/assets/return.webp`,`${out}/assets/hero.webp`);fs.writeFileSync(`${out}/index.html`,shell('Studies',`<section class="intro"><h1>Small interactions.<br>Longer attention.</h1><p>I explore the moments around a task: arriving, pausing, leaving, and finding a way back. Three original studies, with room for questions.</p></section>${studies.map(s=>`<article class="study-row"><a href="${s.id}.html"><div><h2>${s.title}</h2><p>${s.subtitle}</p></div><time>${s.year} ↗</time></a><a href="${s.id}.html" aria-label="View ${s.title} study"><img src="assets/${s.id}.webp" width="1200" height="720" alt="${e(s.lead)}"></a></article>`).join('')}`));studies.forEach((s,i)=>fs.writeFileSync(`${out}/${s.id}.html`,shell(s.title,`<article><header class="case-head"><p class="meta">Independent interaction study / ${s.year}</p><h1>${s.title}: ${s.subtitle}</h1><p>${s.lead}</p></header><figure class="figure"><img src="assets/${s.id}.webp" width="1200" height="720" alt="${e(s.question)}"><figcaption>Interface sketch / ${s.question}</figcaption></figure><div class="prose"><section><h2>The question</h2><p>${s.context}</p></section><section><h2>The interaction</h2><p>${s.decision}</p></section><section><h2>A detail that matters</h2><p>${s.detail}</p></section></div><section class="try" data-demo data-result="${e(s.result)}"><h2>Try the moment</h2><p>A local demonstration of the confirmation language.</p><button data-act>${s.action}</button><button class="reset" data-reset>Reset</button><div class="result" role="status">Ready to try. This is a local interaction study.</div></section><div class="prose"><section><h2>The tradeoff</h2><p>${s.tradeoff}</p></section><section><h2>What remains open</h2><p>${s.reflection}</p></section></div><nav class="next" aria-label="Next study"><a href="index.html">← All studies</a><a href="${studies[(i+1)%3].id}.html">${studies[(i+1)%3].title} →</a></nav></article>`)));fs.writeFileSync(`${out}/about.html`,shell('About',`<article class="about"><h1>Designing the edges of a task.</h1><p>Ada Form is a fictional interaction designer created for this original portfolio. The studies focus on continuity: how a person understands what has happened, what remains open and where to return.</p><p>The work begins with a small observation and turns it into a concrete interface question. It does not claim user research results, client launches or measured improvements. The prototypes are things to test, not proof that the answer is settled.</p><h2>Three habits</h2><ul><li>Describe the state before asking for another action.</li><li>Make exits and recovery part of the main flow.</li><li>Keep the language as precise as the control.</li></ul><h2>About the demonstrations</h2><p>Each case includes a local confirmation interaction with reset. It illustrates the wording and state change; it does not save documents, contact collaborators or connect to another service.</p><h2>Contact</h2><p>Use your own details when adapting this template.<br>Example address: [email protected]</p><p><a href="index.html">Return to studies →</a></p></article>`));fs.writeFileSync(`${out}/assets/CREDITS.txt`,'Ada Form: original fictional portfolio, case narratives and vector interface studies. Research reference https://nelson.co via https://desengs.com/minimum/. No reference identity, employer claims or artwork reused. Geist font license included.');const prompt=fs.readFileSync(`${src}/PROMPT.md`,'utf8');fs.writeFileSync(`${out}/PROMPT.md`,prompt);fs.writeFileSync('public/prompts/ada-form.md',prompt);return{prompt};}if(process.argv[1]?.endsWith('/ada-form/build.mjs'))await buildAdaForm();
Detailed review of the three state transitions
The Return demonstration begins in a neutral state with the action enabled. Activating Continue here changes the confirmation to a sentence that names Delivery details and the unresolved date check. The action becomes disabled because the local demonstration has already reached its result. This disabled state must remain visually legible; do not reduce the opacity of its text until it becomes unreadable. Reset is still enabled and returns the demonstration to the neutral sentence. The user can then repeat the action. This is a two-state presentation with explicit recovery, not a simulated asynchronous workflow.
The Soft close demonstration uses the same small interaction contract but different meaning. Its result explicitly says that a draft is saved and that leaving does not mark it approved. Keep that distinction intact in the button label, explanatory paragraph and result. Do not replace the text with Done, Success or All set. Those phrases remove the very uncertainty the study is examining. The case is about language at an exit, so the confirmation text is the central artifact rather than incidental feedback beneath an image.
Nearby names the saved passage's source in the result. The source title is fictional and should be kept as plain text. The interface does not need a fake link to an article that does not exist. A functioning local study can be honest about its boundary while still making the content decision concrete. The confirmation should wrap naturally on a narrow phone and remain in the reading flow. Do not use a disappearing toast for the primary result, because a reader may need time to compare it with the preceding explanation.
For every study, check that Reset changes both the text and disabled state. A test that only sees the new message could miss a permanently disabled button. Likewise, a test that only checks enabled state could miss stale confirmation text. Inspect the actual rendered state after each action. Keep the result region's minimum height large enough that the surrounding essay does not jump sharply when a longer sentence appears. On phones the region can be taller because wrapping is expected. This is a small stability measure, not an invitation to put the entire case in a fixed-height panel.
Finally, review the relation between the artwork and the live control. The artwork introduces the question and gives it a visual setting; the HTML demonstration lets the visitor inspect a single consequential response. They should not contradict each other. If a future adaptation changes the action name or result, update the SVG, caption, case narrative and data together. The exact source is included to make those dependencies visible. A portfolio feels considered when its smallest labels agree across the image, explanation and working interaction.