server {
    listen 80;
    listen [::]:80;
    server_name _;

    root /usr/share/nginx/html;
    # VitePress renders folder READMEs as `<folder>/README.html`, not
    # `index.html`. Adding both means a request for `/<folder>/` resolves
    # cleanly without an explicit index.md per folder.
    index index.html README.html;

    # VitePress emits clean URLs (cleanUrls: true). Resolution order for
    # any path:
    #   1. exact file        → /foo.html
    #   2. directory index   → /foo/index.html OR /foo/README.html
    #   3. with .html suffix → /foo.html
    #   4. README inside dir → /foo/README.html
    #   5. otherwise         → 404
    location / {
        try_files $uri $uri/ $uri.html $uri/README.html =404;
    }

    # Pre-rendered per-screen help fragments. The build emits one HTML
    # fragment per (locale, screen) at /<lang>/help/<slug>.html. The
    # in-app `<HelpButton />` drawer iframes these. CORS is permissive
    # for the public portal; tighten to the app origin once
    # `app.dentalpin.com` is known.
    location ~ ^/(?<helplang>en|es)/help/ {
        add_header Access-Control-Allow-Origin * always;
        add_header Access-Control-Allow-Methods "GET, OPTIONS" always;
        add_header Access-Control-Allow-Headers "*" always;
        # Frame embedding from the app origin.
        add_header X-Frame-Options "ALLOWALL" always;

        if ($request_method = OPTIONS) {
            add_header Access-Control-Allow-Origin * always;
            add_header Access-Control-Allow-Methods "GET, OPTIONS" always;
            add_header Access-Control-Allow-Headers "*" always;
            add_header Content-Length 0;
            add_header Content-Type text/plain;
            return 204;
        }

        # Fall back to the per-locale "not documented yet" fragment so
        # the drawer always shows something readable instead of nginx's
        # raw 404 page.
        try_files $uri $uri.html /$helplang/help/_not-found.html =404;
    }

    # Compression for text assets.
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types
        text/plain
        text/css
        text/javascript
        application/javascript
        application/json
        application/xml
        image/svg+xml;

    # Long cache for hashed asset bundles VitePress emits under /assets/.
    location ^~ /assets/ {
        expires 1y;
        add_header Cache-Control "public, immutable";
        try_files $uri =404;
    }

    # Hide nginx version in error pages and headers.
    server_tokens off;
}
