Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ next-env.d.ts
apps/mcp/dist/
apps/mcp/node_modules/
supabase/.temp/

# Generated build artifacts
/GeneratedAssets/
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Built with Next.js + TypeScript. Formerly QuietLedger.

**Current Release:** v0.11.1 (2026-07-03)
**Live domain:** https://ledger.kovina.org
**Deploy status:** Local (v0.11.1 committed, deploy pending)
**Deploy status:** ✅ Live — deployed 2026-07-04 (deploy ID `dpl_FiZA8FZnwU95FR576GjpM8HVTCzz`)

Releases:
v0.11.1 — Open Product Family Branding (header lockup redesign, icon pipeline, OpenPalette alignment, full icon suite)
Expand Down
10 changes: 10 additions & 0 deletions public/kovina-wordmark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
133 changes: 118 additions & 15 deletions src/app/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

export const metadata: Metadata = {
title: "About",
description: "About OpenLedger — a private, editorial personal finance ledger.",
description:
"About OpenLedger — a straightforward tool for keeping track of your money, without the noise.",
};

export default function AboutPage() {
Expand Down Expand Up @@ -43,9 +44,9 @@
marginBottom: 16,
}}
>
OpenLedger is a personal finance ledger designed for clarity, privacy, and calm.
It is not a budgeting app. It is not accounting software. It is a place to record
where your money came from, where it went, and what that means to you.
OpenLedger is a straightforward tool for keeping track of your money. It helps you
record what you earn and spend, review your transactions, and understand your
financial habits — without the noise, notifications, or upsells.
</p>
<p
style={{
Expand All @@ -55,9 +56,101 @@
marginBottom: 16,
}}
>
In a world of financial dashboards, push notifications, and gamified savings
challenges, OpenLedger steps back. It gives you a clean page, a running balance,
and the tools to make sense of your financial life on your own terms.
Think of it as a simple notebook for your finances. You write down each transaction,
organise it by account and category, and come back later to see the full picture.
There are no graphs fighting for your attention, no "you could save more"

Check failure on line 61 in src/app/about/page.tsx

View workflow job for this annotation

GitHub Actions / Lint, typecheck, and build

`"` can be escaped with `&quot;`, `&ldquo;`, `&#34;`, `&rdquo;`

Check failure on line 61 in src/app/about/page.tsx

View workflow job for this annotation

GitHub Actions / Lint, typecheck, and build

`"` can be escaped with `&quot;`, `&ldquo;`, `&#34;`, `&rdquo;`
nudges, and no charts trying to sell you something.
</p>
<p
style={{
fontSize: 15,
lineHeight: 1.7,
color: "var(--text-secondary)",
}}
>
Just a clear, calm record of where your money went.
</p>
</section>

<section style={{ marginBottom: 40 }}>
<h2
style={{
fontSize: 20,
fontWeight: 700,
color: "var(--text-primary)",
marginBottom: 12,
}}
>
What you can do
</h2>
<p
style={{
fontSize: 15,
lineHeight: 1.7,
color: "var(--text-secondary)",
marginBottom: 8,
}}
>
<strong style={{ color: "var(--text-primary)", fontWeight: 600 }}>
Record transactions
</strong>{" "}
— Add income and expenses manually or import them from a CSV file. Each entry
goes into an account and a category so you can find it later.
</p>
<p
style={{
fontSize: 15,
lineHeight: 1.7,
color: "var(--text-secondary)",
marginBottom: 8,
}}
>
<strong style={{ color: "var(--text-primary)", fontWeight: 600 }}>
Organise by account
</strong>{" "}
— Set up accounts for your checking, credit card, savings, loans, crypto, or
anything else. See balances at a glance and keep everything separate.
</p>
<p
style={{
fontSize: 15,
lineHeight: 1.7,
color: "var(--text-secondary)",
marginBottom: 8,
}}
>
<strong style={{ color: "var(--text-primary)", fontWeight: 600 }}>
Review your spending
</strong>{" "}
— See a monthly report of income vs. expenses, explore category breakdowns, and
compare months side by side. The numbers are always yours to interpret.
</p>
<p
style={{
fontSize: 15,
lineHeight: 1.7,
color: "var(--text-secondary)",
marginBottom: 8,
}}
>
<strong style={{ color: "var(--text-primary)", fontWeight: 600 }}>
Set budgets and goals
</strong>{" "}
— Create spending plans for categories you care about and track progress.
Set savings milestones and contribute to them over time.
</p>
<p
style={{
fontSize: 15,
lineHeight: 1.7,
color: "var(--text-secondary)",
}}
>
<strong style={{ color: "var(--text-primary)", fontWeight: 600 }}>
Search and find
</strong>{" "}
— Search across all your transactions, filter by date range or account, and
save frequent searches. Your history is always a few keystrokes away.
</p>
</section>

Expand All @@ -70,7 +163,7 @@
marginBottom: 12,
}}
>
Local-first, privacy-first
Your data stays yours
</h2>
<p
style={{
Expand All @@ -79,10 +172,11 @@
color: "var(--text-secondary)",
}}
>
Your data lives on your device. In guest mode, nothing ever leaves your browser.
If you sign in with Google, you can optionally back up your ledger to the cloud —
but every upload and deletion is manually triggered. No automatic sync, no
background data collection, no analytics.
You can use OpenLedger without creating an account. In guest mode, everything you
enter stays on your own device — it never touches the internet. If you later decide
to sign in with Google, you can optionally save a backup to the cloud. Every backup
and every deletion is something you trigger yourself. Nothing happens automatically.
No data is collected. No analytics run in the background.
</p>
</section>

Expand All @@ -104,8 +198,17 @@
color: "var(--text-secondary)",
}}
>
OpenLedger is free software released under the AGPL-3.0 license. The source
code is available on{" "}
OpenLedger is free software — you can use it, read the code, modify it, and share
it. It is released under the{" "}
<a
href="https://www.gnu.org/licenses/agpl-3.0.html"
target="_blank"
rel="noopener noreferrer"
style={{ color: "var(--accent)" }}
>
AGPL-3.0 license
</a>
. The source code is published on{" "}
<a
href="https://github.com/sparshsam/openledger"
target="_blank"
Expand All @@ -114,7 +217,7 @@
>
GitHub
</a>
. Built with Next.js, TypeScript, and Supabase.
.
</p>
</section>

Expand Down
80 changes: 72 additions & 8 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,20 +124,25 @@ function PrincipleBlock({
title: string;
text: string;
}) {
const icon = PRINCIPLE_ICONS[number as keyof typeof PRINCIPLE_ICONS];

return (
<div style={{ display: "flex", gap: 24, alignItems: "flex-start" }}>
<span
<svg
width={44}
height={44}
viewBox="0 0 44 44"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style={{
fontSize: "clamp(40px, 5vw, 64px)",
fontWeight: 900,
lineHeight: 1,
color: "var(--accent)",
flexShrink: 0,
minWidth: 64,
color: "var(--accent)",
marginTop: 2,
}}
aria-hidden="true"
>
{number}
</span>
{icon}
</svg>
<div>
<h3
style={{
Expand All @@ -164,3 +169,62 @@ function PrincipleBlock({
</div>
);
}

// ── Editorial SVG Icons ─────────────────────────────────────────────────
// Each icon is a 44×44 viewBox with 1.5px stroke, round caps/joins.
// Uses currentColor so it adapts to light/dark theme automatically.

const PRINCIPLE_ICONS = {
"01": (
<>
{/* Ledger / Book — open journal with spine and ruled lines */}
<rect x={5} y={6} width={24} height={32} rx={2} stroke="currentColor" strokeWidth={1.5} />
<line x1={17} y1={6} x2={17} y2={38} stroke="currentColor" strokeWidth={1.5} />
<line x1={9} y1={13} x2={14} y2={13} stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" />
<line x1={9} y1={18} x2={14} y2={18} stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" />
<line x1={20} y1={13} x2={25} y2={13} stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" />
<line x1={20} y1={18} x2={25} y2={18} stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" />
{/* Quill / pen accent */}
<path d="M33 8 L37 5 L39 7 L36 11 Z" stroke="currentColor" strokeWidth={1.5} strokeLinejoin="round" />
<path d="M37 5 L40 8 L39 7" stroke="currentColor" strokeWidth={1.5} strokeLinejoin="round" />
</>
),
"02": (
<>
{/* Shield — privacy guard with subtle lock detail */}
<path
d="M22 4 L38 12 V24 C38 32 30 38 22 40 C14 38 6 32 6 24 V12 Z"
stroke="currentColor"
strokeWidth={1.5}
strokeLinejoin="round"
/>
{/* Lock body */}
<rect x={17} y={21} width={10} height={8} rx={1.5} stroke="currentColor" strokeWidth={1.5} />
{/* Shackle */}
<path
d="M17 21 V16 C17 13.2 19.2 11 22 11 C24.8 11 27 13.2 27 16 V21"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
/>
{/* Keyhole */}
<circle cx={22} cy={25} r={1.5} fill="currentColor" />
<line x1={22} y1={26.5} x2={22} y2={28} stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" />
</>
),
"03": (
<>
{/* Device — local-first, monitor with subtle cloud nod */}
<rect x={7} y={8} width={26} height={20} rx={3} stroke="currentColor" strokeWidth={1.5} />
{/* Stand */}
<line x1={20} y1={28} x2={20} y2={34} stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" />
<line x1={14} y1={34} x2={26} y2={34} stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" />
{/* Screen content — minimal bars */}
<line x1={11} y1={15} x2={17} y2={15} stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" />
<line x1={11} y1={20} x2={15} y2={20} stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" />
{/* Offline dot indicator */}
<circle cx={26} cy={15} r={4} stroke="currentColor" strokeWidth={1.5} />
<line x1={24.2} y1={15} x2={27.8} y2={15} stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" />
</>
),
};
Loading
Loading