Skip to content

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

Description

@TortoiseWolfe

⛔ BLOCKED — not startable, verified 2026-07-28

Reached this in the #376 sequence and stopped rather than guess. Both prerequisites are still OPEN and no decision has been recorded on either:

state why it blocks 3e
#375 Remember Me OPEN, undecided 3e has no Remember Me checkbox. Building it enacts "delete the control" — a product decision #375 explicitly owns.
#374 sign-in layout OPEN 3e restyles the corrected layout. Landing 3e first means restyling a layout that is about to change underneath it.

And the two disagree on "Forgot?": #374 puts it on the Remember-Me row, 3e puts it inline on the password row. Implementing 3e silently resolves that too.

The one decision that unblocks this: does the Remember Me control stay or go? The 3e mock is design input supporting delete, and it corroborates #374's appearance: 'interaction-only' choice — but it is not the decision, and #375 still owns it.

Nothing here is hard once that is answered. Order should be: settle #375 → land #374 → then 3e restyles the corrected layout.

Sign in (3e)/sign-insrc/app/sign-in/page.tsx, src/components/auth/SignInForm/

Inputs as grooves · the form floats on a plate over the logo.

From the mock:

  • Form on a raised plate, oversized logo behind it, background radial-gradient(90% 90% at 22% 40%, …)
  • Email and Password as grooves (pure inset)
  • "Forgot?" inline on the password row
  • Password strength meter ("Strong · 3 of 4")
  • Trust strip: "Same auth your users get" · Rate limited · Session refresh · WCAG AA
  • "or" divider, then GitHub / Google
  • Footer: "New here? Create an account"

Two live tickets to reconcile before starting

#374 is a sign-in layout pass against the current design. It stays — it fixes real defects 3e would otherwise inherit (three of five controls off the form's own grid, 123px of dead space, the orphaned Forgot-password link below the submit button). 3e restyles the corrected layout.

They disagree on "Forgot?" placement. #374 puts "Forgot password?" on the Remember-Me row; 3e puts "Forgot?" inline on the password row and has no Remember-Me row at all. Whoever lands second must not silently undo the first.

#375 owns the Remember Me decision. The 3e mock has no Remember Me checkbox and no visible CAPTCHA — that is design input supporting delete, and it corroborates #374's appearance: 'interaction-only' choice. It is not the decision itself; #375 still owns that.

Do not break auth

The strictest instance of the shared accessible-names guardrail. performSignIn() (tests/e2e/utils/test-user-factory.ts:1159-1167) is called by ~20 specs and uses getByLabel('Password', { exact: true }) — an exact match. Preserve input ids email / password, their htmlFor pairings, data-testid="captcha-widget", and the submit button's accessible name.

The password strength meter is new functionality, not a restyle — scope it explicitly or defer it.

Acceptance criteria

  • Matches the 2a treatment described above, using the shared --sh-plate / --sh-well / --sh-groove tokens — no page-local shadow values.
  • Renders correctly on scripthammer-dark, scripthammer-light and a sample of the other 30 themes.
  • No horizontal overflow at 320, 390, 428, 768, 1024, 1280, 1440px.
  • Contrast measured, not assumed — the a11y suites stay green.
  • No change to data fetching or behaviour; existing E2E for this route passes unmodified.

Part of the 2a "Machine Shop" visual refresh epic (see the epic for the depth primitives, type
decision and shared guardrails).

Design source: ScriptHammer visual refreshScriptHammer Site.dc.html

Shared guardrails

  • Presentational only. No changes to data fetching, auth, Supabase calls or Edge Functions.
  • Accessible names are an API. performSignIn() (tests/e2e/utils/test-user-factory.ts:1159-1167) is called by ~20 specs and uses getByLabel('Email'), getByLabel('Password', { exact: true }), getByRole('button', { name: 'Sign In' }). exact: true means a Password label change breaks it.
  • 5-file component pattern is CI-enforced — use pnpm run generate:component.
  • A11y gates stay green: config/pa11yci.json (AAA, 4 routes), config/pa11yci-auth.json (AA, 5 auth pages), tests/e2e/color-contrast.spec.ts, ~60 per-component axe tests.
  • Touch targets stay 44px (min-h-11 min-w-11).
  • These are HTML mockups, not SVG wireframes — they do not belong in features/**/wireframes/ or the /wireframes pipeline.

Part of epic #376

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority:p3Low — defer (heavy work, polish, nice-to-haves)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions