# Onboarding

The onboarding flow is the first touchpoint with Solid. It should feel like the product: sparse, confident, and intentional. The user creates an account, then tells us how they plan to use Solid. Everyone who signs up goes through the same setup flow and lands on a dashboard while we bring new workspaces online gradually. The free-text response helps us understand likely use cases and prioritize follow-up, but the experience should feel like setup, not an application or marketing waitlist.

---

## Tone

Minimal, functional, practical. Good taste. Every piece of copy should sound like a person wrote it, not a marketing team. The experience should communicate that we read every submission, that there's a human on the other side, and that we may reach out to learn more. Never imply possible rejection — the framing is setup and activation timing, not gatekeeping. Use "when," not "if." Avoid "waitlist," "early access," "request access," and "apply" in user-facing copy before the dashboard.

---

## Landing Page

### Layout

A single centered column (max-width 580px, vertically anchored at ~28vh) on a clean white page. No sidebar, no navigation, no header bar. The page is the experience.

### Content (top to bottom)

**Headline:**

> Most AI tools help you do the work. Solid does the work. You describe what you need, you get the result.

Draws a clean line between Solid and everything else in the first two sentences. The third sentence implies the product's autonomy through omission — the gap between "you describe" and "you get the result" is Solid. No fake urgency, no "limited spots." The user should understand the product before they understand activation timing.

**Primary action — Google login:**

A "Continue with Google" button. This is the only auth path — one click, account created, name and email handled automatically. No email/password fallback.

### Visual Treatment

Follows the global design system (see `design.md`): monochrome, flat, no gradients or shadows. Geist Mono for all direct-address copy — headline, messages, greeting — extending the product's convention that conversational text is set in mono. Geist Sans for UI chrome: buttons, links, form inputs, labels, and hints. The Google button uses a simple bordered style consistent with the monochrome palette — no Google branding colors.

---

## Account Creation

Google OAuth only.

1. User clicks "Continue with Google."
2. Standard Google OAuth flow completes.
3. Account is created using their Google name and email.
4. User is taken directly to the workspace setup page.

One click. No form fields.

---

## Workspace Setup

After account creation, the user sees a single focused page.

### Layout

Same centered column (max-width 580px, 28vh anchor). The user's name is known at this point from their Google profile.

### Content

**Greeting:**

> Welcome, [first name].

Warm, acknowledges they just arrived. Earned, not performative.

**Setup field — placeholder: "How do you plan to use Solid?"**

A boxed auto-growing textarea using the standard composer pattern (see `design.md`). The question lives in the placeholder text — no separate label above the field. This keeps the page clean and lets the textarea feel open and inviting.

**Submit button:** "Set up workspace" — clear, practical, and framed as provisioning rather than asking permission. Supports Cmd/Ctrl+Enter as a keyboard shortcut.

**Log out:** A subtle link below the submit button for users who logged into the wrong account.

---

## Workspace Preparation

After submitting the setup details, the user sees a brief interstitial state:

> Preparing your workspace...

Centered, same column width, same visual system. Uses a blinking terminal cursor animation. This pause should feel like the system is doing real setup work, not theatrically "thinking." Keep it brief and calm — just long enough to make the next state feel like provisioning rather than a form confirmation.

---

## Dashboard

After the preparation state, the user is logged in but their account is inactive. They land on a dashboard — not a dead end, but a deliberate state within the product. The page widens from the setup flow's 580px column to 720px to accommodate the tier grid, and shifts from the 28vh vertical anchor to a fixed 64px top padding since the content is taller.

### Layout

The page is divided into two conceptual zones separated by generous spacing:

**Header zone** — the user's identity and status, grouped tightly (32px between them):

- **Identity bar:** User's name on the left, "Log out" on the right. Ambient, not prominent.
- **Status line:** A pulsing amber dot followed by "Solid is at capacity." Below, an explanation: "You'll get an email at [email] when your workspace is ready."

This is the first moment the user learns that access is paced by capacity. No progress bar, no position number, no estimated time, and no "waitlist" language. Just a clear statement of what's happening and the assurance that "when" — not "if" — their workspace will be ready.

**Action zone** — things the user can do while waiting, grouped tightly (32px between sections) and separated from the header by a larger gap (56px):

### Access Code

An optional input for users who have a code. The section header uses a prompt-style label ("If you have a special code") rather than an uppercase section label — the phrasing makes it clear this isn't required. The code section remains visible in both waiting and activated states, since codes can apply discounts or bonuses at any point.

A compact input row: monospace text field (160px wide), "Apply" button, and inline feedback to the right of the button. Valid codes show "Code applied." Invalid codes show "Code not recognized." Both messages persist in the same format — invalid feedback clears when the user starts typing a new code. The input stays enabled after a valid code so users can enter additional codes.

### Plan Pre-Selection

A 3-column tier grid (Starter / Pro / Max) matching the tiers defined in `monetization.md`. The prompt above the grid: "Choose a plan for when your workspace opens."

Below the grid, a trust-building note: "No charge right now. We'll confirm with you before any billing." This copy should feel slightly quieter than the tier content but not invisible — it's doing important trust work.

Clicking a tier selects it (inset border + checkmark "Selected"). Hovering a selected tier swaps the status to an underlined "Remove" link — clicking the link deselects. Clicking the card itself only selects, never toggles. The entire tier card is the click target (with `role="button"` and keyboard support), not a nested button. This interaction pattern is shared across both waiting and activated modes.

### Payment Method

The section header: "Add a payment method so you're ready when your workspace opens." A bordered row with "+ Add payment" centered as the action. The entire row is clickable when no payment is on file — users don't need to target a small button.

### Phone Verification

Phone verification uses an inline SMS flow. The section header doubles as the status message — it updates at each step to provide context without separate inline feedback.

**Step 1 — Enter phone number.** Header: "Add a phone number to secure your account." A bordered input row (matching the payment row container): phone input field (`type="tel"`, placeholder "Phone number") and "Send code" button.

**Step 2 — Enter verification code.** Header updates to: "We sent a code to [number]." This confirms which number received the code. The phone input is replaced by a 6-digit code input (placeholder "000-000") + "Verify" button. A "Resend code" text link appears below the input. Clicking it updates the header to "Code resent to [number]."

**Verified state.** Header updates to: "Phone verified." The section shows a settled display: the verified phone number with a checkmark, and a hover-revealed "Change" action. Same row pattern as the payment section's "has-payment" state.

### Confirmation

When plan, payment, AND phone are all complete, the three sections fade out together, then a confirmation card fades in:

- Header: checkmark + "You're all set."
- Rows: Plan name, Payment card details, Phone number
- Hover-revealed actions: "Change" (returns to plan selection), "Remove" (clears payment), "Change" (phone)
- Below the card: "No charge right now. We'll confirm with you before any billing."

All three are required — the confirmation card only appears when all three are set.

### Layout

Plan selection, payment, and phone verification are all visible from the start. They are peers, not progressive steps — the user can complete them in any order. The access code section sits above these three.

When all three are complete, the sections fade out and the confirmation card fades in. Each transition uses the standard opacity fade (0.15s) with a 160ms stagger. Users can always go back — "Change" and "Remove" actions on the confirmation card reopen the relevant sections.

### Return Visits

If the user comes back and logs in before being approved, they see the same dashboard with their previous selections intact. This is intentional — it confirms setup is complete and nothing is broken.

---

## Activation Priority (Internal)

The team reviews setup responses and prioritizes activation based on:

- Quality and specificity of the setup response — detailed, concrete responses indicate someone who will stress-test the product and give useful feedback
- Use case fit with what v0 can deliver
- Plan and payment pre-selection — users who pre-select a plan and add payment demonstrate serious intent
- Follow-up conversations via email (if initiated)

Everyone gets in eventually. The setup response helps determine order, not admission.

---

## Activation

Activation is the moment a user's workspace goes from pending to live. It can happen two ways (by code or by backend), with or without a discount, and the user may have pre-selected a plan, added a payment method, both, or neither. This produces 16 theoretical combinations. The design handles all of them through a small number of reusable states, not 16 bespoke screens.

The core principle: activation changes the dashboard from a waiting state into a subscription state. The user must explicitly choose a plan and confirm billing before entering the workspace. No surprise charges, no silent transitions to paid.

### Activation Methods

**By code.** The user enters a valid activation code on the dashboard. The dashboard transforms in place to the activated state. This is the same access code input from the waiting dashboard, but now the code's effect includes workspace activation.

**By backend.** An admin activates the user's account. The user receives an email and sees the activated state on their next visit. No client-side transition needed — the page loads directly into the activated state.

Both methods converge on the same activated dashboard. The method affects the transition, not the destination.

### Activation Types

**Normal.** The workspace is activated. The user can now subscribe at standard pricing.

**Discount.** The workspace is activated with a promotional discount attached to the account. Discounts are defined as: **[X]% off up to $[Y]/mo for [Z] months** — a percentage discount capped at a flat dollar amount per month. After the promotional period, the full price applies.

### The Scenario Matrix

Four pre-selection states crossed with two activation methods (code, backend) and two activation types (normal, discount) gives 16 theoretical combinations. Since code and backend produce the same resulting dashboard (the user just arrives there differently), this reduces to **8 scenarios that resolve into 4 distinct flows:**

| # | Pre-selection | Discount? | Arrives via | Flow |
|---|---|---|---|---|
| 1 | Nothing | No | Code or Backend | **A** |
| 2 | Nothing | Yes | Code or Backend | **B** |
| 3 | Plan only | No | Code or Backend | **A** |
| 4 | Plan only | Yes | Code or Backend | **B** |
| 5 | Payment only | No | Code or Backend | **A** |
| 6 | Payment only | Yes | Code or Backend | **B** |
| 7 | Both | No | Code or Backend | **A** |
| 8 | Both | Yes | Code or Backend | **B** |

**Flow A — Standard pricing.** The activated dashboard shows plans at full price. The user completes whatever's missing (plan, payment, phone verification), reviews the subscription confirmation, and activates.

**Flow B — Discounted pricing.** Identical to Flow A, but tier cards show discounted prices, the confirmation card shows the full billing trajectory (discounted period + post-discount price), and the plan note includes the discount terms.

Within each flow, the number of steps depends on what the user already pre-selected. Phone verification is optional while waiting but **required to activate** — users who verified while waiting skip that step.

| Pre-selection | Steps to workspace |
|---|---|
| Nothing (scenarios 1, 2) | Select plan → Add payment → Verify phone → Confirm → Activate |
| Plan only (scenarios 3, 4) | Add payment → Verify phone → Confirm → Activate |
| Payment only (scenarios 5, 6) | Select plan → Verify phone → Confirm → Activate |
| Both, no phone (scenarios 7, 8) | Verify phone → Confirm → Activate |
| Both + phone verified (scenarios 7, 8) | Confirm → Activate (one click) |

The most streamlined path: a user who pre-selected plan, payment, AND verified their phone while waiting is one click from the workspace at activation.

### The Activated Dashboard

When a workspace is activated, the dashboard transforms in place. Layout stays at 720px max-width with 64px top padding. The identity bar (name + log out) remains.

**Status section transforms into a centered hero.** The waiting status line (amber dot + "Solid is at capacity") is replaced by a centered block: the Solid hex icon, "Welcome to Solid, [first name]." as a page title (20px, 600 weight), and a green badge ("Your workspace is ready" with a `--status-green` dot). This hero is the first thing the user sees — it should feel like an arrival, not a status update.

**Access code section remains visible.** The code input stays available after activation so users can enter discount or bonus codes at any point.

**Plan section copy updates, but interaction stays the same.** The prompt changes from "Choose a plan for when your workspace opens" to "Choose a plan to get started." Tier cards keep the same toggle-select pattern as waiting mode — click to select (border + checkmark "Selected"), hover to reveal underlined "Remove" link. Both modes share the same card interaction so the experience feels continuous, not like a different page. If the user previously pre-selected a plan, that tier starts in the selected state.

**Payment, phone, and confirmation** work the same as waiting mode but with updated copy. Payment prompt changes to "Add a payment method to start your subscription." Phone prompt changes to "Verify your phone number to activate your workspace." All three sections (plan, payment, phone) are visible from the start — same peer layout as waiting mode. If the user completed any of these while waiting, they carry over.

**The subscription confirmation card** (see below) appears when all three are complete: plan selected + payment added + phone verified. Pre-selections carry over, so a user who completed everything while waiting sees the confirmation card immediately on activation.

### Discount Display

**Discount math.** The percentage applies to the plan price, capped at a flat dollar amount per month. Example: 100% off up to $40/mo for 2 months.

| Plan | Base price | 100% off | Cap | User pays | Actual savings |
|---|---|---|---|---|---|
| Starter ($40) | $40 | $40 | $40 | **$0/mo** | $40/mo (percentage = cap) |
| Pro ($160) | $160 | $160 | $40 | **$120/mo** | $40/mo (cap governs) |
| Max ($640) | $640 | $640 | $40 | **$600/mo** | $40/mo (cap governs) |

The cap kicks in at Pro and above. When the percentage discount exceeds the dollar cap, the discount is limited to the cap amount.

**Tier card display (discounted).** Each tier card shows the discounted price as the primary number (32px) with the original price struck through next to the period label ("~~$160~~ / month" in `--text-tertiary`). No per-card discount labels or terms — the tier cards stay clean and scannable. The discount explanation lives in the plan note below the grid.

**Plan note (discounted).** When a discount is active, the note below the tier grid changes from "Billed monthly. Cancel anytime." to: "Includes [X]% off up to $[Y]/mo for [Z] months. After that, you'll be billed at the full price shown. Cancel anytime." This is the single place discount terms are explained — not scattered across the hero and individual cards.

**Discount in the confirmation step.** The subscription confirmation card shows the full billing trajectory in the plan row detail text:

- Normal: "Pro $160/mo"
- Discounted: "Pro ~~$160~~ $120/mo for 2 months, then $160/mo"

The note below the card: "Includes [X]% off up to $[Y]/mo for [Z] months. You'll be charged $[discounted] today. Cancel anytime."

### Subscription Confirmation

This is the gate between the activated dashboard and the workspace. No user enters the workspace without explicitly confirming their subscription through this step.

The confirmation card appears when the user has a plan selected, a payment method on file, AND a verified phone number. All three are required in activated mode. The card should feel like a green light, not a checkout form — the user already made their choices.

**Rows:**

- **Plan:** Plan name in 500 weight with price in `--text-tertiary` detail text. Normal: "Pro $160/mo". Discounted: "Pro ~~$160~~ $120/mo for 2 months, then $160/mo". Hover-revealed "Change" action reopens the tier grid.
- **Payment:** "Visa ending in 4242" with a hover-revealed "Change" action.
- **Phone:** Verified phone number (e.g., "+1 (555) 123-4567") with a hover-revealed "Change" action. Same row-expand pattern as the other rows.

**Action:** A primary button: **"Activate Workspace."** Clear, action-oriented, names the outcome. The charge amount is made explicit in the note below, not in the button text.

**Below the card:** "You'll be charged $[price] today. Cancel anytime." For discounted plans: "Includes [X]% off up to $[Y]/mo for [Z] months. You'll be charged $[discounted] today. Cancel anytime." Clear, specific, no ambiguity about what clicking the button does.

**Steps to workspace:** All three (plan, payment, phone) must be complete. The user completes them in any order. Once all three are set, the confirmation card appears. "Activate Workspace" enters the product.

| Pre-selection | What's left |
|---|---|
| Nothing | Complete all three → Confirmation → Activate |
| Plan only | Add payment + verify phone → Confirmation → Activate |
| Payment only | Select plan + verify phone → Confirmation → Activate |
| Plan + payment | Verify phone → Confirmation → Activate |
| All three | Confirmation → Activate (one click) |

### Code-Based Activation Transition

When a user enters a valid activation code on the dashboard:

1. User types code, clicks "Apply" (or Enter).
2. On success, inline feedback shows "Code applied" (same position as current feedback).
3. After a 600ms pause (enough to read the feedback), the dashboard transitions:
   - The waiting status line hides. The activated hero appears: hex icon scales in (`hexReveal`, 0.2s), then the title and badge stagger-fade in (`activatedFadeIn`, 0.1s offsets).
   - Plan section prompt and trust note update to subscription language.
   - Tier cards update: discount prices appear if applicable, pre-selected plan stays in selected state.
4. If the user had plan + payment pre-selected, the subscription confirmation card appears with an "Activate Workspace" button. They are one click from entering.

**Invalid codes** work as currently specified: "Code not recognized" feedback, input stays enabled, clears on next input.

**Non-activating codes.** Not all codes activate the workspace. Some may grant bonus credits or apply a discount for later use. These show "Code applied" feedback and the dashboard remains in its waiting state with whatever bonus was granted. The activation flow only triggers when a code's effect includes workspace activation. This distinction is backend logic; the frontend checks an activation flag in the response.

### Backend Activation

When an admin activates a user's workspace, the user receives an email.

**Email (normal activation):**

> **Subject:** Your Solid workspace is ready
>
> Hey [first name],
>
> Your workspace is ready. Choose a plan and you're in.
>
> **[Open Solid →]**
>
> — Solid

"Choose a plan and you're in" sets the expectation that subscribing is the next step, so they arrive at the dashboard knowing there is one more thing to do. The link takes them to the Solid dashboard, not directly into the workspace.

**Email (discount activation):**

> **Subject:** Your Solid workspace is ready
>
> Hey [first name],
>
> Your workspace is ready, and we've added a discount to your account: [X]% off up to $[Y]/mo for [Z] months. Choose a plan and you're in.
>
> **[Open Solid →]**
>
> — Solid

The discount terms appear in a single plain sentence. No tables, no "deal" framing, no urgency.

**Return visit.** When a backend-activated user visits the dashboard (from the email link or by navigating to Solid), the page loads directly into the activated state. No transition animation — since they were not watching the page when activation happened, animating would feel arbitrary. Pre-selections are preserved. Discount terms are reflected in pricing if applicable.

### Edge Cases

**Changing plans after seeing discounted prices.** The "Change plan" action on the subscription confirmation card returns the user to the tier grid with discounted prices visible on all tiers. They can compare tiers with full discount math applied, then select a different plan. The confirmation card updates with the new plan's terms. The discount applies to whatever plan they choose.

**Payment-only state.** This occurs when a user added payment but then changed their plan from the confirmation card without reselecting. At activation, the tier grid shows subscribe buttons and payment is on file. When they select a plan, the confirmation card appears immediately with their existing payment, skipping the payment step.

**Discount terms start at subscription, not activation.** The promotional period (e.g., 2 months) begins at the moment of first subscription, not at activation. If a user is activated but doesn't subscribe for days or weeks, the discount remains available. This prevents urgency pressure and avoids punishing users who take time to decide.

**Logout and return during code activation transition.** If a code-activated user closes the browser mid-transition, their next visit shows the settled activated state. Activation is server-side; the transition animation is a client-side nicety, not a state dependency.

**Access codes after activation.** The access code section remains visible after activation so users can enter discount or bonus codes at any point. The promo code input on the subscription page (`monetization.md`) is a separate system for post-subscription codes.

---

## Approval

This section is now covered by the backend activation path in the Activation section above. The emails, return visit behavior, and resulting dashboard state are all defined there.

---

## First Entry

On first login after activation and subscription confirmation, the user lands directly in their workspace with the empty chat view as defined in `workspace.md`. No tutorial overlay, no product tour, no tooltips. The interface is simple enough that it shouldn't need explanation.

The subscription step (choosing a plan, confirming billing, clicking "Subscribe and open workspace") is the final gate. Once the user subscribes, they enter immediately. There is no separate "entering for the first time" moment — the subscribe action *is* the entrance.

They see: a centered text input, autofocused, blinking cursor. Ready to describe what they want to accomplish. They type, the agent gets to work, and they're in.

The entire arc — from landing page to first conversation — should feel like one continuous experience.

---

## Summary

| Step | What happens | What they feel |
|---|---|---|
| **Land** | See the landing page | "This looks different. Intentional." |
| **Auth** | Continue with Google (one click) | "Quick. No unnecessary fields." |
| **Setup** | Describe how they plan to use Solid, hit "Set up workspace" | "This feels like getting set up, not applying." |
| **Prepare** | See "Preparing your workspace..." | "They're setting this up." |
| **Dashboard** | See status, pre-select a plan, optionally add payment | "I'm set up. They'll email me when it's ready." |
| **Activate** | Workspace activated by code or email | "I'm in. One more step." |
| **Subscribe** | Choose/confirm plan, confirm billing, enter workspace | "Clear, fair, no surprises." |
| **Enter** | Land in workspace, cursor blinking | "What do I want to build?" |
