Skip to content

Phase 7 — Teams Surfaces & Wireframes

Status: Discovery / Design companion Source PRD: phase-7-teams-prd.mdLast updated: 2026-07-12 Owner: Josh Lockhart

This document is the surface inventory and low-fidelity wireframe set for every screen, panel, modal, and email that the Teams V1 (and V1.1 shape-only) work introduces or modifies. It is the bridge between the PRD's prose (§7 deep specs, §8 V1.1 sketches) and the Claude Design / Vue implementation work.

It is intentionally tool-agnostic (ASCII boxes, not Figma) so it can be reviewed inside a PR, pasted into a Claude Design prompt, or printed on a wall.


0. How to read this doc

  • NEW = surface does not exist in master today; create from scratch.
  • MODIFIED = surface exists; this work touches it.
  • EMBEDDED = sub-component / banner / strip that lives inside another surface.
  • EMAIL / NOTIFICATION = transactional or lifecycle artifact (no in-app screen).

Each entry has: purpose · personas · trigger · scope (V1 / V1.1 / V1.2) · file targets · wireframe.

Wireframes are mobile-first (390px). A ─┐ tablet/desktop: annotation marks where the layout reflows. All copy is illustrative; final copy ships under the brand-voice filter (see tightening-brand-voice).

The data-boundary contract (PRD §6) governs every admin-visible element. Anywhere a wireframe shows admin-only data, assume the §6 redaction rules already apply.


1. Surface map at a glance

1.1 New surfaces (V1)

#SurfacePersonasWhere
N1Pricing page — Teams tierAnonymous, adminmarketing_landing/index.html + new /pricing/teams panel
N2In-app Teams upgrade bannerCommunity adminTop of any community admin sees
N3Team creation / plan selector — /teams/newTeam OwnerNew view
N4Clerk Billing checkout (external)Team OwnerStripe-hosted; we return to step N5
N5Team provisioning success → invite empty stateTeam OwnerNew view (lands inside Team Settings)
N6Convert existing community → Team flowCommunity adminNew modal off Community Settings
N7Team Settings shell (tabbed)Owner, AdminNew view
N7aTeam Settings · Billing tabOwnerSubtab
N7bTeam Settings · Members tabOwner, AdminSubtab
N7cTeam Settings · Sub-Communities tabOwner, AdminSubtab
N7dTeam Settings · Invites tabOwner, AdminSubtab
N7eTeam Settings · Privacy panel previewOwner, AdminSubtab (read-only reflection of N18)
N8Invite-member modal (link + email)Owner, AdminModal off N7d
N9Create-sub-community modalOwner, AdminModal off N7c
N10Archive-sub-community confirmOwner, AdminModal off N7c
N11Public join landing — /join-team/{code}Invitee (anon or signed-in)New view
N12Sub-Community Browser (self-select)New team memberNew view, first session after invite accept
N13Team Home — dashboard with sub-community switcherMember, AdminNew view
N14Sub-Community switcher (sidebar/top-bar)MemberEmbedded nav
N15Team-wide Collective Progress cardMemberEmbedded in N13
N16Collective Goal detail viewMember, AdminNew view
N17Collective Goal opt-in modalMemberModal off any personal goal
N18Privacy contract panel — "What [Team] can see"MemberNew view, off member settings
N19Team Leaderboard view (scope × period toggles)MemberNew view
N20Leaderboard opt-out toggleMemberEmbedded in member settings
N21Monday Recap (in-app card)MemberNotification + in-app card
N22Trial-ending / past-due / grace bannerOwnerEmbedded at top of Team chrome
N23Team email — inviteInviteeTeamInviteMailer
N24Team email — trial ending in 3d / payment failedOwnerTrialEndingSoonJob, billing emails
N25Team email — welcome / upgraded / downgradedOwner, membersTeamUpgradedJob, TeamDowngradedJob
N26Seat-cap blocker modalOwner, Admin, member-being-invitedModal off invite flow

1.2 New surfaces (V1.1+ shape-only)

#SurfaceVWhere
N27Bulk CSV inviteV1.1Subtab N7d extension
N28Team Admin Dashboard (analytics)V1.1New top-level admin view
N29Custom Badges adminV1.1Inside N7c sub-community settings
N30Manager View (grid of all members)V1.1New top-level admin view
N31Accountability Pair auto-match — opt-in cardV1.1Embedded in N13
N32Sub-community-scoped invite link (lead-shared)V1.1Modal off sub-community settings
N33Per-team brand customization (color, logo)V1.2Subtab inside N7
N34Slack / MS Teams integration configV1.2Subtab inside N7
N35External Coach role managementV1.2Extension to N7b

1.3 Modified existing surfaces

#Existing surfaceWhat changes
M1Community feed (CommunityView.vue and equivalents)If community.team_id set, gains team chrome: sub-community switcher (N14), Collective Progress card (N15), Team Leaderboard CTA
M2Community Settings"Upgrade to Teams" entry → opens N6; existing private community owners get the conversion flow
M3Marketing landing (marketing_landing/index.html)New "Teams" nav item; new Teams pricing panel (N1)
M4App side-nav / root tab bar"Teams" group appears in nav when user has ≥1 TeamMembership; team switcher if ≥2
M5User settings → PrivacyNew row linking to N18 ("What your teams can see")
M6User profile (own)"Member of [Team A], [Team B]"; "Previously a member of [Team C]"
M7Personal Goal detail (GoalView.vue)New "Contributing to: [Collective Goal]" row + opt-in/opt-out from N17
M8Personal Goal create flowAt create-time, if user is in a Team with active matching collective goal, surface opt-in (no auto-link)
M9Notifications inboxNew categories: team_invite, team_billing, monday_recap, collective_goal_milestone
M10Onboarding (post-signup)Net-new step inserted only when signup arrived via team invite: lands on N11 → N12 instead of personal-goal seed flow
M11Admin Dashboard (admin_dashboard/)New top-level "Teams" view: list of Teams, MRR, churn, seat utilization (internal Objectuve admins only)
M12Mailer base layoutTeam emails carry team logo / brand color (V1.2); V1 they reuse Objectuve chrome
M13GraphQL Apollo cache shapesExisting Community queries gain optional team {…} field; UI components read it to decide whether to render team chrome
M14Feature flag registry (featureFlags.ts + PostHog)Adds teams_enabled, teams_billing_v1, teams_collective_goals, teams_leaderboards, teams_bulk_invite

2. NEW surfaces — wireframes

N1 · Pricing page — Teams tier

Purpose: Public-facing pricing surface; primary acquisition lever for the coach + corporate-wellness ICPs. Personas: Anonymous visitor, signed-in community admin. Trigger: Marketing nav /pricing → Teams panel; or in-app Upgrade to Teams CTA. Scope: V1 (panel launched at GA; teams_enabled retired 2026-07-08 — PR #1498, OBJ-1096 — no flag gate remains). File targets: marketing_landing/index.html (Teams panel); link from in-app upgrade banner (N2).

┌──────────────────────────────────────────────────────────────┐
│  Objectuve   Product  Mission  Pricing  Sign in   [Sign up] │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   Pricing                                                    │
│   ┌────────────┐  ┌────────────┐  ┌────────────────────┐    │
│   │  Personal  │  │ Supporter  │  │      TEAMS         │    │
│   │   Free     │  │  $3/mo     │  │   $7 / user / mo   │    │
│   │  Forever   │  │  Cosmetic  │  │   or $70 / yr      │    │
│   │            │  │  perks     │  │   (save ~17%)      │    │
│   │            │  │            │  │                    │    │
│   │ • Goals    │  │ • Themes   │  │ Everything in      │    │
│   │ • Habits   │  │ • Badges   │  │ Personal, plus:    │    │
│   │ • Coach    │  │ • Aura     │  │ • Private team     │    │
│   │ • Streaks  │  │            │  │ • Sub-communities  │    │
│   │            │  │            │  │ • Collective goals │    │
│   │ [Get app]  │  │ [Become]   │  │ • Leaderboards     │    │
│   │            │  │            │  │ • Coach role       │    │
│   │            │  │            │  │                    │    │
│   │            │  │            │  │ [Start free trial] │    │
│   └────────────┘  └────────────┘  └────────────────────┘    │
│                                                              │
│   What's a team?                                             │
│   For coaching cohorts, wellness teams, and school groups.   │
│   One owner pays; up to 200 members; private by default.    │
│                                                              │
│   Compared to: Slack ($7.25), Asana ($10.99)                 │
│                                                              │
│   ▸ Member privacy contract  ▸ FAQ  ▸ Talk to a human       │
└──────────────────────────────────────────────────────────────┘

N2 · In-app Teams upgrade banner

Purpose: Convert existing private-community admins. Personas: Community admin (private community ≥3 members). Trigger: Any time a community admin opens their community (no flag gate — teams_enabled retired at GA, PR #1498). Scope: V1. File targets: New <TeamsUpgradeBanner.vue> injected at top of community feed when community.team_id is null and user is admin.

┌──────────────────────────────────────────────────────────────┐
│ ✨  Make this a Team — collective goals, leaderboards,       │
│     and seats your members can share. 14-day free trial.     │
│                                          [Learn more] [×]    │
└──────────────────────────────────────────────────────────────┘

Dismissal persists per (admin_user_id, community_id). Re-surfaces after 30 days.


N3 · Team creation / plan selector — /teams/new

Purpose: Capture intent → Stripe checkout. Personas: Team Owner. Trigger: N1 CTA, N2 CTA, or direct nav. Scope: V1. File targets: ionic_frontend/src/views/teams/CreateTeamView.vue.

┌──────────────────────────────────────────────────────────────┐
│  ← Back                            Step 1 of 2 · Team setup  │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   Start your team                                            │
│   You'll get a 14-day free trial. No card needed today.      │
│                                                              │
│   ┌──────────────────────────────────────────────────────┐  │
│   │ Team name                                             │  │
│   │ ┌───────────────────────────────────────────────────┐ │  │
│   │ │ e.g. Habit Lab                                    │ │  │
│   │ └───────────────────────────────────────────────────┘ │  │
│   │ This becomes your default sub-community name too.    │  │
│   └──────────────────────────────────────────────────────┘  │
│                                                              │
│   Billing                                                    │
│   ┌────────────────────┐  ┌────────────────────────────┐    │
│   │  ○ Monthly         │  │  ● Annual (save ~17%)      │    │
│   │  $7 / user / mo    │  │  $70 / user / yr           │    │
│   └────────────────────┘  └────────────────────────────┘    │
│                                                              │
│   Seats                                                      │
│   [ − ]   5 seats   [ + ]      $35 / mo after trial          │
│   (You're seat 1 of 5. Add or remove anytime.)               │
│                                                              │
│                       [ Start 14-day trial → ]               │
│                                                              │
│   By starting, you agree to Objectuve's terms. Your team's   │
│   members will never have their personal data shown to you.  │
└──────────────────────────────────────────────────────────────┘

N4 · Clerk Billing checkout (Stripe-hosted)

Out-of-app — Stripe Checkout UI. No wireframe needed. Return URL hits Teams::ProvisionTeam interaction (PRD §7.1).


N5 · Team provisioning success → invite empty state

Purpose: First moment of value — owner sees their team is real, gets pushed to invite. Personas: Team Owner. Trigger: Webhook checkout.session.completed → redirect. Scope: V1. File targets: Lands directly on TeamSettingsView.vue (N7) with Invites tab (N7d) selected and a one-time celebration strip.

┌──────────────────────────────────────────────────────────────┐
│ ✓ Habit Lab is live. 14-day trial — no card needed yet.      │
├──────────────────────────────────────────────────────────────┤
│ Settings  ▾  [Billing][Members][Communities][Invites][Privacy]│
├──────────────────────────────────────────────────────────────┤
│                                                              │
│   Invite your team                                           │
│                                                              │
│   ╭──────────────────────────────────────────────────────╮  │
│   │  🔗 Share your team link                              │  │
│   │  https://app.objectuve.com/join-team/h7k2-9xp4-…     │  │
│   │                                       [Copy] [QR]    │  │
│   ╰──────────────────────────────────────────────────────╯  │
│                                                              │
│   Or send by email                                           │
│   ┌──────────────────────────────────────────────────────┐  │
│   │ devon@example.com, priya@…                            │  │
│   │                                                       │  │
│   └──────────────────────────────────────────────────────┘  │
│   [ Add a personal note ▾ ]                                  │
│                                  [ Send invites (2) ]        │
│                                                              │
│   No one's joined yet. We'll show you here as soon as they  │
│   do.                                                        │
└──────────────────────────────────────────────────────────────┘

N6 · Convert existing community → Team

Purpose: Preserve existing private community when owner upgrades. Personas: Community admin. Trigger: N2 banner CTA inside an existing private community. Scope: V1. File targets: Modal <UpgradeCommunityToTeamModal.vue> mounted from Community Settings.

┌──────────────────────────────────────────────┐
│ Upgrade [Community name] to a Team           │
├──────────────────────────────────────────────┤
│ What stays the same                          │
│ • All 8 members keep their access            │
│ • Your community feed is preserved           │
│ • Posts, goals, encouragements — all intact  │
│                                              │
│ What you'll unlock                           │
│ • Collective goals across the team           │
│ • Weekly leaderboards                        │
│ • Multiple sub-communities (optional)        │
│ • Member seat management                     │
│                                              │
│ Pricing                                      │
│ $7 × 8 seats = $56/mo  ($70/yr/seat option)  │
│ 14-day free trial. No card needed today.     │
│                                              │
│ [ Cancel ]            [ Continue to plan → ] │
└──────────────────────────────────────────────┘

N7 · Team Settings shell (tabbed)

Purpose: All admin operations live here. Personas: Owner (full), Admin (no Billing tab). Trigger: Side-nav Settings icon inside Team Home. Scope: V1. File targets: TeamSettingsView.vue with <router-view>-style tab switching.

┌──────────────────────────────────────────────────────────────┐
│ ← Habit Lab                                                  │
│ Team settings                                                │
├──────────────────────────────────────────────────────────────┤
│ [Billing] [Members] [Communities] [Invites] [Privacy]        │
│                                                              │
│  ↓ tab content renders here                                  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

(Owner sees all 5 tabs; Admin sees 4 — Billing hidden.)


N7a · Team Settings · Billing

┌──────────────────────────────────────────────────────────────┐
│ Plan                                                         │
│ ╭──────────────────────────────────────────────────────────╮ │
│ │ Annual · $70 / user / yr                                  │ │
│ │ 8 seats · $560 / yr  ·  Renews 2027-08-12                 │ │
│ │ [ Switch to monthly ]   [ Change seats ]                  │ │
│ ╰──────────────────────────────────────────────────────────╯ │
│                                                              │
│ Billing owner                                                │
│ Maya Okonkwo (you)              [ Transfer ownership → ]     │
│                                                              │
│ Payment method                                               │
│ Visa •••• 4242                  [ Update via Stripe → ]      │
│                                                              │
│ Invoices                                                     │
│ • 2026-08-12 · $560.00 · Paid     [Download PDF]             │
│ • 2026-05-12 · $35.00  · Paid     [Download PDF]             │
│                                                              │
│ Danger zone                                                  │
│ [ Cancel subscription ]                                      │
└──────────────────────────────────────────────────────────────┘

N7b · Team Settings · Members

┌──────────────────────────────────────────────────────────────┐
│ Members (8 of 8 seats)                  [ Add seats + ]      │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 🔍 Search           Filter ▾ Role  Sub-community  Status │ │
│ └──────────────────────────────────────────────────────────┘ │
│                                                              │
│ ● Maya O. (you)   Owner    Joined 4/12    Active today  ⋮   │
│ ● Devon S.        Member   Joined 5/03    Active 2d ago ⋮   │
│ ● Priya R.        Lead*    Joined 4/14    Active today  ⋮   │
│ ● Marcus T.       Lead*    Joined 4/19    Active 4d ago ⋮   │
│ ○ Jules K.        Member   Joined 5/01    Inactive 9d   ⋮   │
│   …                                                          │
│                                                              │
│ * Lead = admin of one sub-community (not team-wide)          │
│                                                              │
│ Pending invites (2)                                          │
│ • alex@example.com   Sent 5d ago  [Resend][Revoke][Copy]    │
│ • amir@example.com   Sent 1d ago  [Resend][Revoke][Copy]    │
└──────────────────────────────────────────────────────────────┘

Row menu: Change role · Remove from team · View team activity (no personal data). Selecting "View team activity" opens a read-only panel scoped per §6.


N7c · Team Settings · Sub-Communities

┌──────────────────────────────────────────────────────────────┐
│ Sub-communities (5 of 10)               [ + New ]            │
│                                                              │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ #welcome     Default · 47 members · 23 check-ins / wk    │ │
│ │  Lobby for team-wide announcements                  ⋮    │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 🌅 Morning Movers  · 18 members · 142 check-ins / wk    │ │
│ │  Lead: Priya R.                                     ⋮    │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 📚 Deep Work Pod   · 12 members · 88 check-ins / wk     │ │
│ │  Lead: Marcus T.                                    ⋮    │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 🥗 Quiet Plate     · 9 members · request-to-join · ⋮    │ │
│ ├──────────────────────────────────────────────────────────┤ │
│ │ 🧗 Weekend Warriors · 14 members · 31 check-ins / wk    │ │
│ │  Lead: Jules K.                                     ⋮    │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘

menu: Edit · Set as default · Archive · Open feed.


N7d · Team Settings · Invites

Mirrors N5 (link + email composer) plus an active-invites table (same as N7b pending section). Bulk CSV (V1.1) appears as an extra panel:

┌──────────────────────────────────────────────────────────────┐
│ Bulk invite (V1.1)                                           │
│ Drop a CSV with `email`, `team_role`, `communities`          │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │  Drop file or [Browse]                                    │ │
│ └──────────────────────────────────────────────────────────┘ │
│ Preview: 24 valid · 1 malformed · [Assign all to ▾]          │
│                                          [ Send invites ]    │
└──────────────────────────────────────────────────────────────┘

N7e · Team Settings · Privacy panel preview

┌──────────────────────────────────────────────────────────────┐
│ What members see about what you (admin) can see              │
│ This is the privacy panel every member can open. Read it.    │
│ ─────────────────────────────────────────────────────────── │
│ You CAN see                                                  │
│ • Team-tagged goals and contributions                        │
│ • Challenge participation                                    │
│ • Leaderboard points earned in the team                      │
│ • Last-active date (day only)                                │
│                                                              │
│ You CANNOT see (ever)                                        │
│ • Personal goals outside the team                            │
│ • Mood logs · Journal · Coach conversations                  │
│ • Lifetime XP / streaks                                      │
│ • Friend graph · IP / device                                 │
│                                                              │
│ [ Open the member-facing version → ]                         │
└──────────────────────────────────────────────────────────────┘

Lifted out of N5 / N7d when triggered from anywhere else (e.g., empty-state CTA in N13).

┌──────────────────────────────────────────────┐
│ Invite to Habit Lab                          │
├──────────────────────────────────────────────┤
│ ◉ Team link (any sub-community)              │
│ ○ Specific sub-community(s) [Pick ▾]         │
│                                              │
│ https://app.objectuve.com/join-team/h7k2…    │
│                              [Copy] [QR]     │
│                                              │
│ ── or email ──                               │
│ ┌──────────────────────────────────────────┐ │
│ │ name@example.com                          │ │
│ └──────────────────────────────────────────┘ │
│ Pre-join: ☐ Morning Movers ☐ Deep Work Pod   │
│                                              │
│           [ Cancel ]       [ Send → ]        │
└──────────────────────────────────────────────┘

N9 · Create sub-community modal

┌──────────────────────────────────────────────┐
│ New sub-community                            │
├──────────────────────────────────────────────┤
│ Icon  [emoji picker — 🌅]                    │
│ Name  ┌────────────────────────────────────┐ │
│       │ Morning Movers                     │ │
│       └────────────────────────────────────┘ │
│ Short description (1 line)                   │
│ ┌──────────────────────────────────────────┐ │
│ │ 5am club. Daily check-ins.                │ │
│ └──────────────────────────────────────────┘ │
│ Join policy                                  │
│  ◉ Open to all team members                  │
│  ○ Request to join (lead approves)           │
│ Lead [pick member ▾]                         │
│ ☐ Make this the default sub-community        │
│                                              │
│       [ Cancel ]            [ Create ]       │
└──────────────────────────────────────────────┘

N10 · Archive sub-community confirm

┌──────────────────────────────────────────────┐
│ Archive “Quiet Plate”?                       │
├──────────────────────────────────────────────┤
│ 9 members will lose access immediately and   │
│ get a one-time notification.                 │
│                                              │
│ Posts and collective goals will be readable  │
│ for 30 days, then archived.                  │
│                                              │
│ You can un-archive within 30 days from the   │
│ Sub-Communities tab.                         │
│                                              │
│       [ Cancel ]      [ Archive ]            │
└──────────────────────────────────────────────┘

N11 · Public join landing — /join-team/{code}

Purpose: Decode invite, route through auth, hand off to N12. Personas: Anonymous or signed-in invitee. Trigger: Invite link click. Scope: V1. File targets: JoinTeamView.vue.

┌──────────────────────────────────────────────────────────────┐
│                                                              │
│        🌱  You're invited to                                 │
│              Habit Lab                                       │
│                                                              │
│        Coached by Maya Okonkwo · 47 members                  │
│                                                              │
│   Maya is inviting you to a private team on Objectuve.       │
│   You'll choose which rooms (sub-communities) to join next.  │
│                                                              │
│        [ Continue ]                                          │
│                                                              │
│   ▸ What can Maya see about me?                              │
│                                                              │
│   New here? You'll create a free Objectuve account first.    │
└──────────────────────────────────────────────────────────────┘

Signed-out → Continue routes through Clerk sign-up → returns here → N12. Signed-in → Continue → N12. Invite invalid/expired/at-cap → shows N26.


N12 · Sub-Community Browser (self-select)

Purpose: The biggest UX moment for multi-community Teams (PRD §7.2). Already deeply specified by phase-7-teams-claude-design-prompt.md — the wireframe below is the structural skeleton. Personas: New team member, first session only (or surfaced again via "Join more rooms" CTA). Trigger: Invite acceptance, only when team.communities.count > 1 AND not all are gated. Scope: V1. File targets: SubCommunityBrowser.vue.

┌──────────────────────────────────────────────────────────────┐
│                                  Step 2 of 2 · Almost there  │
│                                                              │
│        🌱  Habit Lab                                         │
│        Coached by Maya Okonkwo · 47 members                  │
│   You're in. Pick the rooms that match what you're working   │
│   on — you can join more anytime.                            │
│                                                              │
│  ╭──────────────────────────────────────────────────────╮   │
│  │ #welcome   ·  Default                                │   │
│  │ Team-wide intros and Maya's weekly nudges.           │   │
│  │ 47 members                       ✓ You're already in │   │
│  ╰──────────────────────────────────────────────────────╯   │
│                                                              │
│  ╭───────────────────────╮  ╭───────────────────────╮       │
│  │ 🌅 Morning Movers     │  │ 📚 Deep Work Pod      │       │
│  │ 18 members · Priya    │  │ 12 members · Marcus   │       │
│  │ Daily 5am check-ins   │  │ Two 90-min blocks/day │       │
│  │             [ Join ] │  │             [ Join ] │       │
│  ╰───────────────────────╯  ╰───────────────────────╯       │
│  ╭───────────────────────╮  ╭───────────────────────╮       │
│  │ 🥗 Quiet Plate        │  │ 🧗 Weekend Warriors   │       │
│  │ 9 members · Sam       │  │ 14 members · Jules    │       │
│  │ Slow food habits      │  │ Saturday long-form    │       │
│  │  [ Request to join ] │  │             [ Join ] │       │
│  ╰───────────────────────╯  ╰───────────────────────╯       │
│                                                              │
│  ╭──────────────────────────────────────────────────────╮   │
│  │ 🔒  Maya can see your team activity — check-ins,     │   │
│  │ collective contributions, leaderboard points. She    │   │
│  │ cannot see your personal goals, mood, or Coach. Ever.│   │
│  │                                      ▸ How this works│   │
│  ╰──────────────────────────────────────────────────────╯   │
│                                                              │
│            [  Join Habit Lab + 2 rooms  ]                    │
│              Skip for now (default only)                     │
│              I'm not Devon → switch account                  │
└──────────────────────────────────────────────────────────────┘

When team.communities.count == 1, skip this screen entirely — auto-join default and land on N13.


N13 · Team Home — dashboard

Purpose: Member's daily landing once they're inside a Team. Personas: Member, Admin. Trigger: Tab-bar Teams → pick team; or default landing for team-only members. Scope: V1. File targets: TeamHomeView.vue.

┌──────────────────────────────────────────────────────────────┐
│ ☰  Habit Lab ▾                              🔔   👤          │
├──────────────────────────────────────────────────────────────┤
│ Sub-community: [ #welcome ▾ ]                                │
│   (Switcher lists rooms you've joined + "Browse all rooms")  │
├──────────────────────────────────────────────────────────────┤
│ ╭──────────────────────────────────────────────────────────╮ │
│ │ 🎯 Team goal · 1000 check-ins by Aug 31                  │ │
│ │ ▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░  642 / 1000                    │ │
│ │ You're contributing 47.   [ Add another goal → ]          │ │
│ ╰──────────────────────────────────────────────────────────╯ │
│                                                              │
│ Today                                                        │
│ • You logged "Ran 5km" · 2h ago      +5 team pts             │
│ • Priya completed "Read 30 min" · 4h ago                     │
│ • Marcus posted in #welcome · 6h ago                         │
│                                                              │
│ This week                                                    │
│ [ 📊 Leaderboard ]   [ 🏆 Challenges ]   [ 👥 Members ]      │
│                                                              │
│ ╭──────────────────────────────────────────────────────────╮ │
│ │ Monday recap                                              │ │
│ │ Last week you logged 18 check-ins. That's #3 on the team │ │
│ │ — and #1 in consistency.                                  │ │
│ ╰──────────────────────────────────────────────────────────╯ │
└──────────────────────────────────────────────────────────────┘

Trial / past-due / grace banner (N22) sits above the header strip when active.


N14 · Sub-Community switcher

Purpose: Pivot between rooms the member belongs to. Trigger: Tap Sub-community: ▾ in N13 chrome. Scope: V1. Hidden when team.communities.count == 1 or member belongs to exactly one room.

┌──────────────────────────────────────────────┐
│ Switch room                                  │
├──────────────────────────────────────────────┤
│  ● #welcome           47 members             │
│  ○ 🌅 Morning Movers  18 members             │
│  ○ 🧗 Weekend Warriors 14 members            │
│  ──                                          │
│   + Browse all rooms                         │
└──────────────────────────────────────────────┘

N15 · Collective Progress card

Purpose: Always-visible progress on the active collective goal in the current scope (team-wide on N13; sub-community-scoped on M1 community feed). Embedded in: N13, M1.

╭────────────────────────────────────────────────╮
│ 🎯 Team goal · 1000 check-ins by Aug 31        │
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░  642 / 1000               │
│ You're contributing 47.    [ Opt in / out ]    │
╰────────────────────────────────────────────────╯

If member hasn't opted in, primary CTA is "Contribute" → N17.


N16 · Collective Goal detail view

Personas: Member (own contribution + aggregate), Admin (aggregate + per-contributor counts). Scope: V1. File targets: CollectiveGoalDetailView.vue.

┌──────────────────────────────────────────────────────────────┐
│ ← Team goals                                                 │
│                                                              │
│ 🎯 1000 check-ins by Aug 31                                  │
│ Scope: [Team-wide] · Created by Maya · 18 days left          │
│                                                              │
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░  642 / 1000                        │
│                                                              │
│ ╭──────────────────────────────────────────────────────╮    │
│ │ You're contributing your goal:                       │    │
│ │ "Daily run" — 47 check-ins counted toward team       │    │
│ │                       [ Pause contribution ]         │    │
│ ╰──────────────────────────────────────────────────────╯    │
│                                                              │
│ Contributors (admin view)         (members: see counts only) │
│ • Priya R.   142                                             │
│ • Devon S.    98                                             │
│ • Maya O.     76                                             │
│ • Anonymous member · 47                                      │
│ • Marcus T.   42                                             │
│ …                                                            │
│                                                              │
│ 🔒 Your personal goal details are not visible to admins.     │
└──────────────────────────────────────────────────────────────┘

N17 · Collective Goal opt-in modal

Trigger: Tap "Contribute" on N15, or banner on N13, or opt-in row on personal goal (M7).

┌──────────────────────────────────────────────┐
│ Contribute "Daily run" to the team?          │
├──────────────────────────────────────────────┤
│ Your check-ins on Daily run will count       │
│ toward Habit Lab's 1000 check-ins goal.      │
│                                              │
│ You can opt out anytime. Your personal goal  │
│ details — title, notes, history — stay       │
│ private. Only the count is exposed.          │
│                                              │
│ Show me as ◉ Devon S. · ○ Anonymous member   │
│                                              │
│       [ Cancel ]            [ Opt in ]       │
└──────────────────────────────────────────────┘

N18 · Privacy contract panel — "What [Team] can see"

Personas: Member. Trigger: Settings → Privacy → "What [Team] can see"; also linked from N12 "How this works", from M7, from N17. Scope: V1. File targets: TeamPrivacyContractView.vue.

┌──────────────────────────────────────────────────────────────┐
│ ← What Habit Lab can see                                     │
│                                                              │
│ Maya (Team Owner) and Habit Lab admins CAN see               │
│ • Goals you've tagged to Habit Lab or contributed to a team  │
│   goal                                                       │
│ • Challenges you've joined and how you did                   │
│ • Leaderboard points you earned in Habit Lab                 │
│ • Your last-active day (not time)                            │
│ • The sub-communities you've joined                          │
│                                                              │
│ They CANNOT see, ever                                        │
│ • Any personal goal outside Habit Lab                        │
│ • Mood logs · Journal entries · Coach conversations          │
│ • Lifetime XP, streaks, or check-in totals                   │
│ • Other teams you're part of                                 │
│ • Your friends or allies graph                               │
│ • Your IP, device, or location                               │
│                                                              │
│ Exported reports                                             │
│ When Maya exports a CSV, it includes your display name,      │
│ join date, last-active day, and team-scoped points only.     │
│ No email. No personal goal titles.                           │
│                                                              │
│ When you leave                                               │
│ Your team contributions stay attributed as "Former member."  │
│ Your personal account is untouched.                          │
│                                                              │
│ [ Leave Habit Lab ]                                          │
└──────────────────────────────────────────────────────────────┘

N19 · Team Leaderboard view

Personas: Member. Scope: V1. File targets: TeamLeaderboardView.vue.

┌──────────────────────────────────────────────────────────────┐
│ ← Leaderboard                                                │
│                                                              │
│ Scope:  [ Team-wide  ▾ ]      (or pick a sub-community)      │
│ Period: ( Weekly )  ( Monthly )  ( All-time )                │
│                                                              │
│ Mon 8/05 — Sun 8/11                                          │
│                                                              │
│ 1  🥇 Priya R.            186 pts   ↑                        │
│ 2  🥈 Devon S.            142 pts   ↑                        │
│ 3  🥉 You                  98 pts   ↑                        │
│ 4    Maya O.               76 pts   →                        │
│ 5    Marcus T.             42 pts   ↓                        │
│ 6    Anonymous member       38 pts                           │
│ …                                                            │
│                                                              │
│ Your week                                                    │
│ 18 check-ins · 2 milestones · 4 posts · 6 encouragements     │
│                                                              │
│ ▸ How points work          ▸ Opt out of the board            │
└──────────────────────────────────────────────────────────────┘

For single-community teams, scope toggle is hidden.


N20 · Leaderboard opt-out toggle

Embedded in member settings → Privacy:

☐ Show me on Habit Lab's leaderboard
  When off, you still earn points but appear as
  "Anonymous member" on the board.

N21 · Monday Recap (in-app card + push)

Trigger: WeeklyRecapJob Cron, Monday 9am team-timezone. Scope: V1. Push copy: "Habit Lab · last week's recap is ready." (one push max per week per team per member; counts against the §9 1-push/day cap)

╭──────────────────────────────────────────────╮
│ Monday recap · Habit Lab                     │
│ Last week you logged 18 check-ins. That's    │
│ #3 on the team — and #1 in consistency.      │
│ Team hit 642 / 1000 toward the August goal.  │
│                              [ See recap → ] │
╰──────────────────────────────────────────────╯

N22 · Trial-ending / past-due / grace banner

Embedded above the Team chrome on every team screen for the owner.

─── Trial ending in 3 days ─────────────────────────────────────
   Add a payment method to keep your team's leaderboards and
   collective goals.   [ Add card → ]
────────────────────────────────────────────────────────────────

States: trial_ending_3d · past_due · grace_readonly. Each has tailored copy from PRD §7.1.


N23 · Team email — invite (TeamInviteMailer.team_invite_email)

Subject: Maya invited you to Habit Lab on Objectuve

Hi —

Maya Okonkwo invited you to join "Habit Lab", a private
accountability team for productivity coaching.

It's a small team — 47 members. You'd pick which rooms
to join after accepting.

[ Accept invite ]

If you don't recognize Maya, you can safely ignore this
email. The link expires in 14 days.

N24 · Team email — trial ending / payment failed

Variants for T-3d, payment_failed_d0, payment_failed_d3, payment_failed_d6, grace_d7, downgraded_d14. Plain-text-friendly; one primary CTA per email; never alarmist.


N25 · Team email — welcome / upgraded / downgraded

TeamUpgradedJob: short welcome to owner + 14-day trial framing. Conversion-from-community: member-facing note ("Nothing changed for you — just new tools your admin can use.") Downgrade: TeamDowngradedJob to owner with 1-click resubscribe (30-day window).


N26 · Seat-cap blocker modal

┌──────────────────────────────────────────────┐
│ This team is full                            │
├──────────────────────────────────────────────┤
│ Habit Lab is at its 8-seat limit.            │
│                                              │
│ Ask Maya to add a seat or remove a member,   │
│ then try this link again.                    │
│                                              │
│              [ OK ]                          │
└──────────────────────────────────────────────┘

Owner-side variant when adding seats above subscription:

12 members · 10 seats — add 2 seats to continue.
[ Add 2 seats (+$14/mo) ]   [ Remove members ]

3. V1.1+ shape-only wireframes

N27 · Bulk CSV invite

Already shown inside N7d. V1.1 only. PRD §8.9.


N28 · Team Admin Dashboard (analytics)

Scope: V1.1. PRD §8.2. Strictly aggregate per §6.

┌──────────────────────────────────────────────────────────────┐
│ Habit Lab · Dashboard                                        │
├──────────────────────────────────────────────────────────────┤
│ ┌──────────────┐  ┌──────────────┐  ┌──────────────┐        │
│ │ Active 7d    │  │ Active 30d   │  │ Avg streak   │        │
│ │  31 / 47     │  │  42 / 47     │  │  4.6 days    │        │
│ └──────────────┘  └──────────────┘  └──────────────┘        │
│                                                              │
│ Goal completion rate (team-scoped)                           │
│ ▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░  58%                                │
│                                                              │
│ Health flags (members inactive 7+ days)                      │
│ • Jules K.   9 days       (last activity day shown)          │
│ • Sam P.     11 days                                         │
│                                                              │
│ Sub-community activity                                       │
│ • Morning Movers · 142 check-ins / wk · ▲                   │
│ • Deep Work Pod  ·  88 check-ins / wk · ▼                   │
│ • Quiet Plate    ·  32 check-ins / wk · →                    │
│ • Weekend Warriors · 31 check-ins / wk · →                   │
│                                                              │
│ [ Export CSV (team-scoped) ]                                 │
└──────────────────────────────────────────────────────────────┘

No mood data (Open Question #4 → No, per PRD).


N29 · Custom Badges admin

Lives inside sub-community settings. Defines name, emoji, trigger (manual or rule-based on team challenge participation).


N30 · Manager View (grid)

Scope: V1.1. PRD §8.4.

Members (47)   [ Filter ▾ ]                          [ CSV → ] │
┌────────────────────────────────────────────────────────────┐│
│ Name         Goals  Team-goal contrib  Streak  Last active ││
├────────────────────────────────────────────────────────────┤│
│ Priya R.       3        142            12d     today       ││
│ Devon S.       2         98             4d     2d ago      ││
│ Marcus T.      4         42             6d     4d ago      ││
│ Jules K.       1          0             0d     9d ago  ⚠   ││
│ …                                                          ││
└────────────────────────────────────────────────────────────┘│

Sort, filter, no personal goal titles, no mood.


N31 · Accountability pair card

Embedded in N13 (V1.1).

╭──────────────────────────────────────────────╮
│ 🤝 Accountability pair                       │
│ This week you're paired with Marcus T.       │
│ Both of you have "Daily reading" goals.      │
│   [ Send encouragement ]  [ Skip this week ] │
╰──────────────────────────────────────────────╯

Same shape as N8 but generated by a sub-community Lead, pre-checks just their room. V1.1. PRD §8.10.


N33 · Per-team brand customization

Subtab in N7. V1.2.

Brand color  [HSL picker — contrast-validated]
Team logo    [Upload — 200x200 min, square crop]
Welcome msg  [textarea — shows on N11]

N34 · Slack / MS Teams integration config

Subtab in N7. V1.2. Picks workspace, channel, events to forward (defaults: weekly digest + collective goal hits only).


N35 · External Coach role extension

Subtab in N7b. V1.2. "Add external coach (read-only) — free addon, 1 per team."


4. MODIFIED existing surfaces — diff sketches

For each, the wireframe shows only the delta vs. master.

M1 · Community feed (sub-community variant)

When community.team_id set:

┌──────────────────────────────────────────────────────────────┐
│ ☰  Habit Lab ▾    Sub-community: [ Morning Movers ▾ ]        │
├──────────────────────────────────────────────────────────────┤
│ ╭──── 🎯 Sub-community goal · 200 5am check-ins ────────╮   │   ← NEW (N15)
│ │ ▓▓▓▓▓▓▓▓▓░░░░░░░░░░░  88 / 200                        │   │
│ ╰──────────────────────────────────────────────────────╯   │
│                                                              │
│ Feed posts (existing — unchanged structure)                  │
│ • Priya: "Up at 4:47, ran 6km" ❤️ 🔥                         │
│ • Marcus: "Block 1 done"                                     │
│ …                                                            │
│                                                              │
│  [ Quick post ]   [ Encourage Priya → ]                      │
└──────────────────────────────────────────────────────────────┘

For non-team communities, surface is unchanged.


M2 · Community Settings — "Upgrade to Teams"

Existing settings gain one new row:

─────────────────────────────────────────────
Upgrade                                       
This is a free private community. Convert to  
a Team to unlock collective goals, leader-    
boards, and seats.                            
                          [ Upgrade to Teams ]   ← opens N6
─────────────────────────────────────────────

M3 · Marketing landing — Teams pricing

marketing_landing/index.html adds:

  • Teams nav entry → anchor to pricing panel
  • N1 pricing card
  • "Teams" feature section (collective goals + leaderboards + coach role) above the existing Personal-only sections
  • Schema.org Product markup for SEO (delegate to seo-specialist before merge)

M4 · App side-nav

☰  Menu
─────────────
🏠  Home
🎯  Goals
🤝  Communities
─── Teams ───              ← NEW section appears only when user has ≥1 TeamMembership
   • Habit Lab
   • Acme Wellness
   + Browse / Create
─────────────
⚙️  Settings

For users with no team, the section is absent.


M5 · User settings → Privacy

Adds one row per Team:

─────────────────────────────────────────────
What your teams can see                       
• Habit Lab          ▸                          ← opens N18
• Acme Wellness      ▸                       
─────────────────────────────────────────────

M6 · User profile (own)

Adds a "Teams" strip:

Teams
• Member of Habit Lab · since 4/12/2026
• Previously a member of Reading Club (left 1/2026)

Only visible to the user themselves.


M7 · Personal Goal detail

Existing goal screen adds:

─────────────────────────────────────────────
Team contribution                             
This goal counts toward "1000 check-ins" in   
Habit Lab.            [ Pause / Resume ]      
─────────────────────────────────────────────

If not opted in, row offers [ Contribute to a team goal → ] opening N17.


M8 · Personal Goal create

After "Goal name" / "Target" fields, add:

─────────────────────────────────────────────
☐ Also contribute this goal to Habit Lab's    
  "1000 check-ins by Aug 31"                  
   (Only the count is shared. Your personal   
    notes and history stay private.)          
─────────────────────────────────────────────

Only renders when a team-wide collective goal exists with matching metric.


M9 · Notifications inbox

Adds categories team_invite, team_billing, monday_recap, collective_goal_milestone. Per §9, max 1 push per member per day total across all categories.


M10 · Onboarding (post-signup, team-invite arrival)

Existing personal-onboarding flow has a branch:

[ post-signup ]

    ├── arrived via team invite cookie? → N11 → N12 → N13

    └── normal sign-up                  → existing personal-goal seed flow

The personal-goal seed flow becomes accessible later from the goal create screen for team-only members.


M11 · Admin Dashboard (internal Objectuve admins)

New top-level view in admin_dashboard/:

Teams (internal)
- List: name, owner, plan, seat utilization, MRR contribution, status
- Filters: status (trialing / active / past_due / grace / canceled)
- Per-team detail: subscription history, webhook log, member churn

No member-level data is exposed (we eat our own privacy dog food).


M12 · Mailer base layout

V1: emails reuse Objectuve chrome (no per-team brand). V1.2: Team logo + accent color injected from N33 settings.


M13 · GraphQL Apollo cache shapes

graphql
type CommunityType {
  id, name, slug, private,
  team: TeamType                # NEW (nullable)
  isDefaultForTeam: Boolean!    # NEW

}

type TeamType {
  id, name, slug,
  subscription: TeamSubscriptionType,
  membership: TeamMembershipType,   # current user's membership
  communities: [CommunityType!]!,

}

All UI components branch on community.team being non-null to render team chrome (M1).


M14 · Feature flag registry

Per PRD §11 + CLAUDE.md gotcha:

FlagTypeRegistryPostHog
teams_enabledbooleanretired at GA 2026-07-08 (PR #1498, OBJ-1096) — removed from featureFlags.tsarchived, project 368400
teams_billing_v1boolean
teams_collective_goalsboolean
teams_leaderboardsboolean
teams_bulk_inviteboolean

CI posthog-flag-drift enforces parity.


5. Dual-context user model — personal account × team seat

A single user can be a personal Objectuve user, a member of one or more Teams, an admin of a Team, and still be all of those at once. This section defines how the surfaces compose for that dual-context user, because the answer determines the §6 data-boundary enforcement contract on every modified surface.

5.1 Principle — one identity, one Coach, one Hall, scope-aware overlays

The user has one Objectuve account. Team membership is a lens applied to existing personal surfaces — not a parallel app, not a context switcher modal. This is the calm path: it preserves the lifetime narrative (streaks, badges, XP, Coach memory) that drives retention, and avoids forcing the user to decide which "mode" they're in before they act.

Operationally:

ConceptScopeNotes
Account / identity / avatar / display nameOne (personal)V1.2 may add per-team display name override (Open Q below)
Coach (assistant)Personal only — never sees team activityHard §6 rule; coach conversation history is in the "cannot see ever" list
Achievement HallOne, lifetime; team-earned badges filterableCustom team badges (N29, V1.1) sit in same Hall with a "Habit Lab" filter chip
StreaksPersonal, lifetime — admin cannot seeTeam leaderboard points (§7.4) are a separate scoring system, period-scoped
XP (lifetime)Personal — invisible to team adminsTeam leaderboard points are visible inside their scope only
GoalsPersonal, optionally tagged for team contributionOpt-in per goal (N17); admins see only counts of contributing events, never the goal
Mood log / JournalPersonal only — never team-visibleHard §6 rule; surfaced explicitly in N18
Notifications inboxOne, categorizedPer-team mute and per-category mute available in settings
SettingsOne, with a per-team subsectionPrivacy contract (N18) and notification overrides per team
Profile (own view)One, with a "Teams" stripM6 extension
Profile (team-admin view of a member)Team-scoped sliceStrictly §6 columns; no personal goals, mood, streaks
Data export (user-requested GDPR export)All personal + team-scoped contributionsDistinct from team admin CSV export, which is team-scoped only

5.2 Surface-by-surface diff for dual-context user

5.2.1 Home dashboard (M-dashboard, new diff)

Today's personal Home shows: today's goals, streak, mood prompt, Coach card, recent badges. For a dual-context user, the Home does not split into tabs — it composes:

┌──────────────────────────────────────────────────────────────┐
│  Home                                                        │
├──────────────────────────────────────────────────────────────┤
│  Today                                                       │
│  • Daily run         [✓ Check in]                            │
│  • Read 30 min       [✓ Check in]                            │
│                                                              │
│  ╭──── Your streak — 12 days ────────────────────╮           │
│  │ 🔥 Keep it going. Mood: how are you today? ▸ │           │
│  ╰─────────────────────────────────────────────╯            │
│                                                              │
│  ╭──── Coach ──────────────────────────────────╮             │
│  │ "Want to plan tomorrow's two big rocks?"   ▸│             │
│  ╰────────────────────────────────────────────╯              │
│                                                              │
│  ─── Your teams ───────────────────────────────  ← NEW strip │
│  ╭───────────────────────╮  ╭───────────────────────╮       │
│  │ Habit Lab             │  │ Acme Wellness         │       │
│  │ 🎯 642 / 1000  · #3   │  │ 🎯 88 / 200  · #7     │       │
│  │ Last check-in: today  │  │ Last check-in: 2d ago │       │
│  │           [ Open → ]  │  │           [ Open → ]  │       │
│  ╰───────────────────────╯  ╰───────────────────────╯       │
│  + Browse teams                                              │
│                                                              │
│  Recent badges (lifetime)                                    │
│  🏃 7-day streak · 🥇 Habit Lab — First Contributor · …      │
└──────────────────────────────────────────────────────────────┘

Key points:

  • The personal modules lead. Teams strip lives below, not above.
  • Each team card surfaces the active collective goal + the user's rank in that team's current period (no rank-change push — only on-open per §9).
  • "Recent badges" interleaves personal + team-custom badges (N29) chronologically; a small "Habit Lab" pill tags team-earned ones.
  • For a user with zero teams, the strip is absent. For a user with 5+ teams, the strip caps at 2 with a "Browse teams" overflow.

5.2.2 Goals tab (M7 expanded)

Personal Goal list shows every personal goal. Goals that contribute to a team collective goal get a discreet pill:

┌──────────────────────────────────────────────┐
│ Your goals                       [ + New ]   │
├──────────────────────────────────────────────┤
│ ● Daily run                                  │
│   ▓▓▓▓▓░░░  47 / 90 check-ins                │
│   [Habit Lab · contributing]                 │
│                                              │
│ ● Read 30 min                                │
│   ▓▓▓▓▓▓▓▓░  68 / 90                         │
│                                              │
│ ● Meditation                                 │
│   ▓▓░░░░░░░  15 / 90                         │
│   [Acme Wellness · contributing]             │
└──────────────────────────────────────────────┘

The pill is informational only. Tapping a goal opens the existing detail view; the "Team contribution" row from M7 manages opt-out.

A goal can contribute to at most one collective goal at a time in V1 (Open Q below for whether to allow multi-team contributions of the same goal). The pill makes the binding visible at-a-glance so the user never wonders "what's seeing this?"

5.2.3 Achievement Hall (new diff, M-hall)

The existing Hall is lifetime-scoped. Extending for teams:

┌──────────────────────────────────────────────────────────────┐
│ Achievement Hall                                             │
├──────────────────────────────────────────────────────────────┤
│ Filter: ( All ) ( Personal ) ( Habit Lab ) ( Acme Wellness ) │
│                                                              │
│ Earned                                                       │
│  🥇  First Streak · Common · Personal · 4/12/2026            │
│  🥈  Goal Crusher · Rare · Personal · 4/20/2026              │
│  ✨  First Contributor · Custom · Habit Lab · 5/03/2026      │
│  …                                                           │
│                                                              │
│ In progress                                                  │
│  ⚙️ 30-day streak · 12 / 30  (Personal)                      │
│  ⚙️ Pod regular · 14 / 20 check-ins  (Habit Lab — Deep Work) │
└──────────────────────────────────────────────────────────────┘
  • Custom team badges (PRD §8.1 / N29) live in the same Hall — same visual treatment, with a team-source tag.
  • "Personal" is the default filter; team filters appear only when the user has earned at least one badge in that team.
  • Admins do NOT see a member's Hall (§6: no lifetime data exposure). Admin-view of a member shows team-scoped custom badges only.
  • When a user leaves a team, their custom-badge earnings stay in their Hall, tagged "(former member)" — same anonymization model as collective-goal contributions.

5.2.4 Coach (no change — strictly personal)

Coach is the loudest §6 rule and it deserves an explicit statement in the doc, not just a one-line bullet:

Coach has zero awareness of any Team the user belongs to. Coach memory, prompt context, conversation history, and recommendation surface are scoped to the personal account. A user who joins Habit Lab does not see Coach references to Habit Lab; an admin in Habit Lab cannot see anything Coach said. Coach is the user's private thinking partner; Teams is their accountability surface. The two never cross.

UI implication: no Coach card on N13 (Team Home), no Coach surface on N19 (Leaderboard), no Coach prompts referencing team activity even when the user is clearly active in a team. If we want a team-aware nudge ("Your team is at 642/1000 — want help planning?"), it ships as a team-scoped in-app card on N13, not as a Coach turn.

5.2.5 Profile (M6 expanded)

Own profile view — full transparency:

┌──────────────────────────────────────────────┐
│ Devon S.                                     │
│ Joined 4/02/2026 · 12-day streak             │
│                                              │
│ Teams                                        │
│ • Habit Lab — member since 5/03 · 3 rooms    │
│ • Acme Wellness — member since 5/18 · 1 room │
│ • Previously: Reading Club (left 1/2026)     │
│                                              │
│ Personal stats (only you can see)            │
│ 4,182 lifetime XP · 47 goal events ·         │
│ 18 badges earned                             │
│                                              │
│ ▸ Privacy: what your teams can see           │
└──────────────────────────────────────────────┘

Team-admin view of the same user (surfaced from N7b "View team activity"):

┌──────────────────────────────────────────────┐
│ Devon S. · Member of Habit Lab               │
│ Joined 5/03 · Active today · 3 rooms         │
│                                              │
│ Team-scoped activity                         │
│ • 47 team-tagged events                      │
│ • 142 leaderboard points this week           │
│ • Contributing to: "1000 check-ins" goal     │
│                                              │
│ Custom team badges                           │
│ ✨ First Contributor                         │
│                                              │
│ 🔒 Personal goals, mood, journal, Coach,     │
│    lifetime stats — not visible.             │
└──────────────────────────────────────────────┘

The "what you can't see" footer is not legalese — it's the trust artifact, identical principle to N18 but rendered for the admin.

5.2.6 Settings (M5 expanded)

The Settings tree gains a "Your teams" branch:

Settings
├── Account
├── Profile
├── Notifications
│    ├── Personal
│    ├── Habit Lab           ← per-team mute / digest preferences
│    └── Acme Wellness
├── Privacy
│    ├── Personal (existing — friends, public profile, etc.)
│    └── Teams
│         ├── What Habit Lab can see       ← N18
│         ├── What Acme Wellness can see   ← N18
│         └── Leave a team
├── Appearance
└── Data & export

Data & export is unchanged — the user's GDPR data export includes everything personal + their team-scoped contributions. This is distinct from the admin CSV export (N28) which is team-scoped only and excludes personal data by §6.

5.2.7 Notifications inbox (M9 expanded)

One inbox, multi-source, categorized — never split into "personal" and "team" tabs:

┌──────────────────────────────────────────────┐
│ Inbox                                        │
│ ( All ) ( Personal ) ( Habit Lab ) ( Acme )  │
├──────────────────────────────────────────────┤
│ Today                                        │
│ 🏆 Devon · You earned the 30-day streak      │
│ 📣 Habit Lab · Monday recap — see N21        │
│ 🤝 Priya encouraged your check-in            │
│                                              │
│ Earlier                                      │
│ 💌 Acme Wellness · Trial ends in 3 days      │
│   …                                          │
└──────────────────────────────────────────────┘

Per §9, total push notifications across all sources are bounded at 1/day; the user does not pay an attention tax for joining more teams.

5.2.8 App nav (M4 expanded)

Mobile bottom-tab bar stays as-is — 5 personal tabs (Home, Goals, Communities, Coach, Profile). Teams do not get a top-level tab. Instead:

  • The Communities tab gains a "Teams" section at the top listing teams the user belongs to (Habit Lab, Acme Wellness), above the existing public/free community list.
  • Tapping a team navigates to N13 (Team Home). Back navigates to Communities, not to a separate "Teams root" — there is no separate root.
┌────────────────────────────────────────┐
│ Communities                            │
├────────────────────────────────────────┤
│ Your teams                             │
│ ● Habit Lab        47 members  →       │
│ ● Acme Wellness    32 members  →       │
│                                        │
│ Your communities (free / public)       │
│ ○ Reading Club          →              │
│ ○ Trail Runners         →              │
│                                        │
│   + Browse / Create                    │
└────────────────────────────────────────┘

This preserves the "one app" mental model and avoids a Teams tab competing visually with Coach.

5.2.9 Onboarding split (M10 refined for dual-context arrivals)

Two arrival paths converge into one user state:

Path A — personal-first user joins a team later.

  1. User has 30 days of personal goals, mood, badges.
  2. Receives invite link → N11 → N12 (if multi-community) → lands on N13.
  3. No personal data is touched. Coach memory persists. Streaks persist.
  4. Goals tab gains team pills as the user opts in to contribute (N17).
  5. Settings gains the new team subsection. Notifications inbox gains the team category.

Path B — invite-first user (signed up via team invite).

  1. Clicks invite link, no Objectuve account → Clerk signup → returns to N11 → N12 → N13.
  2. Personal onboarding is deferred, not skipped. First time the user taps Home (N5-personal), they see an "It looks like you're brand new — want to set up a personal goal?" card. Optional. Skippable forever.
  3. Coach is initialized on first conversation, with no team context (§6).
  4. If the user leaves the team and was Path B, their account survives as a normal personal account. No "team-only" account type exists.

5.2.10 Leaving a team — what stays, what goes

When a dual-context user leaves a team:

  • Personal everything (account, goals, mood, journal, Coach, streaks, lifetime XP, lifetime badges including team-custom badges earned, friends, allies, public profile) is untouched.
  • Their team-scoped contributions become "Former member" entries on collective goals and leaderboards.
  • The team card disappears from Home, Communities, Settings, Notifications inbox filters.
  • The team is listed on the user's own Profile under "Previously a member of …" — visible only to them.
  • The privacy contract panel (N18) for that team is archived (read-only) and accessible from settings → Data & export for one year, then purged.

5.3 Edge cases worth naming

  1. User is admin of Team A and member of Team B. They see admin tooling in A's chrome only; B looks like a normal member experience. Single nav, two surfaces, no "switch role" affordance — role is implicit in which team you're inside.
  2. User is the billing owner of a team they never use for personal goal-tracking. (Common for coaches.) The "Your teams" Home strip still surfaces — but their Coach, streak, Hall stay personal. Coaches who don't track personal goals will see a sparse personal Home and a rich team chrome; that's correct.
  3. User in 5+ teams. Home strip caps at 2 most-recent-active; Communities tab shows all. Notifications inbox filters become a overflow at >4 sources. No artificial limit on team count.
  4. User in two teams that both have a collective goal of "1000 check-ins." Their "Daily run" goal can contribute to one at a time (V1) — pill makes the binding explicit. Switching requires opting out then in. (Open Q: should V1.1 allow contributing to multiple? Probably yes, but counts only once per scope per event — needs a dedup rule.)
  5. User is on Supporter tier ($3/mo) AND in a paid team. Supporter cosmetics (themes, aura) apply across all surfaces including team chrome (because identity is one). Team Owner billing is independent.
  6. Admin tries to use Coach to ask about their team. Coach says something like: "I don't see your team's activity — that's by design. Want help thinking about how to run a team check-in?" Coach can talk about coaching practice in general; it just cannot read team data.
  7. User mutes a team. Mute means: no push notifications from that team. The team still shows on Home strip and Communities tab; the user is opting out of attention, not membership. (Distinct from leaving.)
  8. GDPR / data deletion request from a team member. Personal data is purged; their team-scoped contributions persist as "Former member" (anonymized) so the team's historical metrics stay coherent. The user's Privacy panel says this verbatim.

5.4 New / modified surface IDs introduced by this section

Additive only — no existing wireframes are invalidated.

IDSurfaceType
M15Home dashboard — "Your teams" stripModified
M16Goals list — team-contribution pillModified
M17Achievement Hall — team filter + custom-badge integrationModified
M18Coach — §6 affirmation (no UI change; documented constraint)Constraint
M19Profile — own view "Teams" strip + admin-scoped member viewModified
M20Settings tree — "Your teams" branchModified
M21Notifications inbox — multi-source filter chipsModified
M22Communities tab — "Your teams" pinned sectionModified
M23Personal onboarding card for Path B usersNew (low-weight)
M24Leaving-a-team archive of N18 in Data & exportNew (V1.2 polish)

These slot into §4 of this doc when the team formally signs off on the dual-context model. Until then they live here.

5.5 Open questions for the dual-context model

  1. Per-team display name override. Should a user be able to present as "Dr. Devon Sun" in Habit Lab and "Devon" in Acme Wellness? Recommendation: defer to V1.2. Single display name + avatar in V1.
  2. Coach team-awareness toggle. Some users may want Coach to know they have a team. Strict reading of §6 says no. Recommendation: keep no in V1; revisit at SOC 2 phase with an explicit opt-in.
  3. Multi-team contribution of a single personal goal. V1 = one-at-a-time. V1.1 likely = many-to-many with per-scope dedup.
  4. Team-custom-badge weighting in lifetime XP. Should custom team badges (N29) award lifetime XP that admins cannot see? Recommendation: yes — same XP rules as personal badges. Admins see only the badge earned within team scope, never the XP total.
  5. Mute-vs-leave UX. Mute is one tap from any team notification (per §9). Should there also be a "snooze 30d" middle option? Recommendation: defer; mute + leave covers V1.
  6. Team-card recency rule for Home strip cap. "Most-recent-active" by last check-in date in that team. Tie-break: largest collective-goal delta. Confirm with product.
  7. Path B users who never set up a personal goal. How long before the personal-onboarding card stops showing? Recommendation: stop after 60 days of no interaction; surface again on next streak-eligible team check-in.

5.6 Mapping to PRD §6 (data boundary) — the dual-context safety check

The data-boundary contract is unchanged, but the dual-context view sharpens what each row means at the render layer:

§6 rulePersonal surfaceTeam surfaceRisk if violated
Personal goals invisible to adminsGoals tab shows allMember-view (N7b) shows team-tagged onlyHigh — kills the trust artifact
Mood / journal invisiblePersonal modules on HomeNot rendered at all in team chromeHigh
Coach invisibleCoach card on Home + Coach tabNot rendered at all in team chromeHigh
Lifetime XP / streaks invisibleProfile (own) showsMember-view (admin) shows period-scoped onlyMedium
Last-active truncated to dayPersonal profile shows real timeMember-view shows day onlyLow

Every modified surface in §5.2 has been audited against this table. The single biggest risk vector is the Home dashboard composition: any widget that pulls team data into a personal-surface position must be reviewed for accidental cross-leak. We commit to a TeamScopedView Vue mixin (analog of the Rails TeamAccessPolicy from §5 of the PRD) that all team-data widgets must use; rendering a team widget without it should fail a Vitest contract test.


6. Coverage check vs. PRD §7

PRD subsectionWireframe IDs
§7.1 Billing & SubscriptionsN3, N4, N5, N7a, N22, N23, N24, N25
§7.2 Team Invites & Sub-Community Self-SelectN5, N6, N7b, N7c, N7d, N8, N9, N10, N11, N12, N13, N14, N26, M2, M10
§7.3 Team Goals (Collective Progress)N13, N15, N16, N17, N18, M7, M8
§7.4 Team LeaderboardsN13, N19, N20, N21
§6 Data BoundaryN7e, N16 (admin slice), N18 (member-facing)
§8.1 Custom BadgesN29
§8.2 Team Admin DashboardN28
§8.3 Accountability PairN31
§8.4 Manager ViewN30
§8.5 Priority Support(no UI surface — routing only)
§8.7 Slack / MS TeamsN34
§8.8 Brand customizationN33
§8.9 Bulk CSV InviteN27
§8.10 Sub-Community-Scoped Invite LinkN32
External Coach role (Open Q #13)N35

Every V1 MVP feature in PRD §7 maps to at least one wireframe; every V1.1+ shape-only feature has at least a sketch.


7. Open design questions surfaced by this exercise

These complement PRD §12 but are scoped to UI:

  1. Sub-community switcher placement — top-bar dropdown (current sketch) vs. left-rail sidebar on desktop. Decide before N13 build.
  2. Default-community badging — is "Default" pill enough, or do we tag it Lobby instead? Tested in design prompt for N12; revisit after Maya-cohort review.
  3. Monday Recap rendering — inbox card only, or also banner on N13? Default: both, with banner dismissable.
  4. Privacy-panel link weight on N12 — currently a footnote strip; trust research may justify promoting it.
  5. Team switcher (M4) ordering — alphabetical vs. last-active. Default: last-active descending.
  6. Empty leaderboard state for 2-member teams — copy is in §7.4; visual treatment (illustration vs. text-only) TBD.
  7. Multi-team push grouping — when a member is in 2+ teams, do Monday Recaps combine into one push or stay separate? Default: separate (clearer attribution), capped by §9 1/day rule.
  8. Admin "join sub-community to moderate" affordance — PRD §6 says no silent observation; UI needs to show admins this is a member-visible action. Sketch needed.

8. Sequencing (mirrors PRD §Appendix C, UI lens)

SprintWireframes that must shipBehind
1(data model only — no UI)
2N3, N4, N5, N7a, N22, N23, N25teams_billing_v1
3N7, N7b, N7c, N7d, N7e, N8, N9, N10, N11, N12, N13, N14, N26, M1, M2, M4, M5, M6, M10, M13teams_enabled (retired at GA, PR #1498 — no flag gate today)
4N19, N20, N21, M9teams_leaderboards
5N15, N16, N17, N18, M7, M8teams_collective_goals
6(closed beta — bug-fix only)
7N28, N29, N27teams_bulk_invite
8N30, N31, N32
9(priority support; no UI)
10M3 (pricing page live), all flags retired

9. Next steps for designers

  1. Validate N12 against the existing phase-7-teams-claude-design-prompt.md — they should match.
  2. Build Figma boards (or Claude Design artifacts) for the top 5 surfaces in order: N12 → N13 → N19 → N7c → N16. Those carry the multi-sub-community story end-to-end.
  3. Run a flow walkthrough with one beta-cohort admin (Maya analog) before Sprint 3 kicks off.
  4. Confirm the data-boundary copy on N18 with legal/PBC counsel.

End of surfaces & wireframes doc.

Loading…