Interaction design masterclass

The Interaction Layer: seven principles of interaction design, each shown with a live demo

Interaction design is how a product behaves when you use it, not how it looks.

It covers things like whether you can tell your click worked, how fast the product feels, and whether you can undo a mistake. This page walks through seven principles. Each one is grounded in human computer interaction research and has a demo you can use right here, so you can try it for yourself.

Context
My own reference piece
My role
Researched, wrote and built it alone
What I built
Seven interaction design principles, each with a live demo, built by hand with no animation library
Status
Live

Every principle in one working demo

This is a real interface, built by hand with no animation library, and it uses every principle on the page. Open a pattern and it grows into a detail view you can use. Press ⌘K to open the command menu.

Interaction Layerlive reduced motion
Pick a pattern to open it, or press the command key. Use arrow keys to move, Enter to open, Esc to go back.
container transform spring physics orchestration optimistic + undo layout-diff scale-from-origin keyboard reduced-motion safe

Open a tile and it grows out of the spot where it sat, instead of a new screen replacing it. Inside, you can drag the puck and feel the spring, publish a post and undo it, or reveal extra options from the keyboard. Turn on reduced motion from the command menu and every transition becomes an instant, clear change.

Principle 01

Every action gets an answer

Feedback & system status

If you click and nothing visibly happens, the product looks broken, even if it worked.

The first job of any interaction is to confirm it happened: the press registers, progress shows, success is clear and failure explains itself. Without that, people click again. That's where double orders and duplicate messages come from, and it isn't the user's fault.

Nielsen's Heuristic #1: Visibility of system status. The system should always tell people what is going on, with feedback in a reasonable time. It's the first of Nielsen's ten usability heuristics.

Examples: the apps people call delightful are usually just very responsive. A task that checks off with a small animation, live cursors that show who else is on a shared canvas, a letter that appears the instant you type it. All of that is feedback.

Live demo: click both buttons and compare

no feedback

This button adds the item but shows nothing, so you click again to be sure.

Cart: 0

full feedback loop

Shows a pressed state, then "Adding…", then "Added ✓", and tells screen readers too. It can't be clicked again while the request runs.

Cart: 0

The left button invites extra clicks, and each one could add a duplicate. The right one makes the result clear, so you click once.

Motion lens · 01 · feedback

When pressed, the button shrinks to 0.86 of its size and back in 120ms. That's fast enough to say "got it" without slowing down the result.

Principle 02

Perceived speed matters more than measured speed

Perceived performance & latency

What people notice is how fast it feels, and you can design that separately from how fast it is.

You can't make the network faster, but you do control what people see while they wait. Show the result right away and confirm it with the server in the background (an optimistic update), and a 600ms request feels instant. Show a spinner for the same 600ms and the app feels slow.

Nielsen's response-time limits. About 0.1s feels instant. About 1s keeps someone's train of thought. About 10s is the limit for holding attention at all. Past one second, show that something is happening.
The Doherty Threshold (≈400ms). When responses stay under about 400ms, people work faster and get more done. Above that, attention drifts.

Example: sometimes the right move is to add a delay on purpose. Gmail's "Undo Send" holds your message for 5, 10, 20 or 30 seconds (you choose) before it goes, so a mistake can be taken back. The point is to spend time where it helps the person.

Live demo: add a few tasks each way and watch the wait

Both hit the same ~700ms "server." Only one makes you watch it.

    In "wait" mode, the task only shows up after the server answers, so you sit and watch. In optimistic mode it shows up the moment you press Enter, marked "saving," then confirms. It isn't faster. It just doesn't make you wait.

    Motion lens · 02 · speed

    New items fade in over 220ms, starting fast and slowing to a stop. Removals are quicker, about 150ms, so arrivals get noticed and dismissals get out of the way.

    Principle 03

    Show people what they can do

    Affordances & signifiers

    If people can't see that something is possible, they won't try it.

    Don Norman separates two ideas. An affordance is what an object lets you do. A signifier is the visible cue that tells you so. A card might be draggable (the affordance), but it's the grip dots, the cursor change and the lift on hover (the signifiers) that tell you. Most products don't need more affordances. They need clearer signifiers for the ones they have.

    Norman: affordance vs signifier. "Affordances determine what actions are possible. Signifiers communicate where the action should take place." When the cue is missing, people end up saying "I didn't know I could do that."

    Example: pull-to-refresh, invented by Loren Brichter in the Tweetie app (it earned him an Apple Design Award in 2009 and was patented in 2013), works because of its signifier. The list stretches as you pull, which tells you something will happen when you let go. Refreshing is the affordance. The stretch is how you find out about it.

    Live demo: the same draggable rows, with and without signifiers

    Show signifiers
    Both rows are draggable. Can you tell which?
    Quarterly roadmap
    Hiring plan
    Launch checklist

    With signifiers off, the rows look fixed and you can't tell they drag. Turn them on and the grip, the grab cursor and the hover lift make it obvious. What you can do didn't change. Only what you can see did.

    Motion lens · 03 · affordance

    On hover the handle lifts 5px in 120ms. The movement itself tells you it can be picked up, before you touch it.

    Principle 04

    Prefer undo to "Are you sure?"

    Forgiveness & reversibility

    A confirmation dialog slows everyone down, every time, to catch a rare mistake. Undo only costs something for the person who made the mistake.

    Confirmations feel safe, so they pile up, until people click "Yes" without reading and the dialog protects no one. It's better to act right away and offer a quick, easy way back. You get speed and safety instead of trading one for the other.

    Nielsen: user control & freedom. People need a clearly marked "emergency exit." Support undo and redo so a mistake is quick to fix, instead of guarding every action with a confirmation.

    Examples: Gmail's "Undo Send" lets you take a message back for 5 to 30 seconds, whichever you choose. The undo message that pops up after you archive or delete works the same way. So does Cmd/Ctrl-Z, the most common keyboard shortcut there is.

    Live demo: delete the same emails two ways and compare

      "Confirm" asks you a question for every deletion, including the 95% you meant. "Delete + undo" just deletes, and you only do extra work for the one you regret. Count your clicks in each mode.

      Motion lens · 04 · forgiveness

      The undo message rises 16px as it fades in over 220ms, and leaves in 160ms. That's long enough to notice and quick enough not to get in the way.

      Principle 05

      Show what most people need, and keep the rest one step away

      Progressive disclosure & density

      Some complexity can't be removed. The job is to decide who deals with it, and when.

      Put every option on screen and new users are overwhelmed. Hide everything in menus and experienced users are slowed down. Progressive disclosure means showing the few things most people need now and keeping advanced options one deliberate step away. A command palette is a good example: a search box you open with a shortcut that can run any action in the app.

      Tesler's Law: conservation of complexity. Every application has some complexity that can't be removed. Either the system handles it or the person does. Good design moves it onto the system.
      Hick's Law. The more choices there are, and the more complex they are, the longer it takes to decide. A wall of equal buttons is slower than a focused screen with everything else a search away.

      Example: the command palette started in code editors and is now common in productivity apps. One shortcut (usually ⌘K or Ctrl-K) reaches every action without any of them taking up screen space.

      Live demo: press the button or ⌘/Ctrl + K

      Project workspace

      A clean surface. Everything else is one keystroke away.

      No command run yet.

      Type to filter, ↑↓ to move, Enter to run, Esc to close. Every action is within reach, but the screen stays simple.

      Motion lens · 05 · disclosure

      The palette grows from 0.96→1 of its size while fading in over 220ms, slowing as it arrives. It grows out of its button instead of just appearing.

      Principle 06

      Let people act on the thing itself

      Direct manipulation & spatial consistency

      Let people drag the card, instead of opening a "move card" dialog and typing a position number.

      Direct manipulation means the thing you care about is on screen, you can grab it, and it changes as you move it, in a way you can reverse. When things also stay where you left them, people build a mental map of the interface instead of treating it like a form.

      Shneiderman: direct manipulation. Keep the objects people care about on screen. Use physical actions instead of typed commands. Make changes small, quick and reversible, with the effect visible right away.

      Examples: dragging a shape on a design canvas instead of typing its coordinates, dragging a card between columns on a board, reordering a list by dragging rows. This goes with spatial consistency: navigation, controls and items stay in the same place between visits, so people learn where things are.

      Live demo: drag to reorder, or use the keyboard

        Drag a row with the mouse, or select one with Tab, press Space to grab, move with ↑↓, and Space again to drop. Dragging that only works with a mouse leaves keyboard users out, so this works both ways and announces each move to screen readers.

        Motion lens · 06 · manipulation

        While you drag, the row follows the pointer 1:1 with no lag. When you let go, a spring (stiffness 300 / damping 22) carries it into place.

        Principle 07

        Support both mouse and keyboard

        Input, shortcuts & accessibility

        A first-time user with a mouse and an expert who never leaves the keyboard should both be able to reach every action.

        The mouse is easy to discover. The keyboard is fast. You don't have to pick one. Give every important action a visible button and a keyboard shortcut, and show the shortcut on the button so people learn it. This is also where interaction design and accessibility overlap: an interface you can fully use from the keyboard, with a visible focus ring, is faster for experts and usable by people who can't use a mouse at all.

        Fitts's Law. The time it takes to hit a target depends on how far away and how big it is. So make common targets big and close, and give frequent users a target with no distance at all: a keystroke.

        Examples: keyboard-first productivity tools win loyal users by making the shortcut the main way in and the mouse the backup. Every demo on this page follows the same idea. Each one works from the keyboard, announces changes to screen readers, and respects the system setting for less motion (prefers-reduced-motion).

        Live demo: use this toolbar with the mouse or the keyboard

        Click a button, or hold Alt and tap the highlighted letter while focus is in this card.

        No action yet.

        The shortcut is shown on the button, so using the mouse teaches you the keyboard shortcut. Press Tab to see the focus ring that makes all of this usable without a mouse.

        Motion lens · 07 · input

        The focus ring does not animate between fields. It jumps straight there. Animating it would leave keyboard users waiting on their own Tab key, so here the right amount of motion is none.

        Part two: the motion layer

        How motion supports the seven principles

        The seven principles cover what an action does and how you recover from it. This part covers motion: the timing, speed curves and movement that make those changes easy to follow. Every demo is built by hand with no animation library, and each one still works when the system asks for less motion (prefers-reduced-motion). You can drag them, fling them and stop them mid-move.

        Motion 01

        How the speed of a movement changes how it feels

        Physics: easing & springs

        The same move, played on three different speed curves, feels completely different: one mechanical, one smooth, one lively.

        Easing is how speed changes during an animation. Linear motion keeps a constant speed, which nothing in the real world does, so it looks mechanical. Eased motion speeds up and slows down like a real object. A spring goes further: it behaves like a weight on a spring, so it can overshoot and settle. Because it tracks its own speed, it can also be interrupted without looking broken, which matters most on a touch screen.

        Disney's 12 principles: slow in & slow out, follow-through, squash & stretch. The animators who wrote The Illusion of Life never moved anything at a constant speed. Easing and overshoot are how they showed weight and intent. Interface motion borrows the same ideas.

        Examples: iOS animates with springs rather than fixed durations, which is why a sheet you fling feels like a real object. In a work app, a button that squashes slightly when pressed and overshoots on release feels solid. The pixels are the same. Only the speed curve is different.

        Live demo: play the same move on three curves, then adjust the spring

        Linear

        cubic-bezier(0,0,1,1)

        Eased

        cubic-bezier(.2,0,0,1)

        Spring (overshoot)

        stiffness 220 · damping 18

        220 18
        Eased curve: position over time, slowing to a stop
        Spring: goes past the target line, then settles

        Watch how each puck finishes. Linear stops dead. Eased slows to a stop. The spring goes past and settles back. Stiffness is how hard the spring pulls toward its target, and damping is how quickly it calms down. Move the sliders and the graph redraws from the same code that moves the puck. Lower the damping to see more overshoot.

        The decision. For interface motion I default to a snappy spring (stiffness 300, damping 30) instead of a fixed-length animation. It can be interrupted, it adjusts to how far it travels, and the small overshoot feels responsive without looking bouncy. I keep bouncy springs (low damping) for playful, low-stakes moments.

        Reduced motion: the curves are drawn but nothing plays on a loop. The graphs still show the idea.

        Motion 02

        Keep the same object on screen as the view changes

        Continuity: shared-element transitions

        When a small item opens into a larger view, the item itself should grow into that view, not vanish while a new screen appears.

        A hard cut makes the eye find everything again. A shared-element transition keeps one object on screen through the change: the tapped tile's position, size and corner radius all animate into the detail view, so your attention stays with it. It feels like you opened something, not like a new screen loaded.

        Material "container transform" · iOS zoom continuity · Android predictive back. Google's and Apple's guidelines agree: a transition between two states should keep one element on screen throughout, so people don't lose their place.

        Examples: tap a photo in iOS Photos and the thumbnail itself zooms to fill the screen. Linear and Notion open a list row into a detail preview that grows out of the row you clicked, rather than a panel that slides over it.

        Live demo: click any tile or row and watch it grow into the detail view

        The detail view isn't a new element fading in. It's the same card, moved with a technique called FLIP: measure where it starts (First), place it at its final size (Last), shift it back to where it started (Invert), then let it animate to the end (Play). Close it and it shrinks back into its tile.

        The decision. Opening takes 320ms on a standard curve and animates only transform, opacity and border-radius, which are cheap for the browser to draw. Closing takes ~220ms, so opening feels deliberate and closing feels quick.

        Reduced motion: the detail view fades in place, with no zoom or movement. It still reads as the same item, without the kind of motion that makes some people dizzy.

        Motion 03

        Bring items in one after another, not all at once

        Orchestration, stagger & follow-through

        When many things appear together, the order they appear in helps people understand the layout.

        If all of a dashboard's cards appear at the same instant, the screen just pops in and is harder to read. If they appear in a quick sequence, a few dozen milliseconds apart (a stagger), the eye follows them in reading order without anyone noticing why. Too much stagger and loading feels slow. The slider lets you find the right amount.

        Disney: staging & follow-through · Material emphasized-easing list reveal. Stagger decides when each item gets attention. Each item also overshoots slightly and settles just after the one before it (follow-through), so the group moves as one.

        Examples: analytics dashboards bring their cards in one after another on load, so the page builds up instead of blinking on. Social feeds reveal posts in a quick top-to-bottom sequence. Move the slider below to see the difference.

        Live demo: replay the reveal, change the stagger, then replay again

        55 ms

        At 0 ms the cards appear together, flat and a bit jarring. Around 40 to 60 ms they arrive in a clear order. Past about 100 ms it starts to feel like waiting. Every card uses the same spring. Only its start time changes.

        The decision. I stagger each item by ~50ms with a soft spring, capped so the last item lands within ~500ms in total. For longer lists I shorten the delay per item rather than make people wait for the page to finish.

        Reduced motion: every card fades in at once. No rise, no stagger, no overshoot.

        Motion 04

        Animate the change instead of jumping to it

        Layout diff: animating a change in order

        When a list is sorted or filtered, rows should move to their new places, so you can follow the one you were looking at.

        If a sort isn't animated, every row jumps at once and you have to scan the list again to find yours. Animating the difference fixes that: record where each row was, apply the new order, then slide each row from its old place to its new one. Filtering works the same way. Rows that leave fade out, and the rest slide up to close the gap.

        "Always animate the diff." The rule behind this kind of layout animation: if a change moves things, show them moving. Nothing important should teleport to a new position.

        Examples: sort a table in Linear and every row slides to its new place. Things reorders to-dos the same way. Reorder a playlist and the tracks slide rather than jump. Sort and filter the table below and nothing jumps.

        Live demo: sort and filter, and every row slides to its new place

        Sort by

        Each button uses FLIP again: record every row's position (First), reorder the rows in the page (Last), move each row back to where it was (Invert), then let them all slide to their new places (Play). Hide the paused rows and the rest slide up to fill in. You never lose your place.

        The decision. Rows slide over 260ms on a standard curve, animating transform only. The rows are already in their final order, so the browser doesn't have to recalculate the layout on every frame. Rows that leave fade out over ~160ms first, so they're gone before the others arrive.

        Reduced motion: rows reorder and filter instantly. The end result is the same, with no movement.

        Motion 05

        Every animation can be interrupted

        Springs that keep their speed when you grab them

        The test: grab something while it's moving and push it the other way. Does it restart, or does it change direction and keep the speed it had?

        A fixed-length animation can't be interrupted well. Catch it halfway and it either jumps to the end or restarts from a standstill, and both feel broken. A spring tracks position and speed every frame, so giving it a new target mid-move just changes where it's heading. It carries on from where it was, at the speed it had. That's why an iOS sheet feels like something you can throw, catch and redirect.

        Apple HIG: "people can interrupt and reverse animations." iOS sheets are built on springs that track speed. Flick one and let go and it keeps its momentum. Grab it mid-move and control goes straight back to your finger.

        Examples: iOS Control Center and the share sheet, which you can fling, catch and reverse. In a work app, a panel you drag to resize that snaps to set points at 25, 50 and 75%. Both demos below run on the same hand-built spring, about 30 lines of code.

        Live demo: drag and fling the sheet, then grab it mid-move and reverse

        drag the sheet ↕ · fling & catch it
        Now Playing

        Fling me up or down. Catch me mid-animation and drag the other way. I keep my momentum and re-target. I don't restart.

        Half open.

        Work app version: drag to resize, with snap points. Drag the divider (or select it and use ←→), let go, and it springs to the nearest snap point, keeping its speed.

        Sidebar
        Canvas

        Sidebar at 50%.

        It all happens on release. The speed of your last movement is passed straight to the spring, so a fast flick goes farther than a slow drag. Reverse mid-move and the spring changes direction without dropping to zero speed.

        The decision. A snappy spring (stiffness 300, damping 30, mass 1), updated every frame with requestAnimationFrame using a simple physics step (semi-implicit Euler). Release speed comes from the last few pointer positions and is passed to .setTarget(), so the same spring changes target instead of starting over.

        Reduced motion: dragging still follows your finger exactly, but on release it jumps straight to the nearest snap point. No spring, no overshoot.

        Motion 06

        Things appear from whatever opened them

        Origin: cause & effect

        A menu that grows out of the button you pressed clearly came from that press. A menu that fades in at the center of the screen doesn't.

        Motion is the clearest way to show cause and effect. When a popover grows from the corner of its button (its transform-origin, the point it grows from), you can see where it came from. When a new row slides out from the + button that made it, the link between action and result is obvious. Get the starting point wrong and even a nice animation feels random.

        macOS menus · iOS context-menu peek · FAB-to-sheet. macOS and iOS grow menus and sheets out of the control that opened them. Material's floating action button expands into the screen it opens. Where it starts is the explanation.

        Examples: long-press an iOS app icon and the menu grows out of the icon itself. In a work app, a "+ New" button sends the new row out from under your cursor. Try both below.

        Live demo: open the menu, then add a row with the button

          The menu grows from its top-left corner, where the button is, so it clearly belongs to that button. New rows start small and slightly offset toward the button, then settle into place, so you can see the path from click to result.

          The decision. The popover grows from 0.92 → 1 with its transform-origin at the button, over 180ms, slowing as it arrives. New rows come in on a soft spring from a small offset, so the eye follows the path from button to row.

          Reduced motion: the menu and rows fade in place. The movement cue is gone, but they still appear next to the button that made them, so the link stays clear.

          Motion 07

          Act now, then show whether it worked

          Optimistic updates, success & failure

          The rule: act now, reconcile later, visibly. Show the result as soon as someone acts, then use motion to show whether the server agreed.

          This is Principle 2 (perceived speed) in motion. The message moves into place before the network answers, so sending feels instant. Then the app checks with the server, which is what reconcile means here. On success the message settles and gets a timestamp. On failure it shakes, is marked as failed and offers a retry. The animation is how the result gets communicated, including when something goes wrong.

          Optimistic UI · the 0.1 / 1 / 10s response tiers · sub-100ms acknowledgment. Respond within about 100ms and the app feels instant. Check with the server in the background. Design the failure animation as carefully as the success one, because that's when people decide whether to trust the product.

          Examples: iMessage shows your bubble right away and changes its color if it fails to send. A task manager adds a new task instantly and checks with the server afterwards. Turn on "Force failure" below to see what happens when it goes wrong.

          Live demo: send a few messages, then turn on "Force failure"

          The bubble appears the moment you press Send, marked "sending." On success it settles and gets a timestamp. On failure it shakes once, turns red and stays (with a retry) instead of quietly disappearing. Both outcomes get the same care.

          The decision. The bubble comes in over 200ms, slowing as it arrives. On success, the "sending" label fades. On failure it plays one ~320ms shake (small, once, never looping) and changes color, so the meaning doesn't depend on motion alone.

          Reduced motion: the bubble appears without sliding in, and failure is shown with color and text only, no shake.

          Motion 08

          Knowing when not to animate

          Restraint & reduced motion

          For some people, zooms and parallax (layers moving at different speeds) cause real nausea and dizziness. Respecting that shouldn't cost them anything. The interface still has to say everything, without the movement.

          A reduced-motion mode isn't just "animations off." Every big movement gets a calm replacement, like a fade instead of a zoom or an instant reorder instead of a slide, so the information the motion carried still gets across. The switch below controls this whole page, and every demo above responds to it. I design the motion first, then design what replaces it with the same care.

          WCAG 2.3.3 (Animation from Interactions) · Apple "Reduce Motion" swaps. People must be able to turn off non-essential motion triggered by interaction. Well-built products read the operating system setting and swap in safe transitions automatically, rather than just freezing.

          Example: turn on Reduce Motion in iOS and the zoom when you open an app becomes a gentle fade everywhere. The app still opens, just more calmly. Every demo on this page does the same when you flip the switch.

          Live demo: this switch controls the whole page

          Reduce motion (whole page)

          Motion: full. Synced to your system setting.

          Can cause dizziness · large zoom + parallax

          Open
          zoom 0.4→1 + drift

          Safe replacement · fade only

          Open
          opacity only

          With full motion, the left card zooms and drifts. Most people find that fine, but it can make some people feel sick. Turn on the switch and play it again: it becomes the same calm fade as the right one, and nothing is lost.

          The decision. One motionOK() helper checks both the system setting (matchMedia('(prefers-reduced-motion: reduce)')) and this switch. Every demo checks it, and the page root carries data-motion="full|reduced" so CSS transitions switch off too. The page follows your system setting by default. The switch can only reduce motion further, never override someone who asked for less.

          If your system already asks for reduced motion, this page started in reduced mode and the switch shows it.

          Summary

          What the principles have in common

          All seven are about the same thing: what happens between an action and its result. Every action needs an answer (feedback) and should feel fast (speed). People should be able to see what they can do (affordance), get it wrong safely (forgiveness), meet complexity only when they need it (disclosure), work on things directly (manipulation) and use whichever input they prefer (input). When these are right, people stop noticing the interface. Motion ties them together by showing how things change, and knowing when to hold still matters just as much.

          The seven principles at a glance

          01 Feedback
          Nielsen: visibility of system status
          Every action gets an immediate, clear answer.
          02 Speed
          Nielsen response limits · Doherty ≈400ms
          Design how fast it feels, not just how fast it is.
          03 Affordance
          Norman: affordance vs signifier
          Make what's possible visible, not just available.
          04 Forgiveness
          Nielsen: user control & freedom
          Prefer a quick undo to a confirmation dialog.
          05 Disclosure
          Tesler's Law · Hick's Law
          Show what's needed and keep the rest a step away.
          06 Manipulation
          Shneiderman: direct manipulation
          Act on the object itself, and keep things where people left them.
          07 Input
          Fitts's Law · accelerators · access
          Support mouse and keyboard. That's accessibility too.

          The motion layer at a glance

          M1 Physics
          Disney 12 · spring vs. ease
          Springs feel like real objects and can be interrupted. Fixed curves can't.
          M2 Continuity
          Material: container transform
          Animate between states with FLIP so people keep their place.
          M3 Orchestration
          Staggering & choreography
          Bring items in one after another to guide the eye.
          M4 Layout diff
          FLIP: first/last/invert/play
          When a list reorders, move the rows instead of fading them.
          M5 Interruptible
          Velocity handoff
          A gesture passes its speed to the spring, so nothing feels stuck.
          M6 Origin
          Scale-from-source
          Menus and panels grow out of whatever opened them.
          M7 Optimistic
          Latency compensation
          Act instantly, then confirm or roll back where people can see it.
          M8 Restraint
          WCAG 2.3.3 · prefers-reduced-motion
          Know when not to animate, and replace motion with something calm.

          Where these principles show up in my work

          These principles shaped the main decisions in these projects: interview scores you can challenge and watch change, an app agents use at a property with no signal, and a calculator that shows its assumptions on the page.

          Criterion, interview practice with scores you can question
          Every score links to the exact words that earned it. If you disagree with a score, you can challenge it and the AI re-checks it, and can raise, hold, lower or escalate the score. Live at criterionscore.com.
          KeySign, signing a home offer at the property
          Buyers decide right after a showing, but offer tools need a desk and every state has its own forms. KeySign lets the agent write, sign and send a compliant offer from their phone at the property, then open escrow.
          How Much Would I Have If, an investment calculator
          Answers "how much would I have if I had invested in Apple in 2010" with a page for every asset and year, about 1,070 in all, on real market data with charts anyone can use. Built solo, live at howmuchwouldihaveif.com.