The documentation for nginx https://docs.gitea.io/en-us/reverse-proxies/ is very clear and whist it works perfectly for Nginx as a reverse proxy none of us can make it work for Nginx with a sub-path as a reverse proxy.
Much like https://github.com/go-gitea/gitea/issues/5425 the output of the site is mostly garbage and it appears that it is returning the same 4kB of html for / but also for every asset called from /.
As a side note the following form of config is superior when running within a docker environment as it does not require the container to be up when the reverse proxy starts and ultimately will allow the use of the gitea container without the need to expose the web UI to the host (the port listens on the docker network alone and the reverse proxy truely controls all web traffic).
location ^~ /gitea {
        include /config/nginx/proxy.conf;
        resolver 127.0.0.11 valid=30s;
        set $upstream_gitea gitea;
        proxy_pass http://$upstream_gitea:3000/;
}
To be clear this doesnt currently work but i have similar deployed for many (all) other projects.
I have run out of things to try and would very much appreciate if someone can confirm this actually works as documented or any other advice.
    location /git {
        client_max_body_size 100M;
        proxy_pass http://localhost:3000/;
    }
works for me.
What's your app.ini (suitably anonymised)?
I will reply ASAP with proper details but a follow on question based on your reply. Is binding to host i.e. localhost:3000 necessary. In the context of the docker container it is better to bind directly to the containerised IP and add the extra bridged port to the host machine.
Instead of location ^~ /gitea { could you try location /gitea { ?
Using the three suggestions so far (note I cannot use localhost as it it not relevant in docker where reverse proxy and gitea are both containers. however using the hostname gitea resolves correctly to the docker ip):
    location ~/gitea {
    client_max_body_size 100M;
           proxy_pass http://gitea:3000/;
    }
Causes an error
nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in /config/nginx/includes/gitea.subfolder.conf:13
The remaining two suggestions:
    location ^~ /gitea {
            client_max_body_size 100M;
            proxy_pass http://gitea:3000/;
    }
and
    location /gitea {
            client_max_body_size 100M;
            proxy_pass http://gitea:3000/;
    }
both produce the normal broken view

which is not surprising since as you can see every asset is identical in size i.e. / is being sent for every asset

Redacted config.
APP_NAME = Gitea: Git with a cup of tea
RUN_MODE = prod
RUN_USER = git
[repository]
ROOT = /data/git/repositories
FORCE_PRIVATE = true
[repository.local]
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
[repository.upload]
TEMP_PATH = /data/gitea/uploads
[server]
APP_DATA_PATH    = /data/gitea
SSH_DOMAIN       = example.com:222
HTTP_PORT        = 3000
ROOT_URL         = http://example.com/
DISABLE_SSH      = false
SSH_PORT         = 22
LFS_CONTENT_PATH = /data/git/lfs
DOMAIN           = example.com
LFS_START_SERVER = true
LFS_JWT_SECRET   = ****
OFFLINE_MODE     = false
[database]
PATH     = /data/gitea/gitea.db
DB_TYPE  = sqlite3
HOST     = localhost:3306
NAME     = gitea
USER     = root
PASSWD   =
SSL_MODE = disable
[indexer]
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
[session]
PROVIDER_CONFIG = /data/gitea/sessions
PROVIDER        = file
[picture]
AVATAR_UPLOAD_PATH      = /data/gitea/avatars
DISABLE_GRAVATAR        = false
ENABLE_FEDERATED_AVATAR = true
[attachment]
PATH = /data/gitea/attachments
[log]
ROOT_PATH = /data/gitea/log
MODE      = file
LEVEL     = Info
[security]
INSTALL_LOCK   = true
SECRET_KEY     = ***
INTERNAL_TOKEN = ***
[mailer]
ENABLED = false
[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = false
[oauth2]
JWT_SECRET = ***
                    You need to set ROOT_URL = http://example.com/gitea/
That was the magic bullet. I started with this config as it is in the docs but somewhere along the line (likely debugging it was lost).
For what it is worth none of the examples in this thread to date work. The good news is the the solution as documented works. I have no clue why I couldnt get it to work right away as the manual was the very first place I started but for clarity, both location and proxy_pass needs the closing /
location /gitea/ {
       client_max_body_size 100M;
       proxy_pass http://gitea:3000/;
}
I will leave this ticket open for a bit to try and pay back my shame with a working version of:
location /gitea/ {
       auth_basic "off";
       include /config/nginx/proxy.conf;
       resolver 127.0.0.11 valid=30s;
       set $upstream_gitea gitea;
       proxy_pass http://$upstream_gitea:3000/;
}
This form doesn't quite work as-is for me (probably the auth) but once it does it is superior as it ensures nginx can come up even if gitea is not available.
Working docker friendly nginx reverse proxy as promised. 
https://github.com/linuxserver/reverse-proxy-confs/blob/master/gitea.subfolder.conf.sample
Thanks for all the support.
Most helpful comment
You need to set
ROOT_URL = http://example.com/gitea/