{
	email {$ACME_EMAIL}
	http_port 8080
	https_port 8443
	# Admin API stays on container loopback; never publish port 2019.
	admin localhost:2019
	servers {
		protocols h1 h2
		max_header_size 16KB
		timeouts {
			read_header 10s
			read_body 30s
			idle 60s
		}
		# Empty for direct/DNS-only operation. Optional Cloudflare trust below.
		import /etc/caddy/cloudflare-trust.caddy
	}
}

(common) {
	encode gzip
	header {
		-X-Powered-By
		-Server
		X-Content-Type-Options nosniff
		Referrer-Policy strict-origin-when-cross-origin
		X-Frame-Options DENY
	}
	# No blanket CSP/HSTS preload: enable after testing each site's needs.
	# No access logging by default; runtime/error logs have Docker rotation.
}

{$AXIOM_DOMAIN} {
	import common
	route {
		# Research ingestion and provider-backed operations are not public learning endpoints.
		@privateAPI path /api /api/*
		header @privateAPI Cache-Control "no-store"
		respond @privateAPI "Forbidden" 403
		reverse_proxy axiom:8000 {
			# One value, overwritten rather than appended. With no trusted CDN,
			# client_ip is the actual peer, never visitor-supplied XFF.
			header_up X-Forwarded-For {client_ip}
			header_up -Forwarded
			transport http {
				dial_timeout 2s
				response_header_timeout 30s
				max_conns_per_host 32
			}
		}
	}
	# Node serves the public curriculum and server-rendered lesson pages.
}

{$PORTFOLIO_DOMAIN} {
	import common
	root * /srv/static/portfolio
	@dotfiles path_regexp hidden (^|/)\.
	respond @dotfiles 404
	file_server
}
www.{$PORTFOLIO_DOMAIN} {
	redir https://{$PORTFOLIO_DOMAIN}{uri} permanent
}

{$DOCS_DOMAIN} {
	import common
	root * /srv/static/docs
	@dotfiles path_regexp hidden (^|/)\.
	respond @dotfiles 404
	file_server
}
