{"config":{"site":{"defaultTitle":"A minimal web app to create, preview, and download professional invoic","defaultDescription":"A minimal web app to create, preview, and download professional invoices as PDF without accounts or persistent storage.","canonicalOrigin":"","language":"en-US","socialImage":"","socialImageAlt":"","searchVerification":{"google":""},"organization":{"name":"","url":"","logo":""},"crawlerPolicy":{"searchIndexing":true,"aiSearchDiscovery":true,"aiTraining":false}},"design":{"version":"alpha","name":"Ledger","description":"A precision paper-ledger UI: warm paper canvas, deep teal-ink primary, monospace figures for every financial number, calm two-column editor/preview.","fonts":[{"name":"Public Sans","source":"google","stack":"Public Sans, -apple-system, BlinkMacSystemFont, sans-serif","weights":[400,500,600,700]},{"name":"IBM Plex Mono","source":"google","stack":"IBM Plex Mono, ui-monospace, SFMono-Regular, monospace","weights":[400,500,600]}],"colors":{"primary":"#0f4c46","primary-hover":"#0b3a35","on-primary":"#faf8f4","canvas":"#faf8f4","surface":"#ffffff","surface-alt":"#f2efe8","hairline":"#e2ddd0","ink":"#1c1a15","ink-soft":"#5c5748","muted":"#948e7c","success-bg":"#e6f2e9","success-text":"#1e6b3c","error-bg":"#fbeae7","error-text":"#a3311c","accent-amber":"#c98a2b"},"typography":{"hero-display":{"fontSize":"60px","fontWeight":700,"lineHeight":1.05,"letterSpacing":"-1.5px"},"heading-lg":{"fontSize":"34px","fontWeight":700,"lineHeight":1.15,"letterSpacing":"-0.5px"},"heading-md":{"fontSize":"24px","fontWeight":600,"lineHeight":1.25,"letterSpacing":"-0.2px"},"title-sm":{"fontSize":"18px","fontWeight":600,"lineHeight":1.3,"letterSpacing":"0"},"body-md":{"fontSize":"15px","fontWeight":400,"lineHeight":1.55,"letterSpacing":"0"},"body-sm":{"fontSize":"13px","fontWeight":400,"lineHeight":1.5,"letterSpacing":"0"},"caption":{"fontSize":"11px","fontWeight":500,"lineHeight":1.4,"letterSpacing":"0.3px"},"button-md":{"fontSize":"14px","fontWeight":600,"lineHeight":1.2,"letterSpacing":"0.1px"},"mono-lg":{"fontFamily":"IBM Plex Mono, monospace","fontSize":"22px","fontWeight":600,"lineHeight":1.3,"letterSpacing":"0"},"mono-md":{"fontFamily":"IBM Plex Mono, monospace","fontSize":"15px","fontWeight":500,"lineHeight":1.5,"letterSpacing":"0"},"mono-sm":{"fontFamily":"IBM Plex Mono, monospace","fontSize":"13px","fontWeight":500,"lineHeight":1.4,"letterSpacing":"0"}},"rounded":{"xs":"4px","sm":"6px","md":"10px","lg":"14px","full":"999px"},"spacing":{"xs":"4px","sm":"8px","md":"16px","lg":"24px","xl":"40px","section":"72px"},"components":{"topbar":{"backgroundColor":"{colors.surface}","textColor":"{colors.ink}","typography":"{typography.title-sm}","rounded":"{rounded.xs}","padding":"12px 24px","border":"1px solid {colors.hairline}"},"button-primary":{"backgroundColor":"{colors.primary}","textColor":"{colors.on-primary}","typography":"{typography.button-md}","rounded":"{rounded.sm}","padding":"11px 22px"},"button-secondary":{"backgroundColor":"{colors.surface}","textColor":"{colors.ink}","typography":"{typography.button-md}","rounded":"{rounded.sm}","padding":"10px 20px","border":"1px solid {colors.hairline}"},"form-card":{"backgroundColor":"{colors.surface}","textColor":"{colors.ink}","rounded":"{rounded.md}","padding":"{spacing.lg}","border":"1px solid {colors.hairline}"},"preview-card":{"backgroundColor":"{colors.surface}","textColor":"{colors.ink}","rounded":"{rounded.md}","padding":"{spacing.xl}","border":"1px solid {colors.hairline}"},"modal":{"backgroundColor":"{colors.surface}","textColor":"{colors.ink}","rounded":"{rounded.md}","padding":"{spacing.lg}","border":"1px solid {colors.hairline}"},"input-field":{"backgroundColor":"{colors.canvas}","textColor":"{colors.ink}","typography":"{typography.body-md}","rounded":"{rounded.xs}","padding":"9px 12px","border":"1px solid {colors.hairline}"},"line-item-row":{"backgroundColor":"{colors.surface}","textColor":"{colors.ink}","typography":"{typography.mono-sm}","rounded":"{rounded.xs}","padding":"{spacing.sm}","border":"1px solid {colors.hairline}"}},"prose":{"overview":"Ledger treats invoice creation like fine stationery: a warm paper canvas, crisp white document cards, and a single deep teal-ink accent reserved for the Download PDF action. The mood is quiet, trustworthy, and precise — closer to a printed ledger than a flashy SaaS dashboard.","colors":"Warm paper canvas (#faf8f4) with white surface cards and a soft alt surface for section separation. Deep teal-ink primary (#0f4c46) is used sparingly for the CTA and active states only. Neutrals are tinted warm-beige, never pure grey. Success/error are muted and reserved strictly for form validation feedback.","typography":"Public Sans carries all UI text — labels, headings, buttons — with a bold oversized heading-lg for section titles. IBM Plex Mono is reserved exclusively for numeric/financial content: invoice numbers, dates, quantities, unit prices, and totals, reinforcing a ledger/receipt feel and making numbers instantly scannable.","layout":"Two-column responsive layout: form on the left, live preview on the right, stacking on mobile. Sections within the form are separated by generous spacing.lg/xl gaps and hairline dividers rather than boxes-within-boxes. The top bar is slim and fixed with app name left, Download PDF button right.","elevation":"Almost entirely flat — hairline borders define cards instead of shadows. The only elevation is a subtle soft shadow under the live preview card (suggesting a physical paper sheet) and under the PDF confirmation modal to lift it above the page.","shapes":"Small, consistent radius (xs/sm/md) throughout — never pill-shaped except nothing gets full radius. Inputs use the tightest radius, cards use md, giving a crisp document-like edge rather than a soft app feel.","components":"Primary button is a solid teal-ink rectangle with sm radius, used only for Download PDF and Download in modal. Line items render in monospace rows with hairline separators. The PDF modal shows paper-size radio options (A4/Letter), orientation toggle, include-logo checkbox, and a preview thumbnail, all inside a bordered surface card.","dosAndDonts":"Do reserve teal-ink for the primary download action and active/selected states. Do use monospace exclusively for numbers/currency/dates. Don't add shadows to ordinary form cards. Don't introduce a second accent color. Don't use pill radii or purple/indigo hues anywhere."},"agentPromptGuide":"Ledger is a document-tool design system: treat the app like precision paper stationery, not a marketing SaaS page. Base font is Public Sans for UI; use IBM Plex Mono only for numeric/financial values (invoice numbers, amounts, totals, dates) via text-mono-* typography tokens or the 'numeric' component pattern — never mix mono into headings/body prose. Canvas is warm paper (#faf8f4-ish), surfaces are white cards with hairline borders, radius is small and consistent (sm/md only, no pill buttons except nothing — buttons use md radius). Primary color (deep teal-ink #0f4c46) anchors the single Download PDF CTA and active states only; do not sprinkle primary elsewhere. Keep the two-column editor calm: generous spacing.lg/xl between form sections, hairline dividers between line items, no shadows except a subtle one on the modal and the live-preview card (elevation.preview). Success/error colors reserved strictly for validation states. Never invent new tokens; reference existing ones exactly.","designGuide":"This app's design tokens are the sibling fields colors / typography / rounded / spacing / fonts.\nAt runtime they compile into a Tailwind v4 @theme, so always reference them through Tailwind utility classes — never var(--...), raw hex, raw px, or style=\"...\".\n\nToken → utility:\n- colors.<k>     → bg-<k> / text-<k> / border-<k> …\n- typography.<k> → text-<k> (size + weight + line-height + letter-spacing)\n- rounded.<k>    → rounded-<k>\n- spacing.<k>    → p-<k> / m-<k> / gap-<k> …\n\nRules:\n1. Token keys are app-defined; check which keys actually exist before writing className.\n2. Use the nearest existing token; never add, rename, or invent tokens.\n3. fonts[0] is the global base font and is applied automatically; only write a font utility when overriding.\n4. Semi-transparent backgrounds: combine token utility with slash opacity (bg-primary/50) — never bg-opacity-50.\n5. components.* may contain {category.tokenName} references; this is design-system-internal and must never appear in page/module schemas.\n6. Read prose.* (design intent) and agentPromptGuide (mandatory) before choosing colors, density, or hierarchy."},"dataTables":[]},"modules":[{"id":"20f40753ec","name":"TopBar","props":{"appName":"Ledger","showDownloadButton":true,"downloadLabel":"Download PDF","downloadPath":"./pdf_confirmation_modal"},"state":{},"methods":{},"lifecycles":{"onMounted":"","onBeforeUnmount":""},"schema":{"component":"div","className":"fixed top-0 left-0 right-0 z-40 h-16 bg-surface border-b border-hairline flex items-center justify-between px-lg print:hidden","children":[{"id":"topbar-app-name","component":"div","className":"text-heading-md text-ink","children":[{"id":"650ee97803","component":"text","props":{"textContent":"Free Invoice Generator"}}]},{"id":"topbar-download-btn","component":"button","className":"bg-primary text-on-primary text-button-md px-lg py-sm rounded-md hover:bg-primary-hover transition-colors","condition":"props.showDownloadButton","events":{"click":"() => $emit('download')"},"children":[{"id":"bc11393afe","component":"text","props":{"textContent":"{{ props.downloadLabel }}"}}]}],"id":"topbar-root"}}],"pages":[{"id":"4869d473ae","path":"invoice_editor","meta":{},"name":"Invoice Editor","description":"Invoice Editor: a single responsive two-column page for building a professional invoice — business/c","seo":{"title":"Invoice Editor — Ledger","description":"Create a professional invoice with live preview: business and client details, line items, discounts, tax, and download as a print-ready PDF. No account required.","indexable":true,"followLinks":true,"socialImage":"","socialImageAlt":"","sitemap":{"include":true}},"state":{"business_logo":"","business_name":"","business_address":"","business_email":"","business_phone":"","business_website":"","client_name":"","client_address":"","client_email":"","invoice_number":"","invoice_date":"","due_date":"","currency":"USD","items":[{"description":"","quantity":1,"unit_price":0}],"discount_type":"percentage","discount_value":0,"tax_percent":0,"notes":"","payment_instructions":"","errors":{}},"methods":{"loadDraft":{"params":[],"code":"const draft = $app.getStorage('invoiceDraft', null);\nif (draft) {\n  setState(draft);\n}\n"},"persistInvoiceData":{"params":[],"code":"$app.setStorage('invoiceDraft', {\n  business_logo, business_name, business_address, business_email, business_phone, business_website,\n  client_name, client_address, client_email,\n  invoice_number, invoice_date, due_date, currency,\n  items, discount_type, discount_value, tax_percent,\n  notes, payment_instructions\n});"},"handleLogoUpload":{"params":["e"],"code":"const file = e.target.files && e.target.files[0];\nif (!file) return;\nconst reader = new FileReader();\nreader.onload = () => {\n  setState({ business_logo: reader.result });\n  persistInvoiceData();\n};\nreader.readAsDataURL(file);"},"addItem":{"params":[],"code":"setState({ items: [...items, { description: '', quantity: 1, unit_price: 0 }] });\npersistInvoiceData();"},"removeItem":{"params":["item"],"code":"const idx = items.indexOf(item);\nif (idx === -1) return;\nconst next = items.slice();\nnext.splice(idx, 1);\nsetState({ items: next });\npersistInvoiceData();"},"updateItemField":{"params":["item","field","value"],"code":"const idx = items.indexOf(item);\nif (idx === -1) return;\nconst next = items.slice();\nnext[idx] = { ...next[idx], [field]: value };\nsetState({ items: next });\npersistInvoiceData();"},"calcAmount":{"params":["item"],"code":"const qty = parseFloat(item.quantity) || 0;\nconst price = parseFloat(item.unit_price) || 0;\nreturn qty * price;"},"calcSubtotal":{"params":[],"code":"return items.reduce((sum, item) => sum + (parseFloat(item.quantity) || 0) * (parseFloat(item.unit_price) || 0), 0);"},"calcDiscountedSubtotal":{"params":[],"code":"const subtotal = calcSubtotal();\nconst val = parseFloat(discount_value) || 0;\nif (discount_type === 'percentage') {\n  return subtotal - (subtotal * val / 100);\n}\nreturn Math.max(0, subtotal - val);"},"calcDiscountAmount":{"params":[],"code":"return calcSubtotal() - calcDiscountedSubtotal();"},"calcTaxAmount":{"params":[],"code":"const discounted = calcDiscountedSubtotal();\nconst pct = parseFloat(tax_percent) || 0;\nreturn discounted * pct / 100;"},"calcTotal":{"params":[],"code":"return calcDiscountedSubtotal() + calcTaxAmount();"},"formatCurrency":{"params":["amount"],"code":"try {\n  return new Intl.NumberFormat('en-US', { style: 'currency', currency: currency || 'USD' }).format(amount || 0);\n} catch (e) {\n  return (amount || 0).toFixed(2);\n}"},"validateAndProceed":{"params":[],"code":"const errs = {};\nif (!business_name) errs.business_name = 'Business name is required';\nif (!client_name) errs.client_name = 'Client name is required';\nif (!invoice_number) errs.invoice_number = 'Invoice number is required';\nif (!invoice_date) errs.invoice_date = 'Invoice date is required';\nif (!currency) errs.currency = 'Currency is required';\nif (!items.length) errs.items = 'At least one invoice item is required';\nitems.forEach((it) => {\n  if (!it.description) errs.items = 'Every item needs a description';\n  if (!(parseFloat(it.quantity) >= 0.01)) errs.items = 'Quantity must be at least 0.01';\n  if (!(parseFloat(it.unit_price) >= 0)) errs.items = 'Unit price must be 0 or more';\n});\nconst emailPattern = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nif (business_email && !emailPattern.test(business_email)) errs.business_email = 'Invalid email';\nif (client_email && !emailPattern.test(client_email)) errs.client_email = 'Invalid email';\nsetState({ errors: errs });\nif (Object.keys(errs).length) {\n  $app.message.warning('Please fix the highlighted fields before downloading');\n  return false;\n}\npersistInvoiceData();\nreturn true;"},"downloadInvoicePdf":{"params":[],"code":"if (!business_name || !client_name || !invoice_number || !invoice_date || !items.length) {\n  $app.message.error('Please fill in the required invoice fields before downloading');\n  return;\n}\nconst loadingInst = $app.loading.show('Generating PDF...');\ntry {\n  const payload = {\n    business_logo, business_name, business_address, business_email, business_phone, business_website,\n    client_name, client_address, client_email,\n    invoice_number, invoice_date, due_date, currency,\n    items, discount_type, discount_value, tax_percent,\n    notes, payment_instructions,\n  };\n  const response = await $app.post('/c/generate_invoice_pdf', payload, { responseType: 'blob' });\n  const blob = response && response.data ? response.data : response;\n  const filename = (invoice_number ? invoice_number : 'invoice') + '.pdf';\n  const url = window.URL.createObjectURL(blob);\n  const a = document.createElement('a');\n  a.href = url;\n  a.download = filename;\n  document.body.appendChild(a);\n  a.click();\n  document.body.removeChild(a);\n  window.URL.revokeObjectURL(url);\n  $app.message.success('PDF downloaded');\n} catch (e) {\n  $app.message.error('Failed to generate PDF. Please try again.');\n} finally {\n  $app.loading.hide(loadingInst);\n}\n"}},"lifecycles":{"onMounted":"loadDraft()","onBeforeUnmount":""},"mockStates":[{"id":"default","name":"Default draft","description":"Empty invoice with one blank line item, ready for input.","patch":{}},{"id":"filled-example","name":"Filled example","description":"Sample invoice with business/client info and two line items for previewing layout.","patch":{"business_name":"Ledger Studio LLC","business_address":"221 Paper Row, Suite 4, Austin, TX 78701","business_email":"billing@ledgerstudio.com","business_phone":"+1 (512) 555-0134","business_website":"ledgerstudio.com","client_name":"Acme Roasters Co.","client_address":"9 Market St, Denver, CO 80202","client_email":"accounts@acmeroasters.com","invoice_number":"INV-1042","invoice_date":"2024-06-01","due_date":"2024-06-15","currency":"USD","items":[{"description":"Brand identity design","quantity":1,"unit_price":2400},{"description":"Website development (10 hrs)","quantity":10,"unit_price":95}],"discount_type":"percentage","discount_value":10,"tax_percent":8.25,"notes":"Thank you for your business!","payment_instructions":"Please pay via bank transfer within 14 days."}}],"activeMockStateId":"default","schema":{"id":"invoice-editor-page","component":"div","className":"min-h-screen bg-canvas pt-16 print:pt-0 print:[-webkit-print-color-adjust:exact] print:[print-color-adjust:exact] print:[color-adjust:exact]","children":[{"id":"invoice-editor-topbar","component":"TopBar","props":{"appName":"Ledger","showDownloadButton":true,"downloadLabel":"Download PDF","downloadPath":"./pdf_confirmation_modal"},"events":{"download":"() => downloadInvoicePdf()"}},{"id":"invoice-editor-layout","component":"div","className":"max-w-[1280px] mx-auto px-lg py-xl grid grid-cols-1 lg:grid-cols-2 gap-xl print:block print:max-w-none print:p-0","children":[{"id":"invoice-form-column","component":"div","className":"flex flex-col gap-xl print:hidden","children":[{"id":"business-info-section","component":"section","className":"flex flex-col gap-md pb-lg border-b border-hairline","children":[{"id":"business-info-title","component":"h2","className":"text-title-sm text-ink","children":[{"id":"6421174627","component":"text","props":{"textContent":"Business Information"}}]},{"id":"business-logo-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"business-logo-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"dfc852577a","component":"text","props":{"textContent":"Logo (optional)"}}]},{"id":"business-logo-preview","component":"img","className":"h-12 w-auto object-contain rounded-xs border border-hairline p-xs bg-surface","condition":"business_logo","props":{"src":"{{ business_logo }}","alt":"Business logo preview"}},{"id":"business-logo-input","component":"input","className":"border border-hairline rounded-xs text-body-sm text-ink-soft","props":{"type":"file","accept":"image/*","placeholder":""},"events":{"change":"(e) => handleLogoUpload(e)"}}]},{"id":"business-name-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"business-name-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"e47d9e59f2","component":"text","props":{"textContent":"Business Name *"}}]},{"id":"business-name-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"business_name","props":{"type":"text","placeholder":"Your Company LLC"},"events":{"change":"() => persistInvoiceData()"}},{"id":"business-name-error","component":"div","className":"text-caption text-error-text","condition":"errors.business_name","children":[{"id":"4e698ce759","component":"text","props":{"textContent":"{{ errors.business_name }}"}}]}]},{"id":"business-address-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"business-address-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"98dc294259","component":"text","props":{"textContent":"Business Address"}}]},{"id":"business-address-input","component":"textarea","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"business_address","props":{"rows":2,"placeholder":"Street, City, State, ZIP"},"events":{"change":"() => persistInvoiceData()"}}]},{"id":"business-contact-row","component":"div","className":"grid grid-cols-1 sm:grid-cols-2 gap-md","children":[{"id":"business-email-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"business-email-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"7cea77a1ee","component":"text","props":{"textContent":"Email"}}]},{"id":"business-email-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"business_email","props":{"type":"email","placeholder":"you@company.com"},"events":{"change":"() => persistInvoiceData()"}},{"id":"business-email-error","component":"div","className":"text-caption text-error-text","condition":"errors.business_email","children":[{"id":"4ed36c033e","component":"text","props":{"textContent":"{{ errors.business_email }}"}}]}]},{"id":"business-phone-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"business-phone-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"e86bf23f53","component":"text","props":{"textContent":"Phone"}}]},{"id":"business-phone-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"business_phone","props":{"type":"tel","placeholder":"+1 (555) 000-0000"},"events":{"change":"() => persistInvoiceData()"}}]}]},{"id":"business-website-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"business-website-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"30b90e62d8","component":"text","props":{"textContent":"Website"}}]},{"id":"business-website-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"business_website","props":{"type":"text","placeholder":"company.com"},"events":{"change":"() => persistInvoiceData()"}}]}]},{"id":"client-info-section","component":"section","className":"flex flex-col gap-md pb-lg border-b border-hairline","children":[{"id":"client-info-title","component":"h2","className":"text-title-sm text-ink","children":[{"id":"9e1d342cea","component":"text","props":{"textContent":"Client Information"}}]},{"id":"client-name-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"client-name-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"167393c1f4","component":"text","props":{"textContent":"Client Name *"}}]},{"id":"client-name-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"client_name","props":{"type":"text","placeholder":"Client or Company Name"},"events":{"change":"() => persistInvoiceData()"}},{"id":"client-name-error","component":"div","className":"text-caption text-error-text","condition":"errors.client_name","children":[{"id":"28d7594559","component":"text","props":{"textContent":"{{ errors.client_name }}"}}]}]},{"id":"client-address-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"client-address-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"aca7764f54","component":"text","props":{"textContent":"Client Address"}}]},{"id":"client-address-input","component":"textarea","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"client_address","props":{"rows":2,"placeholder":"Street, City, State, ZIP"},"events":{"change":"() => persistInvoiceData()"}}]},{"id":"client-email-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"client-email-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"3bd297959e","component":"text","props":{"textContent":"Client Email"}}]},{"id":"client-email-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"client_email","props":{"type":"email","placeholder":"client@company.com"},"events":{"change":"() => persistInvoiceData()"}},{"id":"client-email-error","component":"div","className":"text-caption text-error-text","condition":"errors.client_email","children":[{"id":"4853171ed6","component":"text","props":{"textContent":"{{ errors.client_email }}"}}]}]}]},{"id":"invoice-details-section","component":"section","className":"flex flex-col gap-md pb-lg border-b border-hairline","children":[{"id":"invoice-details-title","component":"h2","className":"text-title-sm text-ink","children":[{"id":"37a7dd933e","component":"text","props":{"textContent":"Invoice Details"}}]},{"id":"invoice-details-row","component":"div","className":"grid grid-cols-1 sm:grid-cols-2 gap-md","children":[{"id":"invoice-number-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"invoice-number-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"8ad1cd47ca","component":"text","props":{"textContent":"Invoice Number *"}}]},{"id":"invoice-number-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-mono-md bg-surface","model":"invoice_number","props":{"type":"text","placeholder":"INV-0001"},"events":{"change":"() => persistInvoiceData()"}},{"id":"invoice-number-error","component":"div","className":"text-caption text-error-text","condition":"errors.invoice_number","children":[{"id":"abb6c57e02","component":"text","props":{"textContent":"{{ errors.invoice_number }}"}}]}]},{"id":"invoice-currency-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"invoice-currency-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"82d6a5dbdc","component":"text","props":{"textContent":"Currency *"}}]},{"id":"invoice-currency-select","component":"select","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"currency","props":{"options":[{"label":"USD - US Dollar","value":"USD"},{"label":"CAD - Canadian Dollar","value":"CAD"},{"label":"GBP - British Pound","value":"GBP"},{"label":"EUR - Euro","value":"EUR"},{"label":"AUD - Australian Dollar","value":"AUD"},{"label":"NZD - New Zealand Dollar","value":"NZD"},{"label":"SGD - Singapore Dollar","value":"SGD"}]},"events":{"change":"() => persistInvoiceData()"}}]}]},{"id":"invoice-dates-row","component":"div","className":"grid grid-cols-1 sm:grid-cols-2 gap-md","children":[{"id":"invoice-date-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"invoice-date-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"67a1e62429","component":"text","props":{"textContent":"Invoice Date *"}}]},{"id":"invoice-date-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-mono-md bg-surface","model":"invoice_date","props":{"type":"date"},"events":{"change":"() => persistInvoiceData()"}},{"id":"invoice-date-error","component":"div","className":"text-caption text-error-text","condition":"errors.invoice_date","children":[{"id":"9f353dbbc8","component":"text","props":{"textContent":"{{ errors.invoice_date }}"}}]}]},{"id":"due-date-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"due-date-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"d8563eb158","component":"text","props":{"textContent":"Due Date"}}]},{"id":"due-date-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-mono-md bg-surface","model":"due_date","props":{"type":"date"},"events":{"change":"() => persistInvoiceData()"}}]}]}]},{"id":"invoice-items-section","component":"section","className":"flex flex-col gap-md pb-lg border-b border-hairline","children":[{"id":"invoice-items-title","component":"h2","className":"text-title-sm text-ink","children":[{"id":"3b647ef942","component":"text","props":{"textContent":"Invoice Items"}}]},{"id":"invoice-items-error","component":"div","className":"text-caption text-error-text","condition":"errors.items","children":[{"id":"d73caea781","component":"text","props":{"textContent":"{{ errors.items }}"}}]},{"id":"invoice-items-list","component":"div","className":"flex flex-col gap-sm","children":[{"id":"invoice-item-row","component":"div","className":"grid grid-cols-[1fr_60px_90px_90px_28px] gap-xs items-center border-b border-hairline pb-sm","loop":{"source":"items","item":"item"},"children":[{"id":"invoice-item-description","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-body-sm bg-surface","props":{"type":"text","placeholder":"Description","value":"{{ item.description }}"},"events":{"input":"(e) => updateItemField(item, 'description', e.target.value)"}},{"id":"invoice-item-quantity","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-mono-sm bg-surface","props":{"type":"number","step":"0.01","min":"0.01","value":"{{ item.quantity }}"},"events":{"input":"(e) => updateItemField(item, 'quantity', e.target.value)"}},{"id":"invoice-item-unit-price","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-mono-sm bg-surface","props":{"type":"number","step":"0.01","min":"0","value":"{{ item.unit_price }}"},"events":{"input":"(e) => updateItemField(item, 'unit_price', e.target.value)"}},{"id":"invoice-item-amount","component":"div","className":"text-mono-sm text-ink text-right","children":[{"id":"ca0f3b364c","component":"text","props":{"textContent":"{{ formatCurrency(calcAmount(item)) }}"}}]},{"id":"invoice-item-remove","component":"button","className":"text-error-text text-body-sm","props":{"type":"button"},"events":{"click":"() => removeItem(item)"},"children":[{"id":"bc00461786","component":"text","props":{"textContent":"✕"}}]}]}]},{"id":"invoice-item-add-button","component":"button","className":"self-start text-button-md text-primary border border-primary rounded-sm px-md py-xs","props":{"type":"button"},"events":{"click":"() => addItem()"},"children":[{"id":"91dc9ab4ae","component":"text","props":{"textContent":"+ Add Item"}}]}]},{"id":"invoice-discount-tax-section","component":"section","className":"flex flex-col gap-md pb-lg border-b border-hairline","children":[{"id":"discount-tax-title","component":"h2","className":"text-title-sm text-ink","children":[{"id":"903f8b28b7","component":"text","props":{"textContent":"Discount & Tax"}}]},{"id":"discount-row","component":"div","className":"grid grid-cols-1 sm:grid-cols-2 gap-md","children":[{"id":"discount-type-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"discount-type-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"d85d2056e9","component":"text","props":{"textContent":"Discount Type"}}]},{"id":"discount-type-select","component":"select","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"discount_type","props":{"options":[{"label":"Percentage","value":"percentage"},{"label":"Fixed Amount","value":"fixed"}]},"events":{"change":"() => persistInvoiceData()"}}]},{"id":"discount-value-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"discount-value-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"421f1d605c","component":"text","props":{"textContent":"Discount Value"}}]},{"id":"discount-value-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-mono-md bg-surface","model":"discount_value","props":{"type":"number","min":"0","step":"0.01"},"events":{"change":"() => persistInvoiceData()"}}]}]},{"id":"tax-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"tax-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"64d1433431","component":"text","props":{"textContent":"Tax (%)"}}]},{"id":"tax-input","component":"input","className":"border border-hairline rounded-xs px-sm py-xs text-mono-md bg-surface","model":"tax_percent","props":{"type":"number","min":"0","step":"0.01"},"events":{"change":"() => persistInvoiceData()"}}]}]},{"id":"additional-info-section","component":"section","className":"flex flex-col gap-md","children":[{"id":"additional-info-title","component":"h2","className":"text-title-sm text-ink","children":[{"id":"fa5b586adf","component":"text","props":{"textContent":"Additional Information"}}]},{"id":"notes-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"notes-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"94a46ea562","component":"text","props":{"textContent":"Notes"}}]},{"id":"notes-input","component":"textarea","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"notes","props":{"rows":2,"placeholder":"Thank you for your business"},"events":{"change":"() => persistInvoiceData()"}}]},{"id":"payment-instructions-field","component":"div","className":"flex flex-col gap-xs","children":[{"id":"payment-instructions-label","component":"label","className":"text-body-sm text-ink-soft","children":[{"id":"f720e542f9","component":"text","props":{"textContent":"Payment Instructions"}}]},{"id":"payment-instructions-input","component":"textarea","className":"border border-hairline rounded-xs px-sm py-xs text-body-md bg-surface","model":"payment_instructions","props":{"rows":2,"placeholder":"Bank transfer, PayPal, etc."},"events":{"change":"() => persistInvoiceData()"}}]}]}]},{"id":"invoice-preview-column","component":"div","className":"lg:sticky lg:top-16 lg:self-start print:static print:w-full","children":[{"id":"invoice-preview-card","component":"div","className":"bg-surface border border-hairline rounded-md p-xl shadow-sm flex flex-col gap-lg print:border-0 print:shadow-none print:rounded-none print:p-0 print:[-webkit-print-color-adjust:exact] print:[print-color-adjust:exact] print:[color-adjust:exact]","children":[{"id":"preview-header-row","component":"div","className":"flex justify-between items-start gap-md","children":[{"id":"preview-business-block","component":"div","className":"flex flex-col gap-xs","children":[{"id":"preview-logo","component":"img","className":"h-10 object-contain mb-xs self-start","condition":"business_logo","props":{"src":"{{ business_logo }}","alt":"Business logo"}},{"id":"preview-business-name","component":"div","className":"text-heading-md text-ink","children":[{"id":"9e3a2f8847","component":"text","props":{"textContent":"{{ business_name || 'Your Business Name' }}"}}]},{"id":"preview-business-address","component":"div","className":"text-body-sm text-ink-soft whitespace-pre-line","children":[{"id":"55201fab45","component":"text","props":{"textContent":"{{ business_address }}"}}]},{"id":"preview-business-contact","component":"div","className":"text-body-sm text-ink-soft","children":[{"id":"78c1809504","component":"text","props":{"textContent":"{{ [business_email, business_phone, business_website].filter(Boolean).join(' · ') }}"}}]}]},{"id":"preview-invoice-meta","component":"div","className":"flex flex-col items-end gap-xs text-right","children":[{"id":"preview-invoice-label","component":"div","className":"text-title-sm text-ink","children":[{"id":"05a5131d31","component":"text","props":{"textContent":"INVOICE"}}]},{"id":"preview-invoice-number","component":"div","className":"text-mono-sm text-ink-soft","children":[{"id":"9766b1a938","component":"text","props":{"textContent":"#{{ invoice_number || '—' }}"}}]},{"id":"preview-invoice-date","component":"div","className":"text-mono-sm text-ink-soft","children":[{"id":"15a0f06f0b","component":"text","props":{"textContent":"Date: {{ invoice_date || '—' }}"}}]},{"id":"preview-due-date","component":"div","className":"text-mono-sm text-ink-soft","children":[{"id":"93861f26a1","component":"text","props":{"textContent":"Due: {{ due_date || '—' }}"}}]}]}]},{"id":"preview-client-block","component":"div","className":"flex flex-col gap-xs pt-md border-t border-hairline","children":[{"id":"preview-bill-to-label","component":"div","className":"text-caption text-muted","children":[{"id":"1be026e64e","component":"text","props":{"textContent":"BILL TO"}}]},{"id":"preview-client-name","component":"div","className":"text-body-md text-ink","children":[{"id":"826de2a386","component":"text","props":{"textContent":"{{ client_name || 'Client Name' }}"}}]},{"id":"preview-client-address","component":"div","className":"text-body-sm text-ink-soft whitespace-pre-line","children":[{"id":"6bf487117b","component":"text","props":{"textContent":"{{ client_address }}"}}]},{"id":"preview-client-email","component":"div","className":"text-body-sm text-ink-soft","children":[{"id":"27a87e2a93","component":"text","props":{"textContent":"{{ client_email }}"}}]}]},{"id":"preview-items-table","component":"div","className":"flex flex-col gap-xs pt-md border-t border-hairline","children":[{"id":"preview-items-header","component":"div","className":"grid grid-cols-[1fr_60px_90px_90px] gap-xs text-caption text-muted pb-xs border-b border-hairline","children":[{"id":"preview-header-description","component":"div","children":[{"id":"80e40dc6b4","component":"text","props":{"textContent":"Description"}}]},{"id":"preview-header-qty","component":"div","className":"text-right","children":[{"id":"0385abee26","component":"text","props":{"textContent":"Qty"}}]},{"id":"preview-header-price","component":"div","className":"text-right","children":[{"id":"4ebdbaaaab","component":"text","props":{"textContent":"Price"}}]},{"id":"preview-header-amount","component":"div","className":"text-right","children":[{"id":"609d152b31","component":"text","props":{"textContent":"Amount"}}]}]},{"id":"preview-item-row","component":"div","className":"grid grid-cols-[1fr_60px_90px_90px] gap-xs py-xs border-b border-hairline text-body-sm","loop":{"source":"items","item":"item"},"children":[{"id":"preview-item-description","component":"div","className":"text-ink","children":[{"id":"909bcf706e","component":"text","props":{"textContent":"{{ item.description || 'Item description' }}"}}]},{"id":"preview-item-qty","component":"div","className":"text-mono-sm text-ink-soft text-right","children":[{"id":"b98eb840cb","component":"text","props":{"textContent":"{{ item.quantity }}"}}]},{"id":"preview-item-price","component":"div","className":"text-mono-sm text-ink-soft text-right","children":[{"id":"5cf672efed","component":"text","props":{"textContent":"{{ formatCurrency(item.unit_price) }}"}}]},{"id":"preview-item-amount","component":"div","className":"text-mono-sm text-ink text-right","children":[{"id":"6d60106868","component":"text","props":{"textContent":"{{ formatCurrency(calcAmount(item)) }}"}}]}]}]},{"id":"preview-totals-block","component":"div","className":"flex flex-col gap-xs items-end pt-md","children":[{"id":"preview-subtotal-row","component":"div","className":"flex justify-between w-full max-w-[220px] text-body-sm text-ink-soft","children":[{"id":"preview-subtotal-label","component":"div","children":[{"id":"50ced408e3","component":"text","props":{"textContent":"Subtotal"}}]},{"id":"preview-subtotal-value","component":"div","className":"text-mono-sm text-ink","children":[{"id":"140de45e25","component":"text","props":{"textContent":"{{ formatCurrency(calcSubtotal()) }}"}}]}]},{"id":"preview-discount-row","component":"div","className":"flex justify-between w-full max-w-[220px] text-body-sm text-ink-soft","condition":"parseFloat(discount_value) > 0","children":[{"id":"preview-discount-label","component":"div","children":[{"id":"7f53ef42ec","component":"text","props":{"textContent":"Discount {{ discount_type === 'percentage' ? '(' + discount_value + '%)' : '' }}"}}]},{"id":"preview-discount-value","component":"div","className":"text-mono-sm text-ink","children":[{"id":"4039124605","component":"text","props":{"textContent":"- {{ formatCurrency(calcDiscountAmount()) }}"}}]}]},{"id":"preview-tax-row","component":"div","className":"flex justify-between w-full max-w-[220px] text-body-sm text-ink-soft","condition":"parseFloat(tax_percent) > 0","children":[{"id":"preview-tax-label","component":"div","children":[{"id":"679c161b46","component":"text","props":{"textContent":"Tax ({{ tax_percent }}%)"}}]},{"id":"preview-tax-value","component":"div","className":"text-mono-sm text-ink","children":[{"id":"9d484dac54","component":"text","props":{"textContent":"{{ formatCurrency(calcTaxAmount()) }}"}}]}]},{"id":"preview-total-row","component":"div","className":"flex justify-between w-full max-w-[220px] pt-xs border-t border-hairline text-title-sm text-ink","children":[{"id":"preview-total-label","component":"div","children":[{"id":"cf79ec9e31","component":"text","props":{"textContent":"Total"}}]},{"id":"preview-total-value","component":"div","className":"text-mono-lg text-primary","children":[{"id":"4d481842e7","component":"text","props":{"textContent":"{{ formatCurrency(calcTotal()) }}"}}]}]}]},{"id":"preview-notes-block","component":"div","className":"flex flex-col gap-xs pt-md border-t border-hairline","condition":"notes","children":[{"id":"preview-notes-label","component":"div","className":"text-caption text-muted","children":[{"id":"0024a19983","component":"text","props":{"textContent":"NOTES"}}]},{"id":"preview-notes-text","component":"div","className":"text-body-sm text-ink-soft whitespace-pre-line","children":[{"id":"ad09239c3e","component":"text","props":{"textContent":"{{ notes }}"}}]}]},{"id":"preview-payment-block","component":"div","className":"flex flex-col gap-xs","condition":"payment_instructions","children":[{"id":"preview-payment-label","component":"div","className":"text-caption text-muted","children":[{"id":"826338e2e5","component":"text","props":{"textContent":"PAYMENT INSTRUCTIONS"}}]},{"id":"preview-payment-text","component":"div","className":"text-body-sm text-ink-soft whitespace-pre-line","children":[{"id":"1c20cd18a6","component":"text","props":{"textContent":"{{ payment_instructions }}"}}]}]}]}]}]}]}}],"features":{"authentication":{"isEnabled":false,"pages":{}},"permission":{"isEnabled":true},"pdf":{"isEnabled":true,"templates":[{"name":"","contentPage":"","headerfooter":{"isDisplay":true,"headerTemplate":"","footerTemplate":"<div style=\"font-size: 10px; width: 100%; text-align: center; padding: 10px;\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>\""},"paper":{"size":"a4","landscape":"false","scale":1}}]},"chatbot":{"isEnabled":true,"ai":[{"componentId":"","assistantId":"","webhookVerifyToken":""}]},"oauth2":{"isEnabled":false},"stripePayment":{"isEnabled":true,"configurations":{"environments":"sandbox","defaultCurrency":"usd","accountCountry":"US","enabledScenarios":["one_time_custom","one_time_checkout","save_payment_method","subscriptions","refunds_disputes"],"allowedPaymentMethods":["card","google_pay","apple_pay","link","express_checkout"],"requireBillingAddress":false,"requireShippingAddress":false,"checkout":{"collectPhoneNumber":false,"allowPromotionCodes":false,"pageConfigs":{"requiredComponents":["stripe-elements","payment-form","order-summary"],"optionalComponents":["shipping-form","billing-form","promo-code"],"styling":{"theme":"light","primaryColor":"#0570de","borderRadius":"8px","fontSize":"16px"}}},"subscriptions":{"enableTrial":true,"defaultTrialDays":7,"allowMultipleSubscriptions":false,"prorateUpgrades":true,"sendInvoiceEmails":true,"pageConfigs":{"requiredComponents":["stripe-elements","payment-form","order-summary"],"optionalComponents":["shipping-form","billing-form","promo-code"],"styling":{"theme":"light","primaryColor":"#0570de","borderRadius":"8px","fontSize":"16px"}}},"security":{"savePaymentMethods":true},"business":{"statementDescriptor":"","receiptEmail":true,"enableRefunds":true,"refundPolicy":"full_refund_within_30_days"},"notifications":{"sendPaymentConfirmations":true,"sendInvoiceReminders":true,"sendFailedPaymentNotifications":true}}}},"accessibleApis":[],"favicon":{"s3Key":"app_a530eab6-3c78-4184-8916-d9b77f409997/favicon/favicon_1786700853894.zip","bucketName":"4dcff347-a082-4dd9e-0072-46d4e1c54a0a-resources-prod","uploadedAt":"2026-08-14T09:47:34.027Z","sourceFile":{"fileName":"favicon.ico","url":"https://4dcff347-a082-4dd9e-0072-46d4e1c54a0a-resources-prod.s3.ap-southeast-1.amazonaws.com/app_a530eab6-3c78-4184-8916-d9b77f409997/favicon/favicon.ico"},"faviconFiles":[{"fileName":"favicon.ico","url":"https://4dcff347-a082-4dd9e-0072-46d4e1c54a0a-resources-prod.s3.ap-southeast-1.amazonaws.com/app_a530eab6-3c78-4184-8916-d9b77f409997/favicon/favicon.ico"}]}}
