feat: replace setup checklist with a five-screen onboarding flow

Generate-or-recover an identity, establish server trust, then bind an
address — each its own screen with no bleed-through, replacing the
old intro/restore cards plus the post-hoc setup checklist banner.
This commit is contained in:
randogoth 2026-10-08 20:48:09 +03:00
parent 1710d7b144
commit fb0ca5c8cc
4 changed files with 313 additions and 244 deletions

View file

@ -36,42 +36,72 @@
</div>
</header>
<!-- Two cards, one at a time: deciding between "create" and "restore" is the
only question this screen asks. Everything the new identity still needs is
deferred to the checklist in the app, so neither card is a wall of fields. -->
<!-- Five screens, one concern each: generate-or-recover an identity, establish
trust in a server, then bind a name to it. No screen asks about the next
screen's concern — e.g. the server screen never asks for a username. -->
<main id="setup" class="setup" hidden>
<section id="setup-create" class="setup-card">
<section id="setup-intro" class="setup-card">
<h2>welcome</h2>
<p class="lead">Encrypted mail with no account and no password. Your identity is one secret,
kept in this browser and nowhere else.</p>
<button type="button" id="create-identity" class="filled large">create a new identity</button>
<p class="hint centered">The next screen walks you through the three things left to set up.</p>
<button type="button" id="show-restore" class="link">I already have a secret to restore</button>
<button type="button" id="show-restore" class="link">restore existing identity from seed</button>
</section>
<section id="setup-seed" class="setup-card" hidden>
<h2>write this seed down</h2>
<p class="lead">It is the only secret, and it is shown once.</p>
<div class="seed-card">
<div id="setup-seed-value" class="seed"></div>
</div>
<button type="button" id="seed-saved" class="filled large">I saved it</button>
<button type="button" id="seed-back" class="link">back</button>
</section>
<section id="setup-restore" class="setup-card" hidden>
<h2>restore</h2>
<h2>restore from a seed</h2>
<p class="lead">Paste the secret you saved. Your keys come back from it — it is all this client
needs.</p>
<form id="restore-form" class="stack">
<label>your master secret
<input id="restore-master" placeholder="64 hex characters" spellcheck="false" required>
<label>your secret
<input id="restore-master" placeholder="hex or base32" spellcheck="false" required>
</label>
<details id="restore-extra">
<summary>I also know my address</summary>
<p class="hint">Optional, and easy to add later from settings. A secret does not record which
address it was registered under, and this browser was never told — so filling these in is
what brings the address back now.</p>
<label>address
<input id="restore-address" placeholder="alice@example.org" spellcheck="false">
</label>
<label id="restore-key-label">your server's public key
<input id="restore-key" placeholder="base32, from the server's operator" spellcheck="false">
</label>
</details>
<span id="restore-error" class="error"></span>
<button class="filled large">restore</button>
</form>
<button type="button" id="show-create" class="link">back</button>
<button type="button" id="restore-back" class="link">back</button>
</section>
<section id="setup-server" class="setup-card" hidden>
<h2>set up the server</h2>
<form id="server-form" class="stack">
<label>host
<input id="server-host" placeholder="example.org" spellcheck="false" required>
</label>
<div id="server-key-area" class="seed-card" hidden></div>
<span id="server-error" class="error"></span>
<button id="server-action" class="filled large">fetch the server's key</button>
</form>
<button type="button" id="server-back" class="link">start over</button>
</section>
<section id="setup-account" class="setup-card" hidden>
<h2>choose your address</h2>
<div id="account-mode" class="mode-toggle" role="group">
<button type="button" data-mode="new" class="active" aria-current="true">create a new address</button>
<button type="button" data-mode="existing">I already have this address</button>
</div>
<form id="account-form" class="stack">
<label>user
<input id="account-user" placeholder="alice" spellcheck="false" required>
</label>
<label id="account-token-label"><span>invite token <span class="hint">(optional)</span></span>
<input id="account-token" placeholder="only if your server asks">
</label>
<span id="account-error" class="error"></span>
<button id="account-action" class="filled large">register</button>
</form>
<button type="button" id="account-back" class="link">back</button>
</section>
</main>
@ -92,17 +122,6 @@
</div>
</nav>
<div class="listpane">
<!-- What setup still owes, over the mailbox it is holding up rather than
inside the settings dialog the user would have to think to open. -->
<aside id="setup-banner" class="setup-banner" hidden>
<div class="setup-banner-head">
<h2>finish setting up</h2>
<span id="setup-banner-count" class="setup-banner-count"></span>
<button type="button" id="setup-dismiss" class="icon-only" aria-label="hide this checklist"
title="hide this checklist"><svg class="icon"><use href="#i-close"/></svg></button>
</div>
<ol id="setup-steps" class="setup-steps"></ol>
</aside>
<div id="list-toolbar" class="toolbar">
<div id="mail-tools" class="tools">
<button id="fetch" class="primary"><svg class="icon"><use href="#i-refresh"/></svg><span class="label">fetch</span></button>