Options -MultiViews -Indexes
DirectoryIndex index.html

# ---------------------------------------------------------------------------
# Routing
# ---------------------------------------------------------------------------
RewriteEngine On

# Serve the prerendered pages produced by prerender.js.
# /de/technical is a directory, not a file, so the SPA fallback below would
# otherwise swallow it and ship the empty shell to crawlers.
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME}/index.html -f
RewriteRule ^(.+?)/?$ $1/index.html [L]

# SPA fallback, only for paths that are neither a file nor a directory.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html [QSA,L]

# ---------------------------------------------------------------------------
# Security headers
# ---------------------------------------------------------------------------
<IfModule mod_headers.c>
  # script-src keeps 'unsafe-inline' on purpose: Vite injects an inline
  # modulepreload polyfill, and index.html carries four inline JSON-LD blocks
  # that browsers also evaluate against script-src. Removing it silently breaks
  # both the app and the structured data.
  # style-src likewise: React sets inline style attributes (--reveal-delay).
  Header always set Content-Security-Policy "default-src 'self'; base-uri 'self'; font-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; connect-src 'self' https://api.sascha-bach.de; object-src 'none'; frame-ancestors 'none'; form-action 'self' mailto:; upgrade-insecure-requests"

  # No 'preload' yet - that directive is practically irreversible and should
  # only be added once every subdomain is permanently HTTPS.
  Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "DENY"
  Header always set Cross-Origin-Opener-Policy "same-origin"
  Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), browsing-topics=()"

  # Agent discovery documents (ported from the former vercel.json).
  Header always set Link "</llms.txt>; rel=\"alternate\"; type=\"text/markdown\", </llms-full.txt>; rel=\"alternate\"; type=\"text/markdown\", </AGENTS.md>; rel=\"alternate\"; type=\"text/markdown\", </.well-known/agents.json>; rel=\"agents\"; type=\"application/json\", </.well-known/agent-card.json>; rel=\"agent-card\"; type=\"application/json\", </.well-known/webmcp.json>; rel=\"service-desc\"; type=\"application/json\", </.well-known/mcp.json>; rel=\"service-desc\"; type=\"application/json\""
</IfModule>

# ---------------------------------------------------------------------------
# Keep dotfiles unreachable (.env, .git remnants, editor leftovers).
# This matches the final filename only, so /.well-known/agent-card.json stays
# reachable - its basename does not start with a dot.
# ---------------------------------------------------------------------------
<IfModule mod_authz_core.c>
  <FilesMatch "^\.">
    Require all denied
  </FilesMatch>
</IfModule>
