Patterns
How Inline behaves when a student acts: the same decisions for forms, waits, limits, sharing, and consent everywhere in the product. Every pattern protects one fact, the draft is safe, and says so whenever a student could doubt it.
Forms
Applies to every form, from renaming a draft to creating a class. Labels sit above controls, help sits below, and validation arrives only when it can actually help.
control.height.md · radius.sm · border.danger
- Never disable submit as the only signal. A dead button explains nothing; submitting surfaces the first field that needs a change.
- Errors say what to change. Required is a status; add the school domain is an instruction, so write the instruction.
Destructive actions
Applies whenever an action removes student work or ends access: deleting drafts, revoking a link, leaving a class. The dialog does the counting before the product does the deleting.
This deletes 3 drafts and their feedback. There is no undo.
shadow.dialog · radius.lg · bg.overlay
Everywhere else, the dialog plus the named consequence is enough friction. Extra ceremony on small deletions teaches students to type without reading.
- The buttons repeat the verbs. Delete drafts confirms and Keep drafts retreats; never Confirm, OK, or a bare Cancel.
- Name the consequence in plain words. Count what disappears and say whether it can come back, before the button can be pressed.
Loading
Applies whenever the product makes a student wait. The shape of the wait tells them what kind of work is happening.
| The wait | Pattern | Example |
|---|---|---|
| A space is assembling | Skeleton that mirrors the final layout | Question rail while a report opens |
| One action working in place | Plain text label | Saving, Restoring |
| The feedback run | The one full-screen wait | Reading your draft, Writing questions |
The one full-screen wait
Only the feedback run takes the whole screen. It says what is happening in calm lines, sets an honest expectation, and keeps the draft's safety in view. If the run fails, the notice keeps both promises in one breath.
Feedback didn’t come back. Your draft is saved. Rerun feedback
dur.lg · fade only · reduced motion collapses
Loads in place
ink.100 · radius.xs · pulse on dur.lg
no spinner · no skeleton
- Only the feedback run owns the screen. Every other wait happens inside the surface that asked for it.
- A wait never hides draft safety. The run screen and its failure state both say the draft is saved, in words.
Quota and upgrade
Applies when a plan limit meets a student mid-work: feedback runs on Free, daily caps on Pro. The limit is information, never leverage.
The numbers in these states are example values; limits are configuration. Both states keep the editor active. The banner sits exactly where the run action was, states the limit as a fact, and carries one path forward.
- State the limit as a fact. A number, a reset date, and one path forward; never a countdown, never guilt.
- Quota gates the run, never the writing. Composing, saving, and rereading feedback stay available at zero.
Sharing, twice
Applies whenever student work leaves the private space. There are exactly two doors, and they must never look alike: a transient process report link and a permanent course submission.
- The two affordances never look alike. Links are quiet secondary actions in place; submission is a primary flow with its own screen.
- The student sees the exact payload first. Draft snapshot, report, and selected questions appear before the confirming action, never after it.
Joining a class
Applies the moment a student connects their private space to an institution. Before anything joins, one plain screen says what changes and what does not.
yellow marks what stays private
- Consent is the action itself. Join sits after the visibility list; there is no pre-checked box and no joining by scroll.
- The exit stays visible. Leave class lives permanently in settings, never behind a support request.
Search and empty
Applies to every list a student can filter: drafts, questions, classes. Search narrows as you type, and empty spaces explain themselves.
No drafts match “harbor essay”.
filters on input · no submit step
A draft here is read in full before Inline asks anything.
well 48 · icon 24 · one button
- The empty result names the query. Echoing it proves the search ran, and Clear search restores the full list in one action.
- First-run empties orient. One sentence on what the space is for, one action to begin, nothing else.
Upload
Applies when a draft starts life outside Inline. One file at a time, with the rules stated before the picker ever opens.
That file is 12 MiB, over the 8 MiB limit. Your typed draft is untouched.
radius.md · track radius.xs
- Limits live on the control. Accepted types and the size cap are readable before choosing a file, not discovered in an error; the cap itself is configuration, rendered as data.
- A failed upload touches nothing. The typed draft stays exactly as it was, and the failure line says so.
Rules
Eight decisions that hold every pattern together. When a new flow appears, it inherits these before it invents anything.
- The draft is always safe. Loading, failure, quota, and upload states say so in words whenever a student could wonder.
- Never disable the only way forward. Submit stays enabled and the first invalid field explains; a dead button teaches nothing.
- Name the consequence, repeat the verb. Delete drafts confirms, Keep drafts retreats, and Escape always leaves everything unchanged.
- One wait owns the screen. Only the feedback run goes full screen, and it says what is happening and how long it usually takes.
- Limits are facts with a path. State the number and the reset, offer the upgrade once, and never manufacture urgency or guilt.
- The two shares never look alike. Expiring links stay quiet, revocable, and secondary; course submission is a primary flow that shows the exact payload first.
- Visibility is consented before it exists. A student joins a class only through the screen that lists what the professor sees, and the way out stays visible in settings.
- Empty spaces explain themselves. A no-result names the query and clears in one action; a first run says what the space is for with one way to begin.