feat: estimates on the homepage, monthly booking on the freelance page

The homepage showed a price list per case, including a day rate. Buyers of
a result need a way to a price, not rates: each case now shows three steps
to an estimate, one line for orientation and a button that opens the
contact message with that topic chosen.

The developer case is booked by the month, not by the day. The day rate is
gone; the freelance page has the booking terms: 100 EUR per hour, fixed
days of the week agreed for one month at a time, an example month, monthly
invoice, two weeks notice to the end of a month.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 10:01:23 +02:00
co-authored by Claude Opus 5.5
parent 83616433e4
commit c7f8672cd0
8 changed files with 276 additions and 122 deletions
+51 -40
View File
@@ -77,7 +77,28 @@ export const en: Content = {
tablistLabel: "What do you need?",
youGet: "What you get",
howItRuns: "How it runs",
whatItCosts: "What it costs",
estimate: {
label: "What it costs",
title: "How you get to a price",
steps: [
{
title: "A call, about 20 minutes",
text: "You tell me what you need.",
},
{
title: "A written estimate",
text: "You see the estimated hours and what they include.",
},
{
title: "You approve a budget",
text: "I bill the hours actually used and tell you early if it will not be enough.",
},
],
orientationLabel: "For orientation",
net: "All prices net.",
cta: "Ask for an estimate",
freelance: "Booking and rates for teams",
},
paths: [
{
id: "developer",
@@ -111,16 +132,9 @@ export const en: Content = {
text: "The agreement can be ended with two weeks notice to the end of a month.",
},
],
pricingModel: "By effort, for as long as your project runs",
pricingText:
"I work on your project on agreed days of the week and bill the hours I actually worked. There is no package to buy and no minimum term.",
prices: [
{ label: "Per hour", amount: "100 EUR", note: "net" },
{ label: "Per day", amount: "800 EUR", note: "8 hours, net" },
],
smallPrint:
"One invoice per month, with the tracked hours. Either side can end it with two weeks notice to the end of a month.",
cta: GET_IN_TOUCH,
orientation: "100 EUR per hour, booked by the month",
orientationNote:
"You book fixed days of the week for one month at a time. I bill the hours I actually worked.",
},
{
id: "rescue",
@@ -154,15 +168,9 @@ export const en: Content = {
text: "With me, with your own team, or not at all.",
},
],
pricingModel: "A fixed week at a fixed price",
pricingText:
"The scope is one week of my time. You know the cost before I start.",
prices: [
{ label: "One week, 35 hours", amount: "3,500 EUR", note: "net" },
],
smallPrint:
"A week does not fix everything. If I see in the first call that it will not be enough to be useful, I tell you.",
cta: GET_IN_TOUCH,
orientation: "3,500 EUR for one fixed week",
orientationNote:
"The scope is one week of my time, 35 hours. A week does not fix everything: if I see in the first call that it will not be enough to be useful, I tell you.",
},
{
id: "automation",
@@ -198,13 +206,9 @@ export const en: Content = {
text: "You get a note on what it does and what to check when one of the tools changes.",
},
],
pricingModel: "An estimate first, then a budget",
pricingText:
"Once I have seen the process I estimate the hours. That estimate becomes the budget. I bill the hours I actually needed and tell you early if it will not be enough.",
prices: [{ label: "Per hour", amount: "100 EUR", note: "net" }],
smallPrint:
orientation: "100 EUR per hour, after an estimate",
orientationNote:
"How long it takes depends on the process, so there is no price before I have seen it. Fees for the tools themselves are paid by you.",
cta: GET_IN_TOUCH,
},
{
id: "website",
@@ -238,20 +242,9 @@ export const en: Content = {
text: "A new photo or a changed price: you send me an email.",
},
],
pricingModel: "An estimate first, then a budget",
pricingText:
"After the first call you get an estimate. It becomes your budget: I bill the hours actually used. The estimate usually holds, and if it will not, I tell you before the budget is used up.",
prices: [
{
label: "A typical company website",
amount: "from 3,800 EUR",
note: "one-off, net",
},
{ label: "Anything extra, per hour", amount: "100 EUR", note: "net" },
],
smallPrint:
"Hosting and small changes afterwards cost a monthly fee that we agree on before we start. I do not manage email inboxes; they stay with your provider.",
cta: GET_IN_TOUCH,
orientation: "From 3,800 EUR, one-off",
orientationNote:
"This is for a typical company website. Hosting and small changes afterwards cost a monthly fee that we agree on before we start.",
},
],
scenes: {
@@ -498,6 +491,24 @@ export const en: Content = {
intro:
"This page is for people who develop themselves or lead a team: which projects I am right for, what I work with, and how I secure changes before they go live.",
pipelineLabel: "Safeguards",
booking: {
label: "Booking",
title: { lead: "Booked by the month.", rest: "Not by the day." },
text: "I work on your project on fixed days of the week, agreed for one month at a time. There is no package to buy: you pay the hours I actually worked.",
rate: { label: "Per hour", amount: "100 EUR", note: "net" },
example: {
label: "Example: 2 days a week",
amount: "about 6,400 EUR",
note: "64 hours in four weeks, net",
},
terms: [
"Fixed days of the week, agreed for one month at a time",
"One invoice per month, with the tracked hours",
"Either side can end it with two weeks notice to the end of a month",
"I do not book single days",
],
cta: "Ask about availability",
},
teaser: {
title: "You develop yourself or lead a team?",
text: "Which projects I am right for, what I work with and how I secure changes is on a page of its own.",