{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "template-ledger",
  "title": "Ledger: Mac app",
  "author": "Ballmac <https://ui.ballmac.com>",
  "description": "A five-page site for a Mac app: an interactive desktop hero, a menu-bar tour, a native-features bento, a device lineup, license-or-subscription pricing, a download page, release notes and support.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.ballmac.com/r/blur-fade.json",
    "https://ui.ballmac.com/r/changelog-1.json",
    "https://ui.ballmac.com/r/devices-1.json",
    "https://ui.ballmac.com/r/download-1.json",
    "https://ui.ballmac.com/r/faq-2.json",
    "https://ui.ballmac.com/r/features-7.json",
    "https://ui.ballmac.com/r/kbd.json",
    "https://ui.ballmac.com/r/mac-icons.json",
    "https://ui.ballmac.com/r/pricing-4.json",
    "https://ui.ballmac.com/r/showcase-1.json"
  ],
  "files": [
    {
      "path": "registry/ballmac/components/templates/ledger/ledger-fonts.ts",
      "content": "// Ballmac UI: Ledger template fonts. https://ui.ballmac.com/templates/template-ledger\nimport { Inter, Newsreader } from \"next/font/google\"\n\n/** The italic serif used for one emphasised word per heading. Body text uses the system font, like a Mac app. */\nexport const ledgerSerif = Newsreader({ variable: \"--ledger-serif\", subsets: [\"latin\"], style: [\"normal\", \"italic\"], display: \"swap\", preload: false })\n\n/** Used where San Francisco is not installed (Windows, Linux, Android), so the page looks the same everywhere. */\nexport const ledgerSans = Inter({ variable: \"--ledger-sans\", subsets: [\"latin\"], display: \"swap\", preload: false })\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/ledger/ledger-fonts.ts"
    },
    {
      "path": "registry/ballmac/components/templates/ledger/ledger-theme.tsx",
      "content": "// Ballmac UI: Ledger template shell. https://ui.ballmac.com/templates/template-ledger\n\"use client\"\n\nimport * as React from \"react\"\nimport { Menu, X } from \"lucide-react\"\n\nimport { AppIcon } from \"@/components/ballmac/mac-icons\"\nimport { ledgerSans, ledgerSerif } from \"@/components/ballmac/templates/ledger/ledger-fonts\"\nimport { cn } from \"@/lib/utils\"\n\ntype LedgerPage = \"home\" | \"download\" | \"pricing\" | \"changelog\" | \"support\"\ntype LedgerHrefs = Record<LedgerPage, string>\n\nconst defaultHrefs: LedgerHrefs = { home: \"/ledger\", download: \"/ledger/download\", pricing: \"/ledger/pricing\", changelog: \"/ledger/changelog\", support: \"/ledger/support\" }\n\n/** Ledger's palette: Apple-calm. Cool white, soft grey surfaces, one blue. Dark mode follows the system. */\nconst ledgerCss = `\n.ledger-theme{--background:oklch(0.99 0.002 250);--foreground:oklch(0.2 0.01 255);--card:oklch(1 0 0);--card-foreground:oklch(0.2 0.01 255);--popover:oklch(1 0 0);--popover-foreground:oklch(0.2 0.01 255);--primary:oklch(0.2 0.01 255);--primary-foreground:oklch(0.99 0.002 250);--secondary:oklch(0.965 0.004 250);--secondary-foreground:oklch(0.2 0.01 255);--muted:oklch(0.965 0.004 250);--muted-foreground:oklch(0.5 0.012 255);--accent:oklch(0.955 0.006 250);--accent-foreground:oklch(0.2 0.01 255);--border:oklch(0.2 0.01 255 / 10%);--input:oklch(0.2 0.01 255 / 14%);--ring:oklch(0.6 0.19 255);--surface:oklch(0.975 0.003 250);--chart-1:oklch(0.52 0.2 255);--ledger-on-accent:oklch(1 0 0);--chart-2:oklch(0.48 0.14 155);--chart-3:oklch(0.78 0.16 75);--chart-4:oklch(0.62 0.2 305);--chart-5:oklch(0.68 0.19 25);--radius:1rem}\n.dark .ledger-theme{--background:oklch(0.16 0.006 255);--foreground:oklch(0.96 0.004 250);--card:oklch(0.2 0.008 255);--card-foreground:oklch(0.96 0.004 250);--popover:oklch(0.22 0.008 255);--popover-foreground:oklch(0.96 0.004 250);--primary:oklch(0.96 0.004 250);--primary-foreground:oklch(0.2 0.01 255);--secondary:oklch(0.25 0.009 255);--secondary-foreground:oklch(0.96 0.004 250);--muted:oklch(0.24 0.009 255);--muted-foreground:oklch(0.72 0.012 250);--accent:oklch(0.27 0.01 255);--accent-foreground:oklch(0.96 0.004 250);--border:oklch(1 0 0 / 11%);--input:oklch(1 0 0 / 15%);--ring:oklch(0.7 0.17 255);--surface:oklch(0.18 0.007 255);--chart-1:oklch(0.72 0.15 255);--ledger-on-accent:oklch(0.16 0.01 255);--chart-2:oklch(0.76 0.16 160);--chart-3:oklch(0.83 0.15 80);--chart-4:oklch(0.72 0.17 305);--chart-5:oklch(0.76 0.16 25)}\n`\n\nconst links: { key: LedgerPage; label: string }[] = [\n  { key: \"home\", label: \"Overview\" },\n  { key: \"pricing\", label: \"Pricing\" },\n  { key: \"changelog\", label: \"What’s new\" },\n  { key: \"support\", label: \"Support\" },\n]\n\ntype LedgerShellProps = React.ComponentProps<\"div\"> & {\n  /** The page being shown, so its nav link is marked current. */\n  page: LedgerPage\n  /** Override where pages live (used by previews). */\n  hrefs?: Partial<LedgerHrefs>\n}\n\n/** Ledger's frame: a frosted, centred header like a Mac app’s site, and a quiet footer. Wrap every Ledger page in it. */\nfunction LedgerShell({ page, hrefs: overrides, className, style, children, ...props }: LedgerShellProps) {\n  const hrefs = { ...defaultHrefs, ...overrides }\n  const [open, setOpen] = React.useState(false)\n  return (\n    <div\n      data-slot=\"ledger\"\n      className={cn(\"ledger-theme bg-background text-foreground relative min-h-dvh overflow-x-clip antialiased\", ledgerSerif.variable, ledgerSans.variable, className)}\n      style={{ fontFamily: \"-apple-system, BlinkMacSystemFont, 'SF Pro Text', var(--ledger-sans), ui-sans-serif, system-ui, sans-serif\", ...style }}\n      {...props}\n    >\n      <style>{ledgerCss}</style>\n      <header className=\"bg-background/72 sticky top-0 z-40 border-b backdrop-blur-xl backdrop-saturate-150\">\n        <div className=\"mx-auto flex h-12 max-w-6xl items-center justify-between px-4 sm:px-6\">\n          <a href={hrefs.home} className=\"focus-visible:ring-ring/50 flex items-center gap-2 rounded-md text-sm font-semibold outline-none focus-visible:ring-[3px]\">\n            <AppIcon size={22} tone=\"blue\"><span className=\"text-[11px] font-bold\">L</span></AppIcon> Ledger\n          </a>\n          <nav aria-label=\"Main\" className=\"hidden items-center gap-7 md:flex\">\n            {links.map((l) => (\n              <a key={l.key} href={hrefs[l.key]} aria-current={page === l.key ? \"page\" : undefined} className=\"text-muted-foreground hover:text-foreground aria-[current=page]:text-foreground focus-visible:ring-ring/50 rounded text-[13px] outline-none transition-colors focus-visible:ring-[3px]\">\n                {l.label}\n              </a>\n            ))}\n          </nav>\n          <div className=\"flex items-center gap-2\">\n            <a href={hrefs.download} className=\"bg-chart-1 focus-visible:ring-ring/50 inline-flex h-7 items-center rounded-full px-3.5 text-[13px] font-medium text-[var(--ledger-on-accent)] outline-none transition-opacity hover:opacity-90 focus-visible:ring-[3px]\">Download</a>\n            <button type=\"button\" aria-label={open ? \"Close menu\" : \"Open menu\"} aria-expanded={open} aria-controls=\"ledger-mobile-menu\" onClick={() => setOpen((v) => !v)} className=\"text-muted-foreground focus-visible:ring-ring/50 inline-flex size-8 items-center justify-center rounded-md outline-none focus-visible:ring-[3px] md:hidden\">\n              {open ? <X className=\"size-5\" aria-hidden=\"true\" /> : <Menu className=\"size-5\" aria-hidden=\"true\" />}\n            </button>\n          </div>\n        </div>\n        {open && (\n          <nav id=\"ledger-mobile-menu\" aria-label=\"Mobile\" className=\"border-t px-4 py-2 md:hidden\">\n            {links.map((l) => <a key={l.key} href={hrefs[l.key]} className=\"hover:bg-accent block rounded-lg px-3 py-2.5 text-sm\">{l.label}</a>)}\n          </nav>\n        )}\n      </header>\n      {children}\n      <footer className=\"bg-surface border-t\">\n        <div className=\"mx-auto max-w-6xl px-4 py-12 sm:px-6\">\n          <div className=\"grid gap-8 sm:grid-cols-2 lg:grid-cols-4\">\n            {[\n              { title: \"Ledger\", items: [[\"Overview\", \"home\"], [\"What’s new\", \"changelog\"], [\"Pricing\", \"pricing\"], [\"Download\", \"download\"]] },\n              { title: \"Support\", items: [[\"Help center\", \"support\"], [\"Keyboard shortcuts\", \"support\"], [\"Contact us\", \"support\"], [\"System status\", \"support\"]] },\n              { title: \"Company\", items: [[\"About\", \"home\"], [\"Press kit\", \"home\"], [\"Privacy\", \"home\"], [\"Terms\", \"home\"]] },\n              { title: \"Elsewhere\", items: [[\"Mastodon\", \"home\"], [\"GitHub\", \"home\"], [\"RSS\", \"changelog\"], [\"Newsletter\", \"home\"]] },\n            ].map((c) => (\n              <div key={c.title}>\n                <h2 className=\"text-xs font-semibold\">{c.title}</h2>\n                <ul className=\"mt-3 space-y-2\">\n                  {c.items.map(([label, key]) => <li key={label}><a href={hrefs[key as LedgerPage]} className=\"text-muted-foreground hover:text-foreground text-xs transition-colors\">{label}</a></li>)}\n                </ul>\n              </div>\n            ))}\n          </div>\n          <p className=\"text-muted-foreground mt-10 border-t pt-5 text-xs text-pretty\">Ledger requires macOS 13 Ventura or later. Apple, Mac, macOS and iCloud are trademarks of Apple Inc. © 2026 Ledger Software, made in Portland.</p>\n        </div>\n      </footer>\n    </div>\n  )\n}\n\n/** A heading with one italic serif word, the template's signature. Wrap the word to emphasise in `<em>`. */\nfunction LedgerHeading({ className, children, as: Tag = \"h2\", ...props }: React.ComponentProps<\"h2\"> & { as?: \"h1\" | \"h2\" | \"h3\" }) {\n  return (\n    <Tag className={cn(\"font-semibold tracking-[-0.035em] text-balance [&_em]:font-normal [&_em]:tracking-[-0.02em] [&_em]:[font-family:var(--ledger-serif),ui-serif,Georgia,serif]\", className)} {...props}>\n      {children}\n    </Tag>\n  )\n}\n\nexport { LedgerHeading, LedgerShell, defaultHrefs as ledgerDefaultHrefs, type LedgerHrefs, type LedgerPage, type LedgerShellProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/ledger/ledger-theme.tsx"
    },
    {
      "path": "registry/ballmac/components/templates/ledger/ledger-home.tsx",
      "content": "// Ballmac UI: Ledger home page. https://ui.ballmac.com/templates/template-ledger\n\"use client\"\n\nimport * as React from \"react\"\nimport { ArrowDownToLine, Cloud, Laptop, Lock, ShieldCheck, Star, Zap } from \"lucide-react\"\n\nimport { Devices1 } from \"@/components/ballmac/blocks/devices-1/devices-1\"\nimport { Features7 } from \"@/components/ballmac/blocks/features-7/features-7\"\nimport { Pricing4 } from \"@/components/ballmac/blocks/pricing-4/pricing-4\"\nimport { Showcase1 } from \"@/components/ballmac/blocks/showcase-1/showcase-1\"\nimport { BlurFade } from \"@/components/ballmac/blur-fade\"\nimport { Kbd } from \"@/components/ballmac/kbd\"\nimport { AppIcon } from \"@/components/ballmac/mac-icons\"\nimport { LedgerHeading, LedgerShell, type LedgerHrefs } from \"@/components/ballmac/templates/ledger/ledger-theme\"\nimport { cn } from \"@/lib/utils\"\n\nconst press = [\n  { outlet: \"Mac App Store\", quote: \"Editor’s Choice\" },\n  { outlet: \"MacStories\", quote: \"The calmest way to run a business.\" },\n  { outlet: \"Six Colors\", quote: \"A Mac app that feels like one.\" },\n  { outlet: \"Daring Fireball\", quote: \"Fast, plain and correct.\" },\n]\n\nconst reviews = [\n  { quote: \"I closed the month in an afternoon. The keyboard shortcuts alone paid for the license.\", name: \"Hannah Okafor\", role: \"Freelance designer\", tone: \"bg-chart-1/20\" },\n  { quote: \"It’s the first accounting app that didn’t make me feel like I needed an accountant to use it.\", name: \"Marcus Lindqvist\", role: \"Founder, Studio Fjord\", tone: \"bg-chart-2/20\" },\n  { quote: \"Works offline on the train, syncs when I’m home. Exactly how software should behave.\", name: \"Priya Raman\", role: \"Independent consultant\", tone: \"bg-chart-4/20\" },\n]\n\nconst card = \"bg-card rounded-3xl border p-7 shadow-[0_1px_2px_0_rgb(0_0_0/0.04)]\"\n\ntype LedgerHomeProps = React.ComponentProps<\"div\"> & { hrefs?: Partial<LedgerHrefs> }\n\n/** The Ledger home page: an interactive Mac desktop, a menu-bar tour, a feature bento, devices, reviews and pricing. */\nfunction LedgerHome({ hrefs, ...props }: LedgerHomeProps) {\n  return (\n    <LedgerShell page=\"home\" hrefs={hrefs} {...props}>\n      <main>\n        <section className=\"px-4 pt-16 text-center sm:px-6 sm:pt-24\">\n          <BlurFade>\n            <p className=\"text-chart-1 text-sm font-semibold\">Ledger 2.4 · Now with approvals</p>\n            <LedgerHeading as=\"h1\" className=\"mx-auto mt-4 max-w-3xl text-5xl leading-[1.02] sm:text-7xl\">\n              Your books, kept <em>beautifully</em>.\n            </LedgerHeading>\n            <p className=\"text-muted-foreground mx-auto mt-6 max-w-xl text-lg text-pretty sm:text-xl\">\n              Invoices, expenses and reports in a native Mac app that’s fast, private and a pleasure to open on a Monday.\n            </p>\n            <div className=\"mt-9 flex flex-col items-center justify-center gap-3 sm:flex-row sm:gap-5\">\n              <a href={hrefs?.download ?? \"/ledger/download\"} className=\"bg-chart-1 focus-visible:ring-ring/50 inline-flex h-12 items-center gap-2 rounded-full px-6 font-medium text-[var(--ledger-on-accent)] outline-none transition-opacity hover:opacity-90 focus-visible:ring-[3px]\">\n                <ArrowDownToLine className=\"size-4\" aria-hidden=\"true\" /> Download for Mac\n              </a>\n              <a href={hrefs?.pricing ?? \"/ledger/pricing\"} className=\"text-chart-1 focus-visible:ring-ring/50 rounded-md font-medium underline-offset-4 outline-none hover:underline focus-visible:ring-[3px]\">\n                See pricing ›\n              </a>\n            </div>\n            <p className=\"text-muted-foreground mt-5 text-xs\">Free for 14 days · macOS 13 or later · Apple silicon and Intel</p>\n          </BlurFade>\n          <BlurFade className=\"mx-auto mt-14 max-w-6xl text-start\" delay={0.12}>\n            <Showcase1 app=\"Ledger\" height=\"38rem\" className=\"shadow-[0_40px_100px_-30px_rgb(0_0_0/0.45)]\" />\n          </BlurFade>\n        </section>\n\n        <section aria-label=\"Press\" className=\"mx-auto max-w-6xl px-4 py-16 sm:px-6\">\n          <ul className=\"grid gap-px overflow-hidden rounded-2xl border bg-border sm:grid-cols-2 lg:grid-cols-4\">\n            {press.map((p) => (\n              <li key={p.outlet} className=\"bg-card p-6 text-center\">\n                <p className=\"text-muted-foreground text-xs font-semibold tracking-wide uppercase\">{p.outlet}</p>\n                <p className=\"mt-2 text-sm font-medium text-pretty [font-family:var(--ledger-serif),ui-serif,Georgia,serif] text-lg italic\">“{p.quote}”</p>\n              </li>\n            ))}\n          </ul>\n        </section>\n\n        <Features7 title=\"Always one keystroke away.\" />\n\n        <section className=\"mx-auto max-w-6xl px-4 py-20 sm:px-6\">\n          <div className=\"mx-auto max-w-2xl text-center\">\n            <LedgerHeading className=\"text-4xl sm:text-5xl\">A real Mac app, <em>all the way down</em>.</LedgerHeading>\n            <p className=\"text-muted-foreground mt-4 text-lg text-pretty\">Native, not wrapped. It uses the parts of macOS you already know.</p>\n          </div>\n          <div className=\"mt-12 grid gap-4 md:grid-cols-6\">\n            <div className={cn(card, \"md:col-span-3\")}>\n              <Zap className=\"text-chart-3 size-6\" aria-hidden=\"true\" />\n              <h3 className=\"mt-5 text-xl font-semibold tracking-tight\">Keyboard first</h3>\n              <p className=\"text-muted-foreground mt-2 text-pretty\">Everything has a shortcut. Learn four and you rarely touch the mouse.</p>\n              <ul className=\"mt-6 space-y-2.5 text-sm\">\n                {[[\"New invoice\", [\"⌘\", \"N\"]], [\"Jump to customer\", [\"⌘\", \"K\"]], [\"Mark as paid\", [\"⌃\", \"⌘\", \"P\"]], [\"Export report\", [\"⇧\", \"⌘\", \"E\"]]].map(([label, keys]) => (\n                  <li key={label as string} className=\"flex items-center justify-between\">\n                    {label as string}\n                    <span className=\"flex gap-1\">{(keys as string[]).map((k) => <Kbd key={k}>{k}</Kbd>)}</span>\n                  </li>\n                ))}\n              </ul>\n            </div>\n            <div className={cn(card, \"md:col-span-3\")}>\n              <Cloud className=\"text-chart-1 size-6\" aria-hidden=\"true\" />\n              <h3 className=\"mt-5 text-xl font-semibold tracking-tight\">Local first, iCloud second</h3>\n              <p className=\"text-muted-foreground mt-2 text-pretty\">Your data lives on your Mac and works with no connection. Sync across devices with your own iCloud.</p>\n              <div className=\"bg-secondary/60 mt-6 flex items-center justify-between gap-3 rounded-2xl px-5 py-4 text-sm\">\n                <span className=\"flex items-center gap-2\"><Laptop className=\"size-4\" aria-hidden=\"true\" /> MacBook Pro</span>\n                <span className=\"text-muted-foreground flex-1 border-t border-dashed\" aria-hidden=\"true\" />\n                <span className=\"text-chart-2 flex items-center gap-1.5 text-xs font-medium\"><span className=\"bg-chart-2 size-1.5 rounded-full\" aria-hidden=\"true\" /> Synced just now</span>\n                <span className=\"text-muted-foreground flex-1 border-t border-dashed\" aria-hidden=\"true\" />\n                <span className=\"flex items-center gap-2\"><Cloud className=\"size-4\" aria-hidden=\"true\" /> iCloud</span>\n              </div>\n            </div>\n            <div className={cn(card, \"md:col-span-2\")}>\n              <Lock className=\"text-chart-4 size-6\" aria-hidden=\"true\" />\n              <h3 className=\"mt-5 text-xl font-semibold tracking-tight\">Private by design</h3>\n              <p className=\"text-muted-foreground mt-2 text-pretty\">No account, no analytics, no server that holds your books.</p>\n              <p className=\"mt-6 text-5xl font-semibold tracking-[-0.04em]\">0</p>\n              <p className=\"text-muted-foreground text-sm\">trackers in the app</p>\n            </div>\n            <div className={cn(card, \"md:col-span-4\")}>\n              <ShieldCheck className=\"text-chart-2 size-6\" aria-hidden=\"true\" />\n              <h3 className=\"mt-5 text-xl font-semibold tracking-tight\">Shortcuts and AppleScript</h3>\n              <p className=\"text-muted-foreground mt-2 max-w-md text-pretty\">Create an invoice from a calendar event, or mark paid from a Stripe webhook. Ledger speaks the Mac’s automation language.</p>\n              <pre className=\"bg-secondary/60 mt-6 overflow-x-auto rounded-2xl p-4 font-mono text-[13px] leading-6\" tabIndex={0}>{`tell application \"Ledger\"\n  set inv to make new invoice\n  set customer of inv to \"Northwind\"\n  mark inv as paid\nend tell`}</pre>\n            </div>\n          </div>\n        </section>\n\n        <Devices1 title=\"Mac first. Everywhere else, too.\" />\n\n        <section aria-labelledby=\"ledger-reviews\" className=\"mx-auto max-w-6xl px-4 py-20 sm:px-6\">\n          <h2 id=\"ledger-reviews\" className=\"sr-only\">Reviews</h2>\n          <ul className=\"grid gap-4 md:grid-cols-3\">\n            {reviews.map((r) => (\n              <li key={r.name} className={cn(card, \"flex flex-col\")}>\n                <div className=\"text-chart-3 flex gap-0.5\" role=\"img\" aria-label=\"5 out of 5 stars\">{Array.from({ length: 5 }, (_, i) => <Star key={i} className=\"size-4 fill-current\" aria-hidden=\"true\" />)}</div>\n                <blockquote className=\"mt-4 flex-1 text-[17px] leading-relaxed text-pretty\">“{r.quote}”</blockquote>\n                <footer className=\"mt-6 flex items-center gap-3 text-sm\">\n                  <span className={cn(\"flex size-9 items-center justify-center rounded-full text-xs font-semibold\", r.tone)} aria-hidden=\"true\">{r.name.split(\" \").map((w) => w[0]).join(\"\")}</span>\n                  <span><span className=\"block font-medium\">{r.name}</span><span className=\"text-muted-foreground\">{r.role}</span></span>\n                </footer>\n              </li>\n            ))}\n          </ul>\n        </section>\n\n        <Pricing4 title=\"Buy it once, or stay current.\" />\n\n        <section className=\"px-4 pb-24 text-center sm:px-6\">\n          <AppIcon size={88} tone=\"blue\" className=\"mx-auto\"><span className=\"text-4xl font-bold\">L</span></AppIcon>\n          <LedgerHeading className=\"mx-auto mt-8 max-w-xl text-4xl sm:text-5xl\">Get your Monday <em>back</em>.</LedgerHeading>\n          <p className=\"text-muted-foreground mx-auto mt-4 max-w-md text-lg text-pretty\">Download Ledger and try everything free for 14 days.</p>\n          <a href={hrefs?.download ?? \"/ledger/download\"} className=\"bg-chart-1 focus-visible:ring-ring/50 mt-8 inline-flex h-12 items-center gap-2 rounded-full px-6 font-medium text-[var(--ledger-on-accent)] outline-none transition-opacity hover:opacity-90 focus-visible:ring-[3px]\">\n            <ArrowDownToLine className=\"size-4\" aria-hidden=\"true\" /> Download for Mac\n          </a>\n        </section>\n      </main>\n    </LedgerShell>\n  )\n}\n\nexport { LedgerHome, type LedgerHomeProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/ledger/ledger-home.tsx"
    },
    {
      "path": "registry/ballmac/components/templates/ledger/ledger-download.tsx",
      "content": "// Ballmac UI: Ledger download page. https://ui.ballmac.com/templates/template-ledger\nimport * as React from \"react\"\nimport { Apple, Cpu, HardDrive, ShieldCheck } from \"lucide-react\"\n\nimport { Download1 } from \"@/components/ballmac/blocks/download-1/download-1\"\nimport { LedgerHeading, LedgerShell, type LedgerHrefs } from \"@/components/ballmac/templates/ledger/ledger-theme\"\n\nconst specs = [\n  { icon: Apple, title: \"macOS 13 Ventura or later\", text: \"Runs on every Mac that supports it, including the 2018 MacBook Air.\" },\n  { icon: Cpu, title: \"Apple silicon and Intel\", text: \"A universal app, tuned for M-series chips and still quick on Intel.\" },\n  { icon: HardDrive, title: \"58 MB to download\", text: \"Under 150 MB installed. Your books are a single file you can back up.\" },\n  { icon: ShieldCheck, title: \"Signed and notarized\", text: \"Checked by Apple and by us. SHA-256 checksums are published with every release.\" },\n]\n\ntype LedgerDownloadProps = React.ComponentProps<\"div\"> & { hrefs?: Partial<LedgerHrefs> }\n\n/** Ledger download: the download block, the system requirements and a note on updates. */\nfunction LedgerDownload({ hrefs, ...props }: LedgerDownloadProps) {\n  return (\n    <LedgerShell page=\"home\" hrefs={hrefs} {...props}>\n      <main>\n        <div className=\"mx-auto max-w-6xl px-4 pt-16 text-center sm:px-6 sm:pt-20\">\n          <LedgerHeading as=\"h1\" className=\"text-4xl sm:text-6xl\">Download <em>Ledger</em>.</LedgerHeading>\n          <p className=\"text-muted-foreground mx-auto mt-4 max-w-lg text-lg text-pretty\">Free for 14 days. You only need a license if you keep using it.</p>\n        </div>\n        <Download1 app=\"Ledger\" />\n        <section aria-labelledby=\"ledger-specs\" className=\"mx-auto max-w-6xl px-4 pb-24 sm:px-6\">\n          <h2 id=\"ledger-specs\" className=\"text-2xl font-semibold tracking-[-0.03em]\">Before you download</h2>\n          <ul className=\"mt-6 grid gap-4 sm:grid-cols-2\">\n            {specs.map((s) => (\n              <li key={s.title} className=\"bg-card flex gap-4 rounded-2xl border p-5\">\n                <span className=\"bg-chart-1/12 text-chart-1 flex size-10 shrink-0 items-center justify-center rounded-xl\"><s.icon className=\"size-5\" aria-hidden=\"true\" /></span>\n                <div><h3 className=\"font-medium\">{s.title}</h3><p className=\"text-muted-foreground mt-1 text-sm text-pretty\">{s.text}</p></div>\n              </li>\n            ))}\n          </ul>\n          <p className=\"text-muted-foreground mt-8 text-sm text-pretty\">Ledger updates itself in the background and asks before restarting. Need an older version? <a href={hrefs?.changelog ?? \"/ledger/changelog\"} className=\"text-chart-1 underline underline-offset-4\">Browse every release</a>.</p>\n        </section>\n      </main>\n    </LedgerShell>\n  )\n}\n\nexport { LedgerDownload, type LedgerDownloadProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/ledger/ledger-download.tsx"
    },
    {
      "path": "registry/ballmac/components/templates/ledger/ledger-pricing.tsx",
      "content": "// Ballmac UI: Ledger pricing page. https://ui.ballmac.com/templates/template-ledger\nimport * as React from \"react\"\nimport { Check, Minus } from \"lucide-react\"\n\nimport { Faq2 } from \"@/components/ballmac/blocks/faq-2/faq-2\"\nimport { Pricing4 } from \"@/components/ballmac/blocks/pricing-4/pricing-4\"\nimport { LedgerHeading, LedgerShell, type LedgerHrefs } from \"@/components/ballmac/templates/ledger/ledger-theme\"\n\nconst rows: [string, boolean | string, boolean | string][] = [\n  [\"Invoices and expenses\", \"Up to 10 a month\", \"Unlimited\"],\n  [\"Reports and exports\", \"Basic\", \"Full, with CSV and PDF\"],\n  [\"iCloud sync across Macs\", false, true],\n  [\"Approvals and menu bar capture\", false, true],\n  [\"Shortcuts and AppleScript\", false, true],\n  [\"Custom invoice templates\", false, true],\n  [\"Updates\", \"Bug fixes\", \"All of this major version\"],\n]\n\nfunction Cell({ v }: { v: boolean | string }) {\n  if (typeof v === \"string\") return <span className=\"text-sm\">{v}</span>\n  return v ? <Check className=\"text-chart-2 mx-auto size-4.5\" role=\"img\" aria-label=\"Included\" /> : <Minus className=\"text-muted-foreground mx-auto size-4\" role=\"img\" aria-label=\"Not included\" />\n}\n\ntype LedgerPricingProps = React.ComponentProps<\"div\"> & { hrefs?: Partial<LedgerHrefs> }\n\n/** Ledger pricing: buy once or subscribe with the cost chart, a free-versus-licensed table and questions. */\nfunction LedgerPricing({ hrefs, ...props }: LedgerPricingProps) {\n  return (\n    <LedgerShell page=\"pricing\" hrefs={hrefs} {...props}>\n      <main>\n        <div className=\"px-4 pt-16 text-center sm:px-6 sm:pt-20\">\n          <LedgerHeading as=\"h1\" className=\"mx-auto max-w-2xl text-4xl sm:text-6xl\">Honest pricing for <em>honest</em> software.</LedgerHeading>\n        </div>\n        <Pricing4 title=\"Pick how you like to pay.\" description=\"Buy a license and keep it forever, or subscribe if you’d rather always have the latest. The chart shows exactly when each one pays off.\" />\n        <section aria-labelledby=\"ledger-compare\" className=\"mx-auto max-w-3xl px-4 pb-20 sm:px-6\">\n          <h2 id=\"ledger-compare\" className=\"text-2xl font-semibold tracking-[-0.03em]\">Free trial or licensed</h2>\n          <div tabIndex={0} role=\"region\" aria-label=\"Trial compared with a license\" className=\"bg-card focus-visible:ring-ring/50 mt-6 overflow-x-auto rounded-2xl border outline-none focus-visible:ring-[3px]\">\n            <table className=\"w-full min-w-[30rem] text-start\">\n              <caption className=\"sr-only\">Trial and licensed features</caption>\n              <thead><tr className=\"border-b text-sm\"><th scope=\"col\" className=\"p-4 font-medium\"><span className=\"sr-only\">Feature</span></th><th scope=\"col\" className=\"p-4 text-center font-medium\">14-day trial</th><th scope=\"col\" className=\"p-4 text-center font-medium\">Licensed</th></tr></thead>\n              <tbody>\n                {rows.map(([f, a, b]) => (\n                  <tr key={f} className=\"border-b last:border-b-0\"><th scope=\"row\" className=\"p-4 text-sm font-normal\">{f}</th><td className=\"p-4 text-center\"><Cell v={a} /></td><td className=\"bg-chart-1/5 p-4 text-center\"><Cell v={b} /></td></tr>\n                ))}\n              </tbody>\n            </table>\n          </div>\n        </section>\n        <Faq2\n          title=\"Pricing questions\"\n          description=\"If yours isn’t here, we answer email within a day.\"\n          categories={[\n            { name: \"Licenses\", questions: [\n              { question: \"Is a license really forever?\", answer: \"Yes. A license works on the version you bought and every update in that major version, including all of 2.x. A new major version is a paid upgrade at a discount.\" },\n              { question: \"Can I move my license to another Mac?\", answer: \"Deactivate it from Settings on the old Mac and activate it on the new one. There is no limit on moves, only on how many Macs use it at once.\" },\n            ] },\n            { name: \"Subscriptions\", questions: [\n              { question: \"What happens if I cancel?\", answer: \"Ledger keeps opening your books in read-only mode, and you can export everything. You can resubscribe any time.\" },\n              { question: \"Is there a student or nonprofit discount?\", answer: \"Yes, 50 percent off for students, teachers and registered nonprofits. Write to us from your school or organisation address.\" },\n            ] },\n          ]}\n          support={{ label: \"Email support\", href: \"#\", text: \"Still unsure which is right for you?\" }}\n        />\n      </main>\n    </LedgerShell>\n  )\n}\n\nexport { LedgerPricing, type LedgerPricingProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/ledger/ledger-pricing.tsx"
    },
    {
      "path": "registry/ballmac/components/templates/ledger/ledger-changelog.tsx",
      "content": "// Ballmac UI: Ledger changelog page. https://ui.ballmac.com/templates/template-ledger\nimport * as React from \"react\"\n\nimport { Changelog1 } from \"@/components/ballmac/blocks/changelog-1/changelog-1\"\nimport { LedgerHeading, LedgerShell, type LedgerHrefs } from \"@/components/ballmac/templates/ledger/ledger-theme\"\n\ntype LedgerChangelogProps = React.ComponentProps<\"div\"> & { hrefs?: Partial<LedgerHrefs> }\n\n/** Ledger changelog: release notes with a generated cover on headline releases. */\nfunction LedgerChangelog({ hrefs, ...props }: LedgerChangelogProps) {\n  return (\n    <LedgerShell page=\"changelog\" hrefs={hrefs} {...props}>\n      <main>\n        <div className=\"px-4 pt-16 text-center sm:px-6 sm:pt-20\">\n          <LedgerHeading as=\"h1\" className=\"text-4xl sm:text-6xl\">What’s <em>new</em>.</LedgerHeading>\n        </div>\n        <Changelog1 title=\"Every release, in plain language.\" description=\"We ship every few weeks. Here is what changed and why.\" />\n      </main>\n    </LedgerShell>\n  )\n}\n\nexport { LedgerChangelog, type LedgerChangelogProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/ledger/ledger-changelog.tsx"
    },
    {
      "path": "registry/ballmac/components/templates/ledger/ledger-support.tsx",
      "content": "// Ballmac UI: Ledger support page. https://ui.ballmac.com/templates/template-ledger\n\"use client\"\n\nimport * as React from \"react\"\nimport { BookOpen, CreditCard, Keyboard, LifeBuoy, Mail, Search, Wrench } from \"lucide-react\"\n\nimport { Kbd } from \"@/components/ballmac/kbd\"\nimport { LedgerHeading, LedgerShell, type LedgerHrefs } from \"@/components/ballmac/templates/ledger/ledger-theme\"\nimport { cn } from \"@/lib/utils\"\n\nconst topics = [\n  { icon: BookOpen, title: \"Getting started\", text: \"Import your data, add a customer and send your first invoice.\", articles: [\"Import from a spreadsheet\", \"Your first invoice\", \"Set up iCloud sync\"] },\n  { icon: CreditCard, title: \"Licenses and billing\", text: \"Activate, move or recover a license, and manage a subscription.\", articles: [\"Activate a license\", \"Move to a new Mac\", \"Update a payment method\"] },\n  { icon: Wrench, title: \"Troubleshooting\", text: \"Fix sync conflicts, a stuck export or an app that won’t open.\", articles: [\"Sync says “paused”\", \"Rebuild the index\", \"Reset preferences\"] },\n  { icon: Keyboard, title: \"Shortcuts and automation\", text: \"Every keyboard shortcut and a few AppleScript recipes.\", articles: [\"All keyboard shortcuts\", \"Shortcuts app actions\", \"AppleScript dictionary\"] },\n]\n\nconst shortcuts: [string, string[]][] = [\n  [\"New invoice\", [\"⌘\", \"N\"]],\n  [\"Quick open\", [\"⌘\", \"K\"]],\n  [\"Mark as paid\", [\"⌃\", \"⌘\", \"P\"]],\n  [\"Export report\", [\"⇧\", \"⌘\", \"E\"]],\n  [\"Toggle sidebar\", [\"⌥\", \"⌘\", \"S\"]],\n  [\"Capture expense\", [\"⌃\", \"⌥\", \"N\"]],\n]\n\ntype LedgerSupportProps = React.ComponentProps<\"div\"> & { hrefs?: Partial<LedgerHrefs> }\n\n/** Ledger support: a search field that filters help topics, shortcut cheat sheet and contact options. */\nfunction LedgerSupport({ hrefs, ...props }: LedgerSupportProps) {\n  const [query, setQuery] = React.useState(\"\")\n  const q = query.trim().toLowerCase()\n  const shown = q ? topics.filter((t) => [t.title, t.text, ...t.articles].join(\" \").toLowerCase().includes(q)) : topics\n  return (\n    <LedgerShell page=\"support\" hrefs={hrefs} {...props}>\n      <main>\n        <section className=\"px-4 pt-16 text-center sm:px-6 sm:pt-20\">\n          <LedgerHeading as=\"h1\" className=\"text-4xl sm:text-6xl\">How can we <em>help</em>?</LedgerHeading>\n          <form role=\"search\" onSubmit={(e) => e.preventDefault()} className=\"relative mx-auto mt-8 max-w-xl\">\n            <label htmlFor=\"ledger-search\" className=\"sr-only\">Search help articles</label>\n            <Search className=\"text-muted-foreground pointer-events-none absolute top-1/2 start-4 size-5 -translate-y-1/2\" aria-hidden=\"true\" />\n            <input id=\"ledger-search\" type=\"search\" value={query} onChange={(e) => setQuery(e.target.value)} placeholder=\"Search “license”, “sync”, “export”…\" className=\"bg-card focus-visible:ring-ring/50 placeholder:text-muted-foreground h-13 w-full rounded-full border pe-5 ps-12 text-base shadow-sm outline-none focus-visible:ring-[3px]\" />\n          </form>\n          <p className=\"text-muted-foreground mt-3 text-sm\" role=\"status\">{q ? `${shown.length} ${shown.length === 1 ? \"topic\" : \"topics\"} match “${query}”` : \"Most questions are answered in under a minute.\"}</p>\n        </section>\n\n        <section aria-label=\"Help topics\" className=\"mx-auto max-w-6xl px-4 py-12 sm:px-6\">\n          {shown.length === 0 ? (\n            <div className=\"bg-card rounded-3xl border p-10 text-center\"><p className=\"font-medium\">Nothing found</p><p className=\"text-muted-foreground mt-1 text-sm\">Try a shorter word, or write to us below.</p></div>\n          ) : (\n            <ul className=\"grid gap-4 md:grid-cols-2\">\n              {shown.map((t) => (\n                <li key={t.title} className=\"bg-card rounded-3xl border p-7\">\n                  <t.icon className=\"text-chart-1 size-6\" aria-hidden=\"true\" />\n                  <h2 className=\"mt-4 text-xl font-semibold tracking-tight\">{t.title}</h2>\n                  <p className=\"text-muted-foreground mt-1.5 text-sm text-pretty\">{t.text}</p>\n                  <ul className=\"mt-5 divide-y border-t text-sm\">\n                    {t.articles.map((a) => <li key={a}><a href=\"#\" className=\"hover:text-chart-1 flex items-center justify-between py-2.5 transition-colors\">{a}<span aria-hidden=\"true\">›</span></a></li>)}\n                  </ul>\n                </li>\n              ))}\n            </ul>\n          )}\n        </section>\n\n        <section aria-labelledby=\"ledger-keys\" className=\"mx-auto max-w-6xl px-4 pb-16 sm:px-6\">\n          <h2 id=\"ledger-keys\" className=\"text-2xl font-semibold tracking-[-0.03em]\">Shortcuts worth learning</h2>\n          <ul className=\"mt-6 grid gap-px overflow-hidden rounded-2xl border bg-border sm:grid-cols-2 lg:grid-cols-3\">\n            {shortcuts.map(([label, keys]) => (\n              <li key={label} className=\"bg-card flex items-center justify-between px-5 py-4 text-sm\">{label}<span className=\"flex gap-1\">{keys.map((k) => <Kbd key={k}>{k}</Kbd>)}</span></li>\n            ))}\n          </ul>\n        </section>\n\n        <section aria-labelledby=\"ledger-contact\" className=\"mx-auto max-w-6xl px-4 pb-24 sm:px-6\">\n          <h2 id=\"ledger-contact\" className=\"sr-only\">Contact</h2>\n          <div className=\"grid gap-4 md:grid-cols-2\">\n            {[\n              { icon: Mail, title: \"Email us\", text: \"A person writes back, usually within a day.\", cta: \"support@ledger.app\" },\n              { icon: LifeBuoy, title: \"System status\", text: \"iCloud sync and license servers are running normally.\", cta: \"All systems normal\" },\n            ].map((c) => (\n              <div key={c.title} className={cn(\"bg-card flex items-start gap-4 rounded-3xl border p-6\")}>\n                <span className=\"bg-chart-1/12 text-chart-1 flex size-11 shrink-0 items-center justify-center rounded-2xl\"><c.icon className=\"size-5\" aria-hidden=\"true\" /></span>\n                <div><h3 className=\"font-semibold\">{c.title}</h3><p className=\"text-muted-foreground mt-1 text-sm text-pretty\">{c.text}</p><a href=\"#\" className=\"text-chart-1 mt-3 inline-block text-sm font-medium underline underline-offset-4\">{c.cta}</a></div>\n              </div>\n            ))}\n          </div>\n        </section>\n      </main>\n    </LedgerShell>\n  )\n}\n\nexport { LedgerSupport, type LedgerSupportProps }\n",
      "type": "registry:component",
      "target": "@components/ballmac/templates/ledger/ledger-support.tsx"
    },
    {
      "path": "registry/ballmac/app/ledger/page.tsx",
      "content": "// Ballmac UI: Ledger template route. https://ui.ballmac.com/templates/template-ledger\nimport type { Metadata } from \"next\"\n\nimport { LedgerHome } from \"@/components/ballmac/templates/ledger/ledger-home\"\n\nexport const metadata: Metadata = {\n  title: \"Ledger: Your books, kept beautifully\",\n  description: \"A native Mac app for invoices, expenses and reports.\",\n}\n\nexport default function Page() {\n  return <LedgerHome />\n}\n",
      "type": "registry:page",
      "target": "app/ledger/page.tsx"
    },
    {
      "path": "registry/ballmac/app/ledger/download/page.tsx",
      "content": "// Ballmac UI: Ledger template route. https://ui.ballmac.com/templates/template-ledger\nimport type { Metadata } from \"next\"\n\nimport { LedgerDownload } from \"@/components/ballmac/templates/ledger/ledger-download\"\n\nexport const metadata: Metadata = {\n  title: \"Download Ledger\",\n  description: \"Download Ledger for Mac. Free for 14 days.\",\n}\n\nexport default function Page() {\n  return <LedgerDownload />\n}\n",
      "type": "registry:page",
      "target": "app/ledger/download/page.tsx"
    },
    {
      "path": "registry/ballmac/app/ledger/pricing/page.tsx",
      "content": "// Ballmac UI: Ledger template route. https://ui.ballmac.com/templates/template-ledger\nimport type { Metadata } from \"next\"\n\nimport { LedgerPricing } from \"@/components/ballmac/templates/ledger/ledger-pricing\"\n\nexport const metadata: Metadata = {\n  title: \"Ledger pricing\",\n  description: \"Buy a license once, or subscribe and always have the latest.\",\n}\n\nexport default function Page() {\n  return <LedgerPricing />\n}\n",
      "type": "registry:page",
      "target": "app/ledger/pricing/page.tsx"
    },
    {
      "path": "registry/ballmac/app/ledger/changelog/page.tsx",
      "content": "// Ballmac UI: Ledger template route. https://ui.ballmac.com/templates/template-ledger\nimport type { Metadata } from \"next\"\n\nimport { LedgerChangelog } from \"@/components/ballmac/templates/ledger/ledger-changelog\"\n\nexport const metadata: Metadata = {\n  title: \"What’s new in Ledger\",\n  description: \"Release notes for every version of Ledger.\",\n}\n\nexport default function Page() {\n  return <LedgerChangelog />\n}\n",
      "type": "registry:page",
      "target": "app/ledger/changelog/page.tsx"
    },
    {
      "path": "registry/ballmac/app/ledger/support/page.tsx",
      "content": "// Ballmac UI: Ledger template route. https://ui.ballmac.com/templates/template-ledger\nimport type { Metadata } from \"next\"\n\nimport { LedgerSupport } from \"@/components/ballmac/templates/ledger/ledger-support\"\n\nexport const metadata: Metadata = {\n  title: \"Ledger support\",\n  description: \"Help articles, shortcuts and ways to reach us.\",\n}\n\nexport default function Page() {\n  return <LedgerSupport />\n}\n",
      "type": "registry:page",
      "target": "app/ledger/support/page.tsx"
    }
  ],
  "meta": {
    "schema": 1,
    "tier": "free",
    "tags": [
      "template",
      "mac app",
      "macos",
      "landing page",
      "download",
      "pricing",
      "support",
      "indie"
    ],
    "version": "1.0.0",
    "updated": "2026-10-01",
    "ai": {
      "summary": "Installs a five-page site for a Mac or desktop app, assembled from the Mac blocks (showcase-1, features-7, devices-1, pricing-4, download-1). Change the palette in ledgerCss, and the copy in each page file.",
      "whenToUse": [
        "Marketing sites for Mac, desktop and indie apps",
        "Products that sell a license and a subscription"
      ],
      "whenNotToUse": [
        "Web SaaS with signup flows (use an Orbit-style template)"
      ],
      "composesWith": [
        "showcase-1",
        "download-1",
        "pricing-4"
      ],
      "a11y": [],
      "customization": [
        "Edit ledgerCss for the palette",
        "Pass your own app window to Showcase1 as children",
        "Replace the italic serif in ledger-fonts.ts"
      ]
    },
    "examples": [
      "template-ledger-demo",
      "template-ledger-download",
      "template-ledger-pricing",
      "template-ledger-changelog",
      "template-ledger-support"
    ],
    "url": "https://ui.ballmac.com/components/template-ledger"
  },
  "docs": "Pages are at /ledger, /ledger/download, /ledger/pricing, /ledger/changelog and /ledger/support. The light and dark palettes are the ledgerCss string in ledger-theme.tsx.",
  "categories": [
    "templates"
  ],
  "type": "registry:block"
}