01
Hand-written i18n instead of a library
For two languages and a fixed set of strings, a dependency like next-intl asked for more than it gave. lib/i18n.ts builds paths, lib/messages.ts holds the copy; the type check catches a missing key at build time.
Cost: Adding a language means duplicating every message file by hand.
02
Typed content file instead of MDX + zod
Cases live in lib/content.ts with a TypeScript type. They are validated at build time; nothing is parsed at runtime and every page is static.
Cost: Writing content requires an editor; there is no panel.
03
mailto instead of Server Action + Resend
The form sends nothing to a server: it fills the fields and opens the mail client. No API key, no personal data stored, nothing to declare under KVKK.
Cost: Conversion cannot be measured; I do not know which service gets picked.
04
overflow-x: hidden is forbidden
Overflow is measured, not hidden: scrollWidth is compared at 320, 390, 768 and 1440 px. If it overflows, the layout is fixed.
Cost: Four more measurements after every layout change.
05
No hex in components, only @theme tokens
Colour, radius and type live as tokens in app/globals.css. Components use token classes such as bg-bg and text-ink; a theme change touches one file.
Cost: Habits from Tailwind's default palette had to go.
06
Transparent PNG logo, not SVG
The source files were JPEG with no alpha channel. The background was cleared with a flood fill and a 32-bit PNG was produced. Vectorisation is still pending.
Cost: Extra weight on non-retina screens; SVG would scale freely.