# Allo Aissa — server configuration.
#
# The site is fully static apart from /api/contact.php. Every rule here is
# either a URL that must resolve, a header the site would otherwise not send,
# or a cache lifetime.

Options -Indexes
DirectoryIndex index.html
AddDefaultCharset UTF-8

# ---- pretty URLs ----------------------------------------------------------
# The generator writes BOTH /page/index.html and /page.html, so these rules are
# a convenience rather than a dependency: if mod_rewrite is off, every internal
# link still resolves. That redundancy is deliberate.
<IfModule mod_rewrite.c>
  RewriteEngine On

  # Force one canonical origin. Two hostnames serving the same pages is the
  # cheapest duplicate-content mistake there is.
  RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
  RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]

  RewriteCond %{HTTPS} !=on
  RewriteCond %{HTTP:X-Forwarded-Proto} !https
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

  # /page -> /page/ , so the canonical spelling wins.
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{DOCUMENT_ROOT}/$1/index.html -f
  RewriteRule ^(.+?)/?$ /$1/ [R=301,L]
</IfModule>

ErrorDocument 404 /404.html

# ---- headers --------------------------------------------------------------
<IfModule mod_headers.c>
  Header always set X-Content-Type-Options "nosniff"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), interest-cohort=()"

  # Every font, style, script and image is served from this origin — the site
  # loads nothing from anywhere else — so the policy can be this tight. The only
  # outbound links are wa.me, Google Maps and the credit link, and links are not
  # covered by these directives.
  Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self'; script-src 'self'; font-src 'self'; form-action 'self'; frame-ancestors 'self'; base-uri 'self'; object-src 'none'"

  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</IfModule>

# ---- caching --------------------------------------------------------------
# Assets are requested with a content hash in the query string, so they can be
# cached hard. HTML never is: a price change has to be visible on the next load.
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType text/html                 "access plus 0 seconds"
  ExpiresByType text/css                  "access plus 1 year"
  ExpiresByType application/javascript    "access plus 1 year"
  ExpiresByType font/woff2                "access plus 1 year"
  ExpiresByType image/webp                "access plus 1 year"
  ExpiresByType image/avif                "access plus 1 year"
  ExpiresByType image/svg+xml             "access plus 1 year"
  ExpiresByType image/png                 "access plus 1 year"
</IfModule>

<IfModule mod_headers.c>
  <FilesMatch "\.(html)$">
    Header set Cache-Control "no-cache, must-revalidate"
  </FilesMatch>
</IfModule>

# ---- compression ----------------------------------------------------------
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml \
    application/javascript application/json application/xml image/svg+xml
</IfModule>

# woff2, webp and avif are already compressed; re-compressing them wastes CPU
# for no gain.
<IfModule mod_mime.c>
  AddType font/woff2 .woff2
  AddType image/avif .avif
  AddType image/webp .webp
  AddType text/plain .txt
</IfModule>

# ---- do not serve what is not content -------------------------------------
<FilesMatch "^(config\.local\.php|.*\.log|\.htaccess|DEPLOY\.txt|.*\.example)$">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
    Deny from all
  </IfModule>
</FilesMatch>
