7.7 KiB
| phase | slug | status | shadcn_initialized | preset | created |
|---|---|---|---|---|---|
| 8 | social-sign-in | approved | false | none | 2026-05-15 |
Phase 8 — UI Design Contract
Visual and interaction contract for the Social Sign-in phase. This phase changes the login/signup surfaces and adds a minimal linked-providers account view. It should stay functional and restrained; the user will provide a more polished UI later.
Design System
| Property | Value |
|---|---|
| Tool | none |
| Preset | not applicable |
| Component library | local templ components in backend/internal/web/ui |
| Icon library | none required for Phase 8 |
| Font | inherited app font |
Existing Surface To Preserve
- Keep the centered auth card layout used by
LoginPageandSignupPage. - Keep the current card width:
w-full max-w-sm. - Keep the current card padding:
px-6 py-8. - Keep existing form labels, inputs, and validation error patterns.
- Do not introduce a marketing-style auth page, hero area, decorative background, split layout, or large illustration.
Interaction Contract
Login and Signup Pages
Both /login and /signup must show:
- Page heading
- Equal-prominence Google and Apple provider buttons
- A visual separator between provider buttons and the email/password form
- Existing email/password form
- Existing inline validation/error rendering behavior
Provider buttons:
- Google and Apple are peers; neither is styled as primary over the other.
- Buttons link to provider start routes when configured.
- Buttons render disabled when required provider config is missing.
- Disabled state must be visible and non-clickable.
- Disabled state copy must be short and plain, not diagnostic.
- Provider buttons must not submit the email/password form.
Successful social sign-in redirects to /; no provider-specific welcome page.
Linked Providers View
Add a protected, minimal linked-providers status view.
Required content:
- Heading:
Linked providers - One row for Google
- One row for Apple
- Each row shows one of:
ConnectedNot connected
- If connected, show the stored provider email.
- No unlink action in Phase 8.
- No add-password UI in Phase 8.
The view may live at /account or /account/providers; planner decides route naming.
Spacing Scale
Declared values (must be multiples of 4):
| Token | Value | Usage |
|---|---|---|
| xs | 4px | Provider button inner gaps if icons are later added |
| sm | 8px | Button stack gap, inline provider row gap |
| md | 16px | Default form/provider group spacing |
| lg | 24px | Auth section separator margin |
| xl | 32px | Page card inner section breaks |
| 2xl | 48px | Account page section spacing |
| 3xl | 64px | Existing auth page top spacing equivalent |
Exceptions: none
Auth card layout:
- Heading margin-bottom: 24px (
mb-6) remains acceptable. - Form/provider section gap: 20px (
space-y-5) remains acceptable because it already exists; do not introduce additional non-4px spacing. - Provider button stack gap: 8px.
- Separator vertical margin: 16px above and below.
Typography
| Role | Size | Weight | Line Height |
|---|---|---|---|
| Body | 16px | 400 | 1.5 |
| Label | 14px | 500 | 1.25 |
| Helper / status | 14px | 400 | 1.4 |
| Heading | 24px | 600 | 1.25 |
| Account section heading | 20px | 600 | 1.3 |
Rules:
- Do not use viewport-scaled font sizes.
- Do not use negative letter spacing.
- Keep provider button labels at 16px / 600 if using
ui.Button, matching existing primary button weight. - Disabled explanatory copy uses 14px normal weight.
Color
| Role | Value | Usage |
|---|---|---|
| Dominant (60%) | #ffffff |
Auth card and account content surfaces |
| Secondary (30%) | #f8fafc |
Page background or subtle status surfaces |
| Text | #0f172a |
Primary headings/body |
| Muted text | #64748b |
Helper text, disabled provider explanation |
| Border | #e2e8f0 |
Provider buttons, separators, provider status rows |
| Accent (10%) | #2563eb |
Existing primary email/password submit button and focus ring only |
| Destructive | #b91c1c |
Error text or future destructive actions only |
Accent reserved for:
- Existing primary email/password submit button
- Focus rings
- Links if needed
Provider buttons:
- Use neutral/outline styling rather than blue primary styling.
- Background:
#ffffff - Border:
#e2e8f0 - Text:
#0f172a - Hover when enabled:
#f8fafc - Disabled background:
#f1f5f9 - Disabled text:
#94a3b8
Copywriting Contract
| Element | Copy |
|---|---|
| Google button | Continue with Google |
| Apple button | Continue with Apple |
| Disabled Google button | Google sign-in not configured |
| Disabled Apple button | Apple sign-in not configured |
| Auth separator | or |
| Provider callback generic error | Could not sign you in with this provider. Try another sign-in method. |
| Unverified email error | This provider did not return a verified email. Try another sign-in method. |
| Social-only signup conflict | An account already exists for this email. Sign in with your provider. |
| Linked providers heading | Linked providers |
| Connected status | Connected |
| Not connected status | Not connected |
| No unlink copy | No visible copy needed; simply omit unlink controls |
Error copy rules:
- Do not expose provider tokens, codes, claim names, key IDs, or raw OAuth errors in the UI.
- Server logs may contain structured error categories, but UI copy stays generic unless the user can act on it.
Component Contract
Provider Button
Create a provider button pattern rather than reusing the solid blue primary submit button.
Acceptable implementation options:
- Extend
ui.Buttonwith neutral outline/disabled support. - Add a small auth-local provider button templ component.
Required behavior:
- Full width inside the auth card.
- Stable height of at least 44px.
- Does not resize based on provider config.
- Uses native disabled semantics for button form controls, or
aria-disabled="true"plus no actionablehreffor links. - Keyboard focus ring is visible when enabled.
Separator
Use a simple horizontal rule pattern:
- Left line
- Center text
or - Right line
No decorative icons or large text.
Linked Provider Row
Each row:
- Provider name on the left.
- Status and email on the right or below on small screens.
- Bordered row or subtle card row.
- Minimum row height 44px.
- No nested cards inside cards.
Responsive Contract
- Auth card remains centered and no wider than
max-w-sm. - Provider buttons are stacked vertically on all viewports in Phase 8; do not use a two-column button layout.
- Linked providers view uses a single column on mobile.
- Text must not overflow provider buttons; if future localization makes labels long, allow wrapping before reducing font size.
- No horizontal scrolling.
Accessibility Contract
- Provider buttons must be reachable by keyboard.
- Disabled provider controls must communicate disabled state to assistive tech.
- Separator
ormust not be announced as a form control. - Error messages must be associated with the relevant auth surface and visible near the provider/form area.
- Connected provider rows should expose status text as real text, not only color.
Registry Safety
| Registry | Blocks Used | Safety Gate |
|---|---|---|
| shadcn official | none | not required |
| third-party blocks | none | not allowed for Phase 8 |
Checker Sign-Off
- Dimension 1 Copywriting: PASS
- Dimension 2 Visuals: PASS
- Dimension 3 Color: PASS
- Dimension 4 Typography: PASS
- Dimension 5 Spacing: PASS
- Dimension 6 Registry Safety: PASS
Approval: approved 2026-05-15