Skip to content
Ramunas SabalysProduct Designer & Design Engineer

03 · Kvimo · Managed accounting · Web and iOS · 2026, newest

Accounting you can check.

Accounting done for you. Claude keeps the books, a real accountant checks them, and every number links to its document, payment and entry.

My part. Product calls, design, the web app and the native iOS app.

A business owner's home, on the web and iPhoneDemo company · shown in the theme you are reading in

Scroll to read · 7 chapters · 8 min

At a glance

Kvimo does the accounting for Lithuanian micro companies. Claude, Anthropic's AI, keeps the books, a real accountant supervises, and business owners answer plain questions on the web or in a native iPhone app. The product is what makes the service work: owners never learn bookkeeping, and the accountant sees the evidence behind every number. It holds money, bank access and personal data, so every screen is a trust decision.

days, the longest bank consent most Lithuanian banks allow. Kvimo warns before it ends.
180
payments Kvimo can make from your bank. Bank access only reads.
0
roles, owner, accountant and viewer, over nine areas of the books
3
Service
Managed accounting for micro companies
Role
Product, design and engineering, web and iOS
Team
Me and a supervising accountant
Timeline
2026
Status
In use by a paying client · iOS app submitted to the App Store
Tools
TypeScript, SwiftUI, Stripe

From problem to shipped product

I made the product calls, wrote the rules, designed every screen and built the web and iOS apps. A real accountant supervises the books.

  1. Step 1 · MeWrite the rules down: what each part of the books must enforce
  2. Step 2 · MeDesign every screen, for the web and for iPhone
  3. Step 3 · MeBuild the web app and the native iOS app
  4. Step 4 · A human accountantSupervises the books Claude keeps
  5. Step 5 · MeFix what the accountant flags, and ship again

From first sketch to the App Store

  1. StartTwo dashboard directions side by side
  2. FoundationsLedger, bank feeds, tax filings and the AI policy
  3. Simple viewA simple door for owners, and the iPhone app begins
  4. BrandThe yellow Citrina brand ships
  5. ServiceThe service sold in the app, through Stripe
  6. NowiPhone app submitted to the App Store, launching soon
7 chapters, each readable in under a minute. Open a full story for the process behind it.

01 · Sign-in and two-factor

Easy for you to get in. Useless to anyone guessing.

10failed tries on one email in 15 minutes lock it for 15 minutes, with the same answer whether or not the account exists
  1. The problem

    Kvimo holds bank access, invoices and personal data, so the sign-in is the door to all of it. And a refusal can leak too: say which field was wrong, and a stranger learns the address exists.

  2. What I did

    I kept the same accounts as kvimo.lt and added a six-digit code step in the same sheet when two-factor is on, with AutoFill for the password and the code. A wrong sign-in gets one sentence that never says which field was wrong, and the session token lives in the Keychain and nowhere else.

  3. What changed

    Friction only where it protects. Ten failed tries lock that email for 15 minutes, with the same refusal for addresses that have no account. An expired session says so and returns to sign-in, and being offline at launch doesn't sign anyone out.

Sign inThe same email and password as kvimo.lt.
Two-factorSix boxes in the same sheet, only when two-factor is on.
RefusedWrong email or password. Never which one.

What it says, word for word

MomentIn the appIn English
Wrong email or passwordNeteisingas el. paštas arba slaptažodis.Wrong email or password.
Ten failed triesPer daug nesėkmingų bandymų prisijungti šiuo el. paštu. Pabandyk vėl po 15 minučių arba atkurk slaptažodį.Too many failed tries with this email. Try again in 15 minutes, or reset your password.
Wrong codeKodas netinka. Patikrink autentifikatorių ir bandyk dar kartą.That code doesn't work. Check your authenticator and try again.
Session expiredPrisijungimas baigėsi. Prisijunk dar kartą.Your sign-in has ended. Sign in again.
An area you can't openŠi įmonės dalis tau neprieinama: Apskaita. Prieigą suteikia įmonės savininkas.This part of the company isn't open to you: Accounting. The company owner grants access.
Signed in, but not to everything. Closed areas don't even get a tab.
Locked, not broken: which area is closed, and who can open it. No number is drawn.
A failure looks different: a warning and a retry, not a lock.

The phone signs in to the same accounts as kvimo.lt. The web keeps its session in a cookie; the app gets a token and keeps it in the Keychain, never in settings, a log, a file or a screenshot. Signing out clears it and every cached read.

“Pamiršai slaptažodį?” (forgot your password?) opens kvimo.lt in Safari, so a reset happens in one place.

The lockout counts any email typed, with or without an account, and answers the same way, so it tells nobody which addresses exist. A correct password under the limit clears the count; during a lock even the right one is refused.

On the web, a change made with the session cookie must come from Kvimo's own address. A request from anywhere else is refused, even when the browser attaches the cookie.

An expired session clears the stored token and returns to the welcome screen with one sentence. Being offline at launch is not treated as signed out: the session is kept, and each screen says it couldn't load.

02 · Bank connection

Read only, time limited, and it tells you before it ends.

180days, the longest consent most Lithuanian banks allow. Kvimo reads each bank's own limit instead of assuming one.
  1. The problem

    Owners hand bank access to software and forget it. When consent quietly expires, transactions stop arriving and the books go stale.

  2. What I did

    Banks connect through licensed data aggregators, read only: no payments, no money moved. Before connecting, the app explains the three steps, including that the permission ends.

  3. What changed

    Days before a link ends, the bank screen says so, with one button to renew. Uploading a bank statement always works as a fallback.

Before connecting: what happens, in three steps.
You pick the bank. The bank asks permission to view transactions only, never to move money. The permission has a time limit, and the app reminds you before it ends.
After: every account, and a warning before access ends.
Every account linked through Kvimo, with when it last synced.
“SEB ryšys baigsis po 9 d.”: the SEB connection ends in 9 days. Renew in one tap.

Bank data arrives through licensed aggregators. The simple view and the iPhone app use one aggregator; the accountant's full view can use a PSD2 provider registered by the company itself. SumUp and Stripe connect through their own APIs.

Consent length is never a constant in the code. The adapter clamps it to the bank's published maximum, and the screen prints the consent's own end date: “Banko leidimas galioja iki …”, the bank permission is valid until a given day.

Credentials live in a secret store, and no event in the system has a field a token could go into. A test enforces that. Payment files for the bank are download only: nothing in Kvimo sends money.

03 · Audit trail

Nothing is ever edited. A correction is a reversal, and both stay.

  1. The problem

    In accounting software an edit can quietly rewrite history, and nobody can tell what the books said last month.

  2. What I did

    I made the journal append only. “Taisyti” (correct) posts a reversal and a corrected entry in one step, and a reason is required.

  3. What changed

    Every posting records who or what made it: the person, or the AI run, policy version and prompt hash. An accountant can audit anything, and any number drills down to its document.

The full version's ledger: a cancelled entry stays, struck through, beside its reversal and the corrected entry. Annotations: Full and simple, one switch; Show cancelled entries; Original, cancelled but kept; Its reversal, kept too; The corrected entry.
  • Corrections are reversals, never edits
  • A reason is required for every correction
  • A figure nobody could compute shows a dash, never zero

The rule is written into the architecture: corrections are reversals, never edits, so the log is a complete audit trail rather than a snapshot of the current state. “Taisyti” posts a reversal and a corrected entry in one call, and all three entries stay in the log.

The “Why?” button is the product. That line is from the design doc: any figure drills down to its journal lines, then to the source document and the AI's reasoning. Documents are matched to the bank payment that settled them, and each one shows a timeline: uploaded, read, linked to a payment.

04 · AI that asks

The model proposes, rules decide, a person approves.

85confidence a proposal needs to post on its own, 90 if it touches income. Everything else waits for a person.
  1. The problem

    An AI that guesses with your books is worse than none, and owners don't speak in debits and credits.

  2. What I did

    Claude picks one account from the chart and explains why in one sentence; the system builds the entry. Questions use no accounting words, and the last answer is always “I don't know, let the accountant look”.

  3. What changed

    Owners answer in a tap, on the web or on iPhone. Anything uncertain reaches a real accountant, with the document and bank record attached.

Annotations: A plain question, no accounting words; Why it is asking; Always a way out: let the accountant look.

The same pattern on both: the payment, its evidence one tap away, a suggested answer, and a hand-off to the accountant.

  • Payroll, depreciation, cash income and fixed assets always go to the accountant
  • An account outside the chart is refused
  • The AI can never claim the owner confirmed something

Every company runs on Anthropic's Claude. The policy in the code is short. A proposal posts by itself at confidence 85 or above, or 90 if it touches income. Some things are always queued for the accountant, whatever the confidence: payroll, depreciation, cash income, recurring entries, issued invoices and fixed assets.

Whether a payer is familiar, a duplicate or confirmed by the owner is recomputed from the books, never taken from the model's word. Each company has a monthly AI budget; past it, Kvimo runs on rules and questions only.

Under every AI answer, “Paklausti buhalterio” (ask the accountant) copies the question and the answer into the accountant chat. Nothing is sent until the person presses send.

What the AI may not do: write to the journal directly, claim the owner confirmed something, charge anyone, or issue credentials.

05 · Access and privacy

Privacy down to the lock screen.

  1. The problem

    Accounting holds salaries, personal spending and partners' details, and a phone gets looked at over a shoulder.

  2. What I did

    Three roles, owner, accountant and viewer, over nine areas of the books. “Slėpti sumas” (hide amounts) masks every amount on the device, widgets and Watch included. Personal data is erased field by field.

  3. What changed

    The last owner can never be removed, every grant is kept in an append-only log, and AI chat respects the same access as the person asking.

Privacy one tap from anywhere.
“Slėpti sumas” hides every amount as dots, on this device. “Pilna versija” opens the full version in the browser.
Accountant officeAn accounting office's team: roles, access per client, and who is responsible. Demo data.
  • Erasure decided per field: delete, anonymise, or keep with its legal term
  • Data requests answered within a month, as JSON and PDF
  • Accounting data in Germany, files in the EU

Kvimo has three roles and keeps it that way: an owner administers, an accountant writes, a viewer reads. On top of roles sit nine areas, from the ledger and bank to payroll, declarations and AI chat, so access can be narrowed without inventing new roles.

Under GDPR, erasure is decided per field as one of three acts: delete, anonymise (the record stays and the name is folded out when read), or keep, with its legal term and end date. Invoices must be kept for ten years, so they are kept, and the reason is written down.

“Slėpti sumas” is a per-device preference. After sign-out, no amount stays on the home screen or the wrist.

06 · Simple view and brand

Accounting for people who are not accountants.

  1. The problem

    Micro company owners mostly use a phone, and never want to see a debit, credit or account code.

  2. What I did

    One ledger, two doors. The simple view has five tabs and six jobs; the full view keeps the ledger, registers, declarations and the review queue for the accountant. Then I explored the look: eight marks, and neutral against Citrina against yellow.

  3. What changed

    Yellow won: one highlight colour, ink on warm paper, and a dark mode with no yellow at all. The mark is a till roll torn off at the bottom.

BeforeNeutral, like the full version.
ExploredCitrina, an alternative direction.
ShippedYellow: one highlight, ink on warm paper.
ChosenKvitas: the input, a receipt, rather than the output. It survives 24 px.
ExploredEight directions, one element each. Four are shown here.

When the focus moved to accounting sold as a service to ordinary small businesses, the front door changed. The simple view now covers six jobs: issue an invoice, ask Kvimo's AI, ask a real accountant, connect a bank, see bank operations, and match documents to them.

Owners on the managed service now see only the simple view. The full version stays for accountants.

The brand rules are strict on purpose: yellow #FFE58F is the only highlight, titles and big figures are set in Bricolage Grotesque, text in Figtree, and AA contrast is checked by tests.

07 · One system

One set of values, a web app and a native iPhone app.

  1. The problem

    A web app and a native app drift apart: a colour or a word changes in one and not the other.

  2. What I did

    The iPhone app reads the brand from one values file, generated into Swift tokens, with the same fonts bundled. Light and dark both ship.

  3. What changed

    A native SwiftUI app with document scanning, invoices, bank connect, chat with the AI and the accountant, widgets and an Apple Watch app.

BoardA design board from the canvas.
First buildThe board, built in SwiftUI.
ShippedThe same screen in the brand.

Web and iPhone share values, not a single code base. The marketing site's values are the source; on iOS a JSON file feeds a script that generates the asset catalogue and a Swift tokens file, so a colour change is one edit and a regenerate.

The app sells the service with Stripe, outside in-app purchase, under the App Store rule for that kind of service. Tests cover it on both sides: 3,240 web tests pass in one run, and the iOS app has 634 test functions.

08 · Learnings

What I'd tell the next designer

  1. 01Decide privacy field by field.Some data must be kept by law. Delete, anonymise or keep each field, and write down why.
  2. 02Let the AI say I don't know.The best answer to an unclear payment is often a person.
  3. 03Show when access ends.A permission with a visible end date is one people trust.
  4. 04Simple is a door, not less.Owners and accountants share one ledger through two different views.
Signal strength0%