diff --git a/app/config.yml b/app/config.yml index f5e6598..0aff37b 100644 --- a/app/config.yml +++ b/app/config.yml @@ -389,11 +389,11 @@ translations: de: "Nein" fr: "Non" "no": "Nei" - print-invoice: - en: "Print / Save as PDF" - de: "Drucken / Als PDF speichern" - fr: "Imprimer / Enregistrer en PDF" - "no": "Skriv ut / Lagre som PDF" + download-pdf: + en: "Download PDF" + de: "PDF herunterladen" + fr: "Télécharger PDF" + "no": "Last ned PDF" close: en: Close de: Schließen diff --git a/app/index.html b/app/index.html index a25c389..c575f50 100644 --- a/app/index.html +++ b/app/index.html @@ -8,8 +8,6 @@ /* ── Variables ──────────────────────────────────────────────────────────── */ :root { --navy: #1e2d45; - --navy-mid: #2c4066; - --navy-light: #3b5491; --slate: #64748b; --border: #d1d5db; --border-light:#e5e7eb; @@ -21,7 +19,6 @@ --text-muted: #6b7280; --danger: #dc2626; --success: #15803d; - --warn: #92400e; --radius: 4px; } @@ -53,19 +50,10 @@ input:focus, select:focus { border-color: var(--accent); box-shadow: 0 0 0 2px #dbeafe; } input[type="number"] { text-align: right; } - button { - cursor: pointer; - border: none; - border-radius: var(--radius); - font-size: 13px; - } + button { cursor: pointer; border: none; border-radius: var(--radius); font-size: 13px; } /* ── Layout ─────────────────────────────────────────────────────────────── */ - .wrap { - max-width: 920px; - margin: 0 auto; - padding: 20px 16px 48px; - } + .wrap { max-width: 920px; margin: 0 auto; padding: 20px 16px 48px; } /* ── Language bar ───────────────────────────────────────────────────────── */ #lang-bar { @@ -90,12 +78,7 @@ border-radius: var(--radius); margin-bottom: 14px; } - #inv-banner h1 { - font-size: 26px; - font-weight: 800; - letter-spacing: 5px; - line-height: 1; - } + #inv-banner h1 { font-size: 26px; font-weight: 800; letter-spacing: 5px; line-height: 1; } /* ── Card ───────────────────────────────────────────────────────────────── */ .card { @@ -117,29 +100,13 @@ } /* ── Two-column grid ────────────────────────────────────────────────────── */ - .two-col { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 12px; - } + .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } @media (max-width: 640px) { .two-col { grid-template-columns: 1fr; } } /* ── Form groups ────────────────────────────────────────────────────────── */ .fg { margin-bottom: 8px; } - .fg label { - display: block; - font-size: 11px; - color: var(--text-muted); - font-weight: 500; - margin-bottom: 3px; - } - .fi { - display: grid; - grid-template-columns: 80px 1fr; - gap: 8px; - align-items: center; - margin-bottom: 8px; - } + .fg label { display: block; font-size: 11px; color: var(--text-muted); font-weight: 500; margin-bottom: 3px; } + .fi { display: grid; grid-template-columns: 80px 1fr; gap: 8px; align-items: center; margin-bottom: 8px; } .fi label { font-size: 12px; color: var(--text-muted); white-space: nowrap; } /* ── Line items table ───────────────────────────────────────────────────── */ @@ -156,86 +123,36 @@ .line-tbl thead th { background: #f8f9fb; padding: 7px 10px; - font-size: 10px; - font-weight: 700; - text-transform: uppercase; - letter-spacing: .5px; + font-size: 10px; font-weight: 700; + text-transform: uppercase; letter-spacing: .5px; color: var(--slate); border-bottom: 1px solid var(--border); text-align: left; } .line-tbl thead th.r { text-align: right; } - /* main line row */ - .line-tbl .lr td { - padding: 8px 10px; - border-bottom: 1px solid var(--border-light); - vertical-align: top; - } + .line-tbl .lr td { padding: 8px 10px; border-bottom: 1px solid var(--border-light); vertical-align: top; } .line-tbl .lr.open td { border-bottom: none; } - - /* foreign-currency sub-row */ - .line-tbl .fx td { - padding: 4px 10px 10px; - border-bottom: 1px solid var(--border-light); - background: #f9fafb; - } - - /* add-line row */ + .line-tbl .fx td { padding: 4px 10px 10px; border-bottom: 1px solid var(--border-light); background: #f9fafb; } .line-tbl .al td { padding: 10px; } - .col-qty { width: 72px; } - .col-uom { width: 100px; } - .col-desc { } - .col-price{ width: 110px; } - .col-tot { width: 110px; } - .col-act { width: 36px; } + .col-qty { width: 72px; } .col-uom { width: 100px; } + .col-price { width: 110px; } .col-tot { width: 110px; } .col-act { width: 36px; } - .line-total-val { - font-size: 13px; - font-weight: 600; - text-align: right; - padding-top: 6px; - } + .line-total-val { font-size: 13px; font-weight: 600; text-align: right; padding-top: 6px; } - .fx-grid { - display: grid; - grid-template-columns: 1fr 1fr 1fr; - gap: 8px; - margin-bottom: 6px; - } + .fx-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 6px; } .fx-label { font-size: 11px; color: var(--text-muted); margin-bottom: 3px; } .fx-note { font-size: 11px; color: var(--text-muted); } .fx-note strong { color: var(--text); } - .btn-remove { - background: none; - color: var(--danger); - font-size: 18px; - line-height: 1; - padding: 2px 5px; - border-radius: 3px; - } + .btn-remove { background: none; color: var(--danger); font-size: 18px; line-height: 1; padding: 2px 5px; border-radius: 3px; } .btn-remove:hover { background: #fef2f2; } - - .btn-add-line { - background: none; - color: var(--accent); - font-size: 13px; - font-weight: 500; - padding: 5px 10px; - border: 1px dashed var(--accent); - border-radius: var(--radius); - } + .btn-add-line { background: none; color: var(--accent); font-size: 13px; font-weight: 500; padding: 5px 10px; border: 1px dashed var(--accent); border-radius: var(--radius); } .btn-add-line:hover { background: #eff6ff; } /* ── Totals ─────────────────────────────────────────────────────────────── */ - #totals-card { - background: var(--white); - border: 1px solid var(--border); - border-radius: var(--radius); - margin-bottom: 14px; - } + #totals-card { background: var(--white); border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 14px; } .tot-tbl { width: 100%; border-collapse: collapse; } .tot-tbl td { padding: 8px 16px; } .tot-tbl tr:not(:last-child) td { border-bottom: 1px solid var(--border-light); } @@ -248,14 +165,10 @@ /* ── Generate button ────────────────────────────────────────────────────── */ #btn-generate { - display: block; - width: 100%; + display: block; width: 100%; padding: 14px; - background: var(--accent); - color: var(--white); - font-size: 15px; - font-weight: 700; - letter-spacing: 1px; + background: var(--accent); color: var(--white); + font-size: 15px; font-weight: 700; letter-spacing: 1px; border-radius: var(--radius); margin-bottom: 20px; transition: background .15s; @@ -265,8 +178,7 @@ /* ── Invoice overlay ────────────────────────────────────────────────────── */ #overlay { display: none; - position: fixed; - inset: 0; + position: fixed; inset: 0; background: rgba(15,23,42,.65); z-index: 900; overflow-y: auto; @@ -278,108 +190,65 @@ #overlay.on { display: flex; } #overlay-actions { - display: flex; - gap: 10px; + display: flex; gap: 10px; margin: 0 auto 16px; - width: 794px; - max-width: 100%; + width: 794px; max-width: 100%; } - .btn-print { - background: var(--success); - color: var(--white); - padding: 10px 20px; - font-size: 14px; - font-weight: 600; + .btn-dl { + background: var(--success); color: var(--white); + padding: 10px 20px; font-size: 14px; font-weight: 600; border-radius: var(--radius); } - .btn-print:hover { background: #166534; } + .btn-dl:hover { background: #166534; } .btn-close { - background: var(--white); - color: var(--text); - padding: 10px 20px; - font-size: 14px; - border: 1px solid var(--border); - border-radius: var(--radius); + background: var(--white); color: var(--text); + padding: 10px 20px; font-size: 14px; + border: 1px solid var(--border); border-radius: var(--radius); } .btn-close:hover { background: var(--bg); } - /* ── Invoice document (screen + print) ──────────────────────────────────── */ + /* ── Invoice preview (screen only) ──────────────────────────────────────── */ #inv-doc { background: var(--white); - width: 794px; - max-width: 100%; - min-height: 1100px; + width: 794px; max-width: 100%; min-height: 1100px; padding: 52px 60px 60px; box-shadow: 0 4px 24px rgba(0,0,0,.25); margin: 0 auto; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; - font-size: 11.5px; - color: #111827; + font-size: 11.5px; color: #111827; } - /* header strip */ .d-hdr { - display: flex; - justify-content: space-between; - align-items: flex-start; - padding-bottom: 20px; - margin-bottom: 24px; + display: flex; justify-content: space-between; align-items: flex-start; + padding-bottom: 20px; margin-bottom: 24px; border-bottom: 3px solid var(--navy); } - .d-sender .name { - font-size: 17px; - font-weight: 700; - color: var(--navy); - margin-bottom: 6px; - } + .d-sender .name { font-size: 17px; font-weight: 700; color: var(--navy); margin-bottom: 6px; } .d-sender p { font-size: 10.5px; color: #4b5563; margin-bottom: 2px; } .d-title { text-align: right; } - .d-title h1 { - font-size: 30px; - font-weight: 800; - letter-spacing: 5px; - color: var(--navy); - margin-bottom: 14px; - } + .d-title h1 { font-size: 30px; font-weight: 800; letter-spacing: 5px; color: var(--navy); margin-bottom: 14px; } .d-meta { border-collapse: collapse; margin-left: auto; } .d-meta td { font-size: 10.5px; padding: 2px 0 2px 12px; } .d-meta .ml { color: #6b7280; text-align: right; } .d-meta .mv { font-weight: 600; text-align: right; } - /* bill-to strip */ .d-bill { - padding: 12px 16px; - margin-bottom: 22px; + padding: 12px 16px; margin-bottom: 22px; background: #f8f9fa; border-left: 4px solid var(--navy); border-radius: 0 var(--radius) var(--radius) 0; } - .d-bill .bt-lbl { - font-size: 9px; - font-weight: 700; - text-transform: uppercase; - letter-spacing: 1.2px; - color: #6b7280; - margin-bottom: 5px; - } + .d-bill .bt-lbl { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 1.2px; color: #6b7280; margin-bottom: 5px; } .d-bill .bt-name { font-size: 13px; font-weight: 700; color: var(--navy); margin-bottom: 3px; } .d-bill p { font-size: 10.5px; color: #4b5563; margin-bottom: 2px; } .d-bill .bt-meta { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 6px; } .d-bill .bt-meta span { font-size: 10px; color: #4b5563; } .d-bill .bt-meta strong { color: #111827; } - /* line items */ .d-lines { width: 100%; border-collapse: collapse; margin-bottom: 20px; } - .d-lines thead tr { background: var(--navy); color: var(--white); } - .d-lines thead th { - padding: 7px 10px; - font-size: 9.5px; - font-weight: 700; - text-transform: uppercase; - letter-spacing: .5px; - text-align: left; - } + .d-lines thead tr { background: var(--navy); color: white; } + .d-lines thead th { padding: 7px 10px; font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; text-align: left; } .d-lines thead th.r { text-align: right; } .d-lines tbody tr { border-bottom: 1px solid #e5e7eb; } .d-lines tbody tr:nth-child(even) { background: #f9fafb; } @@ -388,40 +257,18 @@ .d-lines tbody td.b { font-weight: 600; } .d-fx-note { font-size: 9.5px; color: #6b7280; margin-top: 3px; } - /* totals */ .d-tots { width: 100%; border-collapse: collapse; } .d-tots td { padding: 5px 10px; font-size: 11.5px; } .d-tots .sp { width: 55%; } .d-tots .tl { text-align: right; color: #6b7280; padding-right: 20px; } .d-tots .tv { text-align: right; width: 130px; font-weight: 600; } .d-tots .sub td { border-top: 1px solid #e5e7eb; } - .d-tots .fin td { background: var(--navy); color: var(--white); font-size: 14px; font-weight: 700; border-top: 2px solid var(--navy); } + .d-tots .fin td { background: var(--navy); color: white; font-size: 14px; font-weight: 700; border-top: 2px solid var(--navy); } .d-tots .fin .tl { color: rgba(255,255,255,.75); } /* ── Error / loading ────────────────────────────────────────────────────── */ #loading { padding: 48px; text-align: center; color: var(--text-muted); font-size: 14px; } - .error-box { - background: #fef2f2; - border: 1px solid #fca5a5; - color: #991b1b; - padding: 16px 20px; - border-radius: var(--radius); - margin: 20px 0; - font-size: 13px; - } - - /* ── Print styles ───────────────────────────────────────────────────────── */ - @media print { - body > * { display: none !important; } - #overlay { display: block !important; background: none !important; padding: 0 !important; overflow: visible !important; } - #overlay-actions { display: none !important; } - #inv-doc { - box-shadow: none !important; - width: 100% !important; - padding: 0 !important; - min-height: 0 !important; - } - } + .error-box { background: #fef2f2; border: 1px solid #fca5a5; color: #991b1b; padding: 16px 20px; border-radius: var(--radius); margin: 20px 0; font-size: 13px; }
@@ -448,26 +295,29 @@