From 9a92d9651f3ebbfc262250d7491bcdd9b0fd40cd Mon Sep 17 00:00:00 2001 From: m Date: Thu, 2 Apr 2026 10:20:38 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20billableaua.de=20=E2=80=94=20add=20bill?= =?UTF-8?q?able=20hours=20calculator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Interactive calculator: enter annual hours target + vacation days, shows actual billable hours per working day after subtracting weekends, vacation, and public holidays. Makes the absurdity of 2400h targets visible. --- sites/billableaua.de/index.html | 135 ++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/sites/billableaua.de/index.html b/sites/billableaua.de/index.html index 0c50d53..6430cf7 100644 --- a/sites/billableaua.de/index.html +++ b/sites/billableaua.de/index.html @@ -157,6 +157,91 @@ font-weight: 300; } + /* Rechner */ + .rechner { + padding: 120px 0; + } + + .rechner h2 { + font-size: clamp(2.5rem, 7vw, 4rem); + font-weight: 900; + letter-spacing: -0.02em; + text-transform: uppercase; + margin-bottom: 48px; + } + + .rechner h2 .dot { color: var(--red); } + + .rechner-grid { + display: flex; + gap: 32px; + margin-bottom: 48px; + } + + .rechner-input { + flex: 1; + } + + .rechner-input label { + display: block; + font-size: 0.9rem; + color: var(--text-dim); + font-weight: 300; + letter-spacing: 0.08em; + text-transform: uppercase; + margin-bottom: 8px; + } + + .rechner-input input { + width: 100%; + background: transparent; + border: 1px solid var(--text-muted); + color: var(--text); + font-family: inherit; + font-size: 2.4rem; + font-weight: 700; + padding: 12px 16px; + text-align: center; + outline: none; + transition: border-color 0.3s; + -moz-appearance: textfield; + } + + .rechner-input input::-webkit-inner-spin-button, + .rechner-input input::-webkit-outer-spin-button { + -webkit-appearance: none; + } + + .rechner-input input:focus { + border-color: var(--red); + } + + .rechner-result { + font-size: clamp(1.3rem, 3vw, 1.8rem); + font-weight: 300; + color: var(--text-dim); + line-height: 2; + } + + .rechner-result .num { + color: var(--red); + font-weight: 700; + font-size: 1.15em; + } + + .rechner-result .verdict { + display: block; + margin-top: 24px; + font-size: clamp(1.5rem, 4vw, 2.2rem); + font-weight: 600; + color: var(--text); + } + + @media (max-width: 640px) { + .rechner { padding: 80px 0; } + .rechner-grid { flex-direction: column; gap: 24px; } + } + /* Silence */ .silence { padding: 160px 0; @@ -227,6 +312,25 @@
+
+
+

Rechne selbst.

+
+
+ + +
+
+ + +
+
+
+
+
+ +
+
@@ -277,6 +381,37 @@ }, { threshold: 0.15 }); document.querySelectorAll('.reveal').forEach(el => observer.observe(el)); + + // Rechner + function calculate() { + const hours = parseInt(document.getElementById('hours').value) || 0; + const vacation = parseInt(document.getElementById('vacation').value) || 0; + const weekends = 104; + const feiertage = 10; + const workingDays = 365 - weekends - vacation - feiertage; + const perDay = workingDays > 0 ? (hours / workingDays) : 0; + const perDayStr = perDay.toFixed(1).replace('.', ','); + + let verdict = ''; + if (perDay > 10) { + verdict = 'Das ist kein Job. Das ist ein Lifestyle.'; + } else if (perDay > 8) { + verdict = 'Jeden Tag über 8 Stunden billable. Ohne Mittagspause, ohne Admin, ohne Atmen.'; + } else if (perDay > 6) { + verdict = 'Klingt machbar? Vergiss nicht: billable ≠ Arbeitszeit.'; + } + + document.getElementById('result').innerHTML = + '' + workingDays + ' Arbeitstage ' + + '(365 − ' + weekends + ' Wochenenden − ' + vacation + ' Urlaub − ' + feiertage + ' Feiertage)
' + + '' + hours.toLocaleString('de-DE') + ' Stunden ÷ ' + workingDays + ' Tage = ' + + '' + perDayStr + ' Stunden pro Tag.' + + verdict; + } + + document.getElementById('hours').addEventListener('input', calculate); + document.getElementById('vacation').addEventListener('input', calculate); + calculate();