feat: UI polish, a11y, performance optimizations

- Payment summary card with prominent amount display
- "Bezahlt" stamp over dimmed QR code with TX details below
- Hide wallet/address buttons when paid, show only PDF
- URI box removed (was technical noise)
- Smart countdown: "29 Tage, 23 Std." instead of ticking seconds
- Dynamic page title for shared invoices
- Font fallbacks with size-adjust to prevent layout shifts
- Async Google Fonts loading, proper preconnect hints
- Deferred script loading (defer attribute)
- Minified JS (app.min.js, i18n.min.js)
- WCAG contrast fixes for badges and disabled button
- Footer link always underlined for a11y
- Translated aria-labels via data-i18n-aria
- i18n onChange callback for dynamic content updates
- Result card fade-in animation, responsive QR on mobile
This commit is contained in:
Alexander Schmidt
2026-03-25 16:50:55 +01:00
parent b8f2e24a42
commit 8bcdb33fa3
6 changed files with 133 additions and 46 deletions

View File

@@ -1,3 +1,21 @@
@font-face {
font-family: 'Inter fallback';
src: local('Arial');
size-adjust: 107%;
ascent-override: 90%;
descent-override: 25%;
line-gap-override: 0%;
}
@font-face {
font-family: 'JetBrains Mono fallback';
src: local('Courier New');
size-adjust: 112%;
ascent-override: 78%;
descent-override: 22%;
line-gap-override: 0%;
}
:root {
--bg: #0d0d0d;
--bg-card: #1a1a1a;
@@ -10,8 +28,8 @@
--success: #4caf50;
--error: #f44336;
--radius: 8px;
--font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--mono: 'JetBrains Mono', 'Fira Code', monospace;
--font: 'Inter', 'Inter fallback', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--mono: 'JetBrains Mono', 'JetBrains Mono fallback', 'Fira Code', monospace;
}
* {
@@ -133,6 +151,7 @@ main {
width: 100%;
max-width: 480px;
padding: 1rem;
flex: 1;
}
.card {
@@ -247,7 +266,7 @@ input.valid {
background: var(--bg-input);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text-muted);
color: #aaa;
font-family: var(--font);
font-size: 0.8rem;
font-weight: 500;
@@ -301,7 +320,7 @@ textarea {
}
.btn-primary:disabled {
opacity: 0.4;
opacity: 0.5;
cursor: not-allowed;
}
@@ -532,24 +551,39 @@ textarea {
.payment-status.paid {
display: block;
text-align: center;
margin-top: 1rem;
}
.paid-badge {
display: inline-block;
background: var(--success);
color: #fff;
padding: 0.4rem 1.2rem;
border-radius: var(--radius);
font-weight: 700;
font-size: 1rem;
margin-bottom: 0.3rem;
.paid-stamp {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-12deg);
border: 4px solid var(--success);
border-radius: 12px;
padding: 0.4rem 1.5rem;
font-size: 1.8rem;
font-weight: 900;
color: var(--success);
background: rgba(0, 0, 0, 0.75);
text-transform: uppercase;
letter-spacing: 3px;
pointer-events: none;
z-index: 2;
}
.paid-detail {
.qr-container.paid canvas,
.qr-container.paid img {
opacity: 0.3;
}
.qr-container {
position: relative;
}
.paid-info {
color: var(--success);
font-size: 0.75rem;
color: var(--text-muted);
font-family: var(--mono);
}
.btn-new {
@@ -594,10 +628,6 @@ footer {
footer a {
color: var(--accent);
text-decoration: none;
}
footer a:hover {
text-decoration: underline;
}