feat: billableaua.de — add billable hours calculator

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.
This commit is contained in:
m
2026-04-02 10:20:38 +02:00
parent 883904318e
commit 9a92d9651f

View File

@@ -157,6 +157,91 @@
font-weight: 300; 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 */
.silence { .silence {
padding: 160px 0; padding: 160px 0;
@@ -227,6 +312,25 @@
<div class="line"></div> <div class="line"></div>
<section class="rechner">
<div class="wrap">
<h2 class="reveal">Rechne selbst<span class="dot">.</span></h2>
<div class="rechner-grid reveal">
<div class="rechner-input">
<label>Billable-Stunden / Jahr</label>
<input type="number" id="hours" value="2400" min="0" max="5000">
</div>
<div class="rechner-input">
<label>Urlaubstage</label>
<input type="number" id="vacation" value="25" min="0" max="60">
</div>
</div>
<div class="rechner-result reveal" id="result"></div>
</div>
</section>
<div class="line"></div>
<section class="kritik"> <section class="kritik">
<div class="wrap"> <div class="wrap">
@@ -277,6 +381,37 @@
}, { threshold: 0.15 }); }, { threshold: 0.15 });
document.querySelectorAll('.reveal').forEach(el => observer.observe(el)); 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 = '<span class="verdict">Das ist kein Job. <span class="dim">Das ist ein Lifestyle.</span></span>';
} else if (perDay > 8) {
verdict = '<span class="verdict">Jeden Tag &uuml;ber <span class="num">8</span> Stunden billable. <span class="dim">Ohne Mittagspause, ohne Admin, ohne Atmen.</span></span>';
} else if (perDay > 6) {
verdict = '<span class="verdict">Klingt machbar? <span class="dim">Vergiss nicht: billable &ne; Arbeitszeit.</span></span>';
}
document.getElementById('result').innerHTML =
'<span class="num">' + workingDays + '</span> Arbeitstage ' +
'<span class="dim">(365 &minus; ' + weekends + ' Wochenenden &minus; ' + vacation + ' Urlaub &minus; ' + feiertage + ' Feiertage)</span><br>' +
'<span class="num">' + hours.toLocaleString('de-DE') + '</span> Stunden &divide; <span class="num">' + workingDays + '</span> Tage = ' +
'<span class="num">' + perDayStr + '</span> Stunden pro Tag.' +
verdict;
}
document.getElementById('hours').addEventListener('input', calculate);
document.getElementById('vacation').addEventListener('input', calculate);
calculate();
</script> </script>
</body> </body>