Skip to content

feat(#384): apply 3e to /sign-in β€” the form on a plate beside the pitch - #449

Merged
TortoiseWolfe merged 1 commit into
mainfrom
feat/384-signin-3e
Jul 30, 2026
Merged

feat(#384): apply 3e to /sign-in β€” the form on a plate beside the pitch#449
TortoiseWolfe merged 1 commit into
mainfrom
feat/384-signin-3e

Conversation

@TortoiseWolfe

Copy link
Copy Markdown
Owner

The 3e treatment: two panels β€” the pitch on the left, the form floating on a raised plate on the right, over a radial wash. Single column below lg, stacked rather than hidden β€” a hidden lg:block panel is invisible to every gate we run at 390px (#411).

Three conflicts this ticket flagged, decided rather than left to chance

#384 opened β›” BLOCKED on two prerequisites. Both are now resolved, and the ticket warned that whoever landed second must not silently undo the first β€” so here are the calls, on the record:

1. Remember Me stays. The 3e mock has no Remember Me checkbox, which #384 correctly read as design input for deleting it. #375 decided the opposite β€” make it work β€” and that shipped in #446. So the checkbox stays, #374's "Forgot password?" placement on that row stands, and the mock's password-row placement is superseded.

2. Password strength meter deferred. It is new functionality, not a restyle, and #384 permits deferring it. It is also questionable on sign-in, where the user is not choosing a password. SignUpForm already has PasswordStrengthIndicator if it is wanted later.

3. Turnstile stays visible. The appearance: 'interaction-only' change is blocked on #442 (Turnstile is live but undisclosed in the privacy policy), so the CAPTCHA row still costs 65px.

The radial wash needed correcting, not copying

The design writes its gradient stop as the literal oklch(28.51% 0.067 281.32). That value is scripthammer-dark's own --color-base-300 β€” the mock's wrapper carried data-theme="scripthammer-dark", so it was theme-specific.

Lifting it verbatim put a dark purple blob in the middle of the light theme and dragged the headline's contrast down with it. Caught by looking at the rendered page, not by reading the CSS. Now var(--color-base-300), so the wash follows the active theme β€” the same correction #415 made to the semantic colours.

Submit is btn-secondary

Matching the mock. On scripthammer-dark, --color-primary is a silver/steel oklch(76.05% 0.024 258.37) that reads as a disabled control on the primary action of the page.

Every trust pill is backed by something real

Checked, not assumed β€” a badge with nothing behind it is the #422/#383 failure:

pill backing
Rate limited checkRateLimit on submit β€” 3 call sites in SignInForm
Session refresh autoRefreshToken: true, lib/supabase/client.ts
WCAG AA config/pa11yci-auth.json gates /sign-in at WCAG2AA

If one stops being true, delete the pill rather than leave a decorative claim on the page where users hand over a password.

Auth contract preserved, verified in-browser

#384 calls this the strictest instance of the accessible-names guardrail β€” performSignIn() is used by ~20 specs. Measured on the rendered page:

  • input ids email / password with their htmlFor pairings intact
  • labels exactly Email / Password (performSignIn uses exact: true)
  • submit accessible name Sign In
  • data-testid="captcha-widget" present

The h1 moved to the headline, where the visual hierarchy actually starts. The document title still comes from sign-in/layout.tsx, so rate-limiting.spec.ts:85's toHaveTitle(/Sign In/i) is unaffected β€” checked. No spec locates a heading on this route, and the "Sign up" β†’ "Create an account" link change retargets nothing (the five Sign Up locators are all getByRole('button') on the sign-up page).

Contrast measured, not assumed

Read through a <canvas>, because getComputedStyle returns oklch() unparsed:

dark light
submit text 11.81 8.82
headline on page 14.41 11.73

All clear the 7:1 AAA gate.

Closes #384.

Two panels: the pitch on the left, the form floating on a raised plate on the
right, over a radial wash. Single column below lg, stacked rather than hidden β€”
a `hidden lg:block` panel is invisible to every gate we run at 390px (#411).

Three conflicts this ticket flagged, resolved rather than left to chance:

1. The 3e mock has NO Remember Me checkbox, which #384 correctly called design
   input for deleting it. #375 decided the opposite β€” make it work β€” and that
   decision is now shipped. The checkbox STAYS, so #374's "Forgot password?"
   placement on that row stands and the mock's password-row placement is
   superseded. #384 warns whoever lands second not to silently undo the first;
   this is that call, recorded.

2. The password strength meter is NEW functionality, not a restyle. Deferred,
   as #384 permits. It is also questionable on sign-IN, where the user is not
   choosing a password.

3. Turnstile stays visible. The `interaction-only` change is blocked on #442
   (privacy-policy disclosure), so the CAPTCHA row is still 65px.

The radial wash needed correcting, not copying. The design writes its stop as
the literal `oklch(28.51% 0.067 281.32)`, which is scripthammer-dark's own
`--color-base-300` β€” the mock's wrapper carried `data-theme="scripthammer-dark"`,
so that value was theme-SPECIFIC. Lifting it verbatim put a dark purple blob in
the middle of the LIGHT theme and dragged the headline's contrast down with it;
caught by looking at the page. Now `var(--color-base-300)`, so the wash follows
the active theme β€” the same correction #415 made to the semantic colours.

The submit is `btn-secondary`, matching the mock. On scripthammer-dark
`--color-primary` is a silver/steel that reads as a DISABLED control on the
primary action of the page.

All three trust pills are backed by something real, checked not assumed:
Rate limited (checkRateLimit, 3 call sites) Β· Session refresh
(autoRefreshToken: true) Β· WCAG AA (config/pa11yci-auth.json gates /sign-in at
WCAG2AA). If one stops being true, delete the pill.

Auth contract preserved and verified in-browser: ids `email`/`password` with
their htmlFor pairings, labels "Email"/"Password" (performSignIn uses
exact: true), submit accessible name "Sign In", data-testid="captcha-widget".
The h1 moved to the headline, which is where the visual hierarchy actually
starts; the document title still comes from sign-in/layout.tsx so
rate-limiting.spec.ts's toHaveTitle(/Sign In/i) is unaffected.

Contrast measured through canvas readback (getComputedStyle returns oklch()
unparsed): submit text 11.81 dark / 8.82 light, headline 14.41 / 11.73 β€” all
clear the 7:1 AAA gate.

Closes #384.
@TortoiseWolfe
TortoiseWolfe merged commit 43b4397 into main Jul 30, 2026
20 checks passed
@TortoiseWolfe
TortoiseWolfe deleted the feat/384-signin-3e branch July 30, 2026 00:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Apply 3e to /sign-in: inputs as grooves, the form on a plate over the logo

2 participants