Feature: Register screen As the first person to set up a fresh RenewCMS install I want a /register screen that creates the single owner account via POST /v1/auth/register, validates the same rules the API enforces before submitting, and tells me plainly when someone already owns this site or the server failed So that I can create my account once, land on the verification-pending page, and never see a confusing or silent failure Background: Given /register is a public route (meta.auth "public") rendered as RegisterPage inside AuthShell, per docs/design/routes.md And RegisterPage only calls POST /v1/auth/register; it never calls GET /v1/auth/registration And the form has a Username field (placeholder "e.g. marta", a live "N / 20" character counter, help text "Letters and numbers, 3 to 20 characters. You'll use it to log in."), an Email field (placeholder "you@example.com", help text "We'll send a verification link here."), and a Password field (a password input with a show/hide toggle and a live checklist item "At least 8 characters" that is unmet/error until the rule is satisfied, then turns met/green) And client-side validation runs on blur of each field and again on submit, before any request is sent, using the same rules as the API: Username must be 3 to 20 characters (the API has no character-class constraint beyond length, so the client checks length only, matching the help text's length claim but not attempting to enforce "letters and numbers" client-side), Email must be a well-formed email address, and Password must be at least 8 characters And a failing Username shows "Use 3 to 20 characters."; a failing Email shows "Enter a full email address, like name@example.com."; a failing Password leaves the checklist item in its unmet/error state And a valid submit calls POST /v1/auth/register with { username, email, password } And on a 200 response, the jwt cookie is set by the server and the app navigates to /register/pending without re-resolving the session first And a 403 response means someone already verified an owner account (user.ErrRegistrationClosed on the backend) and the whole form is replaced by a ResultPanel And a 500 response, or a request that never reaches the server, is surfaced as a server/network error; the fields keep whatever the user typed and the form re-enables And a 400 response is not expected once client-side validation passes, since the client checks the same rules as the API; it is out of scope for this slice Scenario: Default — a fresh, empty form When the user navigates to /register Then the heading is "Create the owner account" And the description is "This creates the single admin account for this site. Once it's verified, registration closes." And the Username field shows placeholder "e.g. marta" with no value and counter "0 / 20" And the Email field shows placeholder "you@example.com" with no value And the Password field shows no value, with a show/hide toggle and the checklist item "At least 8 characters" in its unmet state And the submit button reads "Create account" And the footer reads "Already set up?" with a "Log in" link to /login Scenario: Validation errors — checked on blur and on submit Given the user is on /register When the user types "ma" into Username and blurs the field Then the Username counter reads "2 / 20" in its error state and the error "Use 3 to 20 characters." is shown When the user types "marta@renew" into Email and blurs the field Then the Email field shows the error "Enter a full email address, like name@example.com." When the user types "lime" into Password and blurs the field Then the checklist item "At least 8 characters" stays in its error state When the user submits with these same values Then POST /v1/auth/register is never called And all three errors from above are still shown Scenario: Filled, valid — every rule is met Given the user is on /register When the user types "marta" into Username, "marta@renew.example" into Email, and "limewash2026" into Password, and reveals the password with the show/hide toggle Then the Username counter reads "5 / 20" with no error, and the help text "Letters and numbers, 3 to 20 characters. You'll use it to log in." is shown And the Email field shows no error, with the help text "We'll send a verification link here." And the Password field shows "limewash2026" as plain text and the checklist item "At least 8 characters" turns to its met/green state And the submit button reads "Create account" and is enabled Scenario: Submitting — fields and button are disabled while the request is in flight Given the user is on /register with Username "marta", Email "marta@renew.example", and Password "limewash2026" When the user submits and POST /v1/auth/register has not yet resolved Then the Username, Email and Password fields are disabled And the submit button reads "Creating account…" and shows a loading state Scenario: Registration closed — the form is replaced by a ResultPanel Given the user is on /register with Username "marta", Email "marta@renew.example", and Password "limewash2026" When the user submits and POST /v1/auth/register resolves 403 Then the form, its fields and the footer are no longer shown And a ResultPanel with tone "info" and icon "user-x" is shown instead, with title "This site already has an owner" and text "Log in instead." And its single action is a primary button "Go to log in" When the user activates "Go to log in" Then the app navigates to /login Scenario Outline: Server or network error — the form is kept and re-enabled Given the user is on /register with Username "marta", Email "marta@renew.example", and Password "limewash2026" When the user submits and POST /v1/auth/register Then an error alert reads "Couldn't create the account" with description "Something went wrong on the server. Try again in a moment." And the Username field still shows "marta", the Email field still shows "marta@renew.example", and the Password field still shows "limewash2026" And the Username, Email and Password fields are re-enabled And the submit button reads "Create account" again, no longer loading Examples: | failure | | fails with a 500 response | | never reaches the server | Scenario: A successful registration goes straight to the pending page Given the user is on /register with Username "marta", Email "marta@renew.example", and Password "limewash2026" When the user submits and POST /v1/auth/register resolves 200 with a jwt cookie Then the app navigates to /register/pending