Clear boundaries, incremental evolution
Request flow
Nginx serves public assets and forwards only index.php to PHP-FPM. Laravel applies locale, indexing policy, and analytics before invoking thin controllers. Repositories and services isolate content, media, documentation, and aggregations.
Main decisions
Server-side rendering as the baseline
Blade produces complete content without JavaScript. Asynchronous tabs, audio, and demos are progressive enhancements: a client-side failure does not remove essential content or navigation.
Structured data without duplication
Projects, skills, interests, and résumé data remain in the database. Narrative content is versioned, while references are resolved through allowed slugs.
Reversible operations
Uploads and data changes use transactions. Orphaned media enters quarantine with a manifest before deletion. Deployments and migrations include smoke tests and rollback paths.
Privacy and security by default
Analytics store aggregates rather than personal events. Admin routes use roles and policies; public documents use an allowlist and Markdown without raw HTML or unsafe links.
An example of the configuration enforced by the renderer:
new Environment([
'html_input' => 'strip',
'allow_unsafe_links' => false,
]);
See the Case studies for these choices in practice.