diff --git a/.env.example b/.env.example
index 1ec8745..ec6ec3a 100644
--- a/.env.example
+++ b/.env.example
@@ -34,6 +34,11 @@ BREVO_API_KEY=""
EMAIL_FROM_NAME="Echo OCR"
EMAIL_FROM_ADDRESS="mars@noreply.stillwell.cloud"
+# ─── Support ticketing (Libredesk) ────────────────────────────
+# Inbox address that Libredesk ingests as tickets.
+# The in-app Contact Support dialog sends tickets here via Brevo.
+SUPPORT_EMAIL="support@stillwell.cloud"
+
# ─── Vercel Cron Secret ────────────────────────────────────────
# Vercel auto-sets this on Pro. Used to authenticate cron job requests.
CRON_SECRET=""
diff --git a/src/app/(dashboard)/docs/faq/page.tsx b/src/app/(dashboard)/docs/faq/page.tsx
new file mode 100644
index 0000000..3532dca
--- /dev/null
+++ b/src/app/(dashboard)/docs/faq/page.tsx
@@ -0,0 +1,96 @@
+import { HelpCircle } from "lucide-react";
+import {
+ DocArticle,
+ DocSection,
+ DocContactCta,
+} from "@/components/support/doc-article";
+
+export const metadata = {
+ title: "FAQ — Echo Help",
+};
+
+export default function FaqPage() {
+ return (
+
+
+
+ For clean, typed-text cards Echo averages better than 98% accuracy.
+ Handwriting varies widely — expect 85–95% on neat printing
+ and lower on cursive. Every card passes through a{" "}
+ Needs Review state so a human can correct anything
+ the AI wasn’t sure about before it hits your CRM.
+
+
+
+
+
+ Yes. Echo stores card images in encrypted object storage, encrypts
+ integration credentials at rest, and transports everything over TLS.
+ Access is scoped to your organization — nobody outside your
+ team can see your cards. See the{" "}
+ Privacy Policy for full details.
+
+
+
+
+
+ By default, cards are retained for 2 years. Administrators can change
+ the retention window under{" "}
+ Settings → Organization, or delete individual
+ cards at any time.
+
+
+
+
+
+ Echo supports cards in most Latin-script languages out of the box
+ (Spanish, Portuguese, French, German, etc.). For non-Latin scripts
+ (Korean, Mandarin, Arabic), reach out — we can enable a
+ different extraction model for your organization.
+
+
+
+
+
+ Echo is priced per card processed, with a generous monthly free tier
+ for small churches. See the pricing page for
+ current tiers. Billing questions? Use the Contact button below —
+ it opens a billing-tagged ticket.
+
+
+
+
+
+ Yes. When you upload, cards go into the review queue for your whole
+ org. Any reviewer or editor can pick up a card; Echo locks it while
+ someone’s editing to prevent conflicts.
+
+
+
+
+
+ Usually because the file was too blurry, too dark, or didn’t
+ look like a form at all (e.g., a blank envelope). The original file
+ is kept — you can retry after adjusting the scan, or re-upload
+ a better version. The{" "}
+ Troubleshooting guide has more
+ detail.
+
+
+
+
+
+ Go to Settings → Organization → Billing and
+ click Cancel plan. Your data stays accessible until
+ the end of the billing period.
+
+ A form template is a schema that describes the
+ fields on a physical response card. When Echo processes an uploaded
+ image or PDF, it uses your active template to decide what to extract
+ (e.g., Name, Email, First-time visitor,
+ etc.) and where to put the values.
+
+
+ You can have as many templates as you want — one per card type,
+ event, or campaign.
+
+
+
+
+
+
+ Go to Settings → Form Templates and click{" "}
+ New template.
+
+
+ Upload a clean, filled-in sample. Echo uses it for the preview and
+ to test extraction later.
+
+
+ For each piece of data on the card, add a field with:
+
+
+
+ Hit Test. Echo runs OCR on your sample and shows
+ exactly what it would write to each field. Iterate on labels and
+ mappings until the output is correct.
+
+
+ Mark the template as Active and set it as the
+ default (or assign per upload source).
+
+
+
+
+
+
+ The AI uses your field labels as hints. If your card says “Best
+ way to reach you?”, name that field the same way — it
+ improves accuracy dramatically.
+
+
+ For rows of checkboxes (e.g., “First time / Returning /
+ Member”), use the Choice field type and list
+ the options exactly as they appear on the card.
+
+
+
+
+
+ If you have more than one card design in rotation (e.g., visitor cards
+ vs. prayer request cards), create one template per design and assign
+ the right template at upload time or per upload source. Echo does{" "}
+ not auto-detect which template fits a given card.
+
+
+
+
+
+ );
+}
diff --git a/src/app/(dashboard)/docs/getting-started/page.tsx b/src/app/(dashboard)/docs/getting-started/page.tsx
new file mode 100644
index 0000000..4a9e2a5
--- /dev/null
+++ b/src/app/(dashboard)/docs/getting-started/page.tsx
@@ -0,0 +1,110 @@
+import { Rocket } from "lucide-react";
+import {
+ DocArticle,
+ DocSection,
+ DocSteps,
+ DocStep,
+ DocCallout,
+ DocNext,
+} from "@/components/support/doc-article";
+
+export const metadata = {
+ title: "Getting Started — Echo Help",
+};
+
+export default function GettingStartedPage() {
+ return (
+
+
+
+
+ Head to /signup and create an account with your work
+ email. If your church already uses Stillwell SSO, click{" "}
+ Sign in with SSO on the login page.
+
+
+ Check your inbox for a verification email from{" "}
+ mars@noreply.stillwell.cloud and click the link. You
+ must verify before uploading cards.
+
+
+ After verifying, you’ll be guided through onboarding. Give your
+ organization a name (usually your church or ministry name) and
+ confirm.
+
+
+
+
+
+
+ Go to Settings → Team Members and click{" "}
+ Invite. Choose a role for each teammate:
+
+
+
+ Admin — full access including billing and
+ settings.
+
+
+ Editor — can upload, review, and assign
+ cards.
+
+
+ Reviewer — can review and confirm OCR
+ results, but not change settings.
+
+
+ Viewer — read-only access to cards and
+ reports.
+
+
+
+ Invites expire after 7 days. You can revoke an unused invitation from
+ the same page.
+
+
+
+
+
+ Echo uses form templates to know what fields to
+ extract from each card. Head to{" "}
+ Settings → Form Templates and either start from
+ a starter template or build your own.
+
+
+ The default “Response Card” template handles name, email,
+ phone, and attendance — a great starting point for most
+ churches.
+
+
+
+
+
+
+ Use the Upload button in the top bar, or press{" "}
+ ⌘K and choose Upload Documents.
+
+
+ Drag & drop PDFs, JPGs, or PNGs. You can upload up to 50 files
+ at a time.
+
+
+ Echo processes each card in the background. Head to{" "}
+ Response Cards to review extracted fields, correct
+ anything, and assign the card to a person.
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/(dashboard)/docs/layout.tsx b/src/app/(dashboard)/docs/layout.tsx
new file mode 100644
index 0000000..0a3812d
--- /dev/null
+++ b/src/app/(dashboard)/docs/layout.tsx
@@ -0,0 +1,85 @@
+"use client";
+
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import {
+ BookOpen,
+ Rocket,
+ Upload,
+ FileText,
+ Plug,
+ BarChart3,
+ HelpCircle,
+ Wrench,
+ LifeBuoy,
+ ArrowRight,
+} from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { cn } from "@/lib/utils";
+import { openContactSupport } from "@/components/support/contact-support-dialog";
+
+const SECTIONS = [
+ { href: "/docs", label: "Overview", icon: BookOpen, exact: true },
+ { href: "/docs/getting-started", label: "Getting Started", icon: Rocket },
+ { href: "/docs/uploading-cards", label: "Uploading Cards", icon: Upload },
+ { href: "/docs/forms-templates", label: "Forms & Templates", icon: FileText },
+ { href: "/docs/integrations", label: "Integrations", icon: Plug },
+ { href: "/docs/reports-exports", label: "Reports & Exports", icon: BarChart3 },
+ { href: "/docs/faq", label: "FAQ", icon: HelpCircle },
+ { href: "/docs/troubleshooting", label: "Troubleshooting", icon: Wrench },
+];
+
+export default function DocsLayout({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const pathname = usePathname();
+
+ return (
+
Reviewer throughput — who confirmed how many cards
+
+
+ Use the filter bar at the top to scope any report by date range,
+ collection day, location, or assignee.
+
+
+
+
+
+
+ On the Response Cards page, filter to the exact
+ set you want to export.
+
+
+ Use the Export button in the toolbar. The CSV includes every mapped
+ field plus metadata (upload date, reviewer, collection day).
+
+
+ Most ChMS and CRM tools accept CSV uploads. Check their docs for
+ column-name requirements.
+
+
+
+ Need a recurring export? Set up the{" "}
+ CSV Export integration to drop a CSV to FTP, email,
+ or a webhook on a schedule.
+
+
+
+
+
+ When a card is Confirmed, Echo can push it to any
+ connected integration. Configure the trigger per integration (every
+ confirm vs. batched daily) under{" "}
+ Settings → Integrations.
+
+
+ For a full walkthrough of each provider, see the{" "}
+ Integrations docs.
+
+ This almost always means the background job queue is backed up.
+ Usually it clears within a few minutes. If a card stays in
+ Processing for more than an hour:
+
+
+
+ Open the card, click More →{" "}
+ Retry processing.
+
+
+ If the retry also gets stuck, the file may be corrupted —
+ delete and re-upload.
+
+
+ If that still fails, reach out to support and include the card
+ ID.
+
+
+
+
+
+
+
+ Use the Forgot password link on the sign-in page
+ to reset.
+
+
+ If your church uses SSO, sign in with the{" "}
+ Sign in with SSO button — the
+ email/password flow won’t work for SSO-only accounts.
+
+
+ If your email isn’t verified yet, check your inbox (and
+ spam) for the verification email from{" "}
+ mars@noreply.stillwell.cloud.
+
+
+
+
+
+ When you contact support about a specific card, mention the card ID
+ (shown in the URL when you open a card). It lets us jump directly to
+ the exact run.
+
+
+
+
+ );
+}
diff --git a/src/app/(dashboard)/docs/uploading-cards/page.tsx b/src/app/(dashboard)/docs/uploading-cards/page.tsx
new file mode 100644
index 0000000..1bbf6b1
--- /dev/null
+++ b/src/app/(dashboard)/docs/uploading-cards/page.tsx
@@ -0,0 +1,129 @@
+import { Upload } from "lucide-react";
+import {
+ DocArticle,
+ DocSection,
+ DocSteps,
+ DocStep,
+ DocCallout,
+ DocNext,
+} from "@/components/support/doc-article";
+
+export const metadata = {
+ title: "Uploading Cards — Echo Help",
+};
+
+export default function UploadingCardsPage() {
+ return (
+
+
+
+
+ PDF — single-page or multi-page. Multi-page
+ PDFs are split into one card per page.
+
+
+ Images — JPG, JPEG, PNG, GIF, TIFF, BMP.
+
+
+ Maximum file size is 25 MB per file,{" "}
+ 50 files per upload batch.
+
+
+
+
+
+
+
+ Click the Upload button in the top bar, or press{" "}
+ ⌘K → Upload Documents.
+
+
+ Tagging the upload with a collection day (e.g., “Easter
+ Sunday”) makes later reporting easier.
+
+
+ Drop files anywhere on the dialog. Echo uploads them to storage and
+ queues each for OCR immediately.
+
+
+
+
+
+
+ Echo can monitor an email inbox and automatically ingest any cards
+ sent as attachments. Configure it under{" "}
+ Settings → Upload Sources → Email:
+
+
+
+ Ideally a Gmail or IMAP-capable inbox only used for Echo (e.g.,{" "}
+ cards@yourchurch.org).
+
+
+ Echo stores the credentials encrypted and uses a long-lived IMAP
+ IDLE connection to pick up new mail within seconds.
+
+
+ Forward a card to the watched address. It should appear in{" "}
+ Response Cards within a minute.
+
+
+
+ For Gmail, create an App Password — your main account password
+ will not work.
+
+
+
+
+
+ If your scanner drops files to an FTP/SFTP location, Echo can poll it
+ and pull new files in automatically. Configure under{" "}
+ Settings → Upload Sources → FTP. Both FTP
+ and SFTP are supported.
+
+
+ Set your scanner to drop each scan into its own subfolder named for
+ the date — Echo tags the upload with that subfolder name so you
+ can group scans later.
+
+
+
+
+
Every uploaded file moves through these states:
+
+
+ Uploaded — file is stored, waiting for a
+ worker.
+
+
+ Processing — AI is extracting fields against
+ your active form template.
+
+
+ Needs Review — extraction succeeded; a human
+ should confirm unclear fields.
+
+
+ Confirmed — reviewer has signed off; card is
+ ready for export/integration push.
+
+
+ Failed — extraction couldn’t run (bad
+ image, unreadable handwriting, etc.). The file is retained so you
+ can retry.
+
diff --git a/src/app/(marketing)/terms/page.tsx b/src/app/(marketing)/terms/page.tsx
index ef0481f..5c2cc51 100644
--- a/src/app/(marketing)/terms/page.tsx
+++ b/src/app/(marketing)/terms/page.tsx
@@ -377,10 +377,10 @@ export default function TermsOfServicePage() {
Either party may terminate these Terms at any time. You may stop using the
Service and delete your account by contacting{" "}
- support@echoocr.com
+ support@stillwell.cloud
.
@@ -423,21 +423,21 @@ export default function TermsOfServicePage() {