---
phase: 28
slug: profile-and-logto-integration
status: draft
shadcn_initialized: false
preset: none
created: 2026-04-12
---

# Phase 28 — UI Design Contract

> Visual and interaction contract for the Profile & Account Management page and Settings page separation.

---

## Design System

| Property | Value |
|----------|-------|
| Tool | none |
| Preset | not applicable |
| Component library | none (custom components) |
| Icon library | Lucide (curated subset via `lib/iconData`) |
| Font | System font stack (Tailwind v4 default) |

---

## Spacing Scale

Declared values (must be multiples of 4):

| Token | Value | Usage |
|-------|-------|-------|
| xs | 4px | Icon gaps, inline padding |
| sm | 8px | Compact element spacing, `gap-2` |
| md | 16px | Default element spacing, `space-y-4` |
| lg | 24px | Section padding, `p-5` on cards |
| xl | 32px | Layout gaps, `space-y-6` within cards |
| 2xl | 48px | Major section breaks, `py-6` page padding |
| 3xl | 64px | Not used in this phase |

Exceptions: none

---

## Typography

| Role | Size | Weight | Line Height |
|------|------|--------|-------------|
| Body | 14px (`text-sm`) | 400 | 1.43 |
| Label | 14px (`text-sm`) | 500 (`font-medium`) | 1.43 |
| Sublabel | 12px (`text-xs`) | 400 | 1.33 |
| Section heading | 14px (`text-sm`) | 500 (`font-medium`) | 1.43 |
| Page heading | 20px (`text-xl`) | 600 (`font-semibold`) | 1.4 |

---

## Color

| Role | Value | Usage |
|------|-------|-------|
| Dominant (60%) | `#ffffff` | Page background, card backgrounds |
| Secondary (30%) | `#f9fafb` (gray-50) | Input backgrounds, hover states, toggle pill bg |
| Accent (10%) | `#374151` (gray-700) | Primary buttons, save actions |
| Destructive | `#ef4444` (red-500) | Delete account button, danger zone border |

Accent reserved for: primary action buttons ("Save Profile", "Change Password"), active toggle pills

---

## Page Layout: /profile

```
┌─────────────────────────────────────────────────┐
│  ← Back                                         │
│  Profile                                        │
│                                                 │
│  ┌─────────────────────────────────────────────┐│
│  │  Profile                                    ││
│  │  Your public profile information            ││
│  │                                             ││
│  │  [Avatar] Change avatar / Remove            ││
│  │                                             ││
│  │  Display Name  [___________________]        ││
│  │  Bio           [___________________]        ││
│  │                [___________________]        ││
│  │                              123/500        ││
│  │                                             ││
│  │  [Save Profile]                             ││
│  └─────────────────────────────────────────────┘│
│                                                 │
│  ┌─────────────────────────────────────────────┐│
│  │  Account                                    ││
│  │  Your account information                   ││
│  │                                             ││
│  │  Email        user@example.com  [Change]    ││
│  │  Member since April 2026                    ││
│  └─────────────────────────────────────────────┘│
│                                                 │
│  ┌─────────────────────────────────────────────┐│
│  │  Security                                   ││
│  │  Manage your password                       ││
│  │                                             ││
│  │  Current Password  [___________________]    ││
│  │  New Password      [___________________]    ││
│  │  Confirm Password  [___________________]    ││
│  │                                             ││
│  │  Password must be at least 8 characters     ││
│  │  with uppercase, lowercase, and a number.   ││
│  │                                             ││
│  │  [Change Password]                          ││
│  └─────────────────────────────────────────────┘│
│                                                 │
│  ┌─────────────────────────────────────────────┐│
│  │  Danger Zone                                ││
│  │                                      border ││
│  │  Delete your account and all personal data. ││
│  │  Public setups will be attributed to        ││
│  │  "Deleted User".                            ││
│  │                                             ││
│  │  [Delete Account]                           ││
│  └─────────────────────────────────────────────┘│
└─────────────────────────────────────────────────┘
```

### Card Structure

Each section uses the existing card pattern:
- `bg-white rounded-xl border border-gray-100 p-5 space-y-6`
- Cards separated by `mt-4`
- Danger Zone card uses `border-red-200` instead of `border-gray-100`

### Section Headers

Each card starts with:
- `h3.text-sm.font-medium.text-gray-900` — section title
- `p.text-xs.text-gray-500.mt-0.5` — section description

This matches the existing pattern in Settings page (Weight Unit, Currency, API Keys sections).

---

## Component Specifications

### Email Display Row

```
Email        user@example.com            [Change]
```
- Label: `text-sm font-medium text-gray-700`
- Value: `text-sm text-gray-900`
- Change button: `text-sm text-gray-600 hover:text-gray-800`
- Layout: flex with justify-between

### Email Change Dialog

Modal dialog triggered by "Change" button:
- Title: "Change Email"
- Step 1: Input for new email + "Send verification code" button
- Step 2: Input for verification code + "Verify and update" button
- Cancel link at bottom
- Uses existing modal/dialog pattern if available, otherwise inline expansion

### Password Change Form

- Three inputs: current password, new password, confirm password
- Inputs use existing style: `px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-gray-200`
- Validation hint below form: `text-xs text-gray-400`
- Submit button: `px-4 py-2 text-sm font-medium text-white bg-gray-700 hover:bg-gray-800 rounded-lg`
- For social-only accounts (no password): show "Set Password" with only new + confirm fields

### Account Deletion Confirmation

Dialog/modal with:
- Title: "Delete Account"
- Warning text: `text-sm text-red-600`
- Input: type "DELETE" to confirm — `placeholder="Type DELETE to confirm"`
- Two buttons: "Cancel" (gray outline) and "Delete Account" (red bg)
- Delete button: `px-4 py-2 text-sm font-medium text-white bg-red-600 hover:bg-red-700 rounded-lg`
- Delete button disabled until confirmation text matches

### Member Since Display

```
Member since    April 2026
```
- Format date as "Month YYYY" using `Intl.DateTimeFormat`
- Label: `text-sm font-medium text-gray-700`
- Value: `text-sm text-gray-500`

---

## Copywriting Contract

| Element | Copy |
|---------|------|
| Profile section heading | "Profile" |
| Profile section description | "Your public profile information" |
| Account section heading | "Account" |
| Account section description | "Your account information" |
| Security section heading | "Security" |
| Security section description | "Manage your password" |
| Danger zone heading | "Danger Zone" |
| Danger zone description | "Delete your account and all personal data. Public setups will be attributed to \"Deleted User\"." |
| Password change CTA | "Change Password" |
| Password set CTA (no existing) | "Set Password" |
| Email change CTA | "Change" |
| Delete account CTA | "Delete Account" |
| Delete confirmation prompt | "This action is permanent. Type DELETE to confirm." |
| Password validation hint | "Password must be at least 8 characters with uppercase, lowercase, and a number." |
| Email verification prompt | "Enter the verification code sent to {email}" |
| Password change success | "Password updated" |
| Email change success | "Email updated" |
| Account deleted redirect | Redirect to /login (no in-app message) |
| Empty email state | "No email on file" |

---

## Interaction States

### Password Change

| State | UI |
|-------|-----|
| Idle | Form with empty fields |
| Submitting | Button text "Changing..." + `disabled:opacity-50` |
| Success | Green message "Password updated" (same pattern as ProfileSection) |
| Error (wrong current) | Red message "Current password is incorrect" |
| Error (policy) | Red message "Password does not meet requirements" |

### Email Change

| State | UI |
|-------|-----|
| Idle | Email displayed with "Change" link |
| Dialog open | New email input + send code button |
| Code sent | Verification code input + verify button |
| Verifying | Button text "Verifying..." + disabled |
| Success | Dialog closes, email display updated |
| Error | Red message below input |

### Account Deletion

| State | UI |
|-------|-----|
| Idle | "Delete Account" button in Danger Zone |
| Dialog open | Warning + confirmation input + disabled delete button |
| Confirmation typed | Delete button enabled (red) |
| Deleting | Button text "Deleting..." + disabled |
| Complete | Redirect to /login |

---

## Registry Safety

| Registry | Blocks Used | Safety Gate |
|----------|-------------|-------------|
| No registries | none | not required |

All components are custom, matching existing GearBox patterns. No third-party UI component registries used.

---

## Responsive Behavior

- Page max-width: `max-w-2xl mx-auto` (matches Settings page)
- Padding: `px-4 sm:px-6 lg:px-8 py-6` (matches Settings page)
- Cards stack vertically at all breakpoints
- No horizontal layout changes needed — single-column at all sizes

---

## 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:** pending
