diff --git a/content/en/docs/comparison/misskey.md b/content/en/docs/comparison/misskey.md
index fbb9d5d1bf1c3a40044db36cdda16d502335da51..33141527cb1e74b4e6bacf0c20ec58c623a8b3ba 100644
--- a/content/en/docs/comparison/misskey.md
+++ b/content/en/docs/comparison/misskey.md
@@ -17,6 +17,7 @@ toc: true
   Facebook, including attachments (threading may not work perfectly,
   and other people's replies to your posts may not get imported)
 * "following" view, inspired by Cohost's "following feed"
+* you can schedule a note to be published at some point in the future
 * admins can require approval for new users' signups
 * admins can silence users
 * admins can mark all of a user's media, or a whole remote instance,
@@ -33,6 +34,7 @@ toc: true
 ### Fun ones
 
 * can play module / tracker music files
+* can play Flash (swf)
 * (federated) listenbrainz integration
 * (federated) background image on user profiles
 * "speak as cat" separate from "is a cat" (both setting are federated
@@ -104,6 +106,8 @@ toc: true
 * CSS class names are human-readable, to simplify browser-side
   customisation
 * you can disable indexing of your notes (the setting is federated)
+* you can disable the RSS feed for your notes, and the "online status"
+  of your profile
 * "likes" and "reactions" federate correctly to Mastodon / Pleroma /
   Akkoma (Misskey sends them all as reactions)
 * different error icons
@@ -140,9 +144,9 @@ toc: true
   domains that won't trigger the confirmation dialog, or disable it
   completely)
 * note attachments are navigable via keyboard
-* user profiles show their latest notes by default, not their pinned
-  notes
 * you can see your pending outgoing follow requests
+* links to notes are rendered like quotes, since many people using
+  instances that don't support real quote-boosts use links that way
 
 ### Ones of interest to admins
 
@@ -192,7 +196,7 @@ toc: true
 * password checks and websocket connections are rate limited now; this
   improves security and resistance to denial-of-service attacks
 * in addition to "authorized fetch", you can disable
-  `attachLdSignatureForRelays to stop sending LD-Signatures to relays
+  `attachLdSignatureForRelays` to stop sending LD-Signatures to relays
 * more checks at startup: db reachability, config file presence
 * you can't accidentally delete your own instance's "system accounts"
 * information about remote instances includes following/followers
diff --git a/content/en/docs/customisation/roles.md b/content/en/docs/customisation/roles.md
new file mode 100644
index 0000000000000000000000000000000000000000..b364eea6bfba7a04a8fb39e887428dcb6eed29a5
--- /dev/null
+++ b/content/en/docs/customisation/roles.md
@@ -0,0 +1,28 @@
+---
+title: "Useful roles"
+weight: 3050
+toc: true
+---
+
+## Relax request rate limits for logged-in users
+
+Sharkey limits how often each API endpoint can be used by each user,
+to prevent denial-of-service attacks and excessive load on the server.
+
+Some users, especially if they use the deck UI with many lists /
+antennas / people they follow, may hit those limits during their
+normal use of Sharkey.
+
+You can relax the limits for these users, or for all your local users,
+by creating a role with a "rate limit" value *smaller* than 100%. For
+example, 50% will let the users who get that role call the API twice
+as often (yes, it feels backwards, sorry).
+
+## Reduce the space used by caching remote files
+
+If you are caching remote files, you may have noticed that they take a
+lot of space which always grows (until you manually purge the cache).
+
+A simple way to limit that growth is to create a role, applied to all
+remote users, with a smaller "drive capacity". 10MB or 20MB seems to
+work fine.
diff --git a/content/en/docs/customisation/themes.md b/content/en/docs/customisation/themes.md
index dd0a697220c4512da2ecb05ad00970693ee5da67..f8e83023ebfba3e95f217a1968dce892e9831fd2 100644
--- a/content/en/docs/customisation/themes.md
+++ b/content/en/docs/customisation/themes.md
@@ -78,10 +78,10 @@ darker).
 
 `panelBorder` is the only property that's not used directly as a
 colour. The default value is something like `" solid 1px
-var(--divider)`. The value starts with a double-quote to tell the
-theme engine "don't try parsing this as a colour" (notice that it
-*doesn't end* with another quote!). `var(--divider)` here is CSS
-syntax, with an effect pretty much the same as `@divider` in the
+var(--MI_THEME-divider)`. The value starts with a double-quote to tell
+the theme engine "don't try parsing this as a colour" (notice that it
+*doesn't end* with another quote!). `var(--MI_THEME-divider)` here is
+CSS syntax, with an effect pretty much the same as `@divider` in the
 colour specifications described above.
 
 #### Fonts
@@ -147,8 +147,8 @@ props: {
 ```
 
 The difference between `$foo` and `foo` is that the latter will be set
-as a CSS variable, so a user's custom CSS could refer to it, while the
-former won't escape the theme.
+as a CSS variable (called `--MI_THEME-foo`), so a user's custom CSS
+could refer to it, while the former won't escape the theme.
 
 #### Code syntax highlighting
 
diff --git a/content/en/docs/customisation/translate.md b/content/en/docs/customisation/translate.md
index fb115f1c07f41f6ebbcdd8534c4ea63f201a1ef4..59184bd75767ed3f10eca14f4bfbcc8e4b09e9ad 100644
--- a/content/en/docs/customisation/translate.md
+++ b/content/en/docs/customisation/translate.md
@@ -1,6 +1,6 @@
 ---
 title: "Translate"
-weight: 1100
+weight: 3150
 toc: true
 ---
 
diff --git a/content/en/docs/install/configuration.md b/content/en/docs/install/configuration.md
new file mode 100644
index 0000000000000000000000000000000000000000..87bc1c6a9cf76c5514f6c5a91e5132566720aedc
--- /dev/null
+++ b/content/en/docs/install/configuration.md
@@ -0,0 +1,36 @@
+---
+title: "Configuration options"
+weight: 1150
+---
+
+There are various ways to set configuration values for Sharkey.
+
+The simplest way is by editing the `.config/default.yml` file.
+
+You can also split the configuration across multiple files, setting
+the `MISSKEY_CONFIG_YML` environment variable to a shell-style glob
+pattern that matches them. For example, if you have
+`/home/sharkey/config/01-base.yml` and
+`/home/sharkey/config/02-details.yml`, you would set
+`MISSKEY_CONFIG_YML=/home/sharkey/config/*.yml`. All files matching
+the pattern will be loaded and merged together, ordered by their name.
+
+By setting environment variables, you can override any setting from
+the configuration file(s).  `MK_CONFIG_FOO_BAR` would override the
+setting `bar` inside section `foo`.
+
+Some examples:
+
+* `MK_CONFIG_DB_USER=the_user MK_CONFIG_DB_PASS=very_secure_password`
+* `MK_CONFIG_REDIS_HOST=myredis.mydomain`
+* `MK_CONFIG_MEILISEARCH_APIKEY=1234`
+
+The `dbSlaves` section is a bit more complicated: you need to create
+an empty element inside it in the configuration file, before you can
+do something like `MK_CONFIG_DBSLAVES_0_PASS=verysecret`.
+
+You can also store the values inside files instead of directly in the
+environment. For example, `MK_CONFIG_DB_PASS_FILE=/etc/secrets/dbpass`
+would set the main database password to the contents of the
+`/etc/secrets/dbpass` file. The values of these `MK_CONFIG_*_FILE`
+variables must be absolute paths.
diff --git a/content/en/docs/install/faqs.md b/content/en/docs/install/faqs.md
index 6c04f63d105047f29ff8d54407b832741d3d76a7..7eae6bbc1e1191bf5bffcbf86e2137d2b6bbbd8c 100644
--- a/content/en/docs/install/faqs.md
+++ b/content/en/docs/install/faqs.md
@@ -75,6 +75,25 @@ them. You can either tell your browser to trust Sharkey with access to
 the Canvas API, or go to the "Drive" section of your settings and
 enable "Keep original image" to bypass the compression.
 
+## Image/file upload still isn't working!
+
+If you are *not* using S3, you may need to change the ownership of the
+`files/` directory used by Sharkey on your server's filesystem.
+
+If you're using Docker, you can run:
+
+```bash
+docker compose exec --user=root web chown -R sharkey:sharkey /sharkey/files
+```
+
+Otherwise, you can run:
+
+```bash
+sudo chown -R 991:991 /home/sharkey/Sharkey/files/
+```
+
+(with the correct directory name for your server).
+
 ## I've enabled the notification dot, but it doesn't show!
 
 You should also see an error in the browser console complaining about
diff --git a/content/en/docs/install/fresh.md b/content/en/docs/install/fresh.md
index 92663a2cbaf008a6daa210542a036c66febb9504..a2480577a7ffa13ba69c3fd9e25bd0548eacfd37 100644
--- a/content/en/docs/install/fresh.md
+++ b/content/en/docs/install/fresh.md
@@ -19,7 +19,11 @@ Prerequisites:
 * Docker
 * Compose Plugin
 
-Create multiple directories:
+Refer to [Docker Engine's install
+page](https://docs.docker.com/engine/install/) to get Docker and
+Compose onto your machine.
+
+Create the directories you'll need:
 
 ```bash
 mkdir Sharkey && mkdir Sharkey/.config
@@ -44,17 +48,12 @@ url: https://{YOUR DOMAIN NAME}/
 (replace `{YOUR DOMAIN NAME}` with the domain name we talked about
 at the start).
 
-You can also set configuration options via environment variables:
-`MK_CONFIG_FOO_BAR` would override the setting `bar` inside section
-`foo` (so for example `MK_CONFIG_DB_PASS=foo`,
-`MK_CONFIG_REDIS_HOST=myredis.mydomain`,
-`MK_CONFIG_DBSLAVES_0_PASS=verysecret` (you still have to create at
-least an empty element inside the `dbSlaves` section for this to
-work), `MK_CONFIG_MEILISEARCH_APIKEY=1234`, &c &c). If you prefer
-having the values inside files instead of directly in the environment,
-you can set `MK_CONFIG_FOO_BAR_FILE` to an absolute path, and the
-contents of the file will be used as the value of the setting (so
-`MK_CONFIG_DB_PASS_FILE=/etc/secrets/dbpass` &c).
+You should also change the `setupPassword` value, so that your new
+instance will be protected between when you start it and when you
+create your first user.
+
+Refer to [the Configuration Options page](../configuration/) for all
+the various ways you can set configuration values.
 
 Edit `docker-compose.yml`, there are multiple comments there as
 well. If you want to set up note search with meilisearch, uncomment
@@ -62,23 +61,51 @@ all of meilisearch options, otherwise proceed to do the following
 changes in the `services:` / `web:` section:
 
 * uncomment the line that starts with `image:`
-* remove the line `build: .`
+* comment out the line that starts with `build: .`
+
+It should look like this:
+
+```yaml
+services:
+  web:
+    image: registry.activitypub.software/transfem-org/sharkey:latest
+    # build: .
+    …
+```
 
-Starting:
+Start the containers:
 
 ```bash
 docker compose up -d
 ```
 
+You can now open your instance's URL in your browser, to complete the
+setup.
+
+If you have problems uploading files to the drive, are *not* using S3,
+you may need to run either:
+
+```bash
+sudo chown -R 991:991 Sharkey/files/
+```
+
+or:
+
+```bash
+docker compose exec --user=root web chown -R sharkey:sharkey /sharkey/files
+```
+
+to fix the permissions on that directory.
+
 ## Manually
 
-[Same as
-Misskey](https://misskey-hub.net/en/docs/install/manual.html).
+These instructions are very similar to [Misskey's manual installation
+instructions](https://misskey-hub.net/en/docs/install/manual.html).
 
 Prerequisites:
 
-* more than 2GB of free RAM
-* Node.js version 20.10 or later, with *both* `npm` and `pnpm`
+* more than 2GB of free RAM, we recommend at least 4GB
+* Node.js version 22.11 or later, with *both* `npm` and `pnpm`
   installed (`corepack enable` should suffice, make sure you run it as
   `root` if you're using your system Node.js)
 * PostgreSQL version 15 or later
@@ -93,13 +120,14 @@ Create a `sharkey` user:
 adduser --disabled-password --disabled-login sharkey
 ```
 
-start a shell as that user:
+Start a shell as that user:
 
 ```bash
 sudo -u sharkey bash
 ```
 
-(or something like that), then:
+(or something like that), then clone the Sharkey repository, and copy
+the example configuration file:
 
 ```bash
 git clone --recurse-submodules -b stable https://activitypub.software/TransFem-org/Sharkey.git
@@ -125,26 +153,22 @@ db:
 this, and `{YOUR DOMAIN NAME}` with the domain name we talked about
 at the start)
 
-You can also set configuration options via environment variables:
-`MK_CONFIG_FOO_BAR` would override the setting `bar` inside section
-`foo` (so for example `MK_CONFIG_DB_PASS=foo`,
-`MK_CONFIG_REDIS_HOST=myredis.mydomain`,
-`MK_CONFIG_DBSLAVES_0_PASS=verysecret` (you still have to create at
-least an empty element inside the `dbSlaves` section for this to
-work), `MK_CONFIG_MEILISEARCH_APIKEY=1234`, &c &c). If you prefer
-having the values inside files instead of directly in the environment,
-you can set `MK_CONFIG_FOO_BAR_FILE` to an absolute path, and the
-contents of the file will be used as the value of the setting (so
-`MK_CONFIG_DB_PASS_FILE=/etc/secrets/dbpass` &c).
+You should also change the `setupPassword` value, so that your new
+instance will be protected between when you start it and when you
+create your first user.
+
+Refer to [the Configuration Options page](../configuration/) for all
+the various ways you can set configuration values.
 
-Building:
+Build Sharkey:
 
 ```bash
 pnpm run build
 ```
 
 Create the PostgreSQL user and database, either with `createuser`
-and `createdb` or with `sudo -u postgres psql` and then:
+and `createdb` or with `sudo -u postgres psql` and then running these
+commands inside `psql`:
 
 ```sql
 CREATE DATABASE sharkey WITH ENCODING = 'UTF8';
@@ -162,7 +186,7 @@ Then create the schema:
 pnpm run init
 ```
 
-And start it:
+And start Sharkey:
 
 ```bash
 pnpm start
@@ -218,6 +242,9 @@ sudo systemctl start sharkey
 After that, `systemctl status sharkey` should show that it's
 running.
 
+You can now open your instance's URL in your browser, to complete the
+setup.
+
 ### With OpenRC
 
 Create a file `/etc/init.d/sharkey` containing:
@@ -256,12 +283,17 @@ sudo rc-service sharkey start
 After that, `rc-service sharkey status` should show that it's
 running.
 
+You can now open your instance's URL in your browser, to complete the
+setup.
+
 ## Configure the web server
 
 ### NGINX
 
 See [Misskey's
-instructions](https://misskey-hub.net/en/docs/admin/nginx.html)
+instructions](https://misskey-hub.net/en/docs/for-admin/install/resources/nginx/)
+about configuring NGINX. They provide a good starting point that can
+be modified to fit your needs.
 
 ### HAProxy
 > Heads up - Sharkey doesn't officially support HAProxy, but you can still find community support for it within the discord.
@@ -371,7 +403,7 @@ docker compose exec --user=root web chown -R sharkey:sharkey /sharkey/files
 Very similar to the installation process:
 
 ```bash
-sudo -u sharkey -i
+sudo -u sharkey bash
 cd Sharkey
 git checkout stable
 git pull --recurse-submodules
@@ -387,6 +419,11 @@ If there's problems with updating, you can run `pnpm run clean`
 and/or `pnpm run clean-all` which will remove all the effects of a
 previous build, then you can install+build+migrate+restart again.
 
+**NOTE**: if you are upgrading from 2024.9.4 or earlier, Sharkey now
+needs Node.js 22.11, and you will almost certainly need to run `pnpm
+run clean-all` before `pnpm install`, otherwise you'll end up with
+some dependencies (e.g. `re2`) linked to the wrong libraries.
+
 ### Caching issues
 
 It's possible that the web server (or the CDN, if you've configured
@@ -397,7 +434,7 @@ therefore need to clear whatever cache you have.
 #### Clear NGINX cache
 
 You may clear NGINX's cache by manually deleting the cache directory
-(or all of the cached files within it).
+or all of the cached files within it.
 
 * First, we must locate the cache directory. This is a configured by
   the `proxy_cache_path` directive, which is found in the global
diff --git a/tools/get-new-changes b/tools/get-new-changes
index e8bab0dabba9b486a52dce20c7e5e1292ec1c5c8..280654364c93fea39d2771baa0c2c3ccb8912e91 100755
--- a/tools/get-new-changes
+++ b/tools/get-new-changes
@@ -22,7 +22,7 @@
 # script printed at the end, commit all the changes
 
 declare -A last_commit_checked=(
-  ["Sharkey"]=5cc2e8d4db4a20ad2cb254dc5fba0573b56f6436
+  ["Sharkey"]=d14f0b140bbc3174a5e187af36e25e5198125fd0
   ["sfm-js"]=eb43eb0298c04b3133e240cc235efce96213666f
 )