From 2fb32173a34c6eaeaa5957c092134b7b61c2d577 Mon Sep 17 00:00:00 2001 From: "Joseph T. French" Date: Tue, 27 Oct 2026 11:16:26 -0500 Subject: [PATCH 1/2] feat(landing): lead with the group, and the features since the last pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The homepage still sold the 2026-09-02 arc, "Connect your books. Ask your AI.", while gtm/plan.md §1 (2026-10-18) sells the group: each company's own books and close, the consolidation drafted by the assistant and posted by a person. Six weeks of features had also shipped with no line on the page, and three lines had gone wrong. - Hero, first band, title, description, social card and llms.txt lead with the group. "Nothing writes back" and "any MCP client" stay. - A new first spotlight, Groups & consolidation, on a new demo (public/demos/group.js): Driftline's real August 2026 worksheet, rounded to the dollar, the drafted adjustments named one at a time, and a person closing the group's month. - How It Works sets the group up (parent's QuickBooks, bank feeds and opening balances for the others) and closes each company, then the group. - Spotlights pick up the drill to the register, figure lineage, segment columns, bank reconciliations, loan and custom-curve schedules, learned suggestions with bulk approve, Posting Rules and AR/AP aging. - Fixes: the inbox "autopilot for trusted sources" (no such setting); the FAQ's "the parent's statements combine them" (they consolidate); event-handler rules "without a dedicated form" (Posting Rules reviews and approves them now). - The price: $99 a month per graph in the FAQ and final band, and an Offer in the SoftwareApplication JSON-LD. - The retired-phrase guard gains the four wrong claims. --- public/demos/group.js | 182 ++++++++++++++++++ public/demos/render.html | 1 + src/app/(landing)/metadata.ts | 12 +- src/app/llms.txt/route.ts | 2 +- src/app/opengraph-image.tsx | 2 +- src/components/landing/AgentSurface.tsx | 26 +-- src/components/landing/FaqSection.tsx | 110 +++++++---- src/components/landing/FinalCTA.tsx | 16 +- src/components/landing/Footer.tsx | 3 +- src/components/landing/HeroSection.tsx | 19 +- src/components/landing/HowItWorks.tsx | 20 +- src/components/landing/PlatformSection.tsx | 8 +- src/components/landing/ProofBand.tsx | 20 +- src/components/landing/Spotlights.tsx | 62 +++--- .../landing/__tests__/retired-phrases.test.ts | 10 + src/lib/site.ts | 9 +- src/lib/structured-data.ts | 19 +- 17 files changed, 410 insertions(+), 111 deletions(-) create mode 100644 public/demos/group.js diff --git a/public/demos/group.js b/public/demos/group.js new file mode 100644 index 00000000..765674b1 --- /dev/null +++ b/public/demos/group.js @@ -0,0 +1,182 @@ +/* + * Spotlight: a group of companies, consolidated. The worksheet fills company by + * company, the drafted adjustments are named one at a time, the consolidated + * column lands, and a person closes the group's month. Driftline's real August + * 2026 worksheet (consolidation-worksheet), rounded to the dollar: Harbor Café + * is 70% owned, Pier Market Kiosk 40% on the equity method. + */ +import { + appChrome, + CURSOR, + dip, + eo, + pageHeader, + PHONE_APP_CSS, + pointer, + push, + rise, + seg, + steps, + swap, +} from './kit.js' + +const COLS = [ + ['Roasters', 'mc'], + ['Café LLC', 'mc'], + ['Harbor Café 70%', 'mc'], + ['Combined', ''], + ['Adjustments', 'adj'], + ['Consolidated', 'con'], +] +// Costs read positive and the outside owners' share is deducted, as on the statement. +const ROWS = [ + ['Revenues', [135830, 21400, 19600, 176830, -1230, 175600]], + ['Cost of revenue', [60000, 5200, 6100, 71300, 0, 71300]], + ['Operating expenses', [61738, 9442, 8488, 79668, -1230, 78438]], + ['Interest, net', [25, -25, 0, 0, 0, 0]], + ['Share of Pier Market 40%', [0, 0, 0, 0, 1080, 1080]], + ["Outside owners' share", [0, 0, 0, 0, 1504, 1504]], + ['Net income', [14117, 6733, 5012, 25862, -424, 25438], 1], +] +const fmt = (v) => + v === 0 + ? '–' + : v < 0 + ? `(${(-v).toLocaleString('en-US')})` + : v.toLocaleString('en-US') + +// What each drafted adjustment is, ringed on its cell in turn: [row, note]. +const NOTES = [ + [ + 0, + 'Business the companies did with each other: $1,230 out of revenue and expense', + ], + [ + 4, + "Pier Market Kiosk, held 40%: the group's share of its $2,700, not its revenue", + ], + [ + 5, + "Harbor Café's outside owners: 30% of its $5,012, as noncontrolling interest", + ], +] +const CHECKS = [ + '4 of 4 companies closed', + 'Entries drafted', + 'Nothing unexplained', + 'Statements tie', +] + +// Column reveal times: the three companies, combined, the adjustments, consolidated. +const REVEAL = [1.5, 1.8, 2.1, 2.6, 3.3, 7.3] +const TOTAL = 12.5 + +const main = `${pageHeader('Live Statements', 'Driftline Coffee Roasters group · August 2026')} +
This entityCombinedConsolidatedWorksheet + Adjustments
+
+ ${COLS.map((c, i) => ``).join('')} + ${ROWS.map( + (r, ri) => + `${r[1].map((v, ci) => ``).join('')}` + ).join('')} +
Income statement${c[0]}
${r[0]}${fmt(v)}
+
+
Drafted by your AI
+
+
Close the group · August 2026 +
${CHECKS.map((c, i) => `${c}`).join('')}
+ Close the group +
+
` + +const css = ` +.ws { position: relative; } +.ws th { font-size: 12px; padding: 10px 10px; line-height: 1.25; } +.ws td { padding: 10px 10px; font-size: 16px; } +.ws td.n { font-size: 15px; white-space: nowrap; } +.ws .v { display: inline-block; } +.ws th:first-child, .ws td:first-child { width: 228px; } +.ws td.adj, .ws th.adj { color: var(--v300); } +.ws tr.tot td.con { color: var(--f400); } +.slot { position: relative; height: 96px; margin-top: 16px; } +.slot .card { position: absolute; inset: 0; padding: 16px 20px; display: flex; align-items: center; gap: 18px; opacity: 0; } +.note span:last-child { font-size: 18px; } +.gl b { font-size: 19px; display: block; margin-bottom: 10px; } +.chk { display: flex; gap: 8px; flex-wrap: wrap; } .chk .badge { font-size: 13px; padding: 5px 10px; } +.gclose .btn { margin-left: auto; white-space: nowrap; } +` + +function setup(ctx) { + const { $ } = ctx + ctx.nav('statements') + // the figures fade in, not the cells, so the table keeps its rows while it fills + const cells = (ci) => [$('h' + ci), ...ROWS.map((_, ri) => $(`v${ri}_${ci}`))] + return (t) => { + rise($('tabs'), eo(seg(t, 0.1, 0.5)), 12) + pointer(ctx, $('cur'), $('tw'), t, 0.6, 1.3) + swap($('tc'), t, 1.3, null, null, ['tab on', 'tab']) + swap($('tw'), t, 1.3, null, null, ['tab', 'tab on']) + REVEAL.forEach((at, ci) => { + const p = eo(seg(t, at, at + 0.45)) + cells(ci).forEach((el) => rise(el, p, 10)) + }) + steps( + $('dr'), + t, + [3.3], + ['Adjustments', 'Adjustments drafted'], + ['badge b-mute', 'badge b-v'] + ) + push($('main'), t, TOTAL, 640, 300) + + // The drafted adjustments, one at a time, then the note gives way to the close. + const k = + t < 3.8 ? 0 : Math.min(NOTES.length - 1, Math.floor((t - 3.8) / 1.15)) + const at = 3.8 + k * 1.15 + $('ntx').textContent = NOTES[k][1] + $('ntx').style.opacity = String(k > 0 ? dip(t, at) : 1) + const noteOn = eo(seg(t, 3.6, 4.0)) * (1 - seg(t, 7.3, 7.7)) + rise($('nt'), noteOn, 12) + ctx.ring($('hl'), $(`c${NOTES[k][0]}_4`), t > 3.8 && t < 7.3 ? noteOn : 0) + + rise($('gc'), eo(seg(t, 7.8, 8.2)), 12) + CHECKS.forEach((_, i) => + steps($('k' + i), t, [8.4 + i * 0.3], null, [ + 'badge b-mute', + 'badge b-good', + ]) + ) + pointer(ctx, $('cur2'), $('cp'), t, 9.7, 10.3, { from: [-220, 120] }) + swap($('cp'), t, 10.4, 'Close the group', 'Closed ✓') + $('cp').style.opacity = (0.4 + 0.6 * eo(seg(t, 9.3, 9.6))) * dip(t, 10.4) + } +} + +// Phone layout: the three companies give way to combined, adjustments and consolidated. +const phoneCss = ` +.ws .mc { display: none; } +.ws th:first-child, .ws td:first-child { width: auto; } +.ws td { font-size: 15px; } .ws td.n { font-size: 14px; } +.tabs { flex-wrap: wrap; gap: 8px; } .tab { font-size: 13px; padding: 7px 10px; } +#dr { display: none; } +.slot { height: 150px; } +.slot .card { flex-wrap: wrap; gap: 10px; padding: 14px 16px; } +.note span:last-child { font-size: 16px; } +.gl b { font-size: 16px; } +.gclose .btn { margin-left: 0; font-size: 15px; padding: 8px 14px; } +` + +export default { + width: 1200, + height: 750, + total: TOTAL, + poster: 11.5, + css, + html: + appChrome({ active: 'statements', main }) + + CURSOR.replace('class="cursor"', 'class="cursor" id="cur"') + + CURSOR.replace('class="cursor"', 'class="cursor" id="cur2"'), + setup, + mobile: { width: 720, height: 740, css: PHONE_APP_CSS + phoneCss }, +} diff --git a/public/demos/render.html b/public/demos/render.html index 9dfb1af3..2164da10 100644 --- a/public/demos/render.html +++ b/public/demos/render.html @@ -44,6 +44,7 @@ 'console', 'close', 'inbox', + 'group', ] const name = new URLSearchParams(location.search).get('demo') || 'hero' if (!DEMOS.includes(name)) { diff --git a/src/app/(landing)/metadata.ts b/src/app/(landing)/metadata.ts index c31d6353..575a0481 100644 --- a/src/app/(landing)/metadata.ts +++ b/src/app/(landing)/metadata.ts @@ -4,9 +4,17 @@ import type { Metadata } from 'next' export const landingMetadata: Metadata = { title: SITE_TITLE, description: SITE_DESCRIPTION, - // The long tail behind the head terms Intuit owns (2026-09-02 SERP sample); the close - // terms left with the old hero. + // The group terms lead since the 2026-10-27 refresh (gtm/seo/keywords.md: "multi-entity + // accounting" rising, "combined vs consolidated" at almost no competition), then the long + // tail behind the head terms Intuit owns (2026-09-02 SERP sample); the close terms left + // with the old hero. keywords: [ + 'multi-entity accounting', + 'consolidated financial statements software', + 'holding company accounting software', + 'accounting software for multiple LLCs', + 'combined vs consolidated financial statements', + 'intercompany eliminations', 'AI-native accounting', 'QuickBooks MCP server', 'connect QuickBooks to Claude', diff --git a/src/app/llms.txt/route.ts b/src/app/llms.txt/route.ts index 06c3fdd8..8e54337a 100644 --- a/src/app/llms.txt/route.ts +++ b/src/app/llms.txt/route.ts @@ -34,7 +34,7 @@ export async function GET() { '', `> ${SITE_DESCRIPTION}`, '', - 'RoboLedger is a finance layer on top of QuickBooks, not a replacement ledger. It syncs the books into a knowledge graph that Claude, ChatGPT, or any MCP client can query at https://api.robosystems.ai/v1/mcp/roboledger: financial statements, forecasts that roll off actuals, comparisons with public companies from their SEC filings, and a month-end close that is drafted for review. Nothing is written back to QuickBooks until a person posts it. It is built on RoboSystems (https://robosystems.ai), open source under Apache 2.0, by RFS LLC.', + "RoboLedger keeps the books of a company or a whole group of companies (a holding company and its LLCs, a franchise operator, a founder with several companies), each with its own chart of accounts and close, and builds the group's consolidated statements from them: the assistant drafts the consolidating entries (eliminations, intercompany balances, noncontrolling interest, equity-method results) and a person posts them. It syncs the group parent's QuickBooks and takes bank feeds for the other companies, into a knowledge graph that Claude, ChatGPT, or any MCP client can query at https://api.robosystems.ai/v1/mcp/roboledger: financial statements, forecasts that roll off actuals, comparisons with public companies from their SEC filings, and a month-end close that is drafted for review. Nothing is written back to QuickBooks until a person posts it. It costs $99 a month per graph on the RoboSystems Standard plan (https://robosystems.ai/pricing). It is built on RoboSystems (https://robosystems.ai), open source under Apache 2.0, by RFS LLC.", '', '## Product', ...PRODUCT_PAGES.map((page) => diff --git a/src/app/opengraph-image.tsx b/src/app/opengraph-image.tsx index 637af737..7d6bbc45 100644 --- a/src/app/opengraph-image.tsx +++ b/src/app/opengraph-image.tsx @@ -10,6 +10,6 @@ export default function Image() { eyebrow: 'RoboLedger', title: 'Connect your books. Ask your AI.', subtitle: - 'Sync QuickBooks into a graph Claude, ChatGPT, or any MCP client can query.', + "Each company keeps its own books. Your AI drafts the group's consolidation.", }) } diff --git a/src/components/landing/AgentSurface.tsx b/src/components/landing/AgentSurface.tsx index d4c10c03..5bd7b716 100644 --- a/src/components/landing/AgentSurface.tsx +++ b/src/components/landing/AgentSurface.tsx @@ -7,7 +7,7 @@ import FloatingElementsVariant from './FloatingElementsVariant' * ship as a screen. * * Every tool named here is a real, registered MCP tool on a writable - * roboledger graph — verified against the backend's tool registry, not + * roboledger graph, verified against the backend's tool registry, not * aspirational. Write operations declared as `OperationSpec`s are * auto-generated into MCP tools by the registrar, which is *why* the agent * surface runs ahead of the UI: a new operation is callable from any MCP @@ -16,7 +16,7 @@ import FloatingElementsVariant from './FloatingElementsVariant' * Keep this list honest. Before adding a row, confirm the tool is actually * registered (an `OperationSpec(name=...)`, or a hand-written tool in * `middleware/mcp/tools/`) and that the app genuinely has no UI input for - * it — several report operations, for instance, are plain REST routes and + * it: several report operations, for instance, are plain REST routes and * are NOT MCP tools, and schedules ARE authorable in the Closing Book. */ @@ -33,10 +33,12 @@ const capabilities: { title: string; blurb: string; tools: string[] }[] = [ 'Declare a metric block and its operands once; the Block Explorer computes and charts its standing time series from then on.', tools: ['create-information-block', 'compute-metrics'], }, + // Posting Rules (2026-10-21) reviews, edits, approves and switches rules on and off, but + // a new rule is still written over MCP, so the card stays and names where it lands. { title: 'Write an event-handler rule', blurb: - 'Teach the ledger how a new kind of business event should post — the same DSL rows the Inbox reads when it pre-classifies a transaction.', + 'Teach the ledger how a new kind of business event should post. The rule your AI writes waits in Posting Rules, booking nothing until a person approves it there.', tools: ['create-event-handler', 'update-event-handler'], }, { @@ -76,7 +78,7 @@ export default function AgentSurface() {

Every write operation on the platform becomes an MCP tool the day it - ships. Screens follow where they earn it — so there are things your + ships. Screens follow where they earn it, so there are things your AI assistant can do today that don't have a button yet.

@@ -89,8 +91,9 @@ export default function AgentSurface() { label="One AI chat with three companies' books connected, reading each and answering which client needs attention this month." />

- One connector per set of books, side by side in the same chat. Your - AI reads each one and answers across all of them. + One connector per set of books, side by side in the same chat. A + group's companies share one; each client gets its own. Your AI + reads each one and answers across all of them.

@@ -131,11 +134,12 @@ export default function AgentSurface() {

Add this address as a connector in Claude, ChatGPT, or any MCP - client, sign in, and choose the company. Add it again for each - company you look after. It can read your books and drive these - tools directly — with you approving each write. No install, no - key to paste. The same tools back the in-app AI Console, so - nothing is locked behind a desktop app. + client, sign in, and choose the books. One connector covers a + whole group; add it again for each client you look after. It can + read your books and drive these tools directly, with you + approving each write. No install, no key to paste. The same + tools back the in-app AI Console, so nothing is locked behind a + desktop app.

diff --git a/src/components/landing/FaqSection.tsx b/src/components/landing/FaqSection.tsx index fd4d7e2b..df25d2cd 100644 --- a/src/components/landing/FaqSection.tsx +++ b/src/components/landing/FaqSection.tsx @@ -1,12 +1,43 @@ +import Link from 'next/link' import type { ReactNode } from 'react' -import { HARBINGER_URL, QUICKBOOKS_AFFILIATE_URL } from './constants' +import { + HARBINGER_URL, + QUICKBOOKS_AFFILIATE_URL, + ROBOSYSTEMS_URL, +} from './constants' +// Every answer holds to gtm/plan.md §5: only the group parent's QuickBooks company +// connects; the assistant drafts the consolidating entries and a person posts them; what +// isn't built (other currencies, nested groups) is said plainly. The price is the +// Standard plan on robosystems.ai/pricing, per graph, and a group shares one graph. const faqs: { q: string; a: ReactNode }[] = [ + { + q: 'Can it consolidate a group of companies?', + a: ( + <> + Yes. A holding company and its LLCs, a franchise operator, a founder + with three companies: each company keeps its own books, chart and close, + and the group is built from shared reporting concepts, never from + account names. Every month your AI drafts the consolidating entries (the + parent's investment against each subsidiary's capital, what + the companies owe and bill each other, an outside owner's share) + and a person posts them. Equity-method companies, acquisitions, changes + in ownership and a company sold out of the group are handled too. Not + yet: companies in another currency, or a group inside a group.{' '} + + How consolidation works + + + ), + }, { q: 'Do I have to leave QuickBooks?', a: ( <> - No. RoboLedger syncs your{' '} + No. RoboLedger syncs the group parent's{' '} QuickBooks {' '} - chart of accounts and transactions. Reading, analysis, and planning - write nothing back; approved entries go back to QuickBooks only when you - post them. It's an AI layer on top of your books, not a replacement for - them. + chart of accounts and transactions. The other companies start from their + opening balance sheet and come in through a bank feed, the API or a + file. Reading, analysis, and planning write nothing back; approved + entries go back to QuickBooks only when you post them. ), }, @@ -27,7 +58,7 @@ const faqs: { q: string; a: ReactNode }[] = [ a: ( <> In your own knowledge graph on the RoboSystems platform. RoboLedger is - open source, so you can inspect exactly how every number is produced — + open source, so you can inspect exactly how every number is produced, and you can fork it and take it in-house whenever you want. ), @@ -36,10 +67,11 @@ const faqs: { q: string; a: ReactNode }[] = [ q: 'Do I need to know XBRL or US-GAAP?', a: ( <> - No. AI Auto-Map proposes the US-GAAP mapping for your chart of accounts - with confidence scores, and the rule engine validates every entry before - you lock a period. You review and adjust — the taxonomy work happens for - you. + No. AI Auto-Map proposes the US-GAAP mapping for each company's + chart of accounts with confidence scores, and the rule engine validates + every entry before you lock a period. You review and adjust, and you can + add, rename, move or retire accounts in the app. The taxonomy work + happens for you. ), }, @@ -49,10 +81,11 @@ const faqs: { q: string; a: ReactNode }[] = [ <> It answers questions about your books in plain English, opens any number down to the facts behind it, rolls plans forward, and compares you to - public companies. When you're ready, it also triages each - transaction in the inbox and drafts the close. You stay in control at - every step — one-click approve/reject, dry-run previews of what would - post, and balanced-entry checks before anything commits. + public companies. When you're ready, it also sorts bank lines into + accounts, drafts the month's schedule entries and the group's + consolidating entries, and proposes posting rules. You stay in control + at every step: previews of what would post, balanced-entry checks, and + nothing posts until a person approves it. ), }, @@ -62,7 +95,7 @@ const faqs: { q: string; a: ReactNode }[] = [ <> You can plan forward. Once you've closed a month, the Plan surface puts your monthly statements and a scenario's assumptions in one - grid spanning the actuals/forecast seam — so the forecast is driven by + grid spanning the actuals/forecast seam, so the forecast is driven by the same ledger the close produced, not a spreadsheet copied out of it. Scenarios are authored from your AI assistant over MCP today; the in-app editor is on the way. @@ -73,27 +106,25 @@ const faqs: { q: string; a: ReactNode }[] = [ q: 'Are there things my AI assistant can do that the app cannot?', a: ( <> - Yes — deliberately. Every write operation on the platform becomes an MCP + Yes, deliberately. Every write operation on the platform becomes an MCP tool the day it ships, while screens follow where they earn their place. - Authoring a forecast scenario, defining a new metric, and writing an - event-handler rule all run from Claude, ChatGPT, or any MCP client today - without a dedicated form in the app. Anything you drive that way lands - in the same ledger and shows up on the same screens. + Authoring a forecast scenario and defining a new metric run from Claude, + ChatGPT, or any MCP client today without a dedicated form in the app. A + new posting rule is written by your AI too, and waits in Posting Rules + until a person approves it. Anything you drive that way lands in the + same ledger and shows up on the same screens. ), }, { - q: 'I look after several companies. Can I see them all here?', + q: 'I look after several clients. Can I see them all here?', a: ( <> - Yes. Companies that report together — a holding company and its - subsidiaries — share one graph as a reporting group: each keeps its own - chart of accounts and closes on its own calendar, and the parent's - statements combine them. Unrelated clients get their own isolated - graphs; switch between them from one account. In your AI chat, add the - RoboLedger connector once per graph and ask across all of them. - It's built for fractional CFOs, controllers, and firms who look - after more than one company.{' '} + Yes. Each client gets its own isolated graph (a client with several + companies keeps them together in one), and you switch between them from + one account. In your AI chat, add the RoboLedger connector once per + graph and ask across all of them. It's built for fractional CFOs, + controllers, and firms who look after more than one company.{' '} - Create an account, then provision a graph on the RoboSystems platform — - enabling RoboLedger gives you access to this app. Plans and provisioning - live on the RoboSystems side; once you've enabled RoboLedger, connect - QuickBooks and ask your AI the first question. Nothing writes back until - you post an entry. + $99 a month per graph on the RoboSystems Standard plan, and a + group's companies share one graph. Comparing against public + companies adds the SEC subscription. Create an account, provision a + graph with RoboLedger enabled, connect your books and ask your AI the + first question. It's open source with no outside investors, so + nobody can reprice it or shut it down on you.{' '} + + See plans + ), }, diff --git a/src/components/landing/FinalCTA.tsx b/src/components/landing/FinalCTA.tsx index cd8b2a5f..7c354f0e 100644 --- a/src/components/landing/FinalCTA.tsx +++ b/src/components/landing/FinalCTA.tsx @@ -4,6 +4,7 @@ import { HARBINGER_URL, LOGIN_PATH, REGISTER_PATH, + ROBOSYSTEMS_URL, } from './constants' import FloatingElementsVariant from './FloatingElementsVariant' @@ -16,10 +17,23 @@ export default function FinalCTA() {

See it on your own books

-

+ {/* The first two sentences match the blog's closing card; keep them in step. */} +

Connect QuickBooks and ask your AI the first question. Nothing writes to QuickBooks until you post an entry.

+

+ $99 a month for the whole group's books. Open source, so + it's yours.{' '} + + See plans + +

- Your books, in the chat you already use + For a holding company and its LLCs, in the chat you already use

- Connect your books. + Your group's books. - Ask your AI. + Consolidated.

- Sync QuickBooks into a graph{' '} + Each company keeps its own books, chart and close. Your AI drafts + the month's consolidating entries from them, a person posts + them, and the group closes like one company does. Ask about any + company, or all of them, from{' '} Claude, ChatGPT, or any MCP client - {' '} - can reason over. Statements that tie, a plan that rolls off your - actuals, and your numbers beside public companies.{' '} + + .{' '} Nothing writes back until you post an entry. - {' '} - When you trust it, it drafts the close. +

{/* CTAs */} diff --git a/src/components/landing/HowItWorks.tsx b/src/components/landing/HowItWorks.tsx index 17e4dcc7..bff05be6 100644 --- a/src/components/landing/HowItWorks.tsx +++ b/src/components/landing/HowItWorks.tsx @@ -1,30 +1,32 @@ import FloatingElementsVariant from './FloatingElementsVariant' -// Three steps in the order of the arc: read the books first, the close last. The -// spotlights below carry the detail, so this stays short. +// Three steps in the order of the arc: set the group up, read the books, the close last. +// Only the group parent's QuickBooks company connects (gtm/plan.md §5): the other companies +// come in through a bank feed, an opening balance sheet, the API or a file. The spotlights +// below carry the detail, so this stays short. const steps = [ { number: '01', - title: 'Connect your books', + title: 'Set up the group', description: - 'Link QuickBooks with one-click OAuth, then add one MCP address to Claude, ChatGPT, or any MCP client and sign in. Add the SEC filings connector beside it to compare against public companies.', - tags: ['QuickBooks', 'MCP', 'SEC filings'], + "Add each company with the share the parent holds. Connect the parent's QuickBooks, give the others a bank feed and their opening balance sheet, then add one MCP address to Claude, ChatGPT, or any MCP client.", + tags: ['QuickBooks', 'Bank feeds', 'MCP'], color: 'violet', }, { number: '02', title: 'Ask, share, plan', description: - 'Ask why a number moved and open it down to the facts behind it. Send the board a statement that ties, roll a plan forward from your actuals, and see where you stand against peers.', + 'Ask why a number moved and open it down to the account register. Send the board a statement that ties, roll a plan forward from your actuals, and add the SEC filings beside your books to see where you stand against public companies.', tags: ['Live Statements', 'Explorer', 'Plan'], color: 'purple', }, { number: '03', - title: 'Approve the close', + title: 'Close each company, then the group', description: - 'When you trust it, the entries arrive drafted and the rule engine checks the period. You review and approve; nothing writes back to QuickBooks until you post an entry.', - tags: ['Inbox', 'Closing Book', 'Rule Engine'], + 'Bank lines arrive with a suggested account, schedules draft their entries, and the close waits on the reconciliations you choose. Then your AI drafts the consolidating entries and the group close posts them. Nothing writes back to QuickBooks until you post an entry.', + tags: ['Inbox', 'Reconciliations', 'Group close'], color: 'pink', }, ] diff --git a/src/components/landing/PlatformSection.tsx b/src/components/landing/PlatformSection.tsx index c61f31d6..a9ce2656 100644 --- a/src/components/landing/PlatformSection.tsx +++ b/src/components/landing/PlatformSection.tsx @@ -10,10 +10,10 @@ export default function PlatformSection() { Powered by RoboSystems

- Your numbers live in a financial knowledge graph — a unified - three-block model of taxonomy, events, and information — so every - figure is traceable to its source, queryable in plain English, and - validated before it's filed + Your numbers live in a financial knowledge graph: a unified + three-block model of taxonomy, events, and information. Every figure + is traceable to its source, queryable in plain English, and + validated before it's filed, for one company or a whole group.

diff --git a/src/components/landing/ProofBand.tsx b/src/components/landing/ProofBand.tsx index f8cb8419..c99375e1 100644 --- a/src/components/landing/ProofBand.tsx +++ b/src/components/landing/ProofBand.tsx @@ -1,20 +1,22 @@ -// The first band under the hero, in the arc's order: nothing writes back (connect and -// analyze with no trust), the comparison (the wedge), then the statements. Each line is -// true at HEAD; the close is further down the page, where the story puts it. +// The first band under the hero: the group first (gtm/plan.md §1), then the trust line +// that lets a stranger start with no risk, then the lineage that makes a consolidated +// figure checkable. Each line is true at HEAD and can be shown on the Driftline demo; the +// close is further down the page, where the story puts it. const stats = [ { - stat: 'Nothing writes back', + stat: 'Consolidated, not combined', label: - 'Nothing reaches QuickBooks until you post an entry. Read, analyze and plan first.', + "Eliminations, an outside owner's share and equity-method companies, drafted from each company's own books.", }, { - stat: 'Beside the filers', + stat: 'Nothing writes back', label: - 'Add the SEC graph next to your books and ask how your margins compare to public companies in your niche.', + 'Nothing reaches QuickBooks until you post an entry. Read, analyze and plan first.', }, { - stat: 'Tavi + XBRL 2.1', - label: 'Statements export as validated reports, straight from your ledger.', + stat: 'Every figure opens', + label: + 'Click a number on a statement or report and see the accounts it was summed from, down to the register.', }, ] diff --git a/src/components/landing/Spotlights.tsx b/src/components/landing/Spotlights.tsx index c50a5da0..e4f27c9c 100644 --- a/src/components/landing/Spotlights.tsx +++ b/src/components/landing/Spotlights.tsx @@ -15,20 +15,37 @@ interface Spotlight { demoLabel: string } -// Ordered for the finance lead, not the bookkeeper: read the numbers, question them, plan -// from them, ask in plain English; the close and the inbox, where the team does the entries -// and the lead approves them, come last. +// Ordered for the finance lead, not the bookkeeper: the group's statements first (the +// homepage leads with the group), then read the numbers, question them, plan from them, ask +// in plain English; the close and the inbox, where the team does the entries and the lead +// approves them, come last. Every bullet can be shown on the Driftline demo account. const spotlights: Spotlight[] = [ + { + id: 'groups', + label: 'Groups & consolidation', + title: "Consolidated statements, drafted from each company's books", + description: + "Add each company with the share the parent holds. Every month your AI drafts the consolidating entries from the books: the parent's investment against each subsidiary's capital, what the companies owe and bill each other, and an outside owner's share. A person posts them, and the group's month closes only when it all ties.", + bullets: [ + 'A worksheet with every company in its own column, then combined, the adjustments and consolidated', + 'Noncontrolling interest, the equity method, and a company bought, partly sold or sold out of the group mid-year', + 'Each company closes on its own calendar; what the books cannot explain is named for you, never plugged', + ], + caption: 'Ledger › Statements › Worksheet', + demo: 'group', + demoLabel: + "Driftline's August consolidation worksheet filling company by company, the drafted adjustments explained one at a time, and a person closing the group's month.", + }, { id: 'reporting', label: 'Reporting & XBRL', - title: 'Live statements & validated reports', + title: 'Live statements, and every figure opens', description: - 'See the Balance Sheet and Income Statement straight from the ledger on any day of the month, no close required, with Cash Flow and Equity as your transactions are classified. When it is time to send, generate a validated report package.', + 'See the balance sheet and income statement straight from the ledger on any day of the month, no close required, for one company or the whole group. Click a figure to see the accounts it was summed from. When it is time to send, generate a validated report package.', bullets: [ - 'Multi-period and comparative reports with a Draft → Under Review → Filed lifecycle', - 'Export Tavi and XBRL 2.1 reports; verification view checks US-GAAP concept relations', - 'Share snapshots with your board, lenders, and investors through publish lists', + "Drill from a statement, the trial balance or the journal into an account's register", + 'Income statement columns by department, class, location or project, and CSV on every statement', + 'Tavi and XBRL 2.1 report packages, shared with your board, lenders and investors through publish lists', ], caption: 'Ledger › Statements', demo: 'statements', @@ -58,7 +75,7 @@ const spotlights: Spotlight[] = [ description: 'Your closed months and your forecast in one monthly grid. Switch to a scenario and see what it does to cash, with its levers sitting right beneath the statements they drive.', bullets: [ - 'Income Statement, Balance Sheet, and Cash Flow month by month — actuals and forward columns in the same row', + 'Income Statement, Balance Sheet, and Cash Flow month by month, with actuals and forward columns in the same row', 'Switch scenarios in place; the assumption levers driving the forecast render in the same grid', 'Trailing-window control, CSV export, and shareable scenario links', ], @@ -75,7 +92,7 @@ const spotlights: Spotlight[] = [ 'Get the answer yourself instead of waiting on a report, and hand off the routine work. Use the AI Console in the app, or connect Claude, ChatGPT, or any MCP client and use the same tools from the chat you already use.', bullets: [ 'Ask in plain English; answers come from your ledger, with the generated query beside the result', - 'Start with /do to sort bank-feed lines, draft the month’s schedule entries, or build a metric, forecast, or draft report — on a stronger model than questions use, because a wrong change costs more than a wrong answer', + 'Start with /do to sort bank-feed lines, draft the month’s schedule entries, or build a metric, forecast, or draft report, on a stronger model than questions use, because a wrong change costs more than a wrong answer', 'Nothing posts on its own: what it sorts or drafts waits for a person to commit, close, or file', ], caption: 'Console', @@ -88,11 +105,11 @@ const spotlights: Spotlight[] = [ label: 'Period close', title: 'Close the period with guard rails', description: - 'The entries get drafted; you review and approve. A guided, sequential close backed by a fiscal calendar and a rule engine, so no one locks an unbalanced or out-of-order period.', + 'The entries get drafted; you review and approve. A sequential close backed by a fiscal calendar, reconciliations and a rule engine, so no one locks an unbalanced, unreconciled or out-of-order month.', bullets: [ - 'Fiscal-calendar bootstrap with human-readable blockers (period incomplete, sync stale, out of sequence)', - 'Schedules post depreciation & prepaid entries to draft; balanced-draft gating before you lock', - 'Optional write-back to QuickBooks on close, and reopen-with-audit-reason', + 'Bank reconciliations against the statement: its cycle, the lines the bank has not cleared, the roll-forward, and a sign-off', + 'Schedules for depreciation, prepaids, loans and custom curves, previewed month by month before they draft', + 'Blockers in plain words (sync stale, out of sequence, unmapped accounts), reopen with an audit reason, optional write-back to QuickBooks', ], caption: 'Ledger › Closing Book', demo: 'close', @@ -104,11 +121,11 @@ const spotlights: Spotlight[] = [ label: 'Event-driven ledger', title: 'An inbox for your books', description: - 'Every transaction lands as a typed business event — captured, classified, then committed. AI proposes the entry; you set the rules and nothing posts without a decision.', + 'Every QuickBooks transaction and bank line lands as a typed business event: captured, classified, then committed. Bank lines arrive with a suggested account and where it came from; you set the rules, and nothing posts without a decision.', bullets: [ - 'AI pre-classifies invoices, bills, payments, and receipts', - 'Preview exactly what would post — matched handler, planned journal entries, validation errors — before it hits the GL', - 'Approve or reject in one click — or enable autopilot for trusted sources', + "Suggestions from the counterparty's learned default, the bank's category or AI, each labelled, and the learned ones approved in bulk", + 'Posting Rules: a rule your AI proposes books nothing until a person approves it', + 'Settle a bill from the line it paid, and see receivables and payables aged by days past due', ], caption: 'Ledger › Inbox', demo: 'inbox', @@ -127,10 +144,10 @@ export default function Spotlights() { Inside RoboLedger

- From the first question to the close + From the group's statements to the close

- Six views of the same live books. Read the statements, open any + Seven views of the same live books. Read the whole group, open any number, plan forward, and ask in plain English. When you trust it, the close and the inbox are there too.

@@ -140,7 +157,8 @@ export default function Spotlights() { {spotlights.map((s, idx) => (
figure]:order-first' : '' }`} > @@ -176,7 +194,7 @@ export default function Spotlights() {
- + Date: Tue, 27 Oct 2026 11:23:52 -0500 Subject: [PATCH 2/2] feat(landing): keep the books-first hero, with the group beside it The group story waits on asks that convert, and the visitors arriving today come from the QuickBooks-and-MCP searches and the directories, mostly with one company. So the hero, title and social card go back to "Connect your books. Ask your AI.", and the group joins them as a sentence rather than replacing them. - Hero: the old badge and headline; the subhead adds "One company or a whole group", with the consolidation drafted by your AI. - Title back; the description adds "consolidate a group". The social card's subtitle now matches its title. - Proof band: "Nothing writes back" first, the group second. - How It Works: "Connect your books" and "Approve the close", the group optional in each. - Spotlights: the statements first, the group second; the heading back. - Keywords: the holding-company and LLC phrasings read blank on the 2026-10-07 volume pull, so they go; "multi entity accounting software", the category's target, comes in after the existing terms. --- src/app/(landing)/metadata.ts | 16 ++++----- src/app/opengraph-image.tsx | 2 +- src/components/landing/HeroSection.tsx | 18 +++++----- src/components/landing/HowItWorks.tsx | 18 +++++----- src/components/landing/ProofBand.tsx | 16 ++++----- src/components/landing/Spotlights.tsx | 49 +++++++++++++------------- src/lib/site.ts | 11 +++--- 7 files changed, 63 insertions(+), 67 deletions(-) diff --git a/src/app/(landing)/metadata.ts b/src/app/(landing)/metadata.ts index 575a0481..6e147c1c 100644 --- a/src/app/(landing)/metadata.ts +++ b/src/app/(landing)/metadata.ts @@ -4,17 +4,10 @@ import type { Metadata } from 'next' export const landingMetadata: Metadata = { title: SITE_TITLE, description: SITE_DESCRIPTION, - // The group terms lead since the 2026-10-27 refresh (gtm/seo/keywords.md: "multi-entity - // accounting" rising, "combined vs consolidated" at almost no competition), then the long - // tail behind the head terms Intuit owns (2026-09-02 SERP sample); the close terms left - // with the old hero. + // The long tail behind the head terms Intuit owns (2026-09-02 SERP sample), then the group + // terms with search volume (gtm/seo/keywords.md, 2026-10-07; the holding-company and LLC + // phrasings read blank); the close terms left with the old hero. keywords: [ - 'multi-entity accounting', - 'consolidated financial statements software', - 'holding company accounting software', - 'accounting software for multiple LLCs', - 'combined vs consolidated financial statements', - 'intercompany eliminations', 'AI-native accounting', 'QuickBooks MCP server', 'connect QuickBooks to Claude', @@ -23,6 +16,9 @@ export const landingMetadata: Metadata = { 'analyze QuickBooks data with AI', 'benchmark small business against public companies', 'QuickBooks scenario planning AI', + 'multi entity accounting software', + 'multi-entity accounting', + 'combined vs consolidated financial statements', 'financial knowledge graph', 'XBRL reporting', ], diff --git a/src/app/opengraph-image.tsx b/src/app/opengraph-image.tsx index 7d6bbc45..8a240a5f 100644 --- a/src/app/opengraph-image.tsx +++ b/src/app/opengraph-image.tsx @@ -10,6 +10,6 @@ export default function Image() { eyebrow: 'RoboLedger', title: 'Connect your books. Ask your AI.', subtitle: - "Each company keeps its own books. Your AI drafts the group's consolidation.", + 'One company or a whole group, in Claude, ChatGPT, or any MCP client.', }) } diff --git a/src/components/landing/HeroSection.tsx b/src/components/landing/HeroSection.tsx index e76086cc..94ca92af 100644 --- a/src/components/landing/HeroSection.tsx +++ b/src/components/landing/HeroSection.tsx @@ -20,27 +20,27 @@ export default function HeroSection() {
- For a holding company and its LLCs, in the chat you already use + Your books, in the chat you already use

- Your group's books. + Connect your books. - Consolidated. + Ask your AI.

- Each company keeps its own books, chart and close. Your AI drafts - the month's consolidating entries from them, a person posts - them, and the group closes like one company does. Ask about any - company, or all of them, from{' '} + Sync QuickBooks into a graph{' '} Claude, ChatGPT, or any MCP client - - .{' '} + {' '} + can reason over. Statements that tie, a plan that rolls off your + actuals, and your numbers beside public companies. One company or a + whole group: each keeps its own books and close, and your AI drafts + the consolidation.{' '} Nothing writes back until you post an entry. diff --git a/src/components/landing/HowItWorks.tsx b/src/components/landing/HowItWorks.tsx index bff05be6..465bef21 100644 --- a/src/components/landing/HowItWorks.tsx +++ b/src/components/landing/HowItWorks.tsx @@ -1,16 +1,16 @@ import FloatingElementsVariant from './FloatingElementsVariant' -// Three steps in the order of the arc: set the group up, read the books, the close last. -// Only the group parent's QuickBooks company connects (gtm/plan.md §5): the other companies -// come in through a bank feed, an opening balance sheet, the API or a file. The spotlights -// below carry the detail, so this stays short. +// Three steps in the order of the arc: read the books first, the close last. A group is +// optional at each step. Only the group parent's QuickBooks company connects (gtm/plan.md +// §5): the other companies come in through a bank feed, an opening balance sheet, the API +// or a file. The spotlights below carry the detail, so this stays short. const steps = [ { number: '01', - title: 'Set up the group', + title: 'Connect your books', description: - "Add each company with the share the parent holds. Connect the parent's QuickBooks, give the others a bank feed and their opening balance sheet, then add one MCP address to Claude, ChatGPT, or any MCP client.", - tags: ['QuickBooks', 'Bank feeds', 'MCP'], + 'Link QuickBooks with one-click OAuth, then add one MCP address to Claude, ChatGPT, or any MCP client and sign in. For a group, add each company with the share the parent holds, with a bank feed and an opening balance sheet.', + tags: ['QuickBooks', 'MCP', 'Bank feeds'], color: 'violet', }, { @@ -23,9 +23,9 @@ const steps = [ }, { number: '03', - title: 'Close each company, then the group', + title: 'Approve the close', description: - 'Bank lines arrive with a suggested account, schedules draft their entries, and the close waits on the reconciliations you choose. Then your AI drafts the consolidating entries and the group close posts them. Nothing writes back to QuickBooks until you post an entry.', + 'Bank lines arrive with a suggested account, schedules draft their entries, and the close waits on the reconciliations you choose. For a group, your AI then drafts the consolidating entries and the group close posts them. Nothing writes back to QuickBooks until you post an entry.', tags: ['Inbox', 'Reconciliations', 'Group close'], color: 'pink', }, diff --git a/src/components/landing/ProofBand.tsx b/src/components/landing/ProofBand.tsx index c99375e1..6c9233fa 100644 --- a/src/components/landing/ProofBand.tsx +++ b/src/components/landing/ProofBand.tsx @@ -1,17 +1,17 @@ -// The first band under the hero: the group first (gtm/plan.md §1), then the trust line -// that lets a stranger start with no risk, then the lineage that makes a consolidated -// figure checkable. Each line is true at HEAD and can be shown on the Driftline demo; the -// close is further down the page, where the story puts it. +// The first band under the hero: the trust line that lets a stranger start with no risk, +// then the group (gtm/plan.md §1), then the lineage that makes a figure checkable. Each +// line is true at HEAD and can be shown on the Driftline demo; the close is further down +// the page, where the story puts it. const stats = [ { - stat: 'Consolidated, not combined', + stat: 'Nothing writes back', label: - "Eliminations, an outside owner's share and equity-method companies, drafted from each company's own books.", + 'Nothing reaches QuickBooks until you post an entry. Read, analyze and plan first.', }, { - stat: 'Nothing writes back', + stat: 'Consolidated, not combined', label: - 'Nothing reaches QuickBooks until you post an entry. Read, analyze and plan first.', + "Eliminations, an outside owner's share and equity-method companies, drafted from each company's own books.", }, { stat: 'Every figure opens', diff --git a/src/components/landing/Spotlights.tsx b/src/components/landing/Spotlights.tsx index e4f27c9c..7f3f8ca9 100644 --- a/src/components/landing/Spotlights.tsx +++ b/src/components/landing/Spotlights.tsx @@ -15,27 +15,11 @@ interface Spotlight { demoLabel: string } -// Ordered for the finance lead, not the bookkeeper: the group's statements first (the -// homepage leads with the group), then read the numbers, question them, plan from them, ask -// in plain English; the close and the inbox, where the team does the entries and the lead -// approves them, come last. Every bullet can be shown on the Driftline demo account. +// Ordered for the finance lead, not the bookkeeper: read the numbers, then the group's +// statements built from them, question them, plan from them, ask in plain English; the +// close and the inbox, where the team does the entries and the lead approves them, come +// last. Every bullet can be shown on the Driftline demo account. const spotlights: Spotlight[] = [ - { - id: 'groups', - label: 'Groups & consolidation', - title: "Consolidated statements, drafted from each company's books", - description: - "Add each company with the share the parent holds. Every month your AI drafts the consolidating entries from the books: the parent's investment against each subsidiary's capital, what the companies owe and bill each other, and an outside owner's share. A person posts them, and the group's month closes only when it all ties.", - bullets: [ - 'A worksheet with every company in its own column, then combined, the adjustments and consolidated', - 'Noncontrolling interest, the equity method, and a company bought, partly sold or sold out of the group mid-year', - 'Each company closes on its own calendar; what the books cannot explain is named for you, never plugged', - ], - caption: 'Ledger › Statements › Worksheet', - demo: 'group', - demoLabel: - "Driftline's August consolidation worksheet filling company by company, the drafted adjustments explained one at a time, and a person closing the group's month.", - }, { id: 'reporting', label: 'Reporting & XBRL', @@ -52,6 +36,22 @@ const spotlights: Spotlight[] = [ demoLabel: 'A balance sheet and income statement rendered live from the ledger, then a report package moving from draft to filed.', }, + { + id: 'groups', + label: 'Groups & consolidation', + title: "Consolidated statements, drafted from each company's books", + description: + "Add each company with the share the parent holds. Every month your AI drafts the consolidating entries from the books: the parent's investment against each subsidiary's capital, what the companies owe and bill each other, and an outside owner's share. A person posts them, and the group's month closes only when it all ties.", + bullets: [ + 'A worksheet with every company in its own column, then combined, the adjustments and consolidated', + 'Noncontrolling interest, the equity method, and a company bought, partly sold or sold out of the group mid-year', + 'Each company closes on its own calendar; what the books cannot explain is named for you, never plugged', + ], + caption: 'Ledger › Statements › Worksheet', + demo: 'group', + demoLabel: + "Driftline's August consolidation worksheet filling company by company, the drafted adjustments explained one at a time, and a person closing the group's month.", + }, { id: 'explorer', label: 'Block Explorer', @@ -144,12 +144,13 @@ export default function Spotlights() { Inside RoboLedger

- From the group's statements to the close + From the first question to the close

- Seven views of the same live books. Read the whole group, open any - number, plan forward, and ask in plain English. When you trust it, - the close and the inbox are there too. + Seven views of the same live books. Read the statements, for one + company or a whole group, open any number, plan forward, and ask in + plain English. When you trust it, the close and the inbox are there + too.

diff --git a/src/lib/site.ts b/src/lib/site.ts index eef76819..f843eff5 100644 --- a/src/lib/site.ts +++ b/src/lib/site.ts @@ -3,14 +3,13 @@ // Until 2026-09-16 the social card, the JSON-LD and the manifest still carried the retired // financial-reporting positioning while the page itself said "Connect your books. Ask // Claude.", so a shared link and a search engine each described a different product. -// Since 2026-10-27 the homepage leads with the group (gtm/plan.md §1): each company's own -// books, the consolidation drafted by the assistant and posted by a person, never "the -// system consolidates" (§5). The description stays under 160 characters so results show it -// whole. +// The group joined the description on 2026-10-27 without taking the title: every search +// impression so far is in the QuickBooks-and-MCP cluster, and the group story waits on asks +// that convert. The description stays under 160 characters so results show it whole. export const SITE_NAME = 'RoboLedger' -export const SITE_TITLE = 'RoboLedger | Multi-Entity Accounting with AI' +export const SITE_TITLE = 'RoboLedger | Connect Your Books. Ask Your AI.' export const SITE_DESCRIPTION = - "Each company keeps its own books and close. Your AI drafts the group's consolidating entries and you post them, from Claude, ChatGPT or any MCP client." + 'Sync QuickBooks into a graph Claude, ChatGPT, or any MCP client can query. Analyze, plan, consolidate a group. Nothing writes back until you post.'