Skip to content
Sections
Language, currently English
Rastrillo Design System

Screens

The sign-in screens are the shipped signin partial, shown in its states. The last two are examples to copy.

Each example is live, but its links go nowhere.

signin signin-title live-head

Signing in

Show one main way in, with the others underneath. Do not split sign-up from sign-in: one button that works for both is less to explain and less to get wrong.

Asking for an address

One field and one button. Nothing to remember and nothing to steal. Rastrillo does this out of the box.

Preview
{{define "title"}}{{template "signin-title" (dict "State" .Signin "Brand" .Brand)}}{{end}}
{{define "content"}}{{template "signin" (dict "State" .Signin "Brand" .Brand)}}{{end}}

Coming back with Keymail

The browser remembers how it got in last time. One tap sends the remembered address, which is checked again from scratch.

Preview
{{define "title"}}{{template "signin-title" (dict "State" .Signin "Brand" .Brand)}}{{end}}
{{define "content"}}{{template "signin" (dict "State" .Signin "Brand" .Brand)}}{{end}}

A passkey

The fastest way in for someone who has one, and nothing to type. Offer a second way as well: people lose devices, and a passkey that will not work is a locked door.

Preview
{{define "title"}}{{template "signin-title" (dict "State" .Signin "Brand" .Brand)}}{{end}}
{{define "content"}}{{template "signin" (dict "State" .Signin "Brand" .Brand)}}{{end}}

After the link is sent

Repeat the address back. It is the only chance to notice a typo before waiting for an email that will never come.

Preview
{{define "title"}}{{template "signin-title" (dict "State" .Signin "Brand" .Brand)}}{{end}}
{{define "content"}}{{template "signin" (dict "State" .Signin "Brand" .Brand)}}{{end}}

After the link is sent, in another browser

When this browser did not send the address, the page does not guess it.

Preview
{{define "title"}}{{template "signin-title" (dict "State" .Signin "Brand" .Brand)}}{{end}}
{{define "content"}}{{template "signin" (dict "State" .Signin "Brand" .Brand)}}{{end}}

When Keymail was offered and a link went out

One line says a link was sent this time. It does not guess why.

Preview
{{define "title"}}{{template "signin-title" (dict "State" .Signin "Brand" .Brand)}}{{end}}
{{define "content"}}{{template "signin" (dict "State" .Signin "Brand" .Brand)}}{{end}}

On the way to Keymail

The page moves on by itself, with a link in case it does not.

Preview
{{define "title"}}{{template "signin-title" (dict "State" .Signin "Brand" .Brand)}}{{end}}
{{define "content"}}{{template "signin" (dict "State" .Signin "Brand" .Brand)}}{{end}}

An address that does not look right

The message belongs to the field, and that is where focus starts.

Preview
{{define "title"}}{{template "signin-title" (dict "State" .Signin "Brand" .Brand)}}{{end}}
{{define "content"}}{{template "signin" (dict "State" .Signin "Brand" .Brand)}}{{end}}

When Keymail could not confirm it

The button changes to send a link instead, so nobody is stuck.

Preview
{{define "title"}}{{template "signin-title" (dict "State" .Signin "Brand" .Brand)}}{{end}}
{{define "content"}}{{template "signin" (dict "State" .Signin "Brand" .Brand)}}{{end}}

Google, Apple and the rest

We give you the buttons, drawn the way each company requires. We do not give you the sign-in itself: you wire that up to whichever provider you use.

Preview
<section rst-box>
  <h1>Sign in</h1>
  <div rst-signin-providers>
    <form method="post" action="/auth/google">
      <button rst-btn="block" type="submit">
        <svg aria-hidden="true" focusable="false" width="1.1em" height="1.1em" viewBox="0 0 48 48"><path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"/><path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"/><path fill="#FBBC05" d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"/><path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"/></svg>
        Continue with Google
      </button>
    </form>
    <form method="post" action="/auth/apple">
      <button rst-btn="block" type="submit">
        <svg aria-hidden="true" focusable="false" width="1.1em" height="1.1em" viewBox="0 0 24 24"><path fill="currentColor" d="M12.15 6.9c-.95 0-2.42-1.08-3.96-1.04-2.04.03-3.91 1.18-4.96 3.01-2.12 3.68-.55 9.1 1.52 12.09 1.01 1.45 2.2 3.09 3.79 3.04 1.52-.07 2.09-.99 3.94-.99 1.83 0 2.35.99 3.96.95 1.64-.03 2.68-1.48 3.68-2.95 1.15-1.69 1.63-3.33 1.66-3.42-.04-.01-3.18-1.22-3.22-4.86-.03-3.04 2.48-4.49 2.6-4.56-1.43-2.09-3.63-2.32-4.39-2.38-2-.15-3.68 1.09-4.62 1.09zm3.38-3.07c.84-1.01 1.4-2.43 1.25-3.83-1.21.05-2.66.8-3.53 1.82-.78.9-1.46 2.34-1.27 3.71 1.34.1 2.71-.69 3.55-1.7z"/></svg>
        Continue with Apple
      </button>
    </form>
    <a href="/signin">Use your email instead</a>
  </div>
</section>

Email and password

If you do use passwords, use the same one-way-in layout, and put a way to reset directly under the button rather than hiding it.

We do not recommend passwords

Rastrillo does not ship this screen. People reuse passwords, they leak, and you inherit the job of storing them safely. Use a link in your email plus a passkey, or passkeys on their own. The markup is here because some products still need it.

Preview
<section rst-box>
  <h1>Sign in</h1>
  <form rst-form method="post" action="/signin">
    <div rst-field>
      <label rst-field-label for="pw-email">Email</label>
      <input rst-input id="pw-email" name="email" type="email" autocomplete="email" required>
    </div>
    <div rst-field>
      <label rst-field-label for="pw-pass">Password</label>
      <input rst-input id="pw-pass" name="password" type="password" autocomplete="current-password" required>
    </div>
    <button rst-btn="primary" type="submit">Continue</button>
  </form>
</section>