VisitLoop is a production-ready Micro SaaS that acts as a field-visit accountability layer for field sales teams. It turns unstructured rep conversations into reliable CRM data and completed follow-ups. VisitLoop is positioned as the post-visit execution layer: a field sales rep speaks for approximately 60 seconds after a visit, and VisitLoop creates the CRM record, assigns follow-ups, and shows managers exactly what was completed.
The product serves three audiences: field sales reps who need to capture visit outcomes in seconds while still in the car, sales managers who need reliable visibility into completed versus outstanding post-visit work, and workspace administrators who keep the account operational, correctly provisioned, and correctly billed.
The design register is systematic product craft — warm paper ground, one hot tangerine accent, tabular numerals as ornament — in the spirit of Linear, Notion, and Vercel, but never the generic indigo/blue-on-white SaaS template.
VisitLoop is delivered as a full-stack web application with a public marketing surface, an application-owned identity layer, and a protected workspace shell.
Current delivery:
Actors:
Narrow exclusions: VisitLoop is the post-visit layer. It does not replace the CRM of record, does not perform pre-visit route planning, and does not own the Stripe payment surface itself (Stripe owns checkout and payment collection).
VisitLoop owns the interaction where a rep speaks a recap and where a manager reads completion. The spoken recap is captured in a first-party surface; the AI extraction that turns speech into structured fields is a backend responsibility that the rep observes as filling fields. Subscription purchase is initiated from the Pricing page and completed on Stripe's own hosted surface; VisitLoop reflects the resulting subscription state on the Billing page. Identity is application-owned: users enroll themselves through Sign Up and return through Login using Google or Email. Protected workspace destinations require an authenticated session; the public Landing page, Pricing page, Sign Up, and Login do not.
Everything described in this document is current. The 20 AI feature recommendations requested by the user are captured in Section 3 as a current deliverable (a documented recommendation set), not as additional product surfaces.
No reference directive declares content_source; this section is intentionally omitted.
01 / PROBLEM, 02 / HOW IT WORKS, 03 / FEATURES, 04 / PROOF, 05 / PRICING, 06 / FAQ.Each requirement is a distinct story point with provenance, lifecycle facts, and observable acceptance.
FR-1 — Self-service enrollment (required_inference) As a prospective user, I should create an account with my name, work email, and password, or continue with Google, so that I can begin using VisitLoop without an invitation.
FR-2 — Returning verification with Google Login (explicit) As a returning user, I should sign in with Google so that I can reach my workspace without entering a password.
FR-3 — Returning verification with Email Login (explicit) As a returning user, I should sign in with my email and password so that I can reach my workspace.
FR-4 — First-run onboarding (required_inference) As a newly enrolled user, I should complete a short setup flow so that my workspace is configured before recurring visit work begins.
FR-5 — Workspace authorization (required_inference) As a workspace member, I should have a role — Field Sales Rep, Sales Manager, or Workspace Administrator — so that I see the destinations and controls appropriate to my responsibilities.
FR-6 — 60-second spoken recap (explicit) As a Field Sales Rep, I should speak for approximately 60 seconds after a visit so that the visit outcome is captured without typing.
FR-7 — Automatic CRM record creation (explicit) As a Field Sales Rep, I should have VisitLoop create the CRM record from my spoken recap so that I do not have to fill in a form.
FR-8 — Follow-up assignment from a visit (explicit) As a Field Sales Rep, I should have follow-ups assigned from my visit record so that nothing is dropped.
FR-9 — Review and update visit records (required_inference) As a Field Sales Rep, I should review and update the CRM records produced from my visit conversations so that the data stays reliable.
FR-10 — Create and assign follow-ups (required_inference) As a Field Sales Rep or Sales Manager, I should create and assign follow-up work arising from visit records so that post-visit commitments are owned.
FR-11 — Complete assigned follow-ups (required_inference) As a Field Sales Rep, I should review and complete the follow-ups assigned to me so that no follow-up is dropped.
FR-12 — Execution accountability view (explicit) As a Sales Manager, I should see exactly what was completed and what remains outstanding after visits so that I can hold the team accountable.
FR-13 — Visit and follow-up analytics (explicit) As a Sales Manager, I should analyze visit and follow-up activity and completion trends so that I can see where execution is slipping.
FR-14 — Workspace administration (explicit) As a Workspace Administrator, I should manage users, roles, invitations, and workspace configuration so that the account stays operational and correctly provisioned.
FR-15 — Subscription purchase (explicit) As a prospective or existing customer, I should subscribe to a VisitLoop plan through Stripe so that my workspace is provisioned at the right tier.
FR-16 — Billing visibility and management (explicit) As a Workspace Administrator, I should see and manage the workspace subscription so that billing stays correct.
FR-17 — User settings (explicit) As an authenticated user, I should configure my profile, preferences, and security so that the product fits how I work.
FR-18 — Responsive design (explicit) As any user, I should use VisitLoop on phone, tablet, and desktop so that I can capture a visit from the car and review execution from a desk.
FR-19 — Dark mode (explicit) As any user, I should switch between light and dark mode so that the product is comfortable in a car at night and in an office.
#141517 with #1C1E21 surfaces and #F2EFE9 text; the tangerine and green accents are unchanged between modes.FR-20 — SEO (explicit) As a prospective customer, I should find VisitLoop through search so that I can evaluate it.
FR-21 — Error handling (explicit) As any user, I should see a clear, actionable message when something fails so that I can recover without losing work.
FR-22 — Loading states (explicit) As any user, I should see a loading indication while data is being fetched so that I know the product is working.
FR-23 — REST APIs (explicit) As a client of VisitLoop, I should interact with the product through REST APIs so that the frontend and any future integrations use one consistent contract.
FR-24 — Database and schema (explicit) As the product owner, I should have a relational database with a defined schema so that visit records, follow-ups, completion state, analytics, workspace administration, and billing state persist reliably.
FR-25 — Deployment configuration, environment variables, README, and sample data (explicit) As the operator, I should have deployment configuration, documented environment variables, a README, and sample data so that the product can be run and evaluated.
FR-26 — Production readiness, review, and refactoring (explicit) As the product owner, I should have a production-ready, reviewed, refactored codebase following best practices so that the product can be operated with confidence.
FR-27 — 20 AI feature recommendations (explicit) As the product owner, I should receive 20 AI feature recommendations that would significantly increase the value of VisitLoop, each with problem solved, user benefit, AI model recommendation, technical implementation, and difficulty, so that I can plan the product's AI roadmap.
Product context. The rep is the primary in-product actor and the origin of every visit record. They work one-handed, often in a car immediately after leaving a customer site, and they log dozens of visits a day. Their tolerance for typing is near zero; their tolerance for a dropped follow-up is also near zero, because a dropped follow-up is a lost deal.
Primary goal. Capture what happened in a visit in about 60 seconds, without typing, and complete every follow-up assigned to them.
Distinct accepted responsibilities. Recording the ~60-second spoken recap on Visit Capture; reviewing and correcting the extracted CRM fields before saving; reviewing and updating the resulting visit records in Visit Records; creating follow-ups from a record when the extraction did not capture one; and completing the follow-ups assigned to them in My Follow-ups.
Relevant inputs and decisions. The spoken recap itself; the extracted Account, Contact, Outcome, Next step, Sentiment, and Products discussed fields, each of which the rep may edit; the decision to confirm and save a record or re-record; and the decision to mark a follow-up complete or reopen it.
Interactions with other accepted participants. The rep's saved record and its follow-ups become the raw material the Sales Manager reads in Execution and Analytics. The rep's role and workspace configuration are set by the Workspace Administrator. The rep does not see the manager's accountability ledger or the administrator's configuration surfaces.
Observable success. No visit goes unrecorded, and no follow-up assigned to the rep is dropped. Success is visible as a growing count of visits logged and a shrinking count of open items in My Follow-ups.
Product context. The manager consumes the accountability layer. They are not in the field; they read completion telemetry and need to know, at a glance, which visits produced follow-ups and which follow-ups actually got done. They scan dense ledgers rather than browsing cards.
Primary goal. Reliable visibility into completed versus outstanding post-visit work across the team.
Distinct accepted responsibilities. Reading the Execution ledger grouped by rep; filtering and exporting it; opening individual visit records to understand context; reassigning an outstanding follow-up; and analyzing visit and follow-up trends in Analytics across adjustable date ranges and groupings.
Relevant inputs and decisions. The date range and grouping selected in Analytics; the rep or status filter applied in Execution; and the decision to reassign an outstanding follow-up to a different rep.
Interactions with other accepted participants. The manager reads records and follow-ups created by Field Sales Reps and can reassign work between them. The manager's own role and access are provisioned by the Workspace Administrator. The manager does not capture visits and does not administer the workspace.
Observable success. The manager can state, without asking anyone, exactly what was completed after each visit and what remains outstanding, and can see whether completion is trending up or down.
Product context. The administrator keeps the account operational. They are the person who onboards teammates, fixes access problems, and makes sure the workspace is on the right plan and correctly billed. They are the only role that touches billing and workspace configuration.
Primary goal. A healthy, correctly provisioned, correctly billed workspace with appropriate user access.
Distinct accepted responsibilities. Inviting users and assigning roles in the Admin dashboard; deactivating users and revoking invitations; editing workspace configuration and reviewing integration status; reading the audit log; and viewing and managing the subscription on the Billing page, including opening the Stripe customer portal.
Relevant inputs and decisions. The email and role for each invitation; the decision to change a user's role or deactivate them; workspace configuration values such as the default follow-up assignment rule and CRM destination preference; and the decision to change plans.
Interactions with other accepted participants. The administrator provisions the roles that determine what Field Sales Reps and Sales Managers can reach, and configures the default assignment rule that governs how follow-ups are created from a rep's visit record. The administrator does not capture visits or read the manager's execution ledger as part of their administrative responsibility.
Observable success. Every teammate has the correct access, the workspace configuration matches how the team actually works, and the subscription state on the Billing page matches what the team is paying for.
The creative direction is authoritative for this section.
Muse: Rasmus Andersson. Headline register: systematic product craft with an opinion — warm paper ground, one hot tangerine accent, tabular numerals as ornament.
Light mode
| Role | Hex | Usage |
|---|---|---|
| Background | #F6F3EE | Warm paper ground; carries ~70% of every screen |
| Surface | #FFFDF9 | Cards and panels |
| Hairline | #E4DFD6 | 1px structural borders; the only separation mechanism |
| Text | #141517 | All readable ink |
| Primary | #E8552B | Tangerine — the only hot colour; rationed to ≤8% of a viewport |
| Accent | #1F6F4A | Deep green — completed/verified states only |
| Muted | #8A857C | Metadata, timestamps, tabular labels |
Dark mode
| Role | Hex | Usage |
|---|---|---|
| Background | #141517 | Graphite ground |
| Surface | #1C1E21 | Cards and panels |
| Hairline | #2A2D31 | 1px structural borders |
| Text | #F2EFE9 | All readable ink |
| Primary | #E8552B | Unchanged between modes |
| Accent | #1F6F4A | Unchanged between modes |
| Muted | #8A857C | Unchanged |
Tangerine is never placed as text on tangerine. Status is never carried by tangerine alone — green always accompanies a completed/verified state.
font-variant-numeric: tabular-nums for every figure that updates — visit counts, completion percentages, streaks, latency, timers.Type scale (1.25 modular on a 4px baseline):
| Token | Size |
|---|---|
| Display | clamp(44px, 7vw, 96px), line-height 1.05 |
| H1 | 32px → 56px |
| H2 | 24px → 36px |
| H3 | 18px → 22px |
| Body | 15px / 24px |
| Small | 13px / 20px |
| Micro-label | 11px / 16px, uppercase, +0.08em |
Line-height tightens as size grows: 1.05 at display, 1.5 at body.
Honest rectangles with a small radius: 6px on controls, 10px on cards, 999px only on the single record button. No blobs, no glass, no soft-focus shadows. Separation is done with 1px hairlines and background value shifts. Borders are structural, not decorative.
Strict 4/8pt spacing scale on a 12-column grid, max content width 1200px, gutters 24px at 1280, 16px at 768, 12px at 375. The app shell is a fixed 56px left icon rail (labels appear on hover and at ≥1280) plus a 240px contextual panel; the working area is a single dense column, not a card grid. The landing page uses asymmetric editorial columns: text column 5/12, product surface 7/12 bleeding off the right edge. Every table is a real table: aligned label/value pairs, tabular numerals right-aligned, hairline row rules, no zebra striping.
The interface is the imagery. The landing page shows real product surfaces — the voice-capture sheet, the extracted CRM record with fields highlighting as they fill, the manager completion ledger — rendered as crisp screenshots on the paper ground with a hairline frame, occasionally cropped by the viewport edge. Supporting diagrams are schematic: a 3-node flow from "spoke" → "structured record" → "assigned follow-up" drawn in 1px strokes with tangerine on the active node. No stock photography of handshakes, no 3D blobs, no abstract gradients.
The hero is a working product surface, not a screenshot.
The public entry is a split asymmetric hero on the warm paper ground. The left 5 columns carry an oversized Inter Tight headline at clamp(44px, 7vw, 96px), set tight and quiet: "Your reps already said what happened. VisitLoop just writes it down." Beneath it sits a single tangerine text-link CTA ("Start free") and a muted 13px supporting line. No gradient, no blob, no centred stack, no blue button.
The right 7 columns are the product itself: a 1:1 rendering of the voice-capture sheet mid-recording, bleeding off the right viewport edge so it is cropped by the browser rather than contained in a card. Inside it, a live tangerine waveform animates, and beside it three extracted CRM fields — Account, Outcome, Next step — type themselves in as the waveform plays, with tabular numerals counting a 60-second timer. The loop runs on a 6-second cycle.
The gesture is carried entirely by imagery and motion: the capture sheet is cropped by the viewport edge, but every readable label, field name, and control inside it stays whole and inside its container at 375px, 768px, and 1280px. At narrow widths the hero stacks — headline first, then the capture sheet at full width — and the sheet's own contents reflow rather than shrink below legibility.
Interaction Model: Animated Motion Tempo: restrained Hero Dimensionality: flat
Focal subject. The voice-capture sheet mid-recording, bleeding off the right viewport edge, with a live tangerine waveform and three extracted CRM fields filling in beside it.
Input → transformation → outcome thesis. The waveform plays (input) → the three extracted fields type themselves in one after another (transformation) → the 60-second timer reaches its mark and the record is shown as saved (outcome). The loop demonstrates the product's defining act — speech becoming structured CRM data — using only accepted behavior.
Motion vocabulary. Functional 120–200ms on cubic-bezier(0.2, 0, 0, 1) for state changes. The waveform breathes at 1.4s intervals because that motion carries meaning: you are being recorded. Field text types in at a steady cadence. Numbers count up in 400ms on first paint and never re-animate on scroll. Section reveals are opacity + 8px translate, staggered 40ms, once.
Composed first frame. The capture sheet is already mid-recording at first paint — waveform active, timer at a nonzero value, the first extracted field partially typed. The headline sits fully rendered and still. Nothing waits for scroll to begin.
Reduced-motion state. With prefers-reduced-motion, the waveform renders as a static tangerine amplitude bar, the three extracted fields appear fully populated, and the timer shows its final value. The capture sheet remains cropped by the viewport edge as a static composition. No element moves, and every readable label and control remains whole and inside its container.
NFR-1 — Production readiness (explicit) The system must be production-ready: real error handling, real loading states, real persistence, and no placeholder behavior in shipped paths. Rationale: explicit user constraint.
NFR-2 — Best practices and refactoring (explicit) The codebase must follow best practices and be refactored, with identified bugs fixed. Rationale: explicit user constraint.
NFR-3 — Modern design register (explicit) The design must be modern in the register of Linear, Notion, and Vercel, expressed through the creative direction in Sections 6–8. Rationale: explicit user constraint plus authoritative creative direction.
NFR-4 — Responsive design (explicit) The product must be responsive across 375px, 768px, and 1280px. Readable text and controls must stay entirely inside the viewport and their containers at every breakpoint. Rationale: explicit user constraint.
NFR-5 — Dark mode (explicit) The product must support dark mode with the token mapping in Section 6. Rationale: explicit user constraint.
NFR-6 — SEO (explicit) Public pages must be search-engine optimized with semantic markup, metadata, structured data, and a sitemap. Rationale: explicit user constraint.
NFR-7 — Error handling (explicit) Every failure path must produce a clear, actionable message with a recovery route where recovery is possible, and must not discard user-entered data. Rationale: explicit user constraint.
NFR-8 — Loading states (explicit) Every data fetch and long-running action must show a loading indication. Rationale: explicit user constraint.
NFR-9 — Accessibility (explicit) The product must be accessible: keyboard-operable controls, visible focus states, sufficient contrast, semantic landmarks, and a usable reduced-motion arrangement. Rationale: explicit user constraint ("Improve ... accessibility").
NFR-10 — Performance (explicit) The product must perform well: fast first paint on the landing page, responsive interaction on dense ledgers, and no unnecessary re-renders or re-animations. Rationale: explicit user constraint ("Improve ... performance").
NFR-11 — Mobile responsiveness for field use (explicit) The capture experience must be usable one-handed on a phone, with the record button reachable at the bottom-right of the mobile shell. Rationale: explicit user constraint plus the product's stated field context.
NFR-12 — Animations (explicit)
Animations must be functional and restrained, per Section 8, and must respect prefers-reduced-motion. Rationale: explicit user constraint plus authoritative creative direction.
NFR-13 — Empty states (explicit) Every list, table, and chart must have a designed empty state with a clear next action. Rationale: explicit user constraint ("Improve ... empty states").
NFR-14 — Onboarding quality (explicit) Onboarding must be short, resumable, and skippable per step. Rationale: explicit user constraint ("Improve ... onboarding").
NFR-15 — Data integrity (required_inference) Writes affecting visit records, follow-ups, and subscription state must be transactional so that a partial failure cannot leave a record without its follow-ups or a workspace with an inconsistent subscription state. Rationale: required to make the accepted accountability outcome reliable.
NFR-16 — Audio retention on failure (required_inference) Recorded audio must be retained locally until the record is successfully saved, so that a network or extraction failure does not force a re-record. Rationale: required to make the accepted 60-second capture lifecycle recoverable.
Assumptions
Constraints
#E8552B is the only hot colour and is rationed to ≤8% of a viewport. Blue and indigo primaries (#0057FF, #2563EB, #4F46E5 and neighbours) are excluded. Plain Inter, Roboto, Arial, Helvetica, Open Sans, Lato, Poppins, and system-ui are excluded in favour of Inter Tight and JetBrains Mono. Gradient-blob heroes, mesh gradients, glassmorphism, frosted panels, drop shadows for elevation, stock photography of handshakes or smiling teams, bouncy or springy easing, and decorative loops that carry no state are all excluded. Only the record button is fully round.font-variant-numeric: tabular-nums so columns of numbers align and can be scanned like a bank statement.
Sixty seconds after the visit, one-handed, still in the car. The CRM record and the assigned follow-up are written before the engine turns over.
Field teams do not lose deals in the room. They lose them in the gap between a conversation that happened and a CRM record that never quite captured it.
Three steps, drawn as a schematic: the spoken recap, the typed record, the assigned follow-up. Nothing else sits between the rep and the data.
Every capability below exists to shorten the distance between a visit ending and a follow-up being owned.
No mockups, no browser chrome. These are the working surfaces a rep and a manager open dozens of times a day.
Coming soon — product surfaces are being captured.
Three plans, hairline-separated, no toggle theatre. Compare the whole grid on the pricing page.
Short answers. The product is small on purpose.

Sixty seconds after the visit, one-handed, still in the car. The CRM record and the assigned follow-up are written before the engine turns over.
Field teams do not lose deals in the room. They lose them in the gap between a conversation that happened and a CRM record that never quite captured it.
Three steps, drawn as a schematic: the spoken recap, the typed record, the assigned follow-up. Nothing else sits between the rep and the data.
Every capability below exists to shorten the distance between a visit ending and a follow-up being owned.
No mockups, no browser chrome. These are the working surfaces a rep and a manager open dozens of times a day.
Coming soon — product surfaces are being captured.
Three plans, hairline-separated, no toggle theatre. Compare the whole grid on the pricing page.
Short answers. The product is small on purpose.
No comments yet. Be the first!