Compare commits

..

9 commits

Author SHA1 Message Date
Claude
3ee874ccee
Replace kb-brand with app-wordmark: mark left of invoice text
Some checks are pending
/ mirror (push) Waiting to run
https://claude.ai/code/session_01MkM7p8Us3L8YAfLKGA13NS
2026-06-08 05:11:32 +00:00
Claude
2dde3450d9
Fix line amount top-alignment and PDF contact line wrapping
Remove align-self:center from line total span so it sits at the top of
the row. Use sp()+forEach in buildPDF to wrap sender and charge-to
contact lines within their column instead of overflowing.

https://claude.ai/code/session_01MkM7p8Us3L8YAfLKGA13NS
2026-06-08 04:46:10 +00:00
Claude
69e4ad9624
Port all development-branch features into kBenestad redesign
Some checks failed
/ mirror (push) Has been cancelled
- Bidirectional FX rate entry: rcur dropdown (e.g. "35 THB per USD" or
  "0.028 USD per THB") with rother label updating dynamically
- FX labels from config translations; currency code appended at runtime
- ct-pick persisted to localStorage; restoreStorage rebuilds client-
  specific project code options before re-applying saved pcode value
- Footer rebuilt by buildFooter() with dynamic About link
- About modal with markdown-rendered content from config.yml (marked.js)
- about section added to config.yml with EN/DE/FR/NO content
- rcur saved/restored in inv_lines_v1; gatherData includes rcur in fxNote
- relabel() calls updateFxLabels() for each active FX line on lang switch

https://claude.ai/code/session_01MkM7p8Us3L8YAfLKGA13NS
2026-06-08 04:35:08 +00:00
Claude
3ef2f9206c
Fix line item row vertical alignment: top-align cells, nudge remove button
https://claude.ai/code/session_01MkM7p8Us3L8YAfLKGA13NS
2026-06-08 04:27:06 +00:00
Claude
b06500512a
Restructure toolbar and header: lang dropdown left, app name in brand
Move language select to the left of the toolbar. Add lowercase "invoice"
app name next to the squircle logo in the brand section.

https://claude.ai/code/session_01MkM7p8Us3L8YAfLKGA13NS
2026-06-08 04:24:39 +00:00
Claude
195e61794d
Add favicons and web manifest
Copies the design-system favicon set into app/ and wires up SVG, PNG
(16/32/48), apple-touch-icon, web manifest, and theme-color meta tag.

https://claude.ai/code/session_01MkM7p8Us3L8YAfLKGA13NS
2026-06-08 04:19:40 +00:00
Claude
46b17cd154
Remove brand text from header — icon only
https://claude.ai/code/session_01MkM7p8Us3L8YAfLKGA13NS
2026-06-08 04:05:29 +00:00
Claude
fcd2f047e7
Add subtle invoice logo to header
Replaces the generic file-icon placeholder with the real invoice.svg squircle
(28px, 82% opacity, accent fill with white glyph). Strips the brand text to
12px muted "kBenestad" at 70% opacity. Tightens header vertical padding so
the whole bar recedes after a few uses — noticeable on first visit, invisible
by the third.

https://claude.ai/code/session_01MkM7p8Us3L8YAfLKGA13NS
2026-06-08 04:04:08 +00:00
Claude
f717a62e11
Redesign app surface to kBenestad design system
Replaces all custom CSS with the kBenestad token set (Schibsted Grotesk +
JetBrains Mono, Nordic-minimal palette, single #2F6FED accent). Converts
the navy-banner layout to kb-header/kb-card/kb-grid/kb-row structure from
kbenestad-forms.css. Adds auto + manual dark mode via data-theme. Switches
line-item and tax tables from <table> to CSS-grid .kb-row divs. Adds a
light/dark toggle button to the toolbar. All JS logic, IDs, localStorage
keys, and PDF output are unchanged.

https://claude.ai/code/session_01MkM7p8Us3L8YAfLKGA13NS
2026-06-08 03:59:15 +00:00
9 changed files with 926 additions and 490 deletions

BIN
app/apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -21,6 +21,58 @@ languages:
name: Norsk
direction: ltr
# ── About modal ───────────────────────────────────────────────────────────────
# Optional. Remove this section entirely to hide the About link in the footer.
about:
en:
title: "About"
content: |
### Invoice Generator
A single-file browser app for generating freelance invoices as PDF.
No backend, no build step — just a browser and a config file.
**Source:** [kbenestad/invoice](https://github.com/kbenestad/invoice)
**Docs:** [docs.benestad.net/invoice](https://docs.benestad.net/invoice)
&copy; 2026 Kristian Benestad. Licensed under the Apache 2 license.
btn-close: "Close"
de:
title: "Über"
content: |
### Rechnungsgenerator
Eine Single-File-Browser-App zur Erstellung von Freiberufler-Rechnungen als PDF.
Kein Backend, kein Build-Schritt.
**Quellcode:** [kbenestad/invoice](https://github.com/kbenestad/invoice)
**Dokumentation:** [docs.benestad.net/invoice](https://docs.benestad.net/invoice)
&copy; 2026 Kristian Benestad. Lizenziert unter Apache 2.
btn-close: "Schließen"
fr:
title: "À propos"
content: |
### Générateur de factures
Une application de navigateur en fichier unique pour générer des factures en PDF.
Aucun backend, aucune étape de build.
**Code source :** [kbenestad/invoice](https://github.com/kbenestad/invoice)
**Documentation :** [docs.benestad.net/invoice](https://docs.benestad.net/invoice)
&copy; 2026 Kristian Benestad. Sous licence Apache 2.
btn-close: "Fermer"
"no":
title: "Om"
content: |
### Fakturagenerator
En nettleserapp i én fil for å generere frilansfakturaer som PDF.
Ingen backend, ingen byggtrinn.
**Kildekode:** [kbenestad/invoice](https://github.com/kbenestad/invoice)
**Dokumentasjon:** [docs.benestad.net/invoice](https://docs.benestad.net/invoice)
&copy; 2026 Kristian Benestad. Lisensiert under Apache 2.
btn-close: "Lukk"
# ── Payment info visibility ───────────────────────────────────────────────────
# Set to true to hide the payment info panel entirely (useful if payment info
# should not appear on invoices, e.g. per company policy).
@ -355,25 +407,25 @@ translations:
fr: Devise étrangère
"no": Utenlandsk valuta
currency-code:
en: Currency code
de: Währungscode
fr: Code devise
"no": Valutakode
en: Foreign currency code
de: Fremdwährungscode
fr: Code devise étrangère
"no": Utenlandsk valutakode
exchange-rate:
en: "Exchange rate (X foreign = 1 local)"
de: "Wechselkurs (X Fremd = 1 Inland)"
fr: "Taux de change (X étranger = 1 local)"
"no": "Valutakurs (X utenlandsk = 1 lokal)"
en: Exchange rate
de: Wechselkurs
fr: Taux de change
"no": Valutakurs
per-item:
en: Price per item (foreign currency)
de: Preis je Einheit (Fremdwährung)
fr: Prix par unité (devise étrangère)
"no": Pris per enhet (utenlandsk valuta)
en: Price per item in
de: Preis je Einheit in
fr: Prix par unité en
"no": Pris per enhet i
total-foreign:
en: Line total in foreign currency
de: Zeilenbetrag (Fremdwährung)
fr: Total ligne en devise étrangère
"no": Linjebeløp i utenlandsk valuta
en: Line total in
de: Zeilenbetrag in
fr: Total ligne en
"no": Linjebeløp i
add-line:
en: "+ Add new line"
de: "+ Neue Zeile hinzufügen"

BIN
app/favicon-16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

BIN
app/favicon-32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

BIN
app/favicon-48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

8
app/favicon.svg Normal file
View file

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48" height="48" role="img" aria-label="invoice">
<rect width="48" height="48" rx="12" fill="#2f6fed"></rect>
<path d="M14 9 H29 L34 14 V39 H14 Z" fill="none" stroke="#fff" stroke-width="3" stroke-linejoin="round"></path>
<path d="M29 9 V14 H34" fill="none" stroke="#fff" stroke-width="3" stroke-linejoin="round"></path>
<path d="M18.5 20 H27" stroke="#fff" stroke-width="2.6" stroke-linecap="round"></path>
<path d="M18.5 25 H29.5" stroke="#fff" stroke-width="2.6" stroke-linecap="round" opacity=".55"></path>
<path d="M18.5 33 H29.5" stroke="#fff" stroke-width="3.2" stroke-linecap="round"></path>
</svg>

After

Width:  |  Height:  |  Size: 684 B

BIN
app/icon-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because it is too large Load diff

35
app/site.webmanifest Normal file
View file

@ -0,0 +1,35 @@
{
"name": "Invoice",
"short_name": "invoice",
"theme_color": "#2f6fed",
"background_color": "#2f6fed",
"display": "standalone",
"icons": [
{
"src": "icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "apple-touch-icon.png",
"sizes": "180x180",
"type": "image/png"
},
{
"src": "favicon-48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "favicon-32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "favicon-16.png",
"sizes": "16x16",
"type": "image/png"
}
]
}