about summary refs log tree commit diff
path: root/app/javascript
diff options
context:
space:
mode:
authorStarfall <us@starfall.systems>2023-01-17 11:41:05 -0600
committerStarfall <us@starfall.systems>2023-01-17 11:41:05 -0600
commit1f9c919b8769f5b0a3424ef343e0049d33d656e3 (patch)
tree1853486629da4b3b76192fe8756e8d4f6d71adcb /app/javascript
parent957c21273ff42d5b2b4a5e16b7869bbb09aeb865 (diff)
parent13227e1dafd308dfe1a3effc3379b766274809b3 (diff)
Merge remote-tracking branch 'glitch/main'
Diffstat (limited to 'app/javascript')
-rw-r--r--app/javascript/core/admin.js2
-rw-r--r--app/javascript/flavours/glitch/actions/announcements.js4
-rw-r--r--app/javascript/flavours/glitch/actions/dropdown_menu.js4
-rw-r--r--app/javascript/flavours/glitch/components/dropdown_menu.js102
-rw-r--r--app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js5
-rw-r--r--app/javascript/flavours/glitch/components/icon_button.js4
-rw-r--r--app/javascript/flavours/glitch/components/media_gallery.js2
-rw-r--r--app/javascript/flavours/glitch/components/status.js8
-rw-r--r--app/javascript/flavours/glitch/components/status_action_bar.js43
-rw-r--r--app/javascript/flavours/glitch/containers/dropdown_menu_container.js5
-rw-r--r--app/javascript/flavours/glitch/containers/mastodon.js5
-rw-r--r--app/javascript/flavours/glitch/containers/status_container.js9
-rw-r--r--app/javascript/flavours/glitch/extra_polyfills.js3
-rw-r--r--app/javascript/flavours/glitch/features/account/components/follow_request_note.js37
-rw-r--r--app/javascript/flavours/glitch/features/account/components/header.js21
-rw-r--r--app/javascript/flavours/glitch/features/account/containers/follow_request_note_container.js15
-rw-r--r--app/javascript/flavours/glitch/features/account_gallery/components/media_item.js1
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/compose_form.js2
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/dropdown.js47
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js46
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.js39
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/language_dropdown.js81
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/poll_form.js1
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/search.js88
-rw-r--r--app/javascript/flavours/glitch/features/compose/containers/options_container.js2
-rw-r--r--app/javascript/flavours/glitch/features/explore/index.js32
-rw-r--r--app/javascript/flavours/glitch/features/hashtag_timeline/index.js2
-rw-r--r--app/javascript/flavours/glitch/features/local_settings/navigation/index.js1
-rw-r--r--app/javascript/flavours/glitch/features/status/components/action_bar.js25
-rw-r--r--app/javascript/flavours/glitch/features/status/components/detailed_status.js9
-rw-r--r--app/javascript/flavours/glitch/features/status/index.js21
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/columns_area.js2
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js6
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/link_footer.js16
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/modal_root.js5
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/video_modal.js1
-rw-r--r--app/javascript/flavours/glitch/features/video/index.js5
-rw-r--r--app/javascript/flavours/glitch/load_polyfills.js5
-rw-r--r--app/javascript/flavours/glitch/locales/af.js7
-rw-r--r--app/javascript/flavours/glitch/locales/af.json1
-rw-r--r--app/javascript/flavours/glitch/locales/an.json1
-rw-r--r--app/javascript/flavours/glitch/locales/ar.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ar.json6
-rw-r--r--app/javascript/flavours/glitch/locales/ast.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ast.json6
-rw-r--r--app/javascript/flavours/glitch/locales/be.json1
-rw-r--r--app/javascript/flavours/glitch/locales/bg.js7
-rw-r--r--app/javascript/flavours/glitch/locales/bg.json6
-rw-r--r--app/javascript/flavours/glitch/locales/bn.js7
-rw-r--r--app/javascript/flavours/glitch/locales/bn.json6
-rw-r--r--app/javascript/flavours/glitch/locales/br.js7
-rw-r--r--app/javascript/flavours/glitch/locales/br.json6
-rw-r--r--app/javascript/flavours/glitch/locales/bs.json1
-rw-r--r--app/javascript/flavours/glitch/locales/ca.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ca.json6
-rw-r--r--app/javascript/flavours/glitch/locales/ckb.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ckb.json6
-rw-r--r--app/javascript/flavours/glitch/locales/co.js7
-rw-r--r--app/javascript/flavours/glitch/locales/co.json6
-rw-r--r--app/javascript/flavours/glitch/locales/cs.js180
-rw-r--r--app/javascript/flavours/glitch/locales/cs.json153
-rw-r--r--app/javascript/flavours/glitch/locales/cy.js7
-rw-r--r--app/javascript/flavours/glitch/locales/cy.json6
-rw-r--r--app/javascript/flavours/glitch/locales/da.js7
-rw-r--r--app/javascript/flavours/glitch/locales/da.json6
-rw-r--r--app/javascript/flavours/glitch/locales/de.js7
-rw-r--r--app/javascript/flavours/glitch/locales/de.json200
-rw-r--r--app/javascript/flavours/glitch/locales/defaultMessages.json1064
-rw-r--r--app/javascript/flavours/glitch/locales/el.js7
-rw-r--r--app/javascript/flavours/glitch/locales/el.json6
-rw-r--r--app/javascript/flavours/glitch/locales/en-GB.json1
-rw-r--r--app/javascript/flavours/glitch/locales/en.js67
-rw-r--r--app/javascript/flavours/glitch/locales/en.json200
-rw-r--r--app/javascript/flavours/glitch/locales/eo.js7
-rw-r--r--app/javascript/flavours/glitch/locales/eo.json52
-rw-r--r--app/javascript/flavours/glitch/locales/es-AR.js7
-rw-r--r--app/javascript/flavours/glitch/locales/es-AR.json95
-rw-r--r--app/javascript/flavours/glitch/locales/es-MX.js7
-rw-r--r--app/javascript/flavours/glitch/locales/es-MX.json95
-rw-r--r--app/javascript/flavours/glitch/locales/es.js119
-rw-r--r--app/javascript/flavours/glitch/locales/es.json95
-rw-r--r--app/javascript/flavours/glitch/locales/et.js7
-rw-r--r--app/javascript/flavours/glitch/locales/et.json6
-rw-r--r--app/javascript/flavours/glitch/locales/eu.js7
-rw-r--r--app/javascript/flavours/glitch/locales/eu.json6
-rw-r--r--app/javascript/flavours/glitch/locales/fa.js7
-rw-r--r--app/javascript/flavours/glitch/locales/fa.json6
-rw-r--r--app/javascript/flavours/glitch/locales/fi.js7
-rw-r--r--app/javascript/flavours/glitch/locales/fi.json6
-rw-r--r--app/javascript/flavours/glitch/locales/fo.json1
-rw-r--r--app/javascript/flavours/glitch/locales/fr-QC.json200
-rw-r--r--app/javascript/flavours/glitch/locales/fr.js7
-rw-r--r--app/javascript/flavours/glitch/locales/fr.json200
-rw-r--r--app/javascript/flavours/glitch/locales/fy.json1
-rw-r--r--app/javascript/flavours/glitch/locales/ga.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ga.json6
-rw-r--r--app/javascript/flavours/glitch/locales/gd.js7
-rw-r--r--app/javascript/flavours/glitch/locales/gd.json6
-rw-r--r--app/javascript/flavours/glitch/locales/gl.js7
-rw-r--r--app/javascript/flavours/glitch/locales/gl.json6
-rw-r--r--app/javascript/flavours/glitch/locales/he.js7
-rw-r--r--app/javascript/flavours/glitch/locales/he.json6
-rw-r--r--app/javascript/flavours/glitch/locales/hi.js7
-rw-r--r--app/javascript/flavours/glitch/locales/hi.json18
-rw-r--r--app/javascript/flavours/glitch/locales/hr.js7
-rw-r--r--app/javascript/flavours/glitch/locales/hr.json6
-rw-r--r--app/javascript/flavours/glitch/locales/hu.js7
-rw-r--r--app/javascript/flavours/glitch/locales/hu.json6
-rw-r--r--app/javascript/flavours/glitch/locales/hy.js7
-rw-r--r--app/javascript/flavours/glitch/locales/hy.json6
-rw-r--r--app/javascript/flavours/glitch/locales/id.js7
-rw-r--r--app/javascript/flavours/glitch/locales/id.json6
-rw-r--r--app/javascript/flavours/glitch/locales/ig.json1
-rw-r--r--app/javascript/flavours/glitch/locales/io.js7
-rw-r--r--app/javascript/flavours/glitch/locales/io.json6
-rw-r--r--app/javascript/flavours/glitch/locales/is.js7
-rw-r--r--app/javascript/flavours/glitch/locales/is.json6
-rw-r--r--app/javascript/flavours/glitch/locales/it.js7
-rw-r--r--app/javascript/flavours/glitch/locales/it.json6
-rw-r--r--app/javascript/flavours/glitch/locales/ja.js158
-rw-r--r--app/javascript/flavours/glitch/locales/ja.json124
-rw-r--r--app/javascript/flavours/glitch/locales/ka.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ka.json6
-rw-r--r--app/javascript/flavours/glitch/locales/kab.js7
-rw-r--r--app/javascript/flavours/glitch/locales/kab.json6
-rw-r--r--app/javascript/flavours/glitch/locales/kk.js7
-rw-r--r--app/javascript/flavours/glitch/locales/kk.json6
-rw-r--r--app/javascript/flavours/glitch/locales/kn.js7
-rw-r--r--app/javascript/flavours/glitch/locales/kn.json6
-rw-r--r--app/javascript/flavours/glitch/locales/ko.js208
-rw-r--r--app/javascript/flavours/glitch/locales/ko.json200
-rw-r--r--app/javascript/flavours/glitch/locales/ku.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ku.json6
-rw-r--r--app/javascript/flavours/glitch/locales/kw.js7
-rw-r--r--app/javascript/flavours/glitch/locales/kw.json6
-rw-r--r--app/javascript/flavours/glitch/locales/la.json1
-rw-r--r--app/javascript/flavours/glitch/locales/lt.js7
-rw-r--r--app/javascript/flavours/glitch/locales/lt.json6
-rw-r--r--app/javascript/flavours/glitch/locales/lv.js7
-rw-r--r--app/javascript/flavours/glitch/locales/lv.json6
-rw-r--r--app/javascript/flavours/glitch/locales/mk.js7
-rw-r--r--app/javascript/flavours/glitch/locales/mk.json6
-rw-r--r--app/javascript/flavours/glitch/locales/ml.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ml.json6
-rw-r--r--app/javascript/flavours/glitch/locales/mr.js7
-rw-r--r--app/javascript/flavours/glitch/locales/mr.json6
-rw-r--r--app/javascript/flavours/glitch/locales/ms.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ms.json6
-rw-r--r--app/javascript/flavours/glitch/locales/my.json1
-rw-r--r--app/javascript/flavours/glitch/locales/nl.js7
-rw-r--r--app/javascript/flavours/glitch/locales/nl.json6
-rw-r--r--app/javascript/flavours/glitch/locales/nn.js7
-rw-r--r--app/javascript/flavours/glitch/locales/nn.json6
-rw-r--r--app/javascript/flavours/glitch/locales/no.js7
-rw-r--r--app/javascript/flavours/glitch/locales/no.json6
-rw-r--r--app/javascript/flavours/glitch/locales/oc.js7
-rw-r--r--app/javascript/flavours/glitch/locales/oc.json6
-rw-r--r--app/javascript/flavours/glitch/locales/pa.js7
-rw-r--r--app/javascript/flavours/glitch/locales/pa.json6
-rw-r--r--app/javascript/flavours/glitch/locales/pl.js79
-rw-r--r--app/javascript/flavours/glitch/locales/pl.json55
-rw-r--r--app/javascript/flavours/glitch/locales/pt-BR.js7
-rw-r--r--app/javascript/flavours/glitch/locales/pt-BR.json200
-rw-r--r--app/javascript/flavours/glitch/locales/pt-PT.js7
-rw-r--r--app/javascript/flavours/glitch/locales/pt-PT.json6
-rw-r--r--app/javascript/flavours/glitch/locales/ro.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ro.json6
-rw-r--r--app/javascript/flavours/glitch/locales/ru.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ru.json6
-rw-r--r--app/javascript/flavours/glitch/locales/sa.js7
-rw-r--r--app/javascript/flavours/glitch/locales/sa.json6
-rw-r--r--app/javascript/flavours/glitch/locales/sc.js7
-rw-r--r--app/javascript/flavours/glitch/locales/sc.json6
-rw-r--r--app/javascript/flavours/glitch/locales/sco.json1
-rw-r--r--app/javascript/flavours/glitch/locales/si.js7
-rw-r--r--app/javascript/flavours/glitch/locales/si.json6
-rw-r--r--app/javascript/flavours/glitch/locales/sk.js7
-rw-r--r--app/javascript/flavours/glitch/locales/sk.json6
-rw-r--r--app/javascript/flavours/glitch/locales/sl.js7
-rw-r--r--app/javascript/flavours/glitch/locales/sl.json6
-rw-r--r--app/javascript/flavours/glitch/locales/sq.js7
-rw-r--r--app/javascript/flavours/glitch/locales/sq.json6
-rw-r--r--app/javascript/flavours/glitch/locales/sr-Latn.js7
-rw-r--r--app/javascript/flavours/glitch/locales/sr-Latn.json6
-rw-r--r--app/javascript/flavours/glitch/locales/sr.js7
-rw-r--r--app/javascript/flavours/glitch/locales/sr.json6
-rw-r--r--app/javascript/flavours/glitch/locales/sv.js7
-rw-r--r--app/javascript/flavours/glitch/locales/sv.json6
-rw-r--r--app/javascript/flavours/glitch/locales/szl.js7
-rw-r--r--app/javascript/flavours/glitch/locales/szl.json201
-rw-r--r--app/javascript/flavours/glitch/locales/ta.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ta.json6
-rw-r--r--app/javascript/flavours/glitch/locales/tai.js7
-rw-r--r--app/javascript/flavours/glitch/locales/tai.json201
-rw-r--r--app/javascript/flavours/glitch/locales/te.js7
-rw-r--r--app/javascript/flavours/glitch/locales/te.json6
-rw-r--r--app/javascript/flavours/glitch/locales/th.js7
-rw-r--r--app/javascript/flavours/glitch/locales/th.json6
-rw-r--r--app/javascript/flavours/glitch/locales/tr.js7
-rw-r--r--app/javascript/flavours/glitch/locales/tr.json6
-rw-r--r--app/javascript/flavours/glitch/locales/tt.js7
-rw-r--r--app/javascript/flavours/glitch/locales/tt.json6
-rw-r--r--app/javascript/flavours/glitch/locales/ug.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ug.json6
-rw-r--r--app/javascript/flavours/glitch/locales/uk.js7
-rw-r--r--app/javascript/flavours/glitch/locales/uk.json48
-rw-r--r--app/javascript/flavours/glitch/locales/ur.js7
-rw-r--r--app/javascript/flavours/glitch/locales/ur.json6
-rw-r--r--app/javascript/flavours/glitch/locales/vi.js7
-rw-r--r--app/javascript/flavours/glitch/locales/vi.json6
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_af.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ar.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ast.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_bg.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_bn.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_br.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ca.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ckb.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_co.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_cs.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_cy.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_da.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_de.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_el.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_en.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_eo.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_es-AR.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_es-MX.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_es.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_et.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_eu.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_fa.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_fi.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_fr.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ga.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_gd.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_gl.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_he.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_hi.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_hr.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_hu.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_hy.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_id.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_io.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_is.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_it.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ja.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ka.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_kab.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_kk.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_kn.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ko.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ku.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_kw.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_lt.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_lv.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_mk.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ml.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_mr.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ms.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_nl.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_nn.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_no.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_oc.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_pa.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_pl.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_pt-BR.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_pt-PT.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ro.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ru.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_sa.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_sc.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_si.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_sk.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_sl.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_sq.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_sr-Latn.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_sr.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_sv.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_szl.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ta.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_tai.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_te.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_th.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_tr.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_tt.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ug.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_uk.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_ur.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_vi.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_zgh.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_zh-CN.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_zh-HK.json2
-rw-r--r--app/javascript/flavours/glitch/locales/whitelist_zh-TW.json2
-rw-r--r--app/javascript/flavours/glitch/locales/zgh.js7
-rw-r--r--app/javascript/flavours/glitch/locales/zgh.json201
-rw-r--r--app/javascript/flavours/glitch/locales/zh-CN.js201
-rw-r--r--app/javascript/flavours/glitch/locales/zh-CN.json176
-rw-r--r--app/javascript/flavours/glitch/locales/zh-HK.js7
-rw-r--r--app/javascript/flavours/glitch/locales/zh-HK.json6
-rw-r--r--app/javascript/flavours/glitch/locales/zh-TW.js7
-rw-r--r--app/javascript/flavours/glitch/locales/zh-TW.json6
-rw-r--r--app/javascript/flavours/glitch/packs/public.js38
-rw-r--r--app/javascript/flavours/glitch/permissions.js7
-rw-r--r--app/javascript/flavours/glitch/reducers/compose.js6
-rw-r--r--app/javascript/flavours/glitch/reducers/dropdown_menu.js4
-rw-r--r--app/javascript/flavours/glitch/reducers/relationships.js11
-rw-r--r--app/javascript/flavours/glitch/selectors/index.js12
-rw-r--r--app/javascript/flavours/glitch/styles/admin.scss15
-rw-r--r--app/javascript/flavours/glitch/styles/components/accounts.scss40
-rw-r--r--app/javascript/flavours/glitch/styles/components/compose_form.scss2
-rw-r--r--app/javascript/flavours/glitch/styles/components/emoji.scss2
-rw-r--r--app/javascript/flavours/glitch/styles/components/index.scss109
-rw-r--r--app/javascript/flavours/glitch/styles/components/modal.scss1
-rw-r--r--app/javascript/flavours/glitch/styles/components/search.scss1
-rw-r--r--app/javascript/flavours/glitch/styles/components/single_column.scss5
-rw-r--r--app/javascript/flavours/glitch/styles/components/status.scss7
-rw-r--r--app/javascript/flavours/glitch/styles/mastodon-light/diff.scss18
-rw-r--r--app/javascript/flavours/glitch/styles/modal.scss2
-rw-r--r--app/javascript/flavours/glitch/styles/polls.scss4
-rw-r--r--app/javascript/flavours/glitch/theme.yml13
-rw-r--r--app/javascript/flavours/vanilla/theme.yml8
-rw-r--r--app/javascript/images/logo-symbol-icon.svg2
-rw-r--r--app/javascript/images/logo-symbol-wordmark.svg2
-rw-r--r--app/javascript/mastodon/actions/account_notes.js8
-rw-r--r--app/javascript/mastodon/actions/accounts.js144
-rw-r--r--app/javascript/mastodon/actions/alerts.js6
-rw-r--r--app/javascript/mastodon/actions/announcements.js4
-rw-r--r--app/javascript/mastodon/actions/blocks.js16
-rw-r--r--app/javascript/mastodon/actions/bookmarks.js16
-rw-r--r--app/javascript/mastodon/actions/columns.js6
-rw-r--r--app/javascript/mastodon/actions/compose.js88
-rw-r--r--app/javascript/mastodon/actions/custom_emojis.js8
-rw-r--r--app/javascript/mastodon/actions/domain_blocks.js32
-rw-r--r--app/javascript/mastodon/actions/dropdown_menu.js4
-rw-r--r--app/javascript/mastodon/actions/emojis.js2
-rw-r--r--app/javascript/mastodon/actions/favourites.js16
-rw-r--r--app/javascript/mastodon/actions/height_cache.js4
-rw-r--r--app/javascript/mastodon/actions/interactions.js80
-rw-r--r--app/javascript/mastodon/actions/markers.js10
-rw-r--r--app/javascript/mastodon/actions/modal.js4
-rw-r--r--app/javascript/mastodon/actions/mutes.js16
-rw-r--r--app/javascript/mastodon/actions/notifications.js18
-rw-r--r--app/javascript/mastodon/actions/pin_statuses.js8
-rw-r--r--app/javascript/mastodon/actions/search.js12
-rw-r--r--app/javascript/mastodon/actions/settings.js4
-rw-r--r--app/javascript/mastodon/actions/statuses.js48
-rw-r--r--app/javascript/mastodon/actions/store.js2
-rw-r--r--app/javascript/mastodon/actions/suggestions.js8
-rw-r--r--app/javascript/mastodon/actions/timelines.js18
-rw-r--r--app/javascript/mastodon/common.js2
-rw-r--r--app/javascript/mastodon/compare_id.js2
-rw-r--r--app/javascript/mastodon/components/admin/Retention.js2
-rw-r--r--app/javascript/mastodon/components/dropdown_menu.js102
-rw-r--r--app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js5
-rw-r--r--app/javascript/mastodon/components/icon_button.js4
-rw-r--r--app/javascript/mastodon/components/media_gallery.js2
-rw-r--r--app/javascript/mastodon/components/status_action_bar.js34
-rw-r--r--app/javascript/mastodon/containers/dropdown_menu_container.js5
-rw-r--r--app/javascript/mastodon/containers/mastodon.js4
-rw-r--r--app/javascript/mastodon/extra_polyfills.js3
-rw-r--r--app/javascript/mastodon/features/account/components/follow_request_note.js37
-rw-r--r--app/javascript/mastodon/features/account/components/header.js21
-rw-r--r--app/javascript/mastodon/features/account/containers/follow_request_note_container.js15
-rw-r--r--app/javascript/mastodon/features/account_gallery/components/media_item.js1
-rw-r--r--app/javascript/mastodon/features/closed_registrations_modal/index.js2
-rw-r--r--app/javascript/mastodon/features/compose/components/compose_form.js15
-rw-r--r--app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js39
-rw-r--r--app/javascript/mastodon/features/compose/components/language_dropdown.js81
-rw-r--r--app/javascript/mastodon/features/compose/components/poll_form.js1
-rw-r--r--app/javascript/mastodon/features/compose/components/privacy_dropdown.js85
-rw-r--r--app/javascript/mastodon/features/compose/components/search.js78
-rw-r--r--app/javascript/mastodon/features/compose/containers/compose_form_container.js1
-rw-r--r--app/javascript/mastodon/features/compose/index.js3
-rw-r--r--app/javascript/mastodon/features/compose/util/counter.js2
-rw-r--r--app/javascript/mastodon/features/explore/index.js32
-rw-r--r--app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js4
-rw-r--r--app/javascript/mastodon/features/hashtag_timeline/index.js2
-rw-r--r--app/javascript/mastodon/features/list_timeline/index.js2
-rw-r--r--app/javascript/mastodon/features/status/components/action_bar.js15
-rw-r--r--app/javascript/mastodon/features/ui/components/columns_area.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/disabled_account_banner.js2
-rw-r--r--app/javascript/mastodon/features/ui/components/focal_point_modal.js6
-rw-r--r--app/javascript/mastodon/features/ui/components/link_footer.js18
-rw-r--r--app/javascript/mastodon/features/ui/components/video_modal.js1
-rw-r--r--app/javascript/mastodon/features/ui/util/react_router_helpers.js2
-rw-r--r--app/javascript/mastodon/features/video/index.js5
-rw-r--r--app/javascript/mastodon/load_polyfills.js5
-rw-r--r--app/javascript/mastodon/locales/af.json10
-rw-r--r--app/javascript/mastodon/locales/an.json10
-rw-r--r--app/javascript/mastodon/locales/ar.json10
-rw-r--r--app/javascript/mastodon/locales/ast.json18
-rw-r--r--app/javascript/mastodon/locales/be.json8
-rw-r--r--app/javascript/mastodon/locales/bg.json204
-rw-r--r--app/javascript/mastodon/locales/bn.json18
-rw-r--r--app/javascript/mastodon/locales/br.json10
-rw-r--r--app/javascript/mastodon/locales/bs.json8
-rw-r--r--app/javascript/mastodon/locales/ca.json144
-rw-r--r--app/javascript/mastodon/locales/ckb.json144
-rw-r--r--app/javascript/mastodon/locales/co.json10
-rw-r--r--app/javascript/mastodon/locales/cs.json8
-rw-r--r--app/javascript/mastodon/locales/cy.json10
-rw-r--r--app/javascript/mastodon/locales/da.json8
-rw-r--r--app/javascript/mastodon/locales/de.json40
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json57
-rw-r--r--app/javascript/mastodon/locales/el.json12
-rw-r--r--app/javascript/mastodon/locales/en-GB.json12
-rw-r--r--app/javascript/mastodon/locales/en.json16
-rw-r--r--app/javascript/mastodon/locales/eo.json40
-rw-r--r--app/javascript/mastodon/locales/es-AR.json6
-rw-r--r--app/javascript/mastodon/locales/es-MX.json8
-rw-r--r--app/javascript/mastodon/locales/es.json10
-rw-r--r--app/javascript/mastodon/locales/et.json304
-rw-r--r--app/javascript/mastodon/locales/eu.json10
-rw-r--r--app/javascript/mastodon/locales/fa.json10
-rw-r--r--app/javascript/mastodon/locales/fi.json78
-rw-r--r--app/javascript/mastodon/locales/fo.json14
-rw-r--r--app/javascript/mastodon/locales/fr-QC.json10
-rw-r--r--app/javascript/mastodon/locales/fr.json18
-rw-r--r--app/javascript/mastodon/locales/fy.json426
-rw-r--r--app/javascript/mastodon/locales/ga.json30
-rw-r--r--app/javascript/mastodon/locales/gd.json10
-rw-r--r--app/javascript/mastodon/locales/gl.json8
-rw-r--r--app/javascript/mastodon/locales/he.json22
-rw-r--r--app/javascript/mastodon/locales/hi.json46
-rw-r--r--app/javascript/mastodon/locales/hr.json160
-rw-r--r--app/javascript/mastodon/locales/hu.json8
-rw-r--r--app/javascript/mastodon/locales/hy.json10
-rw-r--r--app/javascript/mastodon/locales/id.json10
-rw-r--r--app/javascript/mastodon/locales/ig.json8
-rw-r--r--app/javascript/mastodon/locales/io.json10
-rw-r--r--app/javascript/mastodon/locales/is.json12
-rw-r--r--app/javascript/mastodon/locales/it.json16
-rw-r--r--app/javascript/mastodon/locales/ja.json12
-rw-r--r--app/javascript/mastodon/locales/ka.json10
-rw-r--r--app/javascript/mastodon/locales/kab.json10
-rw-r--r--app/javascript/mastodon/locales/kk.json10
-rw-r--r--app/javascript/mastodon/locales/kn.json20
-rw-r--r--app/javascript/mastodon/locales/ko.json14
-rw-r--r--app/javascript/mastodon/locales/ku.json22
-rw-r--r--app/javascript/mastodon/locales/kw.json10
-rw-r--r--app/javascript/mastodon/locales/la.json655
-rw-r--r--app/javascript/mastodon/locales/lt.json10
-rw-r--r--app/javascript/mastodon/locales/lv.json94
-rw-r--r--app/javascript/mastodon/locales/mk.json10
-rw-r--r--app/javascript/mastodon/locales/ml.json10
-rw-r--r--app/javascript/mastodon/locales/mr.json234
-rw-r--r--app/javascript/mastodon/locales/ms.json10
-rw-r--r--app/javascript/mastodon/locales/my.json8
-rw-r--r--app/javascript/mastodon/locales/nl.json22
-rw-r--r--app/javascript/mastodon/locales/nn.json26
-rw-r--r--app/javascript/mastodon/locales/no.json42
-rw-r--r--app/javascript/mastodon/locales/oc.json32
-rw-r--r--app/javascript/mastodon/locales/pa.json10
-rw-r--r--app/javascript/mastodon/locales/pl.json30
-rw-r--r--app/javascript/mastodon/locales/pt-BR.json12
-rw-r--r--app/javascript/mastodon/locales/pt-PT.json238
-rw-r--r--app/javascript/mastodon/locales/ro.json10
-rw-r--r--app/javascript/mastodon/locales/ru.json8
-rw-r--r--app/javascript/mastodon/locales/sa.json10
-rw-r--r--app/javascript/mastodon/locales/sc.json10
-rw-r--r--app/javascript/mastodon/locales/sco.json10
-rw-r--r--app/javascript/mastodon/locales/si.json10
-rw-r--r--app/javascript/mastodon/locales/sk.json22
-rw-r--r--app/javascript/mastodon/locales/sl.json8
-rw-r--r--app/javascript/mastodon/locales/sq.json10
-rw-r--r--app/javascript/mastodon/locales/sr-Latn.json8
-rw-r--r--app/javascript/mastodon/locales/sr.json8
-rw-r--r--app/javascript/mastodon/locales/sv.json10
-rw-r--r--app/javascript/mastodon/locales/szl.json10
-rw-r--r--app/javascript/mastodon/locales/ta.json10
-rw-r--r--app/javascript/mastodon/locales/tai.json18
-rw-r--r--app/javascript/mastodon/locales/te.json10
-rw-r--r--app/javascript/mastodon/locales/th.json8
-rw-r--r--app/javascript/mastodon/locales/tr.json8
-rw-r--r--app/javascript/mastodon/locales/tt.json10
-rw-r--r--app/javascript/mastodon/locales/ug.json10
-rw-r--r--app/javascript/mastodon/locales/uk.json16
-rw-r--r--app/javascript/mastodon/locales/ur.json10
-rw-r--r--app/javascript/mastodon/locales/vi.json22
-rw-r--r--app/javascript/mastodon/locales/whitelist_la.json2
-rw-r--r--app/javascript/mastodon/locales/zgh.json10
-rw-r--r--app/javascript/mastodon/locales/zh-CN.json14
-rw-r--r--app/javascript/mastodon/locales/zh-HK.json10
-rw-r--r--app/javascript/mastodon/locales/zh-TW.json26
-rw-r--r--app/javascript/mastodon/middleware/errors.js2
-rw-r--r--app/javascript/mastodon/middleware/loading_bar.js2
-rw-r--r--app/javascript/mastodon/middleware/sounds.js2
-rw-r--r--app/javascript/mastodon/permissions.js7
-rw-r--r--app/javascript/mastodon/reducers/accounts.js2
-rw-r--r--app/javascript/mastodon/reducers/accounts_counters.js2
-rw-r--r--app/javascript/mastodon/reducers/accounts_map.js2
-rw-r--r--app/javascript/mastodon/reducers/alerts.js2
-rw-r--r--app/javascript/mastodon/reducers/announcements.js2
-rw-r--r--app/javascript/mastodon/reducers/compose.js16
-rw-r--r--app/javascript/mastodon/reducers/contexts.js2
-rw-r--r--app/javascript/mastodon/reducers/conversations.js2
-rw-r--r--app/javascript/mastodon/reducers/custom_emojis.js2
-rw-r--r--app/javascript/mastodon/reducers/domain_lists.js2
-rw-r--r--app/javascript/mastodon/reducers/dropdown_menu.js4
-rw-r--r--app/javascript/mastodon/reducers/filters.js2
-rw-r--r--app/javascript/mastodon/reducers/height_cache.js2
-rw-r--r--app/javascript/mastodon/reducers/list_adder.js2
-rw-r--r--app/javascript/mastodon/reducers/list_editor.js2
-rw-r--r--app/javascript/mastodon/reducers/lists.js2
-rw-r--r--app/javascript/mastodon/reducers/markers.js2
-rw-r--r--app/javascript/mastodon/reducers/media_attachments.js2
-rw-r--r--app/javascript/mastodon/reducers/meta.js2
-rw-r--r--app/javascript/mastodon/reducers/missed_updates.js2
-rw-r--r--app/javascript/mastodon/reducers/modal.js2
-rw-r--r--app/javascript/mastodon/reducers/notifications.js2
-rw-r--r--app/javascript/mastodon/reducers/picture_in_picture.js2
-rw-r--r--app/javascript/mastodon/reducers/push_notifications.js2
-rw-r--r--app/javascript/mastodon/reducers/relationships.js13
-rw-r--r--app/javascript/mastodon/reducers/search.js2
-rw-r--r--app/javascript/mastodon/reducers/settings.js2
-rw-r--r--app/javascript/mastodon/reducers/status_lists.js2
-rw-r--r--app/javascript/mastodon/reducers/statuses.js2
-rw-r--r--app/javascript/mastodon/reducers/suggestions.js2
-rw-r--r--app/javascript/mastodon/reducers/tags.js2
-rw-r--r--app/javascript/mastodon/reducers/timelines.js2
-rw-r--r--app/javascript/mastodon/reducers/trends.js2
-rw-r--r--app/javascript/mastodon/reducers/user_lists.js2
-rw-r--r--app/javascript/mastodon/store/configureStore.js2
-rw-r--r--app/javascript/mastodon/uuid.js2
-rw-r--r--app/javascript/packs/public.js38
-rw-r--r--app/javascript/styles/mastodon-light/diff.scss18
-rw-r--r--app/javascript/styles/mastodon/admin.scss17
-rw-r--r--app/javascript/styles/mastodon/components.scss139
-rw-r--r--app/javascript/styles/mastodon/modal.scss2
-rw-r--r--app/javascript/styles/mastodon/polls.scss4
-rw-r--r--app/javascript/styles/mastodon/widgets.scss2
532 files changed, 8405 insertions, 3974 deletions
diff --git a/app/javascript/core/admin.js b/app/javascript/core/admin.js
index 3175ff560..ac1b2f95f 100644
--- a/app/javascript/core/admin.js
+++ b/app/javascript/core/admin.js
@@ -194,7 +194,7 @@ ready(() => {
   }
 
   document.querySelector('a#add-instance-button')?.addEventListener('click', (e) => {
-    const domain = document.getElementById('by_domain')?.value;
+    const domain = document.querySelector('input[type="text"]#by_domain')?.value;
 
     if (domain) {
       const url = new URL(event.target.href);
diff --git a/app/javascript/flavours/glitch/actions/announcements.js b/app/javascript/flavours/glitch/actions/announcements.js
index 1bdea909f..586dcfd33 100644
--- a/app/javascript/flavours/glitch/actions/announcements.js
+++ b/app/javascript/flavours/glitch/actions/announcements.js
@@ -102,7 +102,7 @@ export const addReaction = (announcementId, name) => (dispatch, getState) => {
     dispatch(addReactionRequest(announcementId, name, alreadyAdded));
   }
 
-  api(getState).put(`/api/v1/announcements/${announcementId}/reactions/${name}`).then(() => {
+  api(getState).put(`/api/v1/announcements/${announcementId}/reactions/${encodeURIComponent(name)}`).then(() => {
     dispatch(addReactionSuccess(announcementId, name, alreadyAdded));
   }).catch(err => {
     if (!alreadyAdded) {
@@ -136,7 +136,7 @@ export const addReactionFail = (announcementId, name, error) => ({
 export const removeReaction = (announcementId, name) => (dispatch, getState) => {
   dispatch(removeReactionRequest(announcementId, name));
 
-  api(getState).delete(`/api/v1/announcements/${announcementId}/reactions/${name}`).then(() => {
+  api(getState).delete(`/api/v1/announcements/${announcementId}/reactions/${encodeURIComponent(name)}`).then(() => {
     dispatch(removeReactionSuccess(announcementId, name));
   }).catch(err => {
     dispatch(removeReactionFail(announcementId, name, err));
diff --git a/app/javascript/flavours/glitch/actions/dropdown_menu.js b/app/javascript/flavours/glitch/actions/dropdown_menu.js
index fb6e55612..023151d4b 100644
--- a/app/javascript/flavours/glitch/actions/dropdown_menu.js
+++ b/app/javascript/flavours/glitch/actions/dropdown_menu.js
@@ -1,8 +1,8 @@
 export const DROPDOWN_MENU_OPEN = 'DROPDOWN_MENU_OPEN';
 export const DROPDOWN_MENU_CLOSE = 'DROPDOWN_MENU_CLOSE';
 
-export function openDropdownMenu(id, placement, keyboard, scroll_key) {
-  return { type: DROPDOWN_MENU_OPEN, id, placement, keyboard, scroll_key };
+export function openDropdownMenu(id, keyboard, scroll_key) {
+  return { type: DROPDOWN_MENU_OPEN, id, keyboard, scroll_key };
 }
 
 export function closeDropdownMenu(id) {
diff --git a/app/javascript/flavours/glitch/components/dropdown_menu.js b/app/javascript/flavours/glitch/components/dropdown_menu.js
index 036e0b909..7c70f750f 100644
--- a/app/javascript/flavours/glitch/components/dropdown_menu.js
+++ b/app/javascript/flavours/glitch/components/dropdown_menu.js
@@ -2,9 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import IconButton from './icon_button';
-import Overlay from 'react-overlays/lib/Overlay';
-import Motion from '../features/ui/util/optional_motion';
-import spring from 'react-motion/lib/spring';
+import Overlay from 'react-overlays/Overlay';
 import { supportsPassiveEvents } from 'detect-passive-events';
 import classNames from 'classnames';
 import { CircularProgress } from 'flavours/glitch/components/loading_indicator';
@@ -24,9 +22,6 @@ class DropdownMenu extends React.PureComponent {
     scrollable: PropTypes.bool,
     onClose: PropTypes.func.isRequired,
     style: PropTypes.object,
-    placement: PropTypes.string,
-    arrowOffsetLeft: PropTypes.string,
-    arrowOffsetTop: PropTypes.string,
     openedViaKeyboard: PropTypes.bool,
     renderItem: PropTypes.func,
     renderHeader: PropTypes.func,
@@ -35,11 +30,6 @@ class DropdownMenu extends React.PureComponent {
 
   static defaultProps = {
     style: {},
-    placement: 'bottom',
-  };
-
-  state = {
-    mounted: false,
   };
 
   handleDocumentClick = e => {
@@ -56,8 +46,6 @@ class DropdownMenu extends React.PureComponent {
     if (this.focusedItem && this.props.openedViaKeyboard) {
       this.focusedItem.focus({ preventScroll: true });
     }
-
-    this.setState({ mounted: true });
   }
 
   componentWillUnmount () {
@@ -139,40 +127,28 @@ class DropdownMenu extends React.PureComponent {
   }
 
   render () {
-    const { items, style, placement, arrowOffsetLeft, arrowOffsetTop, scrollable, renderHeader, loading } = this.props;
-    const { mounted } = this.state;
+    const { items, scrollable, renderHeader, loading } = this.props;
 
     let renderItem = this.props.renderItem || this.renderItem;
 
     return (
-      <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
-        {({ opacity, scaleX, scaleY }) => (
-          // It should not be transformed when mounting because the resulting
-          // size will be used to determine the coordinate of the menu by
-          // react-overlays
-          <div className={`dropdown-menu ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}>
-            <div className={`dropdown-menu__arrow ${placement}`} style={{ left: arrowOffsetLeft, top: arrowOffsetTop }} />
-
-            <div className={classNames('dropdown-menu__container', { 'dropdown-menu__container--loading': loading })}>
-              {loading && (
-                <CircularProgress size={30} strokeWidth={3.5} />
-              )}
-
-              {!loading && renderHeader && (
-                <div className='dropdown-menu__container__header'>
-                  {renderHeader(items)}
-                </div>
-              )}
-
-              {!loading && (
-                <ul className={classNames('dropdown-menu__container__list', { 'dropdown-menu__container__list--scrollable': scrollable })}>
-                  {items.map((option, i) => renderItem(option, i, { onClick: this.handleClick, onKeyPress: this.handleItemKeyPress }))}
-                </ul>
-              )}
-            </div>
+      <div className={classNames('dropdown-menu__container', { 'dropdown-menu__container--loading': loading })} ref={this.setRef}>
+        {loading && (
+          <CircularProgress size={30} strokeWidth={3.5} />
+        )}
+
+        {!loading && renderHeader && (
+          <div className='dropdown-menu__container__header'>
+            {renderHeader(items)}
           </div>
         )}
-      </Motion>
+
+        {!loading && (
+          <ul className={classNames('dropdown-menu__container__list', { 'dropdown-menu__container__list--scrollable': scrollable })}>
+            {items.map((option, i) => renderItem(option, i, { onClick: this.handleClick, onKeyPress: this.handleItemKeyPress }))}
+          </ul>
+        )}
+      </div>
     );
   }
 
@@ -197,7 +173,6 @@ export default class Dropdown extends React.PureComponent {
     isUserTouching: PropTypes.func,
     onOpen: PropTypes.func.isRequired,
     onClose: PropTypes.func.isRequired,
-    dropdownPlacement: PropTypes.string,
     openDropdownId: PropTypes.number,
     openedViaKeyboard: PropTypes.bool,
     renderItem: PropTypes.func,
@@ -213,13 +188,11 @@ export default class Dropdown extends React.PureComponent {
     id: id++,
   };
 
-  handleClick = ({ target, type }) => {
+  handleClick = ({ type }) => {
     if (this.state.id === this.props.openDropdownId) {
       this.handleClose();
     } else {
-      const { top } = target.getBoundingClientRect();
-      const placement = top * 2 < innerHeight ? 'bottom' : 'top';
-      this.props.onOpen(this.state.id, this.handleItemClick, placement, type !== 'click');
+      this.props.onOpen(this.state.id, this.handleItemClick, type !== 'click');
     }
   }
 
@@ -303,7 +276,6 @@ export default class Dropdown extends React.PureComponent {
       disabled,
       loading,
       scrollable,
-      dropdownPlacement,
       openDropdownId,
       openedViaKeyboard,
       children,
@@ -314,7 +286,6 @@ export default class Dropdown extends React.PureComponent {
     const open = this.state.id === openDropdownId;
 
     const button = children ? React.cloneElement(React.Children.only(children), {
-      ref: this.setTargetRef,
       onClick: this.handleClick,
       onMouseDown: this.handleMouseDown,
       onKeyDown: this.handleButtonKeyDown,
@@ -326,7 +297,6 @@ export default class Dropdown extends React.PureComponent {
         active={open}
         disabled={disabled}
         size={size}
-        ref={this.setTargetRef}
         onClick={this.handleClick}
         onMouseDown={this.handleMouseDown}
         onKeyDown={this.handleButtonKeyDown}
@@ -336,19 +306,27 @@ export default class Dropdown extends React.PureComponent {
 
     return (
       <React.Fragment>
-        {button}
-
-        <Overlay show={open} placement={dropdownPlacement} target={this.findTarget}>
-          <DropdownMenu
-            items={items}
-            loading={loading}
-            scrollable={scrollable}
-            onClose={this.handleClose}
-            openedViaKeyboard={openedViaKeyboard}
-            renderItem={renderItem}
-            renderHeader={renderHeader}
-            onItemClick={this.handleItemClick}
-          />
+        <span ref={this.setTargetRef}>
+          {button}
+        </span>
+        <Overlay show={open} offset={[5, 5]} placement={'bottom'} flip target={this.findTarget} popperConfig={{ strategy: 'fixed' }}>
+          {({ props, arrowProps, placement }) => (
+            <div {...props}>
+              <div className={`dropdown-animation dropdown-menu ${placement}`}>
+                <div className={`dropdown-menu__arrow ${placement}`} {...arrowProps} />
+                <DropdownMenu
+                  items={items}
+                  loading={loading}
+                  scrollable={scrollable}
+                  onClose={this.handleClose}
+                  openedViaKeyboard={openedViaKeyboard}
+                  renderItem={renderItem}
+                  renderHeader={renderHeader}
+                  onItemClick={this.handleItemClick}
+                />
+              </div>
+            </div>
+          )}
         </Overlay>
       </React.Fragment>
     );
diff --git a/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js b/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js
index 8b73663d4..a1519757d 100644
--- a/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js
+++ b/app/javascript/flavours/glitch/components/edited_timestamp/containers/dropdown_menu_container.js
@@ -4,7 +4,6 @@ import { fetchHistory } from 'flavours/glitch/actions/history';
 import DropdownMenu from 'flavours/glitch/components/dropdown_menu';
 
 const mapStateToProps = (state, { statusId }) => ({
-  dropdownPlacement: state.getIn(['dropdown_menu', 'placement']),
   openDropdownId: state.getIn(['dropdown_menu', 'openId']),
   openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']),
   items: state.getIn(['history', statusId, 'items']),
@@ -13,9 +12,9 @@ const mapStateToProps = (state, { statusId }) => ({
 
 const mapDispatchToProps = (dispatch, { statusId }) => ({
 
-  onOpen (id, onItemClick, dropdownPlacement, keyboard) {
+  onOpen (id, onItemClick, keyboard) {
     dispatch(fetchHistory(statusId));
-    dispatch(openDropdownMenu(id, dropdownPlacement, keyboard));
+    dispatch(openDropdownMenu(id, keyboard));
   },
 
   onClose (id) {
diff --git a/app/javascript/flavours/glitch/components/icon_button.js b/app/javascript/flavours/glitch/components/icon_button.js
index 41a95e92f..2485f0f48 100644
--- a/app/javascript/flavours/glitch/components/icon_button.js
+++ b/app/javascript/flavours/glitch/components/icon_button.js
@@ -30,6 +30,7 @@ export default class IconButton extends React.PureComponent {
     counter: PropTypes.number,
     obfuscateCount: PropTypes.bool,
     href: PropTypes.string,
+    ariaHidden: PropTypes.bool,
   };
 
   static defaultProps = {
@@ -39,6 +40,7 @@ export default class IconButton extends React.PureComponent {
     animate: false,
     overlay: false,
     tabIndex: '0',
+    ariaHidden: false,
   };
 
   state = {
@@ -115,6 +117,7 @@ export default class IconButton extends React.PureComponent {
       counter,
       obfuscateCount,
       href,
+      ariaHidden,
     } = this.props;
 
     const {
@@ -155,6 +158,7 @@ export default class IconButton extends React.PureComponent {
       <button
         aria-label={title}
         aria-expanded={expanded}
+        aria-hidden={ariaHidden}
         title={title}
         className={classes}
         onClick={this.handleClick}
diff --git a/app/javascript/flavours/glitch/components/media_gallery.js b/app/javascript/flavours/glitch/components/media_gallery.js
index ac0d05926..23e279589 100644
--- a/app/javascript/flavours/glitch/components/media_gallery.js
+++ b/app/javascript/flavours/glitch/components/media_gallery.js
@@ -376,7 +376,7 @@ class MediaGallery extends React.PureComponent {
         </button>
       );
     } else if (visible) {
-      spoilerButton = <IconButton title={intl.formatMessage(messages.toggle_visible, { number: size })} icon='eye-slash' overlay onClick={this.handleOpen} />;
+      spoilerButton = <IconButton title={intl.formatMessage(messages.toggle_visible, { number: size })} icon='eye-slash' overlay onClick={this.handleOpen} ariaHidden />;
     } else {
       spoilerButton = (
         <button type='button' onClick={this.handleOpen} className='spoiler-button__overlay'>
diff --git a/app/javascript/flavours/glitch/components/status.js b/app/javascript/flavours/glitch/components/status.js
index 4041b4819..409ec0adc 100644
--- a/app/javascript/flavours/glitch/components/status.js
+++ b/app/javascript/flavours/glitch/components/status.js
@@ -102,7 +102,7 @@ class Status extends ImmutablePureComponent {
     scrollKey: PropTypes.string,
     deployPictureInPicture: PropTypes.func,
     settings: ImmutablePropTypes.map.isRequired,
-    pictureInPicture: PropTypes.shape({
+    pictureInPicture: ImmutablePropTypes.contains({
       inUse: PropTypes.bool,
       available: PropTypes.bool,
     }),
@@ -603,7 +603,7 @@ class Status extends ImmutablePureComponent {
 
     attachments = status.get('media_attachments');
 
-    if (pictureInPicture.inUse) {
+    if (pictureInPicture.get('inUse')) {
       media.push(<PictureInPicturePlaceholder width={this.props.cachedMediaWidth} />);
       mediaIcons.push('video-camera');
     } else if (attachments.size > 0) {
@@ -631,7 +631,7 @@ class Status extends ImmutablePureComponent {
                 width={this.props.cachedMediaWidth}
                 height={110}
                 cacheWidth={this.props.cacheMediaWidth}
-                deployPictureInPicture={pictureInPicture.available ? this.handleDeployPictureInPicture : undefined}
+                deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined}
                 sensitive={status.get('sensitive')}
                 blurhash={attachment.get('blurhash')}
                 visible={this.state.showMedia}
@@ -660,7 +660,7 @@ class Status extends ImmutablePureComponent {
               onOpenVideo={this.handleOpenVideo}
               width={this.props.cachedMediaWidth}
               cacheWidth={this.props.cacheMediaWidth}
-              deployPictureInPicture={pictureInPicture.available ? this.handleDeployPictureInPicture : undefined}
+              deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined}
               visible={this.state.showMedia}
               onToggleVisibility={this.handleToggleMediaVisibility}
             />)}
diff --git a/app/javascript/flavours/glitch/components/status_action_bar.js b/app/javascript/flavours/glitch/components/status_action_bar.js
index 977c98ccb..baf61000a 100644
--- a/app/javascript/flavours/glitch/components/status_action_bar.js
+++ b/app/javascript/flavours/glitch/components/status_action_bar.js
@@ -9,7 +9,7 @@ import { me } from 'flavours/glitch/initial_state';
 import RelativeTimestamp from './relative_timestamp';
 import { accountAdminLink, statusAdminLink } from 'flavours/glitch/utils/backend_links';
 import classNames from 'classnames';
-import { PERMISSION_MANAGE_USERS } from 'flavours/glitch/permissions';
+import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
 
 const messages = defineMessages({
   delete: { id: 'status.delete', defaultMessage: 'Delete' },
@@ -37,9 +37,10 @@ const messages = defineMessages({
   unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
   embed: { id: 'status.embed', defaultMessage: 'Embed' },
   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
-  admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
-  copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
-  hide: { id: 'status.hide', defaultMessage: 'Hide toot' },
+  admin_status: { id: 'status.admin_status', defaultMessage: 'Open this post in the moderation interface' },
+  admin_domain: { id: 'status.admin_domain', defaultMessage: 'Open moderation interface for {domain}' },
+  copy: { id: 'status.copy', defaultMessage: 'Copy link to post' },
+  hide: { id: 'status.hide', defaultMessage: 'Hide post' },
   edited: { id: 'status.edited', defaultMessage: 'Edited {date}' },
   filter: { id: 'status.filter', defaultMessage: 'Filter this post' },
   openOriginalPage: { id: 'account.open_original_page', defaultMessage: 'Open original page' },
@@ -197,6 +198,7 @@ class StatusActionBar extends ImmutablePureComponent {
 
   render () {
     const { status, intl, withDismiss, withCounters, showReplyCount, scrollKey } = this.props;
+    const { permissions } = this.context.identity;
 
     const anonymousAccess    = !me;
     const mutingConversation = status.get('muted');
@@ -212,11 +214,13 @@ class StatusActionBar extends ImmutablePureComponent {
 
     menu.push({ text: intl.formatMessage(messages.open), action: this.handleOpen });
 
+    if (publicStatus && isRemote) {
+      menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: status.get('url') });
+    }
+
+    menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
+
     if (publicStatus) {
-      if (isRemote) {
-        menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: status.get('url') });
-      }
-      menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
       menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
     }
 
@@ -250,19 +254,19 @@ class StatusActionBar extends ImmutablePureComponent {
       menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
       menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
 
-      if ((this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS && (accountAdminLink || statusAdminLink)) {
+      if (((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS && (accountAdminLink || statusAdminLink)) || (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION)) {
         menu.push(null);
-        if (accountAdminLink !== undefined) {
-          menu.push({
-            text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }),
-            href: accountAdminLink(status.getIn(['account', 'id'])),
-          });
+        if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
+          if (accountAdminLink !== undefined) {
+            menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: accountAdminLink(status.getIn(['account', 'id'])) });
+          }
+          if (statusAdminLink !== undefined) {
+            menu.push({ text: intl.formatMessage(messages.admin_status), href: statusAdminLink(status.getIn(['account', 'id']), status.get('id')) });
+          }
         }
-        if (statusAdminLink !== undefined) {
-          menu.push({
-            text: intl.formatMessage(messages.admin_status),
-            href: statusAdminLink(status.getIn(['account', 'id']), status.get('id')),
-          });
+        if (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION) {
+          const domain = status.getIn(['account', 'acct']).split('@')[1];
+          menu.push({ text: intl.formatMessage(messages.admin_domain, { domain: domain }), href: `/admin/instances/${domain}` });
         }
       }
     }
@@ -326,6 +330,7 @@ class StatusActionBar extends ImmutablePureComponent {
           />
         </div>
 
+        <div className='status__action-bar-spacer' />
         <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'>
           <RelativeTimestamp timestamp={status.get('created_at')} />{status.get('edited_at') && <abbr title={intl.formatMessage(messages.edited, { date: intl.formatDate(status.get('edited_at'), { hour12: false, year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) })}> *</abbr>}
         </a>
diff --git a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js
index b2dff63db..43ce8ca63 100644
--- a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js
+++ b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js
@@ -5,18 +5,17 @@ import DropdownMenu from 'flavours/glitch/components/dropdown_menu';
 import { isUserTouching } from '../is_mobile';
 
 const mapStateToProps = state => ({
-  dropdownPlacement: state.getIn(['dropdown_menu', 'placement']),
   openDropdownId: state.getIn(['dropdown_menu', 'openId']),
   openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']),
 });
 
 const mapDispatchToProps = (dispatch, { status, items, scrollKey }) => ({
-  onOpen(id, onItemClick, dropdownPlacement, keyboard) {
+  onOpen(id, onItemClick, keyboard) {
     dispatch(isUserTouching() ? openModal('ACTIONS', {
       status,
       actions: items,
       onClick: onItemClick,
-    }) : openDropdownMenu(id, dropdownPlacement, keyboard, scrollKey));
+    }) : openDropdownMenu(id, keyboard, scrollKey));
   },
 
   onClose(id) {
diff --git a/app/javascript/flavours/glitch/containers/mastodon.js b/app/javascript/flavours/glitch/containers/mastodon.js
index 6c92376d8..dd7623a81 100644
--- a/app/javascript/flavours/glitch/containers/mastodon.js
+++ b/app/javascript/flavours/glitch/containers/mastodon.js
@@ -27,8 +27,9 @@ store.dispatch(hydrateAction);
 // check for deprecated local settings
 store.dispatch(checkDeprecatedLocalSettings());
 
-// load custom emojis
-store.dispatch(fetchCustomEmojis());
+if (initialState.meta.me) {
+  store.dispatch(fetchCustomEmojis());
+}
 
 const createIdentityContext = state => ({
   signedIn: !!state.meta.me,
diff --git a/app/javascript/flavours/glitch/containers/status_container.js b/app/javascript/flavours/glitch/containers/status_container.js
index 947573fc7..645919ebe 100644
--- a/app/javascript/flavours/glitch/containers/status_container.js
+++ b/app/javascript/flavours/glitch/containers/status_container.js
@@ -1,7 +1,7 @@
 import { connect } from 'react-redux';
 import Status from 'flavours/glitch/components/status';
 import { List as ImmutableList } from 'immutable';
-import { makeGetStatus } from 'flavours/glitch/selectors';
+import { makeGetStatus, makeGetPictureInPicture } from 'flavours/glitch/selectors';
 import {
   replyCompose,
   mentionCompose,
@@ -60,6 +60,7 @@ const messages = defineMessages({
 
 const makeMapStateToProps = () => {
   const getStatus = makeGetStatus();
+  const getPictureInPicture = makeGetPictureInPicture();
 
   const mapStateToProps = (state, props) => {
 
@@ -83,11 +84,7 @@ const makeMapStateToProps = () => {
       account: account || props.account,
       settings: state.get('local_settings'),
       prepend: prepend || props.prepend,
-
-      pictureInPicture: {
-        inUse: state.getIn(['meta', 'layout']) !== 'mobile' && state.get('picture_in_picture').statusId === props.id,
-        available: state.getIn(['meta', 'layout']) !== 'mobile',
-      },
+      pictureInPicture: getPictureInPicture(state, props),
     };
   };
 
diff --git a/app/javascript/flavours/glitch/extra_polyfills.js b/app/javascript/flavours/glitch/extra_polyfills.js
index 0d45c23b0..6e8004f07 100644
--- a/app/javascript/flavours/glitch/extra_polyfills.js
+++ b/app/javascript/flavours/glitch/extra_polyfills.js
@@ -1,6 +1,3 @@
 import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';
 import 'intersection-observer';
 import 'requestidlecallback';
-import objectFitImages  from 'object-fit-images';
-
-objectFitImages();
diff --git a/app/javascript/flavours/glitch/features/account/components/follow_request_note.js b/app/javascript/flavours/glitch/features/account/components/follow_request_note.js
new file mode 100644
index 000000000..73c1737a6
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/account/components/follow_request_note.js
@@ -0,0 +1,37 @@
+import React from 'react';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { FormattedMessage } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import Icon from 'flavours/glitch/components/icon';
+
+export default class FollowRequestNote extends ImmutablePureComponent {
+
+  static propTypes = {
+    account: ImmutablePropTypes.map.isRequired,
+  };
+
+  render () {
+    const { account, onAuthorize, onReject } = this.props;
+
+    return (
+      <div className='follow-request-banner'>
+        <div className='follow-request-banner__message'>
+          <FormattedMessage id='account.requested_follow' defaultMessage='{name} has requested to follow you' values={{ name: <bdi><strong dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} /></bdi> }} />
+        </div>
+
+        <div className='follow-request-banner__action'>
+          <button type='button' className='button button-tertiary button--confirmation' onClick={onAuthorize}>
+            <Icon id='check' fixedWidth />
+            <FormattedMessage id='follow_request.authorize' defaultMessage='Authorize' />
+          </button>
+
+          <button type='button' className='button button-tertiary button--destructive' onClick={onReject}>
+            <Icon id='times' fixedWidth />
+            <FormattedMessage id='follow_request.reject' defaultMessage='Reject' />
+          </button>
+        </div>
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js
index 9a5f2fd62..ec4a192bc 100644
--- a/app/javascript/flavours/glitch/features/account/components/header.js
+++ b/app/javascript/flavours/glitch/features/account/components/header.js
@@ -13,7 +13,8 @@ import Button from 'flavours/glitch/components/button';
 import { NavLink } from 'react-router-dom';
 import DropdownMenuContainer from 'flavours/glitch/containers/dropdown_menu_container';
 import AccountNoteContainer from '../containers/account_note_container';
-import { PERMISSION_MANAGE_USERS } from 'flavours/glitch/permissions';
+import FollowRequestNoteContainer from '../containers/follow_request_note_container';
+import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
 import { Helmet } from 'react-helmet';
 
 const messages = defineMessages({
@@ -51,6 +52,7 @@ const messages = defineMessages({
   unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
   add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
+  admin_domain: { id: 'status.admin_domain', defaultMessage: 'Open moderation interface for {domain}' },
   add_account_note: { id: 'account.add_account_note', defaultMessage: 'Add note for @{name}' },
   languages: { id: 'account.languages', defaultMessage: 'Change subscribed languages' },
   openOriginalPage: { id: 'account.open_original_page', defaultMessage: 'Open original page' },
@@ -154,7 +156,7 @@ class Header extends ImmutablePureComponent {
 
   render () {
     const { account, hidden, intl, domain } = this.props;
-    const { signedIn } = this.context.identity;
+    const { signedIn, permissions } = this.context.identity;
 
     if (!account) {
       return null;
@@ -290,9 +292,14 @@ class Header extends ImmutablePureComponent {
       }
     }
 
-    if (account.get('id') !== me && (this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS && accountAdminLink) {
+    if (account.get('id') !== me && ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS && accountAdminLink) || (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION)) {
       menu.push(null);
-      menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: accountAdminLink(account.get('id')) });
+      if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS && accountAdminLink) {
+        menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: accountAdminLink(account.get('id')) });
+      }
+      if (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION) {
+        menu.push({ text: intl.formatMessage(messages.admin_domain, { domain: remoteDomain }), href: `/admin/instances/${remoteDomain}` });
+      }
     }
 
     const content          = { __html: account.get('note_emojified') };
@@ -314,6 +321,8 @@ class Header extends ImmutablePureComponent {
 
     return (
       <div className={classNames('account__header', { inactive: !!account.get('moved') })} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
+        {!(suspended || hidden || account.get('moved')) && account.getIn(['relationship', 'requested_by']) && <FollowRequestNoteContainer account={account} />}
+
         <div className='account__header__image'>
           <div className='account__header__info'>
             {info}
@@ -345,7 +354,9 @@ class Header extends ImmutablePureComponent {
           <div className='account__header__tabs__name'>
             <h1>
               <span dangerouslySetInnerHTML={displayNameHtml} /> {badge}
-              <small>@{acct} {lockedIcon}</small>
+              <small>
+                <span>@{acct}</span> {lockedIcon}
+              </small>
             </h1>
           </div>
 
diff --git a/app/javascript/flavours/glitch/features/account/containers/follow_request_note_container.js b/app/javascript/flavours/glitch/features/account/containers/follow_request_note_container.js
new file mode 100644
index 000000000..c6a3afb7e
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/account/containers/follow_request_note_container.js
@@ -0,0 +1,15 @@
+import { connect } from 'react-redux';
+import FollowRequestNote from '../components/follow_request_note';
+import { authorizeFollowRequest, rejectFollowRequest } from 'flavours/glitch/actions/accounts';
+
+const mapDispatchToProps = (dispatch, { account }) => ({
+  onAuthorize () {
+    dispatch(authorizeFollowRequest(account.get('id')));
+  },
+
+  onReject () {
+    dispatch(rejectFollowRequest(account.get('id')));
+  },
+});
+
+export default connect(null, mapDispatchToProps)(FollowRequestNote);
diff --git a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js
index f7a7fd467..f20ee685e 100644
--- a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js
+++ b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js
@@ -104,6 +104,7 @@ export default class MediaItem extends ImmutablePureComponent {
           <video
             className='media-gallery__item-gifv-thumbnail'
             aria-label={attachment.get('description')}
+            title={attachment.get('description')}
             role='application'
             src={attachment.get('url')}
             onMouseEnter={this.handleMouseEnter}
diff --git a/app/javascript/flavours/glitch/features/compose/components/compose_form.js b/app/javascript/flavours/glitch/features/compose/components/compose_form.js
index abdd247a0..0462c7c4b 100644
--- a/app/javascript/flavours/glitch/features/compose/components/compose_form.js
+++ b/app/javascript/flavours/glitch/features/compose/components/compose_form.js
@@ -310,7 +310,7 @@ class ComposeForm extends ImmutablePureComponent {
 
         <ReplyIndicatorContainer />
 
-        <div className={`spoiler-input ${spoiler ? 'spoiler-input--visible' : ''}`} ref={this.setRef}>
+        <div className={`spoiler-input ${spoiler ? 'spoiler-input--visible' : ''}`} ref={this.setRef} aria-hidden={!this.props.spoiler}>
           <AutosuggestInput
             placeholder={intl.formatMessage(messages.spoiler_placeholder)}
             value={spoilerText}
diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown.js b/app/javascript/flavours/glitch/features/compose/components/dropdown.js
index 3de198c45..d98b311d9 100644
--- a/app/javascript/flavours/glitch/features/compose/components/dropdown.js
+++ b/app/javascript/flavours/glitch/features/compose/components/dropdown.js
@@ -2,7 +2,7 @@
 import classNames from 'classnames';
 import PropTypes from 'prop-types';
 import React from 'react';
-import Overlay from 'react-overlays/lib/Overlay';
+import Overlay from 'react-overlays/Overlay';
 
 //  Components.
 import IconButton from 'flavours/glitch/components/icon_button';
@@ -45,7 +45,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
   };
 
   //  Toggles opening and closing the dropdown.
-  handleToggle = ({ target, type }) => {
+  handleToggle = ({ type }) => {
     const { onModalOpen } = this.props;
     const { open } = this.state;
 
@@ -59,11 +59,9 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
         }
       }
     } else {
-      const { top } = target.getBoundingClientRect();
       if (this.state.open && this.activeElement) {
         this.activeElement.focus({ preventScroll: true });
       }
-      this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
       this.setState({ open: !this.state.open, openedViaKeyboard: type !== 'click' });
     }
   }
@@ -158,6 +156,18 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
     };
   }
 
+  setTargetRef = c => {
+    this.target = c;
+  }
+
+  findTarget = () => {
+    return this.target;
+  }
+
+  handleOverlayEnter = (state) => {
+    this.setState({ placement: state.placement });
+  }
+
   //  Rendering.
   render () {
     const {
@@ -179,6 +189,7 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
       <div
         className={classNames('privacy-dropdown', placement, { active: open })}
         onKeyDown={this.handleKeyDown}
+        ref={this.setTargetRef}
       >
         <div className={classNames('privacy-dropdown__value', { active })}>
           <IconButton
@@ -204,18 +215,26 @@ export default class ComposerOptionsDropdown extends React.PureComponent {
           containerPadding={20}
           placement={placement}
           show={open}
-          target={this}
+          flip
+          target={this.findTarget}
           container={container}
+          popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}
         >
-          <DropdownMenu
-            items={items}
-            renderItemContents={renderItemContents}
-            onChange={onChange}
-            onClose={this.handleClose}
-            value={value}
-            openedViaKeyboard={this.state.openedViaKeyboard}
-            closeOnChange={closeOnChange}
-          />
+          {({ props, placement }) => (
+            <div {...props}>
+              <div className={`dropdown-animation privacy-dropdown__dropdown ${placement}`}>
+                <DropdownMenu
+                  items={items}
+                  renderItemContents={renderItemContents}
+                  onChange={onChange}
+                  onClose={this.handleClose}
+                  value={value}
+                  openedViaKeyboard={this.state.openedViaKeyboard}
+                  closeOnChange={closeOnChange}
+                />
+              </div>
+            </div>
+          )}
         </Overlay>
       </div>
     );
diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js b/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js
index 09e8fc35a..c4895dfd0 100644
--- a/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js
+++ b/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js
@@ -1,7 +1,6 @@
 //  Package imports.
 import PropTypes from 'prop-types';
 import React from 'react';
-import spring from 'react-motion/lib/spring';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import classNames from 'classnames';
 
@@ -10,15 +9,8 @@ import Icon from 'flavours/glitch/components/icon';
 
 //  Utils.
 import { withPassive } from 'flavours/glitch/utils/dom_helpers';
-import Motion from '../../ui/util/optional_motion';
 import { assignHandlers } from 'flavours/glitch/utils/react_helpers';
 
-//  The spring to use with our motion.
-const springMotion = spring(1, {
-  damping: 35,
-  stiffness: 400,
-});
-
 //  The component.
 export default class ComposerOptionsDropdownContent extends React.PureComponent {
 
@@ -44,7 +36,6 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
   };
 
   state = {
-    mounted: false,
     value: this.props.openedViaKeyboard ? this.props.items[0].name : undefined,
   };
 
@@ -56,7 +47,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
   }
 
   //  Stores our node in `this.node`.
-  handleRef = (node) => {
+  setRef = (node) => {
     this.node = node;
   }
 
@@ -69,7 +60,6 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
     } else {
       this.node.firstChild.focus({ preventScroll: true });
     }
-    this.setState({ mounted: true });
   }
 
   //  On unmounting, we remove our listeners.
@@ -191,7 +181,6 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
 
   //  Rendering.
   render () {
-    const { mounted } = this.state;
     const {
       items,
       onChange,
@@ -201,36 +190,9 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent
 
     //  The result.
     return (
-      <Motion
-        defaultStyle={{
-          opacity: 0,
-          scaleX: 0.85,
-          scaleY: 0.75,
-        }}
-        style={{
-          opacity: springMotion,
-          scaleX: springMotion,
-          scaleY: springMotion,
-        }}
-      >
-        {({ opacity, scaleX, scaleY }) => (
-          // It should not be transformed when mounting because the resulting
-          // size will be used to determine the coordinate of the menu by
-          // react-overlays
-          <div
-            className='privacy-dropdown__dropdown'
-            ref={this.handleRef}
-            role='listbox'
-            style={{
-              ...style,
-              opacity: opacity,
-              transform: mounted ? `scale(${scaleX}, ${scaleY})` : null,
-            }}
-          >
-            {!!items && items.map((item, i) => this.renderItem(item, i))}
-          </div>
-        )}
-      </Motion>
+      <div style={{ ...style }} role='listbox' ref={this.setRef}>
+        {!!items && items.map((item, i) => this.renderItem(item, i))}
+      </div>
     );
   }
 
diff --git a/app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.js b/app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.js
index 546d398a0..38c735551 100644
--- a/app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.js
+++ b/app/javascript/flavours/glitch/features/compose/components/emoji_picker_dropdown.js
@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import { EmojiPicker as EmojiPickerAsync } from '../../ui/util/async-components';
-import Overlay from 'react-overlays/lib/Overlay';
+import Overlay from 'react-overlays/Overlay';
 import classNames from 'classnames';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import { supportsPassiveEvents } from 'detect-passive-events';
@@ -155,9 +155,6 @@ class EmojiPickerMenu extends React.PureComponent {
     onClose: PropTypes.func.isRequired,
     onPick: PropTypes.func.isRequired,
     style: PropTypes.object,
-    placement: PropTypes.string,
-    arrowOffsetLeft: PropTypes.string,
-    arrowOffsetTop: PropTypes.string,
     intl: PropTypes.object.isRequired,
     skinTone: PropTypes.number.isRequired,
     onSkinTone: PropTypes.func.isRequired,
@@ -326,14 +323,13 @@ class EmojiPickerDropdown extends React.PureComponent {
   state = {
     active: false,
     loading: false,
-    placement: null,
   };
 
   setRef = (c) => {
     this.dropdown = c;
   }
 
-  onShowDropdown = ({ target }) => {
+  onShowDropdown = () => {
     this.setState({ active: true });
 
     if (!EmojiPicker) {
@@ -348,9 +344,6 @@ class EmojiPickerDropdown extends React.PureComponent {
         this.setState({ loading: false, active: false });
       });
     }
-
-    const { top } = target.getBoundingClientRect();
-    this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
   }
 
   onHideDropdown = () => {
@@ -384,7 +377,7 @@ class EmojiPickerDropdown extends React.PureComponent {
   render () {
     const { intl, onPickEmoji, onSkinTone, skinTone, frequentlyUsedEmojis, button } = this.props;
     const title = intl.formatMessage(messages.emoji);
-    const { active, loading, placement } = this.state;
+    const { active, loading } = this.state;
 
     return (
       <div className='emoji-picker-dropdown' onKeyDown={this.handleKeyDown}>
@@ -396,16 +389,22 @@ class EmojiPickerDropdown extends React.PureComponent {
           />}
         </div>
 
-        <Overlay show={active} placement={placement} target={this.findTarget}>
-          <EmojiPickerMenu
-            custom_emojis={this.props.custom_emojis}
-            loading={loading}
-            onClose={this.onHideDropdown}
-            onPick={onPickEmoji}
-            onSkinTone={onSkinTone}
-            skinTone={skinTone}
-            frequentlyUsedEmojis={frequentlyUsedEmojis}
-          />
+        <Overlay show={active} placement={'bottom'} target={this.findTarget} popperConfig={{ strategy: 'fixed' }}>
+          {({ props, placement })=> (
+            <div {...props} style={{ ...props.style, width: 299 }}>
+              <div className={`dropdown-animation ${placement}`}>
+                <EmojiPickerMenu
+                  custom_emojis={this.props.custom_emojis}
+                  loading={loading}
+                  onClose={this.onHideDropdown}
+                  onPick={onPickEmoji}
+                  onSkinTone={onSkinTone}
+                  skinTone={skinTone}
+                  frequentlyUsedEmojis={frequentlyUsedEmojis}
+                />
+              </div>
+            </div>
+          )}
         </Overlay>
       </div>
     );
diff --git a/app/javascript/flavours/glitch/features/compose/components/language_dropdown.js b/app/javascript/flavours/glitch/features/compose/components/language_dropdown.js
index a3256aa9b..3a1fa0226 100644
--- a/app/javascript/flavours/glitch/features/compose/components/language_dropdown.js
+++ b/app/javascript/flavours/glitch/features/compose/components/language_dropdown.js
@@ -2,9 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { injectIntl, defineMessages } from 'react-intl';
 import TextIconButton from './text_icon_button';
-import Overlay from 'react-overlays/lib/Overlay';
-import Motion from 'flavours/glitch/features/ui/util/optional_motion';
-import spring from 'react-motion/lib/spring';
+import Overlay from 'react-overlays/Overlay';
 import { supportsPassiveEvents } from 'detect-passive-events';
 import classNames from 'classnames';
 import { languages as preloadedLanguages } from 'flavours/glitch/initial_state';
@@ -22,10 +20,8 @@ const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
 class LanguageDropdownMenu extends React.PureComponent {
 
   static propTypes = {
-    style: PropTypes.object,
     value: PropTypes.string.isRequired,
     frequentlyUsedLanguages: PropTypes.arrayOf(PropTypes.string).isRequired,
-    placement: PropTypes.string.isRequired,
     onClose: PropTypes.func.isRequired,
     onChange: PropTypes.func.isRequired,
     languages: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)),
@@ -37,7 +33,6 @@ class LanguageDropdownMenu extends React.PureComponent {
   };
 
   state = {
-    mounted: false,
     searchValue: '',
   };
 
@@ -50,7 +45,6 @@ class LanguageDropdownMenu extends React.PureComponent {
   componentDidMount () {
     document.addEventListener('click', this.handleDocumentClick, false);
     document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
-    this.setState({ mounted: true });
 
     // Because of https://github.com/react-bootstrap/react-bootstrap/issues/2614 we need
     // to wait for a frame before focusing
@@ -222,29 +216,22 @@ class LanguageDropdownMenu extends React.PureComponent {
   }
 
   render () {
-    const { style, placement, intl } = this.props;
-    const { mounted, searchValue } = this.state;
+    const { intl } = this.props;
+    const { searchValue } = this.state;
     const isSearching = searchValue !== '';
     const results = this.search();
 
     return (
-      <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
-        {({ opacity, scaleX, scaleY }) => (
-          // It should not be transformed when mounting because the resulting
-          // size will be used to determine the coordinate of the menu by
-          // react-overlays
-          <div className={`language-dropdown__dropdown ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}>
-            <div className='emoji-mart-search'>
-              <input type='search' value={searchValue} onChange={this.handleSearchChange} onKeyDown={this.handleSearchKeyDown} placeholder={intl.formatMessage(messages.search)} />
-              <button className='emoji-mart-search-icon' disabled={!isSearching} aria-label={intl.formatMessage(messages.clear)} onClick={this.handleClear}>{!isSearching ? loupeIcon : deleteIcon}</button>
-            </div>
+      <div ref={this.setRef}>
+        <div className='emoji-mart-search'>
+          <input type='search' value={searchValue} onChange={this.handleSearchChange} onKeyDown={this.handleSearchKeyDown} placeholder={intl.formatMessage(messages.search)} />
+          <button type='button' className='emoji-mart-search-icon' disabled={!isSearching} aria-label={intl.formatMessage(messages.clear)} onClick={this.handleClear}>{!isSearching ? loupeIcon : deleteIcon}</button>
+        </div>
 
-            <div className='language-dropdown__dropdown__results emoji-mart-scroll' role='listbox' ref={this.setListRef}>
-              {results.map(this.renderItem)}
-            </div>
-          </div>
-        )}
-      </Motion>
+        <div className='language-dropdown__dropdown__results emoji-mart-scroll' role='listbox' ref={this.setListRef}>
+          {results.map(this.renderItem)}
+        </div>
+      </div>
     );
   }
 
@@ -266,14 +253,11 @@ class LanguageDropdown extends React.PureComponent {
     placement: 'bottom',
   };
 
-  handleToggle = ({ target }) => {
-    const { top } = target.getBoundingClientRect();
-
+  handleToggle = () => {
     if (this.state.open && this.activeElement) {
       this.activeElement.focus({ preventScroll: true });
     }
 
-    this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
     this.setState({ open: !this.state.open });
   }
 
@@ -293,13 +277,25 @@ class LanguageDropdown extends React.PureComponent {
     onChange(value);
   }
 
+  setTargetRef = c => {
+    this.target = c;
+  }
+
+  findTarget = () => {
+    return this.target;
+  }
+
+  handleOverlayEnter = (state) => {
+    this.setState({ placement: state.placement });
+  }
+
   render () {
     const { value, intl, frequentlyUsedLanguages } = this.props;
     const { open, placement } = this.state;
 
     return (
-      <div className={classNames('privacy-dropdown', { active: open })}>
-        <div className='privacy-dropdown__value'>
+      <div className={classNames('privacy-dropdown', placement, { active: open })}>
+        <div className='privacy-dropdown__value' ref={this.setTargetRef} >
           <TextIconButton
             className='privacy-dropdown__value-icon'
             label={value && value.toUpperCase()}
@@ -309,15 +305,20 @@ class LanguageDropdown extends React.PureComponent {
           />
         </div>
 
-        <Overlay show={open} placement={placement} target={this}>
-          <LanguageDropdownMenu
-            value={value}
-            frequentlyUsedLanguages={frequentlyUsedLanguages}
-            onClose={this.handleClose}
-            onChange={this.handleChange}
-            placement={placement}
-            intl={intl}
-          />
+        <Overlay show={open} placement={'bottom'} flip target={this.findTarget} popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}>
+          {({ props, placement }) => (
+            <div {...props}>
+              <div className={`dropdown-animation language-dropdown__dropdown ${placement}`} >
+                <LanguageDropdownMenu
+                  value={value}
+                  frequentlyUsedLanguages={frequentlyUsedLanguages}
+                  onClose={this.handleClose}
+                  onChange={this.handleChange}
+                  intl={intl}
+                />
+              </div>
+            </div>
+          )}
         </Overlay>
       </div>
     );
diff --git a/app/javascript/flavours/glitch/features/compose/components/poll_form.js b/app/javascript/flavours/glitch/features/compose/components/poll_form.js
index d5edccff3..afb5da097 100644
--- a/app/javascript/flavours/glitch/features/compose/components/poll_form.js
+++ b/app/javascript/flavours/glitch/features/compose/components/poll_form.js
@@ -153,6 +153,7 @@ class PollForm extends ImmutablePureComponent {
             <option value={1800}>{intl.formatMessage(messages.minutes, { number: 30 })}</option>
             <option value={3600}>{intl.formatMessage(messages.hours, { number: 1 })}</option>
             <option value={21600}>{intl.formatMessage(messages.hours, { number: 6 })}</option>
+            <option value={43200}>{intl.formatMessage(messages.hours, { number: 12 })}</option>
             <option value={86400}>{intl.formatMessage(messages.days, { number: 1 })}</option>
             <option value={259200}>{intl.formatMessage(messages.days, { number: 3 })}</option>
             <option value={604800}>{intl.formatMessage(messages.days, { number: 7 })}</option>
diff --git a/app/javascript/flavours/glitch/features/compose/components/search.js b/app/javascript/flavours/glitch/features/compose/components/search.js
index 326fe5b70..e5874de75 100644
--- a/app/javascript/flavours/glitch/features/compose/components/search.js
+++ b/app/javascript/flavours/glitch/features/compose/components/search.js
@@ -3,13 +3,12 @@ import classNames from 'classnames';
 import PropTypes from 'prop-types';
 import React from 'react';
 import { connect } from 'react-redux';
-import spring from 'react-motion/lib/spring';
 import {
   injectIntl,
   FormattedMessage,
   defineMessages,
 } from 'react-intl';
-import Overlay from 'react-overlays/lib/Overlay';
+import Overlay from 'react-overlays/Overlay';
 
 //  Components.
 import Icon from 'flavours/glitch/components/icon';
@@ -17,7 +16,6 @@ import Icon from 'flavours/glitch/components/icon';
 //  Utils.
 import { focusRoot } from 'flavours/glitch/utils/dom_helpers';
 import { searchEnabled } from 'flavours/glitch/initial_state';
-import Motion from '../../ui/util/optional_motion';
 
 const messages = defineMessages({
   placeholder: { id: 'search.placeholder', defaultMessage: 'Search' },
@@ -26,31 +24,20 @@ const messages = defineMessages({
 
 class SearchPopout extends React.PureComponent {
 
-  static propTypes = {
-    style: PropTypes.object,
-  };
-
   render () {
-    const { style } = this.props;
     const extraInformation = searchEnabled ? <FormattedMessage id='search_popout.tips.full_text' defaultMessage='Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.' /> : <FormattedMessage id='search_popout.tips.text' defaultMessage='Simple text returns matching display names, usernames and hashtags' />;
     return (
-      <div style={{ ...style, position: 'absolute', width: 285, zIndex: 2 }}>
-        <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
-          {({ opacity, scaleX, scaleY }) => (
-            <div className='search-popout' style={{ opacity: opacity, transform: `scale(${scaleX}, ${scaleY})` }}>
-              <h4><FormattedMessage id='search_popout.search_format' defaultMessage='Advanced search format' /></h4>
-
-              <ul>
-                <li><em>#example</em> <FormattedMessage id='search_popout.tips.hashtag' defaultMessage='hashtag' /></li>
-                <li><em>@username@domain</em> <FormattedMessage id='search_popout.tips.user' defaultMessage='user' /></li>
-                <li><em>URL</em> <FormattedMessage id='search_popout.tips.user' defaultMessage='user' /></li>
-                <li><em>URL</em> <FormattedMessage id='search_popout.tips.status' defaultMessage='status' /></li>
-              </ul>
-
-              {extraInformation}
-            </div>
-          )}
-        </Motion>
+      <div className='search-popout'>
+        <h4><FormattedMessage id='search_popout.search_format' defaultMessage='Advanced search format' /></h4>
+
+        <ul>
+          <li><em>#example</em> <FormattedMessage id='search_popout.tips.hashtag' defaultMessage='hashtag' /></li>
+          <li><em>@username@domain</em> <FormattedMessage id='search_popout.tips.user' defaultMessage='user' /></li>
+          <li><em>URL</em> <FormattedMessage id='search_popout.tips.user' defaultMessage='user' /></li>
+          <li><em>URL</em> <FormattedMessage id='search_popout.tips.status' defaultMessage='status' /></li>
+        </ul>
+
+        {extraInformation}
       </div>
     );
   }
@@ -136,6 +123,10 @@ class Search extends React.PureComponent {
     }
   }
 
+  findTarget = () => {
+    return this.searchForm;
+  }
+
   render () {
     const { intl, value, submitted } = this.props;
     const { expanded } = this.state;
@@ -144,34 +135,31 @@ class Search extends React.PureComponent {
 
     return (
       <div className='search'>
-        <label>
-          <span style={{ display: 'none' }}>{intl.formatMessage(messages.placeholder)}</span>
-          <input
-            ref={this.setRef}
-            className='search__input'
-            type='text'
-            placeholder={intl.formatMessage(signedIn ? messages.placeholderSignedIn : messages.placeholder)}
-            value={value || ''}
-            onChange={this.handleChange}
-            onKeyUp={this.handleKeyUp}
-            onFocus={this.handleFocus}
-            onBlur={this.handleBlur}
-          />
-        </label>
-
-        <div
-          aria-label={intl.formatMessage(messages.placeholder)}
-          className='search__icon'
-          onClick={this.handleClear}
-          role='button'
-          tabIndex='0'
-        >
+        <input
+          ref={this.setRef}
+          className='search__input'
+          type='text'
+          placeholder={intl.formatMessage(signedIn ? messages.placeholderSignedIn : messages.placeholder)}
+          aria-label={intl.formatMessage(signedIn ? messages.placeholderSignedIn : messages.placeholder)}
+          value={value || ''}
+          onChange={this.handleChange}
+          onKeyUp={this.handleKeyUp}
+          onFocus={this.handleFocus}
+          onBlur={this.handleBlur}
+        />
+
+        <div role='button' tabIndex='0' className='search__icon' onClick={this.handleClear}>
           <Icon id='search' className={hasValue ? '' : 'active'} />
           <Icon id='times-circle' className={hasValue ? 'active' : ''} />
         </div>
-
-        <Overlay show={expanded && !hasValue} placement='bottom' target={this}>
-          <SearchPopout />
+        <Overlay show={expanded && !hasValue} placement='bottom' target={this.findTarget} popperConfig={{ strategy: 'fixed' }}>
+          {({ props, placement }) => (
+            <div {...props} style={{ ...props.style, width: 285, zIndex: 2 }}>
+              <div className={`dropdown-animation ${placement}`}>
+                <SearchPopout />
+              </div>
+            </div>
+          )}
         </Overlay>
       </div>
     );
diff --git a/app/javascript/flavours/glitch/features/compose/containers/options_container.js b/app/javascript/flavours/glitch/features/compose/containers/options_container.js
index 6c3db8173..5de9f5419 100644
--- a/app/javascript/flavours/glitch/features/compose/containers/options_container.js
+++ b/app/javascript/flavours/glitch/features/compose/containers/options_container.js
@@ -46,7 +46,7 @@ const mapDispatchToProps = (dispatch) => ({
   },
 
   onDoodleOpen() {
-    dispatch(openModal('DOODLE', { noEsc: true }));
+    dispatch(openModal('DOODLE', { noEsc: true, noClose: true }));
   },
 });
 
diff --git a/app/javascript/flavours/glitch/features/explore/index.js b/app/javascript/flavours/glitch/features/explore/index.js
index ba435d7e3..da0dc7f7c 100644
--- a/app/javascript/flavours/glitch/features/explore/index.js
+++ b/app/javascript/flavours/glitch/features/explore/index.js
@@ -24,16 +24,6 @@ const mapStateToProps = state => ({
   isSearching: state.getIn(['search', 'submitted']) || !showTrends,
 });
 
-// Fix strange bug on Safari where <span> (rendered by FormattedMessage) disappears
-// after clicking around Explore top bar (issue #20885).
-// Removing width=100% from <a> also fixes it, as well as replacing <span> with <div>
-// We're choosing to wrap span with div to keep the changes local only to this tool bar.
-const WrapFormattedMessage = ({ children, ...props }) => <div><FormattedMessage {...props}>{children}</FormattedMessage></div>;
-WrapFormattedMessage.propTypes = {
-  children: PropTypes.any,
-};
-
-
 export default @connect(mapStateToProps)
 @injectIntl
 class Explore extends React.PureComponent {
@@ -78,12 +68,22 @@ class Explore extends React.PureComponent {
           {isSearching ? (
             <SearchResults />
           ) : (
-            <React.Fragment>
+            <>
               <div className='account__section-headline'>
-                <NavLink exact to='/explore'><WrapFormattedMessage id='explore.trending_statuses' defaultMessage='Posts' /></NavLink>
-                <NavLink exact to='/explore/tags'><WrapFormattedMessage id='explore.trending_tags' defaultMessage='Hashtags' /></NavLink>
-                <NavLink exact to='/explore/links'><WrapFormattedMessage id='explore.trending_links' defaultMessage='News' /></NavLink>
-                {signedIn && <NavLink exact to='/explore/suggestions'><WrapFormattedMessage id='explore.suggested_follows' defaultMessage='For you' /></NavLink>}
+                <NavLink exact to='/explore'>
+                  <FormattedMessage tagName='div' id='explore.trending_statuses' defaultMessage='Posts' />
+                </NavLink>
+                <NavLink exact to='/explore/tags'>
+                  <FormattedMessage tagName='div' id='explore.trending_tags' defaultMessage='Hashtags' />
+                </NavLink>
+                <NavLink exact to='/explore/links'>
+                  <FormattedMessage tagName='div' id='explore.trending_links' defaultMessage='News' />
+                </NavLink>
+                {signedIn && (
+                  <NavLink exact to='/explore/suggestions'>
+                    <FormattedMessage tagName='div' id='explore.suggested_follows' defaultMessage='For you' />
+                  </NavLink>
+                )}
               </div>
 
               <Switch>
@@ -97,7 +97,7 @@ class Explore extends React.PureComponent {
                 <title>{intl.formatMessage(messages.title)}</title>
                 <meta name='robots' content={isSearching ? 'noindex' : 'all'} />
               </Helmet>
-            </React.Fragment>
+            </>
           )}
         </div>
       </Column>
diff --git a/app/javascript/flavours/glitch/features/hashtag_timeline/index.js b/app/javascript/flavours/glitch/features/hashtag_timeline/index.js
index 4428fdecf..219dc0ec6 100644
--- a/app/javascript/flavours/glitch/features/hashtag_timeline/index.js
+++ b/app/javascript/flavours/glitch/features/hashtag_timeline/index.js
@@ -194,7 +194,7 @@ class HashtagTimeline extends React.PureComponent {
       const following = tag.get('following');
 
       followButton = (
-        <button className={classNames('column-header__button')} onClick={this.handleFollow} disabled={!signedIn} title={intl.formatMessage(following ? messages.unfollowHashtag : messages.followHashtag)} aria-label={intl.formatMessage(following ? messages.unfollowHashtag : messages.followHashtag)}>
+        <button className={classNames('column-header__button')} onClick={this.handleFollow} disabled={!signedIn} active={following} title={intl.formatMessage(following ? messages.unfollowHashtag : messages.followHashtag)} aria-label={intl.formatMessage(following ? messages.unfollowHashtag : messages.followHashtag)}>
           <Icon id={following ? 'user-times' : 'user-plus'} fixedWidth className='column-header__icon' />
         </button>
       );
diff --git a/app/javascript/flavours/glitch/features/local_settings/navigation/index.js b/app/javascript/flavours/glitch/features/local_settings/navigation/index.js
index e618a981e..98dda182f 100644
--- a/app/javascript/flavours/glitch/features/local_settings/navigation/index.js
+++ b/app/javascript/flavours/glitch/features/local_settings/navigation/index.js
@@ -13,7 +13,6 @@ const messages = defineMessages({
   general: {  id: 'settings.general', defaultMessage: 'General' },
   compose: {  id: 'settings.compose_box_opts', defaultMessage: 'Compose box' },
   content_warnings: { id: 'settings.content_warnings', defaultMessage: 'Content Warnings' },
-  filters: { id: 'settings.filters', defaultMessage: 'Filters' },
   collapsed: { id: 'settings.collapsed_statuses', defaultMessage: 'Collapsed toots' },
   media: { id: 'settings.media', defaultMessage: 'Media' },
   preferences: { id: 'settings.preferences', defaultMessage: 'Preferences' },
diff --git a/app/javascript/flavours/glitch/features/status/components/action_bar.js b/app/javascript/flavours/glitch/features/status/components/action_bar.js
index b6f8a9877..73913dd49 100644
--- a/app/javascript/flavours/glitch/features/status/components/action_bar.js
+++ b/app/javascript/flavours/glitch/features/status/components/action_bar.js
@@ -7,7 +7,7 @@ import { defineMessages, injectIntl } from 'react-intl';
 import { me } from 'flavours/glitch/initial_state';
 import { accountAdminLink, statusAdminLink } from 'flavours/glitch/utils/backend_links';
 import classNames from 'classnames';
-import { PERMISSION_MANAGE_USERS } from 'flavours/glitch/permissions';
+import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'flavours/glitch/permissions';
 
 const messages = defineMessages({
   delete: { id: 'status.delete', defaultMessage: 'Delete' },
@@ -34,6 +34,7 @@ const messages = defineMessages({
   embed: { id: 'status.embed', defaultMessage: 'Embed' },
   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
   admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
+  admin_domain: { id: 'status.admin_domain', defaultMessage: 'Open moderation interface for {domain}' },
   copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
   openOriginalPage: { id: 'account.open_original_page', defaultMessage: 'Open original page' },
 });
@@ -177,19 +178,19 @@ class ActionBar extends React.PureComponent {
       menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
       menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
       menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
-      if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS && (accountAdminLink || statusAdminLink)) {
+      if (((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS && (accountAdminLink || statusAdminLink)) || (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION)) {
         menu.push(null);
-        if (accountAdminLink !== undefined) {
-          menu.push({
-            text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }),
-            href: accountAdminLink(status.getIn(['account', 'id'])),
-          });
+        if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
+          if (accountAdminLink !== undefined) {
+            menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: accountAdminLink(status.getIn(['account', 'id'])) });
+          }
+          if (statusAdminLink !== undefined) {
+            menu.push({ text: intl.formatMessage(messages.admin_status), href: statusAdminLink(status.getIn(['account', 'id']), status.get('id')) });
+          }
         }
-        if (statusAdminLink !== undefined) {
-          menu.push({
-            text: intl.formatMessage(messages.admin_status),
-            href: statusAdminLink(status.getIn(['account', 'id']), status.get('id')),
-          });
+        if (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION) {
+          const domain = status.getIn(['account', 'acct']).split('@')[1];
+          menu.push({ text: intl.formatMessage(messages.admin_domain, { domain: domain }), href: `/admin/instances/${domain}` });
         }
       }
     }
diff --git a/app/javascript/flavours/glitch/features/status/components/detailed_status.js b/app/javascript/flavours/glitch/features/status/components/detailed_status.js
index 7d2c2aace..907fc3f1c 100644
--- a/app/javascript/flavours/glitch/features/status/components/detailed_status.js
+++ b/app/javascript/flavours/glitch/features/status/components/detailed_status.js
@@ -41,7 +41,10 @@ class DetailedStatus extends ImmutablePureComponent {
     domain: PropTypes.string.isRequired,
     compact: PropTypes.bool,
     showMedia: PropTypes.bool,
-    usingPiP: PropTypes.bool,
+    pictureInPicture: ImmutablePropTypes.contains({
+      inUse: PropTypes.bool,
+      available: PropTypes.bool,
+    }),
     onToggleMediaVisibility: PropTypes.func,
     intl: PropTypes.object.isRequired,
   };
@@ -120,7 +123,7 @@ class DetailedStatus extends ImmutablePureComponent {
 
   render () {
     const status = (this.props.status && this.props.status.get('reblog')) ? this.props.status.get('reblog') : this.props.status;
-    const { expanded, onToggleHidden, settings, usingPiP, intl } = this.props;
+    const { expanded, onToggleHidden, settings, pictureInPicture, intl } = this.props;
     const outerStyle = { boxSizing: 'border-box' };
     const { compact } = this.props;
 
@@ -153,7 +156,7 @@ class DetailedStatus extends ImmutablePureComponent {
       outerStyle.height = `${this.state.height}px`;
     }
 
-    if (usingPiP) {
+    if (pictureInPicture.get('inUse')) {
       media.push(<PictureInPicturePlaceholder />);
       mediaIcons.push('video-camera');
     } else if (status.get('media_attachments').size > 0) {
diff --git a/app/javascript/flavours/glitch/features/status/index.js b/app/javascript/flavours/glitch/features/status/index.js
index e190652b0..c22e7f0bd 100644
--- a/app/javascript/flavours/glitch/features/status/index.js
+++ b/app/javascript/flavours/glitch/features/status/index.js
@@ -41,7 +41,7 @@ import { initMuteModal } from 'flavours/glitch/actions/mutes';
 import { initBlockModal } from 'flavours/glitch/actions/blocks';
 import { initReport } from 'flavours/glitch/actions/reports';
 import { initBoostModal } from 'flavours/glitch/actions/boosts';
-import { makeGetStatus } from 'flavours/glitch/selectors';
+import { makeGetStatus, makeGetPictureInPicture } from 'flavours/glitch/selectors';
 import ScrollContainer from 'flavours/glitch/containers/scroll_container';
 import ColumnBackButton from 'flavours/glitch/components/column_back_button';
 import ColumnHeader from '../../components/column_header';
@@ -67,11 +67,12 @@ const messages = defineMessages({
   detailedStatus: { id: 'status.detailed_status', defaultMessage: 'Detailed conversation view' },
   replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
   replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
-  tootHeading: { id: 'column.toot', defaultMessage: 'Toots and replies' },
+  tootHeading: { id: 'account.posts_with_replies', defaultMessage: 'Posts and replies' },
 });
 
 const makeMapStateToProps = () => {
   const getStatus = makeGetStatus();
+  const getPictureInPicture = makeGetPictureInPicture();
 
   const getAncestorsIds = createSelector([
     (_, { id }) => id,
@@ -129,11 +130,12 @@ const makeMapStateToProps = () => {
 
   const mapStateToProps = (state, props) => {
     const status = getStatus(state, { id: props.params.statusId });
-    let ancestorsIds = Immutable.List();
+
+    let ancestorsIds   = Immutable.List();
     let descendantsIds = Immutable.List();
 
     if (status) {
-      ancestorsIds = getAncestorsIds(state, { id: status.get('in_reply_to_id') });
+      ancestorsIds   = getAncestorsIds(state, { id: status.get('in_reply_to_id') });
       descendantsIds = getDescendantsIds(state, { id: status.get('id') });
     }
 
@@ -145,7 +147,7 @@ const makeMapStateToProps = () => {
       settings: state.get('local_settings'),
       askReplyConfirmation: state.getIn(['local_settings', 'confirm_before_clearing_draft']) && state.getIn(['compose', 'text']).trim().length !== 0,
       domain: state.getIn(['meta', 'domain']),
-      usingPiP: state.get('picture_in_picture').statusId === props.params.statusId,
+      pictureInPicture: getPictureInPicture(state, { id: props.params.statusId }),
     };
   };
 
@@ -190,7 +192,10 @@ class Status extends ImmutablePureComponent {
     askReplyConfirmation: PropTypes.bool,
     multiColumn: PropTypes.bool,
     domain: PropTypes.string.isRequired,
-    usingPiP: PropTypes.bool,
+    pictureInPicture: ImmutablePropTypes.contains({
+      inUse: PropTypes.bool,
+      available: PropTypes.bool,
+    }),
   };
 
   state = {
@@ -604,7 +609,7 @@ class Status extends ImmutablePureComponent {
 
   render () {
     let ancestors, descendants;
-    const { isLoading, status, settings, ancestorsIds, descendantsIds, intl, domain, multiColumn, usingPiP } = this.props;
+    const { isLoading, status, settings, ancestorsIds, descendantsIds, intl, domain, multiColumn, pictureInPicture } = this.props;
     const { fullscreen } = this.state;
 
     if (isLoading) {
@@ -682,7 +687,7 @@ class Status extends ImmutablePureComponent {
                   domain={domain}
                   showMedia={this.state.showMedia}
                   onToggleMediaVisibility={this.handleToggleMediaVisibility}
-                  usingPiP={usingPiP}
+                  pictureInPicture={pictureInPicture}
                 />
 
                 <ActionBar
diff --git a/app/javascript/flavours/glitch/features/ui/components/columns_area.js b/app/javascript/flavours/glitch/features/ui/components/columns_area.js
index bf3e79c24..993a50796 100644
--- a/app/javascript/flavours/glitch/features/ui/components/columns_area.js
+++ b/app/javascript/flavours/glitch/features/ui/components/columns_area.js
@@ -99,7 +99,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
       if (this.mediaQuery.removeEventListener) {
         this.mediaQuery.removeEventListener('change', this.handleLayoutChange);
       } else {
-        this.mediaQuery.removeListener(this.handleLayouteChange);
+        this.mediaQuery.removeListener(this.handleLayoutChange);
       }
     }
   }
diff --git a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js
index de330b3a1..0dd07fb76 100644
--- a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js
@@ -291,11 +291,11 @@ class FocalPointModal extends ImmutablePureComponent {
     let descriptionLabel = null;
 
     if (media.get('type') === 'audio') {
-      descriptionLabel = <FormattedMessage id='upload_form.audio_description' defaultMessage='Describe for people with hearing loss' />;
+      descriptionLabel = <FormattedMessage id='upload_form.audio_description' defaultMessage='Describe for people who are hard of hearing' />;
     } else if (media.get('type') === 'video') {
-      descriptionLabel = <FormattedMessage id='upload_form.video_description' defaultMessage='Describe for people with hearing loss or visual impairment' />;
+      descriptionLabel = <FormattedMessage id='upload_form.video_description' defaultMessage='Describe for people who are deaf, hard of hearing, blind or have low vision' />;
     } else {
-      descriptionLabel = <FormattedMessage id='upload_form.description' defaultMessage='Describe for the visually impaired' />;
+      descriptionLabel = <FormattedMessage id='upload_form.description' defaultMessage='Describe for people who are blind or have low vision' />;
     }
 
     let ocrMessage = '';
diff --git a/app/javascript/flavours/glitch/features/ui/components/link_footer.js b/app/javascript/flavours/glitch/features/ui/components/link_footer.js
index 28adf5e06..ac0c78674 100644
--- a/app/javascript/flavours/glitch/features/ui/components/link_footer.js
+++ b/app/javascript/flavours/glitch/features/ui/components/link_footer.js
@@ -52,6 +52,8 @@ class LinkFooter extends React.PureComponent {
     const canInvite = signedIn && ((permissions & PERMISSION_INVITE_USERS) === PERMISSION_INVITE_USERS);
     const canProfileDirectory = profileDirectory;
 
+    const DividingCircle = <span aria-hidden>{' · '}</span>;
+
     return (
       <div className='link-footer'>
         <p>
@@ -60,17 +62,17 @@ class LinkFooter extends React.PureComponent {
           <Link key='about' to='/about'><FormattedMessage id='footer.about' defaultMessage='About' /></Link>
           {canInvite && (
             <>
-              {' · '}
+              {DividingCircle}
               <a key='invites' href='/invites' target='_blank'><FormattedMessage id='footer.invite' defaultMessage='Invite people' /></a>
             </>
           )}
           {canProfileDirectory && (
             <>
-              {' · '}
+              {DividingCircle}
               <Link key='directory' to='/directory'><FormattedMessage id='footer.directory' defaultMessage='Profiles directory' /></Link>
             </>
           )}
-          {' · '}
+          {DividingCircle}
           <Link key='privacy-policy' to='/privacy-policy'><FormattedMessage id='footer.privacy_policy' defaultMessage='Privacy policy' /></Link>
         </p>
 
@@ -78,11 +80,13 @@ class LinkFooter extends React.PureComponent {
           <strong>Mastodon</strong>:
           {' '}
           <a href='https://joinmastodon.org' target='_blank'><FormattedMessage id='footer.about' defaultMessage='About' /></a>
-          {' · '}
+          {DividingCircle}
+          <a href='https://joinmastodon.org/apps' target='_blank'><FormattedMessage id='footer.get_app' defaultMessage='Get the app' /></a>
+          {DividingCircle}
           <Link to='/keyboard-shortcuts'><FormattedMessage id='footer.keyboard_shortcuts' defaultMessage='Keyboard shortcuts' /></Link>
-          {' · '}
+          {DividingCircle}
           <a href={source_url} rel='noopener noreferrer' target='_blank'><FormattedMessage id='footer.source_code' defaultMessage='View source code' /></a>
-          {' · '}
+          {DividingCircle}
           v{version}
         </p>
       </div>
diff --git a/app/javascript/flavours/glitch/features/ui/components/modal_root.js b/app/javascript/flavours/glitch/features/ui/components/modal_root.js
index d2ee28948..379f57cbb 100644
--- a/app/javascript/flavours/glitch/features/ui/components/modal_root.js
+++ b/app/javascript/flavours/glitch/features/ui/components/modal_root.js
@@ -116,13 +116,16 @@ export default class ModalRoot extends React.PureComponent {
     this._modal = c;
   }
 
+  // prevent closing of modal when clicking the overlay
+  noop = () => {}
+
   render () {
     const { type, props, ignoreFocus } = this.props;
     const { backgroundColor } = this.state;
     const visible = !!type;
 
     return (
-      <Base backgroundColor={backgroundColor} onClose={this.handleClose} noEsc={props ? props.noEsc : false} ignoreFocus={ignoreFocus}>
+      <Base backgroundColor={backgroundColor} onClose={props && props.noClose ? this.noop : this.handleClose} noEsc={props ? props.noEsc : false} ignoreFocus={ignoreFocus}>
         {visible && (
           <>
             <BundleContainer fetchComponent={MODAL_COMPONENTS[type]} loading={this.renderLoading(type)} error={this.renderError} renderDelay={200}>
diff --git a/app/javascript/flavours/glitch/features/ui/components/video_modal.js b/app/javascript/flavours/glitch/features/ui/components/video_modal.js
index 6b6e615a6..90be11e4b 100644
--- a/app/javascript/flavours/glitch/features/ui/components/video_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/video_modal.js
@@ -50,6 +50,7 @@ export default class VideoModal extends ImmutablePureComponent {
             autoPlay={options.autoPlay}
             volume={options.defaultVolume}
             onCloseVideo={onClose}
+            autoFocus
             detailed
             alt={media.get('description')}
           />
diff --git a/app/javascript/flavours/glitch/features/video/index.js b/app/javascript/flavours/glitch/features/video/index.js
index cb4655f7f..0daab747b 100644
--- a/app/javascript/flavours/glitch/features/video/index.js
+++ b/app/javascript/flavours/glitch/features/video/index.js
@@ -124,6 +124,7 @@ class Video extends React.PureComponent {
     volume: PropTypes.number,
     muted: PropTypes.bool,
     componentIndex: PropTypes.number,
+    autoFocus: PropTypes.bool,
   };
 
   static defaultProps = {
@@ -537,7 +538,7 @@ class Video extends React.PureComponent {
   }
 
   render () {
-    const { preview, src, inline, onOpenVideo, onCloseVideo, intl, alt, letterbox, fullwidth, detailed, sensitive, editable, blurhash } = this.props;
+    const { preview, src, inline, onOpenVideo, onCloseVideo, intl, alt, letterbox, fullwidth, detailed, sensitive, editable, blurhash, autoFocus } = this.props;
     const { containerWidth, currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
     const progress = Math.min((currentTime / duration) * 100, 100);
     const playerStyle = {};
@@ -635,7 +636,7 @@ class Video extends React.PureComponent {
 
           <div className='video-player__buttons-bar'>
             <div className='video-player__buttons left'>
-              <button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay} autoFocus={detailed}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
+              <button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay} autoFocus={autoFocus}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
               <button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} className='player-button' onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
 
               <div className={classNames('video-player__volume', { active: this.state.hovered })} onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
diff --git a/app/javascript/flavours/glitch/load_polyfills.js b/app/javascript/flavours/glitch/load_polyfills.js
index cc5bcd18f..f5a897f75 100644
--- a/app/javascript/flavours/glitch/load_polyfills.js
+++ b/app/javascript/flavours/glitch/load_polyfills.js
@@ -23,15 +23,14 @@ function loadPolyfills() {
   );
 
   // Latest version of Firefox and Safari do not have IntersectionObserver.
-  // Edge does not have requestIdleCallback and object-fit CSS property.
+  // Edge does not have requestIdleCallback.
   // This avoids shipping them all the polyfills.
   const needsExtraPolyfills = !(
     window.AbortController &&
     window.IntersectionObserver &&
     window.IntersectionObserverEntry &&
     'isIntersecting' in IntersectionObserverEntry.prototype &&
-    window.requestIdleCallback &&
-    'object-fit' in (new Image()).style
+    window.requestIdleCallback
   );
 
   return Promise.all([
diff --git a/app/javascript/flavours/glitch/locales/af.js b/app/javascript/flavours/glitch/locales/af.js
deleted file mode 100644
index 4c97b644a..000000000
--- a/app/javascript/flavours/glitch/locales/af.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/af.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/af.json b/app/javascript/flavours/glitch/locales/af.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/af.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/an.json b/app/javascript/flavours/glitch/locales/an.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/an.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/ar.js b/app/javascript/flavours/glitch/locales/ar.js
deleted file mode 100644
index 1081147d5..000000000
--- a/app/javascript/flavours/glitch/locales/ar.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ar.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ar.json b/app/javascript/flavours/glitch/locales/ar.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ar.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/ast.js b/app/javascript/flavours/glitch/locales/ast.js
deleted file mode 100644
index 41355c24c..000000000
--- a/app/javascript/flavours/glitch/locales/ast.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ast.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ast.json b/app/javascript/flavours/glitch/locales/ast.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ast.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/be.json b/app/javascript/flavours/glitch/locales/be.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/be.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/bg.js b/app/javascript/flavours/glitch/locales/bg.js
deleted file mode 100644
index 979039376..000000000
--- a/app/javascript/flavours/glitch/locales/bg.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/bg.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/bg.json b/app/javascript/flavours/glitch/locales/bg.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/bg.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/bn.js b/app/javascript/flavours/glitch/locales/bn.js
deleted file mode 100644
index a453498b3..000000000
--- a/app/javascript/flavours/glitch/locales/bn.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/bn.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/bn.json b/app/javascript/flavours/glitch/locales/bn.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/bn.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/br.js b/app/javascript/flavours/glitch/locales/br.js
deleted file mode 100644
index 966bd1b2f..000000000
--- a/app/javascript/flavours/glitch/locales/br.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/br.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/br.json b/app/javascript/flavours/glitch/locales/br.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/br.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/bs.json b/app/javascript/flavours/glitch/locales/bs.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/bs.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/ca.js b/app/javascript/flavours/glitch/locales/ca.js
deleted file mode 100644
index baf76bd6f..000000000
--- a/app/javascript/flavours/glitch/locales/ca.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ca.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ca.json b/app/javascript/flavours/glitch/locales/ca.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ca.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/ckb.js b/app/javascript/flavours/glitch/locales/ckb.js
deleted file mode 100644
index c2e177d5f..000000000
--- a/app/javascript/flavours/glitch/locales/ckb.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ckb.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ckb.json b/app/javascript/flavours/glitch/locales/ckb.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ckb.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/co.js b/app/javascript/flavours/glitch/locales/co.js
deleted file mode 100644
index 6e9e46797..000000000
--- a/app/javascript/flavours/glitch/locales/co.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/co.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/co.json b/app/javascript/flavours/glitch/locales/co.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/co.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/cs.js b/app/javascript/flavours/glitch/locales/cs.js
deleted file mode 100644
index e789facb0..000000000
--- a/app/javascript/flavours/glitch/locales/cs.js
+++ /dev/null
@@ -1,180 +0,0 @@
-import inherited from 'mastodon/locales/cs.json';
-
-const messages = {
-  'about.fork_disclaimer': 'Glitch-soc je svobodný software s otevřeným zdrojovým kódem založený na Mastodonu.',
-  'settings.layout_opts': 'Možnosti rozvržení',
-  'settings.layout': 'Rozložení:',
-  'layout.current_is': 'Nastavené rozložení je:',
-  'layout.auto': 'Automatické',
-  'layout.desktop': 'Desktop',
-  'layout.mobile': 'Mobil',
-  'layout.hint.auto': 'Vybrat rozložení automaticky v závislosti na nastavení “Povolit pokročilé webové rozhraní” a velikosti obrazovky.',
-  'layout.hint.desktop': 'Použít vícesloupcové rozložení nezávisle na nastavení “Povolit pokročilé webové rozhraní” a velikosti obrazovky.',
-  'layout.hint.single': 'Použít jednosloupcové rozložení nezávisle na nastavení “Povolit pokročilé webové rozhraní” a velikosti obrazovky.',
-  'navigation_bar.app_settings': 'Nastavení aplikace',
-  'navigation_bar.featured_users': 'Vybraní uživatelé',
-  'endorsed_accounts_editor.endorsed_accounts': 'Vybrané účty',
-  'navigation_bar.info': 'Rozšířené informace',
-  'navigation_bar.misc': 'Různé',
-  'navigation_bar.keyboard_shortcuts': 'Klávesové zkratky',
-  'getting_started.onboarding': 'Ukaž mi to tu', 
-  'onboarding.skip': 'Přeskočit',
-  'onboarding.next': 'Další',
-  'onboarding.done': 'Hotovo',
-  'onboarding.page_one.federation': '{domain} je \'instance\' Mastodonu. Mastodon je síť nezávislých serverů, které jsou spolu propojené do jedné velké sociální sítě. Těmto serverům říkáme instance.',
-  'onboarding.page_one.handle': 'Jste na instanci {domain}, takže celá adresa vašeho profilu je {handle}',
-  'onboarding.page_one.welcome': 'Vítá vás {domain}!',
-  'onboarding.page_two.compose': 'Příspěvky se píší v levém sloupci. Pomocí ikon pod příspěvkem k němu můžete připojit obrázky, změnit úroveň soukromí nebo přidat varování o obsahu.',
-  'onboarding.page_three.search': 'Pomocí vyhledávací lišty můžete hledat lidi nebo hashtagy. Pokud hledáte někoho z jiné instance, musíte použít celou adresu jeho profilu.',
-  'onboarding.page_three.profile': 'Upravte si svůj profil a nastavte si profilový obrázek, jméno, a krátký text o sobě. Naleznete tam i další možnosti nastavení.',
-  'onboarding.page_four.home': 'Domovská časová osa zobrazuje příspěvky od lidí, které sledujete.',
-  'onboarding.page_four.notifications': 'Notifikace se zobrazí, když s vámi někdo interaguje.',
-  'onboarding.page_five.public_timelines': 'Místní časová osa zobrazuje veřejné příspěvky všech uživatelů instance {domain}. Federovaná časová osa zobrazí příspěvky od všech, koho uživatelé instance {domain} sledují. Tyto veřejné časové osy jsou skvělý způsob, jak objevit nové lidi.',
-  'onboarding.page_six.almost_done': 'Skoro hotovo...',
-  'onboarding.page_six.github': 'Na serveru {domain} běží Glitchsoc. Glitchsoc je přátelský {fork} programu {Mastodon}, a je kompatibilní s jakoukoliv jinou mastodoní instancí nebo aplikací. Glitchsoc je zcela svobodný a má otevřený zdrojový kód. Na stránce {github} můžete hlásit chyby, žádat o nové funkce, nebo ke kódu vlastnoručně přispět.',
-  'onboarding.page_six.apps_available': 'Jsou dostupné {apps} pro iOS, Android i jiné platformy.',
-  'onboarding.page_six.various_app': 'mobilní aplikace',
-  'onboarding.page_six.appetoot': 'Veselé mastodonění!',
-  'settings.auto_collapse': 'Automaticky sbalit',
-  'settings.auto_collapse_all': 'Všechno',
-  'settings.auto_collapse_lengthy': 'Dlouhé příspěvky',
-  'settings.auto_collapse_media': 'Příspěvky s přílohami',
-  'settings.auto_collapse_notifications': 'Oznámení',
-  'settings.auto_collapse_reblogs': 'Boosty',
-  'settings.auto_collapse_replies': 'Odpovědi',
-  'settings.show_action_bar': 'Zobrazit ve sbalených příspěvcích tlačítka s akcemi',
-  'settings.close': 'Zavřít',
-  'settings.collapsed_statuses': 'Sbalené příspěvky',
-  'settings.confirm_boost_missing_media_description': 'Zobrazit potvrzovací dialog před boostnutím příspěvku s chybějícími popisky obrázků',
-  'boost_modal.missing_description': 'Příspěvek obsahuje obrázky bez popisků',
-  'settings.enable_collapsed': 'Povolit sbalené příspěvky',
-  'settings.enable_collapsed_hint': 'U sbalených příspěvků je část jejich obsahu skrytá, aby zabraly méně místa na obrazovce. (Tohle není stejná funkce jako varování o obsahu.)',
-  'settings.general': 'Obecné',
-  'settings.hicolor_privacy_icons': 'Barevné ikony soukromí',
-  'settings.hicolor_privacy_icons.hint': 'Zobrazit ikony úrovně soukromí příspěvků v jasných, snadno rozlišitelných barvách',
-  'settings.image_backgrounds': 'Obrázkové pozadí',
-  'settings.image_backgrounds_media': 'Náhled médií ve sbalených příspěvcích',
-  'settings.image_backgrounds_media_hint': 'Pokud jsou k příspěvku přiložena média, použije se první z nich jako pozadí', 
-  'settings.image_backgrounds_users': 'Nastavit sbaleným příspěvkům obrázkové pozadí',
-  'settings.inline_preview_cards': 'Zobrazit v časové ose náhledy externích odkazů',
-  'settings.media': 'Média',
-  'settings.media_letterbox': 'Neořezávat obrázky',
-  'settings.media_letterbox_hint': 'Místo výřezu obrázku zobrazit obrázek celý, doplněný podle potřeby o prázdné okraje',
-  'settings.media_fullwidth': 'Zobrazit náhledy v plné šířce',
-  'settings.notifications_opts': 'Možnosti oznámení',
-  'settings.notifications.tab_badge': 'Zobrazit počet nepřečtených oznámení',
-  'settings.notifications.tab_badge.hint': 'Počet nepřečtených oznámení se viditelně zobrazí na hlavní stránce (pokud není seznam oznámení viditelný)',
-  'settings.notifications.favicon_badge': 'Zobrazit počet na ikoně serveru',
-  'settings.notifications.favicon_badge.hint': 'Zobrazí počet nepřečtených oznámení na ikoně serveru',
-  'settings.preferences': 'Předvolby',
-  'settings.rewrite_mentions': 'Přepsat zmínky v zobrazených příspěvcích',
-  'settings.rewrite_mentions_no': 'Nepřepisovat zmínky',
-  'settings.rewrite_mentions_acct': 'Přepsat uživatelským jménem a doménou (pokud je účet na jiném serveru)',
-  'settings.rewrite_mentions_username': 'Přepsat uživatelským jménem',
-  'settings.show_reply_counter': 'Zobrazit odhad počtu odpovědí',
-  'settings.status_icons': 'Ikony u příspěvků',
-  'settings.status_icons_language': 'Indikace jazyk',
-  'settings.status_icons_reply': 'Indikace odpovědi',
-  'settings.status_icons_local_only': 'Indikace lokálního příspěvku',
-  'settings.status_icons_media': 'Indikace obrázků a anket',
-  'settings.status_icons_visibility': 'Indikace úrovně soukromí',
-  'settings.tag_misleading_links': 'Označit zavádějící odkazy',
-  'settings.tag_misleading_links.hint': 'Zobrazit skutečný cíl u každého odkazu, který ho explicitně nezmiňuje',
-  'settings.wide_view': 'Široké sloupce (pouze v režimu Desktop)',
-  'settings.wide_view_hint': 'Sloupce se roztáhnout, aby lépe vyplnily dostupný prostor.',
-  'settings.navbar_under': 'Navigační lišta vespod (pouze v režimu Mobil)',
-  'settings.compose_box_opts': 'Editační pole',
-  'settings.always_show_spoilers_field': 'Vždy zobrazit pole pro varování o obsahu',
-  'settings.prepend_cw_re': 'Při odpovídání přidat před varování o obsahu “re: ”',
-  'settings.preselect_on_reply': 'Při odpovědi označit uživatelská jména',
-  'settings.preselect_on_reply_hint': 'Při odpovídání na konverzaci s více účastníky se jména všech kromě prvního označí, aby šla jednoduše smazat',
-  'settings.confirm_missing_media_description': 'Zobrazit potvrzovací dialog při odesílání příspěvku, ve kterém chybí popisky obrázků',
-  'settings.confirm_before_clearing_draft': 'Zobrazit potvrzovací dialog před přepsáním právě vytvářené zprávy',
-  'settings.show_content_type_choice': 'Zobrazit volbu formátu příspěvku',
-  'settings.side_arm': 'Vedlejší odesílací tlačítko:',
-  'settings.side_arm.none': 'Žádné',
-  'settings.side_arm_reply_mode': 'Při odpovídání na příspěvek by vedlejší odesílací tlačítko mělo:',  
-  'settings.side_arm_reply_mode.keep': 'Použít svou nastavenou úroveň soukromí',
-  'settings.side_arm_reply_mode.copy': 'Použít úroveň soukromí příspěvku, na který odpovídáte',
-  'settings.side_arm_reply_mode.restrict': 'Zvýšit úroveň soukromí nejméně na úroveň příspěvku, na který odpovídáte',  
-  'settings.content_warnings': 'Varování o obsahu',
-  'settings.content_warnings_shared_state': 'Zobrazit/schovat všechny kopie naráz',
-  'settings.content_warnings_shared_state_hint': 'Tlačítko varování o obsahu bude mít efekt na všechny kopie příspěvku naráz, stejně jako na běžném Mastodonu. Nebude pak možné automaticky sbalit jakoukoliv kopii příspěvku, která má rozbalené varování o obsahu',
-  'settings.content_warnings_media_outside': 'Zobrazit obrázky a videa mimo varování o obsahu',
-  'settings.content_warnings_media_outside_hint': 'Obrázky a videa z příspěvku s varováním o obsahu se zobrazí se separátním přepínačem zobrazení, stejně jako na běžném Mastodonu.',
-  'settings.content_warnings_unfold_opts': 'Možnosti automatického rozbalení',
-  'settings.enable_content_warnings_auto_unfold': 'Vždy rozbalit příspěvky označené varováním o obsahu',
-  'settings.deprecated_setting': 'Tato možnost se nyní nastavuje v {settings_page_link}',
-  'settings.shared_settings_link': 'předvolbách Mastodonu',
-  'settings.content_warnings_filter': 'Tato varování o obsahu automaticky nerozbalovat:',
-  'settings.content_warnings.regexp': 'Regulární výraz',
-  'settings.media_reveal_behind_cw': 'Automaticky zobrazit média označená varováním o obsahu',
-  'settings.pop_in_player': 'Povolit plovoucí okno přehrávače',
-  'settings.pop_in_position': 'Pozice plovoucího okna:',
-  'settings.pop_in_left': 'Vlevo',
-  'settings.pop_in_right': 'Vpravo',
- 
-  
-  'status.collapse': 'Sbalit',
-  'status.uncollapse': 'Rozbalit',  
-  'status.in_reply_to': 'Tento příspěvek je odpověď',
-  'status.has_preview_card': 'Obsahuje náhled odkazu',
-  'status.has_pictures': 'Obsahuje obrázky',
-  'status.is_poll': 'Tento příspěvek je anketa',
-  'status.has_video': 'Obsahuje video',
-  'status.has_audio': 'Obsahuje audio',
-  'status.local_only': 'Viditelné pouze z vaší instance',
-
-  'media_gallery.sensitive': 'Citlivý obsah',
-
-  'favourite_modal.combo': 'Příště můžete pro přeskočení stisknout {combo}',
-
-  'home.column_settings.show_direct': 'Zobrazit přímé zprávy',
-
-  'notification_purge.start': 'Čistící režim',
-  'notifications.mark_as_read': 'Označit všechna oznámení jako přečtená',
-
-  'notification.markForDeletion': 'Označit pro smazání',
-  'notifications.clear': 'Vymazat všechna oznámení',
-  'notifications.marked_clear_confirmation': 'Určitě chcete trvale smazat všechna vybraná oznámení?',
-  'notifications.marked_clear': 'Smazat vybraná oznámení',
-
-  'notification_purge.btn_all': 'Vybrat\nvše',
-  'notification_purge.btn_none': 'Nevybrat\nnic',
-  'notification_purge.btn_invert': 'Obrátit\nvýběr',
-  'notification_purge.btn_apply': 'Smazat\nvybrané',
-
-  'compose.attach.upload': 'Nahrát soubor',
-  'compose.attach.doodle': 'Něco namalovat',
-  'compose.attach': 'Připojit...',
-
-  'advanced_options.local-only.short': 'Lokální příspěvek',
-  'advanced_options.local-only.long': 'Neposílat na jiné servery',
-  'advanced_options.local-only.tooltip': 'Tento příspěvek je pouze lokální',
-  'advanced_options.icon_title': 'Pokročilá nastavení',
-  'advanced_options.threaded_mode.short': 'Režim vlákna',
-  'advanced_options.threaded_mode.long': 'Po odeslání automaticky otevře pole pro odpověď',
-  'advanced_options.threaded_mode.tooltip': 'Režim vlákna je zapnutý',
-  
-  'home.column_settings.advanced': 'Pokročilé',
-  'home.column_settings.filter_regex': 'Filtrovat podle regulárních výrazů',
-  
-  'compose_form.poll.single_choice': 'Povolit jednu odpověď',
-  'compose_form.poll.multiple_choices': 'Povolit více odpovědí',
-  
-  'compose.content-type.plain': 'Prostý text',
-  'content-type.change': 'Formát příspěvku',
-  'compose_form.spoiler': 'Přidat varování o obsahu',
-  
-  'direct.group_by_conversations': 'Seskupit do konverzací',
-  'column.toot': 'Příspěvky a odpovědi',
-  'confirmation_modal.do_not_ask_again': 'Příště se už neptat',
-  
-  'keyboard_shortcuts.bookmark': 'Přidat do záložek',
-  'keyboard_shortcuts.toggle_collapse': 'Sbalit/rozbalit příspěvek',
-  'keyboard_shortcuts.secondary_toot': 'Odeslat příspěvek s druhotným nastavením soukromí',
-  
-  'column.subheading': 'Různé',
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/cs.json b/app/javascript/flavours/glitch/locales/cs.json
new file mode 100644
index 000000000..09ad53140
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/cs.json
@@ -0,0 +1,153 @@
+{
+  "about.fork_disclaimer": "Glitch-soc je svobodný software s otevřeným zdrojovým kódem založený na Mastodonu.",
+  "advanced_options.icon_title": "Pokročilá nastavení",
+  "advanced_options.local-only.long": "Neposílat na jiné servery",
+  "advanced_options.local-only.short": "Lokální příspěvek",
+  "advanced_options.local-only.tooltip": "Tento příspěvek je pouze lokální",
+  "advanced_options.threaded_mode.long": "Po odeslání automaticky otevře pole pro odpověď",
+  "advanced_options.threaded_mode.short": "Režim vlákna",
+  "advanced_options.threaded_mode.tooltip": "Režim vlákna je zapnutý",
+  "boost_modal.missing_description": "Příspěvek obsahuje obrázky bez popisků",
+  "column.subheading": "Různé",
+  "compose.attach": "Připojit...",
+  "compose.attach.doodle": "Něco namalovat",
+  "compose.attach.upload": "Nahrát soubor",
+  "compose.content-type.plain": "Prostý text",
+  "compose_form.poll.multiple_choices": "Povolit více odpovědí",
+  "compose_form.poll.single_choice": "Povolit jednu odpověď",
+  "compose_form.spoiler": "Přidat varování o obsahu",
+  "confirmation_modal.do_not_ask_again": "Příště se už neptat",
+  "content-type.change": "Formát příspěvku",
+  "direct.group_by_conversations": "Seskupit do konverzací",
+  "endorsed_accounts_editor.endorsed_accounts": "Vybrané účty",
+  "favourite_modal.combo": "Příště můžete pro přeskočení stisknout {combo}",
+  "getting_started.onboarding": "Ukaž mi to tu",
+  "home.column_settings.advanced": "Pokročilé",
+  "home.column_settings.filter_regex": "Filtrovat podle regulárních výrazů",
+  "home.column_settings.show_direct": "Zobrazit přímé zprávy",
+  "keyboard_shortcuts.bookmark": "Přidat do záložek",
+  "keyboard_shortcuts.secondary_toot": "Odeslat příspěvek s druhotným nastavením soukromí",
+  "keyboard_shortcuts.toggle_collapse": "Sbalit/rozbalit příspěvek",
+  "layout.auto": "Automatické",
+  "layout.hint.auto": "Vybrat rozložení automaticky v závislosti na nastavení “Povolit pokročilé webové rozhraní” a velikosti obrazovky.",
+  "layout.hint.desktop": "Použít vícesloupcové rozložení nezávisle na nastavení “Povolit pokročilé webové rozhraní” a velikosti obrazovky.",
+  "layout.hint.single": "Použít jednosloupcové rozložení nezávisle na nastavení “Povolit pokročilé webové rozhraní” a velikosti obrazovky.",
+  "media_gallery.sensitive": "Citlivý obsah",
+  "navigation_bar.app_settings": "Nastavení aplikace",
+  "navigation_bar.featured_users": "Vybraní uživatelé",
+  "navigation_bar.info": "Rozšířené informace",
+  "navigation_bar.keyboard_shortcuts": "Klávesové zkratky",
+  "navigation_bar.misc": "Různé",
+  "notification.markForDeletion": "Označit pro smazání",
+  "notification_purge.btn_all": "Vybrat\nvše",
+  "notification_purge.btn_apply": "Smazat\nvybrané",
+  "notification_purge.btn_invert": "Obrátit\nvýběr",
+  "notification_purge.btn_none": "Nevybrat\nnic",
+  "notification_purge.start": "Čistící režim",
+  "notifications.marked_clear": "Smazat vybraná oznámení",
+  "notifications.marked_clear_confirmation": "Určitě chcete trvale smazat všechna vybraná oznámení?",
+  "onboarding.done": "Hotovo",
+  "onboarding.next": "Další",
+  "onboarding.page_five.public_timelines": "Místní časová osa zobrazuje veřejné příspěvky všech uživatelů instance {domain}. Federovaná časová osa zobrazí příspěvky od všech, koho uživatelé instance {domain} sledují. Tyto veřejné časové osy jsou skvělý způsob, jak objevit nové lidi.",
+  "onboarding.page_four.home": "Domovská časová osa zobrazuje příspěvky od lidí, které sledujete.",
+  "onboarding.page_four.notifications": "Notifikace se zobrazí, když s vámi někdo interaguje.",
+  "onboarding.page_one.federation": "{domain} je 'instance' Mastodonu. Mastodon je síť nezávislých serverů, které jsou spolu propojené do jedné velké sociální sítě. Těmto serverům říkáme instance.",
+  "onboarding.page_one.handle": "Jste na instanci {domain}, takže celá adresa vašeho profilu je {handle}",
+  "onboarding.page_one.welcome": "Vítá vás {domain}!",
+  "onboarding.page_six.almost_done": "Skoro hotovo...",
+  "onboarding.page_six.appetoot": "Veselé mastodonění!",
+  "onboarding.page_six.apps_available": "Jsou dostupné {apps} pro iOS, Android i jiné platformy.",
+  "onboarding.page_six.github": "Na serveru {domain} běží Glitchsoc. Glitchsoc je přátelský {fork} programu {Mastodon}, a je kompatibilní s jakoukoliv jinou mastodoní instancí nebo aplikací. Glitchsoc je zcela svobodný a má otevřený zdrojový kód. Na stránce {github} můžete hlásit chyby, žádat o nové funkce, nebo ke kódu vlastnoručně přispět.",
+  "onboarding.page_six.various_app": "mobilní aplikace",
+  "onboarding.page_three.profile": "Upravte si svůj profil a nastavte si profilový obrázek, jméno, a krátký text o sobě. Naleznete tam i další možnosti nastavení.",
+  "onboarding.page_three.search": "Pomocí vyhledávací lišty můžete hledat lidi nebo hashtagy. Pokud hledáte někoho z jiné instance, musíte použít celou adresu jeho profilu.",
+  "onboarding.page_two.compose": "Příspěvky se píší v levém sloupci. Pomocí ikon pod příspěvkem k němu můžete připojit obrázky, změnit úroveň soukromí nebo přidat varování o obsahu.",
+  "onboarding.skip": "Přeskočit",
+  "settings.always_show_spoilers_field": "Vždy zobrazit pole pro varování o obsahu",
+  "settings.auto_collapse": "Automaticky sbalit",
+  "settings.auto_collapse_all": "Všechno",
+  "settings.auto_collapse_lengthy": "Dlouhé příspěvky",
+  "settings.auto_collapse_media": "Příspěvky s přílohami",
+  "settings.auto_collapse_notifications": "Oznámení",
+  "settings.auto_collapse_reblogs": "Boosty",
+  "settings.auto_collapse_replies": "Odpovědi",
+  "settings.close": "Zavřít",
+  "settings.collapsed_statuses": "Sbalené příspěvky",
+  "settings.compose_box_opts": "Editační pole",
+  "settings.confirm_before_clearing_draft": "Zobrazit potvrzovací dialog před přepsáním právě vytvářené zprávy",
+  "settings.confirm_boost_missing_media_description": "Zobrazit potvrzovací dialog před boostnutím příspěvku s chybějícími popisky obrázků",
+  "settings.confirm_missing_media_description": "Zobrazit potvrzovací dialog při odesílání příspěvku, ve kterém chybí popisky obrázků",
+  "settings.content_warnings": "Varování o obsahu",
+  "settings.content_warnings.regexp": "Regulární výraz",
+  "settings.content_warnings_filter": "Tato varování o obsahu automaticky nerozbalovat:",
+  "settings.content_warnings_media_outside": "Zobrazit obrázky a videa mimo varování o obsahu",
+  "settings.content_warnings_media_outside_hint": "Obrázky a videa z příspěvku s varováním o obsahu se zobrazí se separátním přepínačem zobrazení, stejně jako na běžném Mastodonu.",
+  "settings.content_warnings_shared_state": "Zobrazit/schovat všechny kopie naráz",
+  "settings.content_warnings_shared_state_hint": "Tlačítko varování o obsahu bude mít efekt na všechny kopie příspěvku naráz, stejně jako na běžném Mastodonu. Nebude pak možné automaticky sbalit jakoukoliv kopii příspěvku, která má rozbalené varování o obsahu",
+  "settings.content_warnings_unfold_opts": "Možnosti automatického rozbalení",
+  "settings.deprecated_setting": "Tato možnost se nyní nastavuje v {settings_page_link}",
+  "settings.enable_collapsed": "Povolit sbalené příspěvky",
+  "settings.enable_collapsed_hint": "U sbalených příspěvků je část jejich obsahu skrytá, aby zabraly méně místa na obrazovce. (Tohle není stejná funkce jako varování o obsahu.)",
+  "settings.enable_content_warnings_auto_unfold": "Vždy rozbalit příspěvky označené varováním o obsahu",
+  "settings.general": "Obecné",
+  "settings.hicolor_privacy_icons": "Barevné ikony soukromí",
+  "settings.hicolor_privacy_icons.hint": "Zobrazit ikony úrovně soukromí příspěvků v jasných, snadno rozlišitelných barvách",
+  "settings.image_backgrounds": "Obrázkové pozadí",
+  "settings.image_backgrounds_media": "Náhled médií ve sbalených příspěvcích",
+  "settings.image_backgrounds_media_hint": "Pokud jsou k příspěvku přiložena média, použije se první z nich jako pozadí",
+  "settings.image_backgrounds_users": "Nastavit sbaleným příspěvkům obrázkové pozadí",
+  "settings.inline_preview_cards": "Zobrazit v časové ose náhledy externích odkazů",
+  "settings.layout": "Rozložení:",
+  "settings.layout_opts": "Možnosti rozvržení",
+  "settings.media": "Média",
+  "settings.media_fullwidth": "Zobrazit náhledy v plné šířce",
+  "settings.media_letterbox": "Neořezávat obrázky",
+  "settings.media_letterbox_hint": "Místo výřezu obrázku zobrazit obrázek celý, doplněný podle potřeby o prázdné okraje",
+  "settings.media_reveal_behind_cw": "Automaticky zobrazit média označená varováním o obsahu",
+  "settings.notifications.favicon_badge": "Zobrazit počet na ikoně serveru",
+  "settings.notifications.favicon_badge.hint": "Zobrazí počet nepřečtených oznámení na ikoně serveru",
+  "settings.notifications.tab_badge": "Zobrazit počet nepřečtených oznámení",
+  "settings.notifications.tab_badge.hint": "Počet nepřečtených oznámení se viditelně zobrazí na hlavní stránce (pokud není seznam oznámení viditelný)",
+  "settings.notifications_opts": "Možnosti oznámení",
+  "settings.pop_in_left": "Vlevo",
+  "settings.pop_in_player": "Povolit plovoucí okno přehrávače",
+  "settings.pop_in_position": "Pozice plovoucího okna:",
+  "settings.pop_in_right": "Vpravo",
+  "settings.preferences": "Předvolby",
+  "settings.prepend_cw_re": "Při odpovídání přidat před varování o obsahu “re: ”",
+  "settings.preselect_on_reply": "Při odpovědi označit uživatelská jména",
+  "settings.preselect_on_reply_hint": "Při odpovídání na konverzaci s více účastníky se jména všech kromě prvního označí, aby šla jednoduše smazat",
+  "settings.rewrite_mentions": "Přepsat zmínky v zobrazených příspěvcích",
+  "settings.rewrite_mentions_acct": "Přepsat uživatelským jménem a doménou (pokud je účet na jiném serveru)",
+  "settings.rewrite_mentions_no": "Nepřepisovat zmínky",
+  "settings.rewrite_mentions_username": "Přepsat uživatelským jménem",
+  "settings.shared_settings_link": "předvolbách Mastodonu",
+  "settings.show_action_bar": "Zobrazit ve sbalených příspěvcích tlačítka s akcemi",
+  "settings.show_content_type_choice": "Zobrazit volbu formátu příspěvku",
+  "settings.show_reply_counter": "Zobrazit odhad počtu odpovědí",
+  "settings.side_arm": "Vedlejší odesílací tlačítko:",
+  "settings.side_arm.none": "Žádné",
+  "settings.side_arm_reply_mode": "Při odpovídání na příspěvek by vedlejší odesílací tlačítko mělo:",
+  "settings.side_arm_reply_mode.copy": "Použít úroveň soukromí příspěvku, na který odpovídáte",
+  "settings.side_arm_reply_mode.keep": "Použít svou nastavenou úroveň soukromí",
+  "settings.side_arm_reply_mode.restrict": "Zvýšit úroveň soukromí nejméně na úroveň příspěvku, na který odpovídáte",
+  "settings.status_icons": "Ikony u příspěvků",
+  "settings.status_icons_language": "Indikace jazyk",
+  "settings.status_icons_local_only": "Indikace lokálního příspěvku",
+  "settings.status_icons_media": "Indikace obrázků a anket",
+  "settings.status_icons_reply": "Indikace odpovědi",
+  "settings.status_icons_visibility": "Indikace úrovně soukromí",
+  "settings.tag_misleading_links": "Označit zavádějící odkazy",
+  "settings.tag_misleading_links.hint": "Zobrazit skutečný cíl u každého odkazu, který ho explicitně nezmiňuje",
+  "settings.wide_view": "Široké sloupce (pouze v režimu Desktop)",
+  "settings.wide_view_hint": "Sloupce se roztáhnout, aby lépe vyplnily dostupný prostor.",
+  "status.collapse": "Sbalit",
+  "status.has_audio": "Obsahuje audio",
+  "status.has_pictures": "Obsahuje obrázky",
+  "status.has_preview_card": "Obsahuje náhled odkazu",
+  "status.has_video": "Obsahuje video",
+  "status.in_reply_to": "Tento příspěvek je odpověď",
+  "status.is_poll": "Tento příspěvek je anketa",
+  "status.local_only": "Viditelné pouze z vaší instance",
+  "status.uncollapse": "Rozbalit"
+}
diff --git a/app/javascript/flavours/glitch/locales/cy.js b/app/javascript/flavours/glitch/locales/cy.js
deleted file mode 100644
index 09412bd72..000000000
--- a/app/javascript/flavours/glitch/locales/cy.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/cy.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/cy.json b/app/javascript/flavours/glitch/locales/cy.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/cy.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/da.js b/app/javascript/flavours/glitch/locales/da.js
deleted file mode 100644
index 2b08806be..000000000
--- a/app/javascript/flavours/glitch/locales/da.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/da.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/da.json b/app/javascript/flavours/glitch/locales/da.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/da.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/de.js b/app/javascript/flavours/glitch/locales/de.js
deleted file mode 100644
index ce6453623..000000000
--- a/app/javascript/flavours/glitch/locales/de.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/de.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/de.json b/app/javascript/flavours/glitch/locales/de.json
new file mode 100644
index 000000000..c5e3cdb35
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/de.json
@@ -0,0 +1,200 @@
+{
+  "about.fork_disclaimer": "Glitch-soc ist freie, quelloffene Software geforkt von Mastodon.",
+  "account.add_account_note": "Notiz für @{name} hinzufügen",
+  "account.disclaimer_full": "Die folgenden Informationen könnten das Profil des Nutzers unvollständig wiedergeben.",
+  "account.follows": "Folgt",
+  "account.joined": "Beigetreten am {date}",
+  "account.suspended_disclaimer_full": "Dieser Nutzer wurde durch einen Moderator gesperrt.",
+  "account.view_full_profile": "Vollständiges Profil anzeigen",
+  "account_note.cancel": "Abbrechen",
+  "account_note.edit": "Bearbeiten",
+  "account_note.glitch_placeholder": "Kein Kommentar angegeben",
+  "account_note.save": "Speichern",
+  "advanced_options.icon_title": "Erweiterte Optionen",
+  "advanced_options.local-only.long": "Nicht auf anderen Instanzen posten",
+  "advanced_options.local-only.short": "Nur lokal",
+  "advanced_options.local-only.tooltip": "Dieser Post ist nur lokal",
+  "advanced_options.threaded_mode.long": "Öffnet automatisch eine Antwort beim Schreiben",
+  "advanced_options.threaded_mode.short": "Thread-Modus",
+  "advanced_options.threaded_mode.tooltip": "Thread-Modus aktiviert",
+  "boost_modal.missing_description": "Dieser Toot enthält Medien ohne Beschreibung",
+  "column.favourited_by": "Favorisiert von",
+  "column.heading": "Sonstiges",
+  "column.reblogged_by": "Geteilt von",
+  "column.subheading": "Sonstige Optionen",
+  "column_header.profile": "Profil",
+  "column_subheading.lists": "Listen",
+  "column_subheading.navigation": "Navigation",
+  "community.column_settings.allow_local_only": "Nur-lokale Toots anzeigen",
+  "compose.attach": "Anhängen...",
+  "compose.attach.doodle": "Etwas zeichnen",
+  "compose.attach.upload": "Eine Datei hochladen",
+  "compose.content-type.html": "HTML",
+  "compose.content-type.markdown": "Markdown",
+  "compose.content-type.plain": "Unformatierter Text",
+  "compose_form.poll.multiple_choices": "Mehrfachauswahl erlauben",
+  "compose_form.poll.single_choice": "Eine Auswahl erlauben",
+  "compose_form.spoiler": "Text hinter Warnung verbergen",
+  "confirmation_modal.do_not_ask_again": "Nicht erneut nach Bestätigung fragen",
+  "confirmations.deprecated_settings.confirm": "Mastodon-Einstellungen verwenden",
+  "confirmations.deprecated_settings.message": "Einige der von dir verwendeten, glitch-soc-spezifischen {app_settings} wurden durch Mastodon {preferences} ersetzt und werden überschrieben:",
+  "confirmations.missing_media_description.confirm": "Trotzdem absenden",
+  "confirmations.missing_media_description.edit": "Anhänge bearbeiten",
+  "confirmations.missing_media_description.message": "Mindestens einem Anhang fehlt eine Beschreibung. Denke darüber nach, alle Anhänge für Sehbeeinträchtigte zu beschreiben, bevor du den Toot absendest.",
+  "confirmations.unfilter.author": "Urheber",
+  "confirmations.unfilter.confirm": "Anzeigen",
+  "confirmations.unfilter.edit_filter": "Filter bearbeiten",
+  "confirmations.unfilter.filters": "Passende{count, plural, one {r} other {}} Filter",
+  "content-type.change": "Inhaltstyp",
+  "direct.group_by_conversations": "Nach Unterhaltung gruppieren",
+  "endorsed_accounts_editor.endorsed_accounts": "Empfohlene Konten",
+  "favourite_modal.combo": "Mit {combo} wird dieses Fenster beim nächsten Mal nicht mehr angezeigt",
+  "getting_started.onboarding": "Führe mich herum",
+  "home.column_settings.advanced": "Erweitert",
+  "home.column_settings.filter_regex": "Mit regulären Ausdrücken herausfiltern",
+  "home.column_settings.show_direct": "Direktnachrichten anzeigen",
+  "home.settings": "Spalteneinstellungen",
+  "keyboard_shortcuts.bookmark": "zu Lesezeichen hinzufügen",
+  "keyboard_shortcuts.secondary_toot": "Toot mit sekundärer Privatsphäreeinstellung absenden",
+  "keyboard_shortcuts.toggle_collapse": "Toots ein-/ausklappen",
+  "layout.auto": "Automatisch",
+  "layout.desktop": "Desktop",
+  "layout.hint.auto": "Automatisch das Layout anhand der Einstellung \"Erweitertes Webinterface verwenden\" und Bildschirmgröße auswählen.",
+  "layout.hint.desktop": "Das mehrspaltige Layout verwenden, unabhängig von der Einstellung \"Erweitertes Webinterface verwenden\".",
+  "layout.hint.single": "Das einspaltige Layout verwenden, unabhängig von der Einstellung \"Erweitertes Webinterface verwenden\".",
+  "layout.single": "Mobil",
+  "media_gallery.sensitive": "Empfindlich",
+  "moved_to_warning": "Dieses Konto ist als verschoben zu {moved_to_link} markiert und akzeptiert daher keine neuen Follower.",
+  "navigation_bar.app_settings": "App-Einstellungen",
+  "navigation_bar.featured_users": "Empfohlene Nutzer",
+  "navigation_bar.info": "Erweiterte Informationen",
+  "navigation_bar.keyboard_shortcuts": "Tastaturkürzel",
+  "navigation_bar.misc": "Sonstiges",
+  "notification.markForDeletion": "Zum Entfernen auswählen",
+  "notification_purge.btn_all": "Alle\nauswählen",
+  "notification_purge.btn_apply": "Ausgewählte\nentfernen",
+  "notification_purge.btn_invert": "Auswahl\numkehren",
+  "notification_purge.btn_none": "Auswahl\naufheben",
+  "notification_purge.start": "Benachrichtigungen-Aufräumen-Modus starten",
+  "notifications.marked_clear": "Ausgewählte Benachrichtigungen entfernen",
+  "notifications.marked_clear_confirmation": "Möchtest du wirklich alle auswählten Benachrichtigungen für immer entfernen?",
+  "onboarding.done": "Fertig",
+  "onboarding.next": "Weiter",
+  "onboarding.page_five.public_timelines": "Die lokale Timeline zeigt öffentliche Posts von allen auf {domain}. Die föderierte Timeline zeigt öffentliche Posts von allen, denen Leute auf {domain} folgen. Das sind die öffentlichen Timelines, eine tolle Möglichkeit, neue Leute zu entdecken.",
+  "onboarding.page_four.home": "Die Startseite zeigt Posts von Leuten an, denen du folgst.",
+  "onboarding.page_four.notifications": "Die Benachrichtigungs-Spalte zeigt an, wenn jemand mit dir interagiert.",
+  "onboarding.page_one.federation": "{domain} ist eine \"Instanz\" von Mastodon. Mastodon ist ein Netzwerk aus unabhängigen Servern, die zusammen ein größeres soziales Netzwerk bilden. Diese Server nennen wir Instanzen.",
+  "onboarding.page_one.handle": "Du bist auf {domain}, also ist dein vollständiger Nutzername {handle}",
+  "onboarding.page_one.welcome": "Willkommen auf {domain}!",
+  "onboarding.page_six.admin": "Dein Instanz-Admin ist {admin}.",
+  "onboarding.page_six.almost_done": "Fast geschafft...",
+  "onboarding.page_six.appetoot": "Bon Appetoot!",
+  "onboarding.page_six.apps_available": "Es gibt {apps} für iOS, Android und andere Plattformen.",
+  "onboarding.page_six.github": "{domain} läuft auf glitch-soc. glitch-soc ist ein freundlicher {fork} von {Mastodon}, und ist mit jeder Mastodon-App oder -Instanz kompatibel. glitch-soc ist komplett frei und quelloffen. Auf {github} kannst du Fehler melden, Features anfragen oder Code beitragen.",
+  "onboarding.page_six.guidelines": "Community-Richtlinien",
+  "onboarding.page_six.read_guidelines": "Bitte lies die {guidelines} von {domain}!",
+  "onboarding.page_six.various_app": "mobile Apps",
+  "onboarding.page_three.profile": "Bearbeite dein Profil, um deinen Avatar, \"Über mich\" und den Anzeigenamen zu ändern. Dort findest du auch andere Einstellungen.",
+  "onboarding.page_three.search": "Benutze die Suchleiste, um Leute zu finden und Hashtags anzusehen, wie etwa {illustration} und {introductions}. Um nach einer Person zu suchen, die nicht auf dieser Instanz ist, benutze deren vollständigen Nutzername.",
+  "onboarding.page_two.compose": "Schreibe Posts in der Verfassen-Spalte. Mit den Symbolen unten kannst du Bilder hochladen, Privatsphäre-Einstellungen ändern, und Inhaltswarnungen hinzufügen.",
+  "onboarding.skip": "Überspringen",
+  "settings.always_show_spoilers_field": "Das Inhaltswarnungs-Feld immer aktivieren",
+  "settings.auto_collapse": "Automatisches Einklappen",
+  "settings.auto_collapse_all": "Alles",
+  "settings.auto_collapse_lengthy": "Lange Toots",
+  "settings.auto_collapse_media": "Toots mit Anhängen",
+  "settings.auto_collapse_notifications": "Benachrichtigungen",
+  "settings.auto_collapse_reblogs": "Geteilte Toots",
+  "settings.auto_collapse_replies": "Antworten",
+  "settings.close": "Schließen",
+  "settings.collapsed_statuses": "Eingeklappte Toots",
+  "settings.compose_box_opts": "Verfassen-Box",
+  "settings.confirm_before_clearing_draft": "Zeige einen Bestätigungsdialog, bevor der derzeitige Entwurf verworfen wird",
+  "settings.confirm_boost_missing_media_description": "Zeige einen Bestätigungsdialog, bevor Toots mit Anhängen ohne Beschreibung geteilt werden",
+  "settings.confirm_missing_media_description": "Zeige einen Bestätigungsdialog, bevor Toots mit Anhängen ohne Beschreibung abgesendet werden",
+  "settings.content_warnings": "Content warnings",
+  "settings.content_warnings.regexp": "Regulärer Ausdruck",
+  "settings.content_warnings_filter": "Inhaltswarnungen, die nicht ausgeklappt werden sollen:",
+  "settings.content_warnings_media_outside": "Medienanhänge außerhalb von Inhaltswarnungen anzeigen",
+  "settings.content_warnings_media_outside_hint": "Das ursprüngliche Verhalten von Mastodon wiederherstellen, in welchem Inhaltswarnungen keine Auswirkungen auf Anhänge haben",
+  "settings.content_warnings_shared_state": "Inhalt aller Kopien auf einmal ein-/ausblenden",
+  "settings.content_warnings_shared_state_hint": "Das ursprüngliche Verhalten von Mastodon wiederhertstellen, in welchem der Inhaltswarnungs-Knopf alle Kopien eines Posts auf einmal ein-/ausklappt. Das wird das automatische Einklappen jedweder Kopie eines Toots mit ausgeklappter Inhaltswarnung",
+  "settings.content_warnings_unfold_opts": "Optionen zum automatischen Ausklappen",
+  "settings.deprecated_setting": "Diese Einstellung wird nun von Mastodons {settings_page_link} gesteuert",
+  "settings.enable_collapsed": "Eingeklappte Toots aktivieren",
+  "settings.enable_collapsed_hint": "Eingeklappte Posts haben einen Teil ihres Inhalts verborgen, um weniger Platz am Bildschirm einzunehmen. Das passiert unabhängig von der Inhaltswarnfunktion",
+  "settings.enable_content_warnings_auto_unfold": "Inhaltswarnungen automatisch ausklappen",
+  "settings.general": "Allgemein",
+  "settings.hicolor_privacy_icons": "Eingefärbte Privatsphäre-Symbole",
+  "settings.hicolor_privacy_icons.hint": "Zeige Privatsphäre-Symbole in hellen und leicht zu unterscheidenden Farben",
+  "settings.image_backgrounds": "Bildhintergründe",
+  "settings.image_backgrounds_media": "Vorschau eingeklappter Toot-Anhänge",
+  "settings.image_backgrounds_media_hint": "Wenn der Post Anhänge hat, wird der erste als Hintergrund verwendet",
+  "settings.image_backgrounds_users": "Eingeklappten Toots einen Bild-Hintergrund geben",
+  "settings.inline_preview_cards": "Eingebettete Vorschaukarten für externe Links",
+  "settings.layout": "Layout:",
+  "settings.layout_opts": "Layout-Optionen",
+  "settings.media": "Medien",
+  "settings.media_fullwidth": "Medienvorschau in voller Breite",
+  "settings.media_letterbox": "Mediengröße anpassen",
+  "settings.media_letterbox_hint": "Medien runterskalieren und einpassen um die Bildbehälter zu füllen anstatt zu strecken und zuzuschneiden",
+  "settings.media_reveal_behind_cw": "Empfindliche Medien hinter Inhaltswarnungen standardmäßig anzeigen",
+  "settings.notifications.favicon_badge": "Favicon-Badge für ungelesene Benachrichtigungen",
+  "settings.notifications.favicon_badge.hint": "Ein Badge für ungelesene Benachrichtigungen zum Favicon hinzufügen",
+  "settings.notifications.tab_badge": "Badge für ungelesene Benachrichtigungen",
+  "settings.notifications.tab_badge.hint": "Ein Badge für ungelesene Benachrichtigungen in den Spaltensymbolen anzeigen, wenn die Benachrichtigungen nicht offen sind",
+  "settings.notifications_opts": "Benachrichtigungsoptionen",
+  "settings.pop_in_left": "Links",
+  "settings.pop_in_player": "Pop-In-Player aktivieren",
+  "settings.pop_in_position": "Position des Pop-In-Players:",
+  "settings.pop_in_right": "Rechts",
+  "settings.preferences": "Preferences",
+  "settings.prepend_cw_re": "\"re: \" beim Antworten an Inhaltswarnung voranstellen",
+  "settings.preselect_on_reply": "Nutzernamen bei Antwort vorauswählen",
+  "settings.preselect_on_reply_hint": "Beim Antworten auf eine Konversation alle Nutzernamen auswählen, die nach dem ersten kommen",
+  "settings.rewrite_mentions": "Erwähnungen in angezeigten Status umschreiben",
+  "settings.rewrite_mentions_acct": "Mit Nutzernamen und Domain umschreiben (wenn das Konto auf einer anderen Instanz ist)",
+  "settings.rewrite_mentions_no": "Erwähnungen nicht umschreiben",
+  "settings.rewrite_mentions_username": "Mit Nutzername umschreiben",
+  "settings.shared_settings_link": "Nutzereinstellungen",
+  "settings.show_action_bar": "Aktions-Knöpfe in eingeklappten Toots anzeigen",
+  "settings.show_content_type_choice": "Auswahl für die Inhaltsart beim Verfassen von Toots anzeigen",
+  "settings.show_reply_counter": "Schätzung der Antwortanzahl anzeigen",
+  "settings.side_arm": "Sekundärer Toot-Knopf:",
+  "settings.side_arm.none": "Nichts",
+  "settings.side_arm_reply_mode": "Beim Antworten auf einen Toot sollte der sekundäre Toot-Knopf:",
+  "settings.side_arm_reply_mode.copy": "Privatsphäre-Einstellung des zu beantwortenden Toot verwenden",
+  "settings.side_arm_reply_mode.keep": "Die eingestellte Privatsphäre beibehalten",
+  "settings.side_arm_reply_mode.restrict": "Privatsphäre-Einstellung auf die des zu beantwortenden Toot beschränken",
+  "settings.status_icons": "Toot-Symbole",
+  "settings.status_icons_language": "Sprach-Indikator",
+  "settings.status_icons_local_only": "\"nur Lokal\"-Indikator",
+  "settings.status_icons_media": "Medien- und Umfragen-Indikatoren",
+  "settings.status_icons_reply": "Antwort-Indikator",
+  "settings.status_icons_visibility": "Toot-Privatsphäre-Indikator",
+  "settings.swipe_to_change_columns": "Das Wechseln der Spalte durch Wischen erlauben (nur für die mobile Ansicht)",
+  "settings.tag_misleading_links": "Irreführende Links markieren",
+  "settings.tag_misleading_links.hint": "Füge eine visuelle Indikation mit dem Ziel-Host des Links zu jedem Link hinzu, bei dem dieser nicht explizit genannt wird",
+  "settings.wide_view": "Breite Ansicht (nur für den Desktop-Modus)",
+  "settings.wide_view_hint": "Verbreitert Spalten, um den verfügbaren Platz besser zu füllen.",
+  "status.collapse": "Einklappen",
+  "status.has_audio": "Hat angehängte Audiodateien",
+  "status.has_pictures": "Hat angehängte Bilder",
+  "status.has_preview_card": "Hat eine Vorschaukarte",
+  "status.has_video": "Hat angehängte Videos",
+  "status.in_reply_to": "Dieser Toot ist eine Antwort",
+  "status.is_poll": "Dieser Toot ist eine Umfrage",
+  "status.local_only": "Nur auf deiner Instanz sichtbar",
+  "status.sensitive_toggle": "Zum Anzeigen klicken",
+  "status.uncollapse": "Ausklappen",
+  "web_app_crash.change_your_settings": "Deine {settings} ändern",
+  "web_app_crash.content": "Du kannst folgende Dinge ausprobieren:",
+  "web_app_crash.debug_info": "Debug-Informationen",
+  "web_app_crash.disable_addons": "Browser-Add-ons oder eingebaute Übersetzungswerkzeuge deaktivieren",
+  "web_app_crash.issue_tracker": "Issue-Tracker",
+  "web_app_crash.reload": "neu laden",
+  "web_app_crash.reload_page": "Die Seite {reload}",
+  "web_app_crash.report_issue": "Einen Fehler im {issuetracker} melden",
+  "web_app_crash.settings": "Einstellungen",
+  "web_app_crash.title": "Es tut uns leid, aber mit der Mastodon-App ist etwas schiefgelaufen."
+}
diff --git a/app/javascript/flavours/glitch/locales/defaultMessages.json b/app/javascript/flavours/glitch/locales/defaultMessages.json
new file mode 100644
index 000000000..d7aec67ac
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/defaultMessages.json
@@ -0,0 +1,1064 @@
+[
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "We're sorry, but something went wrong with the Mastodon app.",
+        "id": "web_app_crash.title"
+      },
+      {
+        "defaultMessage": "You could try any of the following:",
+        "id": "web_app_crash.content"
+      },
+      {
+        "defaultMessage": "Disable browser add-ons or built-in translation tools",
+        "id": "web_app_crash.disable_addons"
+      },
+      {
+        "defaultMessage": "Report a bug in the {issuetracker}",
+        "id": "web_app_crash.report_issue"
+      },
+      {
+        "defaultMessage": "issue tracker",
+        "id": "web_app_crash.issue_tracker"
+      },
+      {
+        "defaultMessage": "Debug information",
+        "id": "web_app_crash.debug_info"
+      },
+      {
+        "defaultMessage": "{reload} the current page",
+        "id": "web_app_crash.reload_page"
+      },
+      {
+        "defaultMessage": "Reload",
+        "id": "web_app_crash.reload"
+      },
+      {
+        "defaultMessage": "Change your {settings}",
+        "id": "web_app_crash.change_your_settings"
+      },
+      {
+        "defaultMessage": "settings",
+        "id": "web_app_crash.settings"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/components/error_boundary.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Sensitive",
+        "id": "media_gallery.sensitive"
+      },
+      {
+        "defaultMessage": "Click to view",
+        "id": "status.sensitive_toggle"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/components/media_gallery.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Select\nall",
+        "id": "notification_purge.btn_all"
+      },
+      {
+        "defaultMessage": "Select\nnone",
+        "id": "notification_purge.btn_none"
+      },
+      {
+        "defaultMessage": "Invert\nselection",
+        "id": "notification_purge.btn_invert"
+      },
+      {
+        "defaultMessage": "Clear\nselected",
+        "id": "notification_purge.btn_apply"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/components/notification_purge_buttons.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Collapse",
+        "id": "status.collapse"
+      },
+      {
+        "defaultMessage": "Uncollapse",
+        "id": "status.uncollapse"
+      },
+      {
+        "defaultMessage": "This toot is a reply",
+        "id": "status.in_reply_to"
+      },
+      {
+        "defaultMessage": "Features an attached preview card",
+        "id": "status.has_preview_card"
+      },
+      {
+        "defaultMessage": "Features attached pictures",
+        "id": "status.has_pictures"
+      },
+      {
+        "defaultMessage": "This toot is a poll",
+        "id": "status.is_poll"
+      },
+      {
+        "defaultMessage": "Features attached videos",
+        "id": "status.has_video"
+      },
+      {
+        "defaultMessage": "Features attached audio files",
+        "id": "status.has_audio"
+      },
+      {
+        "defaultMessage": "Only visible from your instance",
+        "id": "status.local_only"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/components/status_icons.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Are you sure you want to permanently clear all selected notifications?",
+        "id": "notifications.marked_clear_confirmation"
+      },
+      {
+        "defaultMessage": "Clear selected notifications",
+        "id": "notifications.marked_clear"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/containers/notification_purge_buttons_container.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Show",
+        "id": "confirmations.unfilter.confirm"
+      },
+      {
+        "defaultMessage": "Author",
+        "id": "confirmations.unfilter.author"
+      },
+      {
+        "defaultMessage": "Matching {count, plural, one {filter} other {filters}}",
+        "id": "confirmations.unfilter.filters"
+      },
+      {
+        "defaultMessage": "Edit filter",
+        "id": "confirmations.unfilter.edit_filter"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/containers/status_container.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Glitch-soc is free open source software forked from Mastodon.",
+        "id": "about.fork_disclaimer"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/about/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "No comment provided",
+        "id": "account_note.glitch_placeholder"
+      },
+      {
+        "defaultMessage": "Cancel",
+        "id": "account_note.cancel"
+      },
+      {
+        "defaultMessage": "Save",
+        "id": "account_note.save"
+      },
+      {
+        "defaultMessage": "Edit",
+        "id": "account_note.edit"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/account/components/account_note.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "This user has been suspended by a moderator.",
+        "id": "account.suspended_disclaimer_full"
+      },
+      {
+        "defaultMessage": "Information below may reflect the user's profile incompletely.",
+        "id": "account.disclaimer_full"
+      },
+      {
+        "defaultMessage": "View full profile",
+        "id": "account.view_full_profile"
+      },
+      {
+        "defaultMessage": "Follows",
+        "id": "account.follows"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/account/components/action_bar.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Add note for @{name}",
+        "id": "account.add_account_note"
+      },
+      {
+        "defaultMessage": "Joined {date}",
+        "id": "account.joined"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/account/components/header.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Profile",
+        "id": "column_header.profile"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/account/components/profile_column_header.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Filter out by regular expressions",
+        "id": "home.column_settings.filter_regex"
+      },
+      {
+        "defaultMessage": "Column settings",
+        "id": "home.settings"
+      },
+      {
+        "defaultMessage": "Advanced",
+        "id": "home.column_settings.advanced"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/community_timeline/components/column_settings.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.",
+        "id": "confirmations.missing_media_description.message"
+      },
+      {
+        "defaultMessage": "Send anyway",
+        "id": "confirmations.missing_media_description.confirm"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/compose/components/compose_form.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "App settings",
+        "id": "navigation_bar.app_settings"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/compose/components/header.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Advanced options",
+        "id": "advanced_options.icon_title"
+      },
+      {
+        "defaultMessage": "Attach...",
+        "id": "compose.attach"
+      },
+      {
+        "defaultMessage": "Content type",
+        "id": "content-type.change"
+      },
+      {
+        "defaultMessage": "Draw something",
+        "id": "compose.attach.doodle"
+      },
+      {
+        "defaultMessage": "HTML",
+        "id": "compose.content-type.html"
+      },
+      {
+        "defaultMessage": "Do not post to other instances",
+        "id": "advanced_options.local-only.long"
+      },
+      {
+        "defaultMessage": "Local-only",
+        "id": "advanced_options.local-only.short"
+      },
+      {
+        "defaultMessage": "Markdown",
+        "id": "compose.content-type.markdown"
+      },
+      {
+        "defaultMessage": "Plain text",
+        "id": "compose.content-type.plain"
+      },
+      {
+        "defaultMessage": "Hide text behind warning",
+        "id": "compose_form.spoiler"
+      },
+      {
+        "defaultMessage": "Automatically opens a reply on posting",
+        "id": "advanced_options.threaded_mode.long"
+      },
+      {
+        "defaultMessage": "Threaded mode",
+        "id": "advanced_options.threaded_mode.short"
+      },
+      {
+        "defaultMessage": "Upload a file",
+        "id": "compose.attach.upload"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/compose/components/options.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Allow one choice",
+        "id": "compose_form.poll.single_choice"
+      },
+      {
+        "defaultMessage": "Allow multiple choices",
+        "id": "compose_form.poll.multiple_choices"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/compose/components/poll_form.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "This post is local-only",
+        "id": "advanced_options.local-only.tooltip"
+      },
+      {
+        "defaultMessage": "Threaded mode enabled",
+        "id": "advanced_options.threaded_mode.tooltip"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/compose/components/textarea_icons.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.",
+        "id": "confirmations.missing_media_description.message"
+      },
+      {
+        "defaultMessage": "Send anyway",
+        "id": "confirmations.missing_media_description.confirm"
+      },
+      {
+        "defaultMessage": "Edit media",
+        "id": "confirmations.missing_media_description.edit"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/compose/containers/compose_form_container.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Filter out by regular expressions",
+        "id": "home.column_settings.filter_regex"
+      },
+      {
+        "defaultMessage": "Column settings",
+        "id": "home.settings"
+      },
+      {
+        "defaultMessage": "Group by conversation",
+        "id": "direct.group_by_conversations"
+      },
+      {
+        "defaultMessage": "Advanced",
+        "id": "home.column_settings.advanced"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/direct_timeline/components/column_settings.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Favourited by",
+        "id": "column.favourited_by"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/favourites/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Misc",
+        "id": "column.heading"
+      },
+      {
+        "defaultMessage": "Miscellaneous options",
+        "id": "column.subheading"
+      },
+      {
+        "defaultMessage": "Extended information",
+        "id": "navigation_bar.info"
+      },
+      {
+        "defaultMessage": "Show me around",
+        "id": "getting_started.onboarding"
+      },
+      {
+        "defaultMessage": "Keyboard shortcuts",
+        "id": "navigation_bar.keyboard_shortcuts"
+      },
+      {
+        "defaultMessage": "Featured users",
+        "id": "navigation_bar.featured_users"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/getting_started_misc/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Navigation",
+        "id": "column_subheading.navigation"
+      },
+      {
+        "defaultMessage": "App settings",
+        "id": "navigation_bar.app_settings"
+      },
+      {
+        "defaultMessage": "Keyboard shortcuts",
+        "id": "navigation_bar.keyboard_shortcuts"
+      },
+      {
+        "defaultMessage": "Lists",
+        "id": "column_subheading.lists"
+      },
+      {
+        "defaultMessage": "Misc",
+        "id": "navigation_bar.misc"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/getting_started/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Filter out by regular expressions",
+        "id": "home.column_settings.filter_regex"
+      },
+      {
+        "defaultMessage": "Column settings",
+        "id": "home.settings"
+      },
+      {
+        "defaultMessage": "Show DMs",
+        "id": "home.column_settings.show_direct"
+      },
+      {
+        "defaultMessage": "Advanced",
+        "id": "home.column_settings.advanced"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/home_timeline/components/column_settings.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "to bookmark",
+        "id": "keyboard_shortcuts.bookmark"
+      },
+      {
+        "defaultMessage": "to collapse/uncollapse toots",
+        "id": "keyboard_shortcuts.toggle_collapse"
+      },
+      {
+        "defaultMessage": "to send toot using secondary privacy setting",
+        "id": "keyboard_shortcuts.secondary_toot"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/keyboard_shortcuts/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "General",
+        "id": "settings.general"
+      },
+      {
+        "defaultMessage": "Compose box",
+        "id": "settings.compose_box_opts"
+      },
+      {
+        "defaultMessage": "Content Warnings",
+        "id": "settings.content_warnings"
+      },
+      {
+        "defaultMessage": "Collapsed toots",
+        "id": "settings.collapsed_statuses"
+      },
+      {
+        "defaultMessage": "Media",
+        "id": "settings.media"
+      },
+      {
+        "defaultMessage": "Preferences",
+        "id": "settings.preferences"
+      },
+      {
+        "defaultMessage": "Close",
+        "id": "settings.close"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/local_settings/navigation/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Auto",
+        "id": "layout.auto"
+      },
+      {
+        "defaultMessage": "Automatically chose layout based on “Enable advanced web interface” setting and screen size.",
+        "id": "layout.hint.auto"
+      },
+      {
+        "defaultMessage": "Desktop",
+        "id": "layout.desktop"
+      },
+      {
+        "defaultMessage": "Use multiple-column layout regardless of the “Enable advanced web interface” setting or screen size.",
+        "id": "layout.hint.desktop"
+      },
+      {
+        "defaultMessage": "Mobile",
+        "id": "layout.single"
+      },
+      {
+        "defaultMessage": "Use single-column layout regardless of the “Enable advanced web interface” setting or screen size.",
+        "id": "layout.hint.single"
+      },
+      {
+        "defaultMessage": "None",
+        "id": "settings.side_arm.none"
+      },
+      {
+        "defaultMessage": "Keep its set privacy",
+        "id": "settings.side_arm_reply_mode.keep"
+      },
+      {
+        "defaultMessage": "Copy privacy setting of the toot being replied to",
+        "id": "settings.side_arm_reply_mode.copy"
+      },
+      {
+        "defaultMessage": "Restrict privacy setting to that of the toot being replied to",
+        "id": "settings.side_arm_reply_mode.restrict"
+      },
+      {
+        "defaultMessage": "Regular expression",
+        "id": "settings.content_warnings.regexp"
+      },
+      {
+        "defaultMessage": "Do not rewrite mentions",
+        "id": "settings.rewrite_mentions_no"
+      },
+      {
+        "defaultMessage": "Rewrite with username and domain (when the account is remote)",
+        "id": "settings.rewrite_mentions_acct"
+      },
+      {
+        "defaultMessage": "Rewrite with username",
+        "id": "settings.rewrite_mentions_username"
+      },
+      {
+        "defaultMessage": "Left",
+        "id": "settings.pop_in_left"
+      },
+      {
+        "defaultMessage": "Right",
+        "id": "settings.pop_in_right"
+      },
+      {
+        "defaultMessage": "General",
+        "id": "settings.general"
+      },
+      {
+        "defaultMessage": "Display an estimate of the reply count",
+        "id": "settings.show_reply_counter"
+      },
+      {
+        "defaultMessage": "High color privacy icons",
+        "id": "settings.hicolor_privacy_icons"
+      },
+      {
+        "defaultMessage": "Display privacy icons in bright and easily distinguishable colors",
+        "id": "settings.hicolor_privacy_icons.hint"
+      },
+      {
+        "defaultMessage": "Show confirmation dialog before boosting toots lacking media descriptions",
+        "id": "settings.confirm_boost_missing_media_description"
+      },
+      {
+        "defaultMessage": "Tag misleading links",
+        "id": "settings.tag_misleading_links"
+      },
+      {
+        "defaultMessage": "Add a visual indication with the link target host to every link not mentioning it explicitly",
+        "id": "settings.tag_misleading_links.hint"
+      },
+      {
+        "defaultMessage": "Rewrite mentions in displayed statuses",
+        "id": "settings.rewrite_mentions"
+      },
+      {
+        "defaultMessage": "Notifications options",
+        "id": "settings.notifications_opts"
+      },
+      {
+        "defaultMessage": "Unread notifications badge",
+        "id": "settings.notifications.tab_badge"
+      },
+      {
+        "defaultMessage": "Display a badge for unread notifications in the column icons when the notifications column isn't open",
+        "id": "settings.notifications.tab_badge.hint"
+      },
+      {
+        "defaultMessage": "Unread notifications favicon badge",
+        "id": "settings.notifications.favicon_badge"
+      },
+      {
+        "defaultMessage": "Add a badge for unread notifications to the favicon",
+        "id": "settings.notifications.favicon_badge.hint"
+      },
+      {
+        "defaultMessage": "Toot icons",
+        "id": "settings.status_icons"
+      },
+      {
+        "defaultMessage": "Language indicator",
+        "id": "settings.status_icons_language"
+      },
+      {
+        "defaultMessage": "Reply indicator",
+        "id": "settings.status_icons_reply"
+      },
+      {
+        "defaultMessage": "Local-only indicator",
+        "id": "settings.status_icons_local_only"
+      },
+      {
+        "defaultMessage": "Media and poll indicators",
+        "id": "settings.status_icons_media"
+      },
+      {
+        "defaultMessage": "Toot privacy indicator",
+        "id": "settings.status_icons_visibility"
+      },
+      {
+        "defaultMessage": "Layout options",
+        "id": "settings.layout_opts"
+      },
+      {
+        "defaultMessage": "Layout:",
+        "id": "settings.layout"
+      },
+      {
+        "defaultMessage": "Wide view (Desktop mode only)",
+        "id": "settings.wide_view"
+      },
+      {
+        "defaultMessage": "Stretches columns to better fill the available space.",
+        "id": "settings.wide_view_hint"
+      },
+      {
+        "defaultMessage": "Compose box",
+        "id": "settings.compose_box_opts"
+      },
+      {
+        "defaultMessage": "Always enable the Content Warning field",
+        "id": "settings.always_show_spoilers_field"
+      },
+      {
+        "defaultMessage": "Prepend “re: ” to content warnings when replying",
+        "id": "settings.prepend_cw_re"
+      },
+      {
+        "defaultMessage": "Pre-select usernames on reply",
+        "id": "settings.preselect_on_reply"
+      },
+      {
+        "defaultMessage": "When replying to a conversation with multiple participants, pre-select usernames past the first",
+        "id": "settings.preselect_on_reply_hint"
+      },
+      {
+        "defaultMessage": "Show confirmation dialog before sending toots lacking media descriptions",
+        "id": "settings.confirm_missing_media_description"
+      },
+      {
+        "defaultMessage": "Show confirmation dialog before overwriting the message being composed",
+        "id": "settings.confirm_before_clearing_draft"
+      },
+      {
+        "defaultMessage": "Show content-type choice when authoring toots",
+        "id": "settings.show_content_type_choice"
+      },
+      {
+        "defaultMessage": "Secondary toot button:",
+        "id": "settings.side_arm"
+      },
+      {
+        "defaultMessage": "When replying to a toot, the secondary toot button should:",
+        "id": "settings.side_arm_reply_mode"
+      },
+      {
+        "defaultMessage": "Content warnings",
+        "id": "settings.content_warnings"
+      },
+      {
+        "defaultMessage": "Show/hide content of all copies at once",
+        "id": "settings.content_warnings_shared_state"
+      },
+      {
+        "defaultMessage": "Reproduce upstream Mastodon behavior by having the Content Warning button affect all copies of a post at once. This will prevent automatic collapsing of any copy of a toot with unfolded CW",
+        "id": "settings.content_warnings_shared_state_hint"
+      },
+      {
+        "defaultMessage": "Display media attachments outside content warnings",
+        "id": "settings.content_warnings_media_outside"
+      },
+      {
+        "defaultMessage": "Reproduce upstream Mastodon behavior by having the Content Warning toggle not affect media attachments",
+        "id": "settings.content_warnings_media_outside_hint"
+      },
+      {
+        "defaultMessage": "Auto-unfolding options",
+        "id": "settings.content_warnings_unfold_opts"
+      },
+      {
+        "defaultMessage": "Automatically unfold content-warnings",
+        "id": "settings.enable_content_warnings_auto_unfold"
+      },
+      {
+        "defaultMessage": "This setting is now controlled from Mastodon's {settings_page_link}",
+        "id": "settings.deprecated_setting"
+      },
+      {
+        "defaultMessage": "user preferences",
+        "id": "settings.shared_settings_link"
+      },
+      {
+        "defaultMessage": "Content warnings to not automatically unfold:",
+        "id": "settings.content_warnings_filter"
+      },
+      {
+        "defaultMessage": "Collapsed toots",
+        "id": "settings.collapsed_statuses"
+      },
+      {
+        "defaultMessage": "Enable collapsed toots",
+        "id": "settings.enable_collapsed"
+      },
+      {
+        "defaultMessage": "Collapsed posts have parts of their contents hidden to take up less screen space. This is distinct from the Content Warning feature",
+        "id": "settings.enable_collapsed_hint"
+      },
+      {
+        "defaultMessage": "Show action buttons in collapsed toots",
+        "id": "settings.show_action_bar"
+      },
+      {
+        "defaultMessage": "Automatic collapsing",
+        "id": "settings.auto_collapse"
+      },
+      {
+        "defaultMessage": "Everything",
+        "id": "settings.auto_collapse_all"
+      },
+      {
+        "defaultMessage": "Notifications",
+        "id": "settings.auto_collapse_notifications"
+      },
+      {
+        "defaultMessage": "Lengthy toots",
+        "id": "settings.auto_collapse_lengthy"
+      },
+      {
+        "defaultMessage": "Boosts",
+        "id": "settings.auto_collapse_reblogs"
+      },
+      {
+        "defaultMessage": "Replies",
+        "id": "settings.auto_collapse_replies"
+      },
+      {
+        "defaultMessage": "Toots with media",
+        "id": "settings.auto_collapse_media"
+      },
+      {
+        "defaultMessage": "Image backgrounds",
+        "id": "settings.image_backgrounds"
+      },
+      {
+        "defaultMessage": "Give collapsed toots an image background",
+        "id": "settings.image_backgrounds_users"
+      },
+      {
+        "defaultMessage": "Preview collapsed toot media",
+        "id": "settings.image_backgrounds_media"
+      },
+      {
+        "defaultMessage": "If the post has any media attachment, use the first one as a background",
+        "id": "settings.image_backgrounds_media_hint"
+      },
+      {
+        "defaultMessage": "Media",
+        "id": "settings.media"
+      },
+      {
+        "defaultMessage": "Letterbox media",
+        "id": "settings.media_letterbox"
+      },
+      {
+        "defaultMessage": "Scale down and letterbox media to fill the image containers instead of stretching and cropping them",
+        "id": "settings.media_letterbox_hint"
+      },
+      {
+        "defaultMessage": "Full-width media previews",
+        "id": "settings.media_fullwidth"
+      },
+      {
+        "defaultMessage": "Inline preview cards for external links",
+        "id": "settings.inline_preview_cards"
+      },
+      {
+        "defaultMessage": "Reveal sensitive media behind a CW by default",
+        "id": "settings.media_reveal_behind_cw"
+      },
+      {
+        "defaultMessage": "Enable pop-in player",
+        "id": "settings.pop_in_player"
+      },
+      {
+        "defaultMessage": "Pop-in player position:",
+        "id": "settings.pop_in_position"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/local_settings/page/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Mark for deletion",
+        "id": "notification.markForDeletion"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/notifications/components/overlay.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Enter notification cleaning mode",
+        "id": "notification_purge.start"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/notifications/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Featured accounts",
+        "id": "endorsed_accounts_editor.endorsed_accounts"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/pinned_accounts_editor/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Filter out by regular expressions",
+        "id": "home.column_settings.filter_regex"
+      },
+      {
+        "defaultMessage": "Show local-only toots",
+        "id": "community.column_settings.allow_local_only"
+      },
+      {
+        "defaultMessage": "Advanced",
+        "id": "home.column_settings.advanced"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/public_timeline/components/column_settings.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Boosted by",
+        "id": "column.reblogged_by"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/reblogs/index.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "This toot contains some media without description",
+        "id": "boost_modal.missing_description"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/ui/components/boost_modal.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Do not ask for confirmation again",
+        "id": "confirmation_modal.do_not_ask_again"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/ui/components/confirmation_modal.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Use Mastodon preferences",
+        "id": "confirmations.deprecated_settings.confirm"
+      },
+      {
+        "defaultMessage": "Automatically unfold content-warnings",
+        "id": "settings.enable_content_warnings_auto_unfold"
+      },
+      {
+        "defaultMessage": "Allow swiping to change columns (Mobile only)",
+        "id": "settings.swipe_to_change_columns"
+      },
+      {
+        "defaultMessage": "Some of the glitch-soc device-specific {app_settings} you are using have been replaced by Mastodon {preferences} and will be overriden:",
+        "id": "confirmations.deprecated_settings.message"
+      },
+      {
+        "defaultMessage": "App settings",
+        "id": "navigation_bar.app_settings"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/ui/components/deprecated_settings_modal.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "You can press {combo} to skip this next time",
+        "id": "favourite_modal.combo"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/ui/components/favourite_modal.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "App settings",
+        "id": "navigation_bar.app_settings"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/ui/components/navigation_panel.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "Welcome to {domain}!",
+        "id": "onboarding.page_one.welcome"
+      },
+      {
+        "defaultMessage": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+        "id": "onboarding.page_one.federation"
+      },
+      {
+        "defaultMessage": "You are on {domain}, so your full handle is {handle}",
+        "id": "onboarding.page_one.handle"
+      },
+      {
+        "defaultMessage": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
+        "id": "onboarding.page_two.compose"
+      },
+      {
+        "defaultMessage": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
+        "id": "onboarding.page_three.search"
+      },
+      {
+        "defaultMessage": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
+        "id": "onboarding.page_three.profile"
+      },
+      {
+        "defaultMessage": "The home timeline shows posts from people you follow.",
+        "id": "onboarding.page_four.home"
+      },
+      {
+        "defaultMessage": "The notifications column shows when someone interacts with you.",
+        "id": "onboarding.page_four.notifications"
+      },
+      {
+        "defaultMessage": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
+        "id": "onboarding.page_five.public_timelines"
+      },
+      {
+        "defaultMessage": "Your instance's admin is {admin}.",
+        "id": "onboarding.page_six.admin"
+      },
+      {
+        "defaultMessage": "Please read {domain}'s {guidelines}!",
+        "id": "onboarding.page_six.read_guidelines"
+      },
+      {
+        "defaultMessage": "community guidelines",
+        "id": "onboarding.page_six.guidelines"
+      },
+      {
+        "defaultMessage": "Almost done...",
+        "id": "onboarding.page_six.almost_done"
+      },
+      {
+        "defaultMessage": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+        "id": "onboarding.page_six.github"
+      },
+      {
+        "defaultMessage": "There are {apps} available for iOS, Android and other platforms.",
+        "id": "onboarding.page_six.apps_available"
+      },
+      {
+        "defaultMessage": "mobile apps",
+        "id": "onboarding.page_six.various_app"
+      },
+      {
+        "defaultMessage": "Bon Appetoot!",
+        "id": "onboarding.page_six.appetoot"
+      },
+      {
+        "defaultMessage": "Next",
+        "id": "onboarding.next"
+      },
+      {
+        "defaultMessage": "Done",
+        "id": "onboarding.done"
+      },
+      {
+        "defaultMessage": "Skip",
+        "id": "onboarding.skip"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/ui/components/onboarding_modal.json"
+  },
+  {
+    "descriptors": [
+      {
+        "defaultMessage": "This account is marked as moved to {moved_to_link}, and may thus not accept new follows.",
+        "id": "moved_to_warning"
+      }
+    ],
+    "path": "app/javascript/flavours/glitch/features/ui/index.json"
+  }
+]
\ No newline at end of file
diff --git a/app/javascript/flavours/glitch/locales/el.js b/app/javascript/flavours/glitch/locales/el.js
deleted file mode 100644
index 2d9bb829f..000000000
--- a/app/javascript/flavours/glitch/locales/el.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/el.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/el.json b/app/javascript/flavours/glitch/locales/el.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/el.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/en-GB.json b/app/javascript/flavours/glitch/locales/en-GB.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/en-GB.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/en.js b/app/javascript/flavours/glitch/locales/en.js
deleted file mode 100644
index 90e924d4a..000000000
--- a/app/javascript/flavours/glitch/locales/en.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import inherited from 'mastodon/locales/en.json';
-
-const messages = {
-  'getting_started.open_source_notice': 'Glitchsoc is free open source software forked from {Mastodon}. You can contribute or report issues on GitHub at {github}.',
-  'layout.auto': 'Auto',
-  'layout.current_is': 'Your current layout is:',
-  'layout.desktop': 'Desktop',
-  'layout.mobile': 'Mobile',
-  'navigation_bar.app_settings': 'App settings',
-  'getting_started.onboarding': 'Show me around',
-  'onboarding.page_one.federation': '{domain} is an \'instance\' of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.',
-  'onboarding.page_one.welcome': 'Welcome to {domain}!',
-  'onboarding.page_six.github': '{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}, and is compatible with any Mastodon instance or app. Glitchsoc is entirely free and open-source. You can report bugs, request features, or contribute to the code on {github}.',
-  'settings.auto_collapse': 'Automatic collapsing',
-  'settings.auto_collapse_all': 'Everything',
-  'settings.auto_collapse_lengthy': 'Lengthy toots',
-  'settings.auto_collapse_media': 'Toots with media',
-  'settings.auto_collapse_notifications': 'Notifications',
-  'settings.auto_collapse_reblogs': 'Boosts',
-  'settings.auto_collapse_replies': 'Replies',
-  'settings.show_action_bar': 'Show action buttons in collapsed toots',
-  'settings.close': 'Close',
-  'settings.collapsed_statuses': 'Collapsed toots',
-  'settings.enable_collapsed': 'Enable collapsed toots',
-  'settings.general': 'General',
-  'settings.image_backgrounds': 'Image backgrounds',
-  'settings.image_backgrounds_media': 'Preview collapsed toot media',
-  'settings.image_backgrounds_users': 'Give collapsed toots an image background',
-  'settings.media': 'Media',
-  'settings.media_letterbox': 'Letterbox media',
-  'settings.media_fullwidth': 'Full-width media previews',
-  'settings.preferences': 'User preferences',
-  'settings.wide_view': 'Wide view (Desktop mode only)',
-  'settings.navbar_under': 'Navbar at the bottom (Mobile only)',
-  'status.collapse': 'Collapse',
-  'status.uncollapse': 'Uncollapse',
-
-  'media_gallery.sensitive': 'Sensitive',
-
-  'favourite_modal.combo': 'You can press {combo} to skip this next time',
-
-  'home.column_settings.show_direct': 'Show DMs',
-
-  'notification.markForDeletion': 'Mark for deletion',
-  'notifications.clear': 'Clear all my notifications',
-  'notifications.marked_clear_confirmation': 'Are you sure you want to permanently clear all selected notifications?',
-  'notifications.marked_clear': 'Clear selected notifications',
-
-  'notification_purge.btn_all': 'Select\nall',
-  'notification_purge.btn_none': 'Select\nnone',
-  'notification_purge.btn_invert': 'Invert\nselection',
-  'notification_purge.btn_apply': 'Clear\nselected',
-
-  'compose.attach.upload': 'Upload a file',
-  'compose.attach.doodle': 'Draw something',
-  'compose.attach': 'Attach...',
-
-  'advanced_options.local-only.short': 'Local-only',
-  'advanced_options.local-only.long': 'Do not post to other instances',
-  'advanced_options.local-only.tooltip': 'This post is local-only',
-  'advanced_options.icon_title': 'Advanced options',
-  'advanced_options.threaded_mode.short': 'Threaded mode',
-  'advanced_options.threaded_mode.long': 'Automatically opens a reply on posting',
-  'advanced_options.threaded_mode.tooltip': 'Threaded mode enabled',
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/en.json b/app/javascript/flavours/glitch/locales/en.json
new file mode 100644
index 000000000..59f2f74b1
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/en.json
@@ -0,0 +1,200 @@
+{
+  "about.fork_disclaimer": "Glitch-soc is free open source software forked from Mastodon.",
+  "account.add_account_note": "Add note for @{name}",
+  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
+  "account.follows": "Follows",
+  "account.joined": "Joined {date}",
+  "account.suspended_disclaimer_full": "This user has been suspended by a moderator.",
+  "account.view_full_profile": "View full profile",
+  "account_note.cancel": "Cancel",
+  "account_note.edit": "Edit",
+  "account_note.glitch_placeholder": "No comment provided",
+  "account_note.save": "Save",
+  "advanced_options.icon_title": "Advanced options",
+  "advanced_options.local-only.long": "Do not post to other instances",
+  "advanced_options.local-only.short": "Local-only",
+  "advanced_options.local-only.tooltip": "This post is local-only",
+  "advanced_options.threaded_mode.long": "Automatically opens a reply on posting",
+  "advanced_options.threaded_mode.short": "Threaded mode",
+  "advanced_options.threaded_mode.tooltip": "Threaded mode enabled",
+  "boost_modal.missing_description": "This toot contains some media without description",
+  "column.favourited_by": "Favourited by",
+  "column.heading": "Misc",
+  "column.reblogged_by": "Boosted by",
+  "column.subheading": "Miscellaneous options",
+  "column_header.profile": "Profile",
+  "column_subheading.lists": "Lists",
+  "column_subheading.navigation": "Navigation",
+  "community.column_settings.allow_local_only": "Show local-only toots",
+  "compose.attach": "Attach...",
+  "compose.attach.doodle": "Draw something",
+  "compose.attach.upload": "Upload a file",
+  "compose.content-type.html": "HTML",
+  "compose.content-type.markdown": "Markdown",
+  "compose.content-type.plain": "Plain text",
+  "compose_form.poll.multiple_choices": "Allow multiple choices",
+  "compose_form.poll.single_choice": "Allow one choice",
+  "compose_form.spoiler": "Hide text behind warning",
+  "confirmation_modal.do_not_ask_again": "Do not ask for confirmation again",
+  "confirmations.deprecated_settings.confirm": "Use Mastodon preferences",
+  "confirmations.deprecated_settings.message": "Some of the glitch-soc device-specific {app_settings} you are using have been replaced by Mastodon {preferences} and will be overriden:",
+  "confirmations.missing_media_description.confirm": "Send anyway",
+  "confirmations.missing_media_description.edit": "Edit media",
+  "confirmations.missing_media_description.message": "At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.",
+  "confirmations.unfilter.author": "Author",
+  "confirmations.unfilter.confirm": "Show",
+  "confirmations.unfilter.edit_filter": "Edit filter",
+  "confirmations.unfilter.filters": "Matching {count, plural, one {filter} other {filters}}",
+  "content-type.change": "Content type",
+  "direct.group_by_conversations": "Group by conversation",
+  "endorsed_accounts_editor.endorsed_accounts": "Featured accounts",
+  "favourite_modal.combo": "You can press {combo} to skip this next time",
+  "getting_started.onboarding": "Show me around",
+  "home.column_settings.advanced": "Advanced",
+  "home.column_settings.filter_regex": "Filter out by regular expressions",
+  "home.column_settings.show_direct": "Show DMs",
+  "home.settings": "Column settings",
+  "keyboard_shortcuts.bookmark": "to bookmark",
+  "keyboard_shortcuts.secondary_toot": "to send toot using secondary privacy setting",
+  "keyboard_shortcuts.toggle_collapse": "to collapse/uncollapse toots",
+  "layout.auto": "Auto",
+  "layout.desktop": "Desktop",
+  "layout.hint.auto": "Automatically chose layout based on “Enable advanced web interface” setting and screen size.",
+  "layout.hint.desktop": "Use multiple-column layout regardless of the “Enable advanced web interface” setting or screen size.",
+  "layout.hint.single": "Use single-column layout regardless of the “Enable advanced web interface” setting or screen size.",
+  "layout.single": "Mobile",
+  "media_gallery.sensitive": "Sensitive",
+  "moved_to_warning": "This account is marked as moved to {moved_to_link}, and may thus not accept new follows.",
+  "navigation_bar.app_settings": "App settings",
+  "navigation_bar.featured_users": "Featured users",
+  "navigation_bar.info": "Extended information",
+  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
+  "navigation_bar.misc": "Misc",
+  "notification.markForDeletion": "Mark for deletion",
+  "notification_purge.btn_all": "Select\nall",
+  "notification_purge.btn_apply": "Clear\nselected",
+  "notification_purge.btn_invert": "Invert\nselection",
+  "notification_purge.btn_none": "Select\nnone",
+  "notification_purge.start": "Enter notification cleaning mode",
+  "notifications.marked_clear": "Clear selected notifications",
+  "notifications.marked_clear_confirmation": "Are you sure you want to permanently clear all selected notifications?",
+  "onboarding.done": "Done",
+  "onboarding.next": "Next",
+  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
+  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
+  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
+  "onboarding.page_one.federation": "{domain} is an 'instance' of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_one.handle": "You are on {domain}, so your full handle is {handle}",
+  "onboarding.page_one.welcome": "Welcome to {domain}!",
+  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
+  "onboarding.page_six.almost_done": "Almost done...",
+  "onboarding.page_six.appetoot": "Bon Appetoot!",
+  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}, and is compatible with any Mastodon instance or app. Glitchsoc is entirely free and open-source. You can report bugs, request features, or contribute to the code on {github}.",
+  "onboarding.page_six.guidelines": "community guidelines",
+  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
+  "onboarding.page_six.various_app": "mobile apps",
+  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
+  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
+  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
+  "onboarding.skip": "Skip",
+  "settings.always_show_spoilers_field": "Always enable the Content Warning field",
+  "settings.auto_collapse": "Automatic collapsing",
+  "settings.auto_collapse_all": "Everything",
+  "settings.auto_collapse_lengthy": "Lengthy toots",
+  "settings.auto_collapse_media": "Toots with media",
+  "settings.auto_collapse_notifications": "Notifications",
+  "settings.auto_collapse_reblogs": "Boosts",
+  "settings.auto_collapse_replies": "Replies",
+  "settings.close": "Close",
+  "settings.collapsed_statuses": "Collapsed toots",
+  "settings.compose_box_opts": "Compose box",
+  "settings.confirm_before_clearing_draft": "Show confirmation dialog before overwriting the message being composed",
+  "settings.confirm_boost_missing_media_description": "Show confirmation dialog before boosting toots lacking media descriptions",
+  "settings.confirm_missing_media_description": "Show confirmation dialog before sending toots lacking media descriptions",
+  "settings.content_warnings": "Content Warnings",
+  "settings.content_warnings.regexp": "Regular expression",
+  "settings.content_warnings_filter": "Content warnings to not automatically unfold:",
+  "settings.content_warnings_media_outside": "Display media attachments outside content warnings",
+  "settings.content_warnings_media_outside_hint": "Reproduce upstream Mastodon behavior by having the Content Warning toggle not affect media attachments",
+  "settings.content_warnings_shared_state": "Show/hide content of all copies at once",
+  "settings.content_warnings_shared_state_hint": "Reproduce upstream Mastodon behavior by having the Content Warning button affect all copies of a post at once. This will prevent automatic collapsing of any copy of a toot with unfolded CW",
+  "settings.content_warnings_unfold_opts": "Auto-unfolding options",
+  "settings.deprecated_setting": "This setting is now controlled from Mastodon's {settings_page_link}",
+  "settings.enable_collapsed": "Enable collapsed toots",
+  "settings.enable_collapsed_hint": "Collapsed posts have parts of their contents hidden to take up less screen space. This is distinct from the Content Warning feature",
+  "settings.enable_content_warnings_auto_unfold": "Automatically unfold content-warnings",
+  "settings.general": "General",
+  "settings.hicolor_privacy_icons": "High color privacy icons",
+  "settings.hicolor_privacy_icons.hint": "Display privacy icons in bright and easily distinguishable colors",
+  "settings.image_backgrounds": "Image backgrounds",
+  "settings.image_backgrounds_media": "Preview collapsed toot media",
+  "settings.image_backgrounds_media_hint": "If the post has any media attachment, use the first one as a background",
+  "settings.image_backgrounds_users": "Give collapsed toots an image background",
+  "settings.inline_preview_cards": "Inline preview cards for external links",
+  "settings.layout": "Layout:",
+  "settings.layout_opts": "Layout options",
+  "settings.media": "Media",
+  "settings.media_fullwidth": "Full-width media previews",
+  "settings.media_letterbox": "Letterbox media",
+  "settings.media_letterbox_hint": "Scale down and letterbox media to fill the image containers instead of stretching and cropping them",
+  "settings.media_reveal_behind_cw": "Reveal sensitive media behind a CW by default",
+  "settings.notifications.favicon_badge": "Unread notifications favicon badge",
+  "settings.notifications.favicon_badge.hint": "Add a badge for unread notifications to the favicon",
+  "settings.notifications.tab_badge": "Unread notifications badge",
+  "settings.notifications.tab_badge.hint": "Display a badge for unread notifications in the column icons when the notifications column isn't open",
+  "settings.notifications_opts": "Notifications options",
+  "settings.pop_in_left": "Left",
+  "settings.pop_in_player": "Enable pop-in player",
+  "settings.pop_in_position": "Pop-in player position:",
+  "settings.pop_in_right": "Right",
+  "settings.preferences": "User preferences",
+  "settings.prepend_cw_re": "Prepend “re: ” to content warnings when replying",
+  "settings.preselect_on_reply": "Pre-select usernames on reply",
+  "settings.preselect_on_reply_hint": "When replying to a conversation with multiple participants, pre-select usernames past the first",
+  "settings.rewrite_mentions": "Rewrite mentions in displayed statuses",
+  "settings.rewrite_mentions_acct": "Rewrite with username and domain (when the account is remote)",
+  "settings.rewrite_mentions_no": "Do not rewrite mentions",
+  "settings.rewrite_mentions_username": "Rewrite with username",
+  "settings.shared_settings_link": "user preferences",
+  "settings.show_action_bar": "Show action buttons in collapsed toots",
+  "settings.show_content_type_choice": "Show content-type choice when authoring toots",
+  "settings.show_reply_counter": "Display an estimate of the reply count",
+  "settings.side_arm": "Secondary toot button:",
+  "settings.side_arm.none": "None",
+  "settings.side_arm_reply_mode": "When replying to a toot, the secondary toot button should:",
+  "settings.side_arm_reply_mode.copy": "Copy privacy setting of the toot being replied to",
+  "settings.side_arm_reply_mode.keep": "Keep its set privacy",
+  "settings.side_arm_reply_mode.restrict": "Restrict privacy setting to that of the toot being replied to",
+  "settings.status_icons": "Toot icons",
+  "settings.status_icons_language": "Language indicator",
+  "settings.status_icons_local_only": "Local-only indicator",
+  "settings.status_icons_media": "Media and poll indicators",
+  "settings.status_icons_reply": "Reply indicator",
+  "settings.status_icons_visibility": "Toot privacy indicator",
+  "settings.swipe_to_change_columns": "Allow swiping to change columns (Mobile only)",
+  "settings.tag_misleading_links": "Tag misleading links",
+  "settings.tag_misleading_links.hint": "Add a visual indication with the link target host to every link not mentioning it explicitly",
+  "settings.wide_view": "Wide view (Desktop mode only)",
+  "settings.wide_view_hint": "Stretches columns to better fill the available space.",
+  "status.collapse": "Collapse",
+  "status.has_audio": "Features attached audio files",
+  "status.has_pictures": "Features attached pictures",
+  "status.has_preview_card": "Features an attached preview card",
+  "status.has_video": "Features attached videos",
+  "status.in_reply_to": "This toot is a reply",
+  "status.is_poll": "This toot is a poll",
+  "status.local_only": "Only visible from your instance",
+  "status.sensitive_toggle": "Click to view",
+  "status.uncollapse": "Uncollapse",
+  "web_app_crash.change_your_settings": "Change your {settings}",
+  "web_app_crash.content": "You could try any of the following:",
+  "web_app_crash.debug_info": "Debug information",
+  "web_app_crash.disable_addons": "Disable browser add-ons or built-in translation tools",
+  "web_app_crash.issue_tracker": "issue tracker",
+  "web_app_crash.reload": "Reload",
+  "web_app_crash.reload_page": "{reload} the current page",
+  "web_app_crash.report_issue": "Report a bug in the {issuetracker}",
+  "web_app_crash.settings": "settings",
+  "web_app_crash.title": "We're sorry, but something went wrong with the Mastodon app."
+}
diff --git a/app/javascript/flavours/glitch/locales/eo.js b/app/javascript/flavours/glitch/locales/eo.js
deleted file mode 100644
index 04192f506..000000000
--- a/app/javascript/flavours/glitch/locales/eo.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/eo.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/eo.json b/app/javascript/flavours/glitch/locales/eo.json
new file mode 100644
index 000000000..87fe6c657
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/eo.json
@@ -0,0 +1,52 @@
+{
+  "account.add_account_note": "Aldoni noton por @{name}",
+  "account_note.cancel": "Nuligi",
+  "account_note.edit": "Redakti",
+  "account_note.save": "Konservi",
+  "column.reblogged_by": "Diskonigita de",
+  "column.subheading": "Diversaj agordoj",
+  "column_header.profile": "Profilo",
+  "column_subheading.lists": "Listoj",
+  "compose.attach": "Aldoni…",
+  "compose.attach.doodle": "Desegni ion",
+  "compose.attach.upload": "Alŝuti dosieron",
+  "compose.content-type.html": "HTML",
+  "compose.content-type.markdown": "Markdown",
+  "confirmations.unfilter.author": "Aŭtoro",
+  "confirmations.unfilter.confirm": "Montri",
+  "confirmations.unfilter.edit_filter": "Redakti filtrilon",
+  "navigation_bar.keyboard_shortcuts": "Fulmoklavoj",
+  "notification_purge.btn_all": "Selekti ĉiujn",
+  "notification_purge.btn_apply": "Forigi selektajn",
+  "notification_purge.btn_invert": "Inverti selekton",
+  "notification_purge.btn_none": "Elekti neniun",
+  "notifications.marked_clear": "Forigi selektajn sciigojn",
+  "onboarding.next": "Sekva",
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.almost_done": "Preskaŭ finita…",
+  "onboarding.page_six.apps_available": "Estas {apps} disponeblaj por iOS, Android kaj aliaj sistemoj.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "onboarding.page_six.various_app": "poŝtelefonaj aplikaĵoj",
+  "settings.auto_collapse_all": "Ĉiuj",
+  "settings.auto_collapse_lengthy": "Longaj afiŝoj",
+  "settings.auto_collapse_media": "Afiŝoj kun aŭdovidaĵoj",
+  "settings.auto_collapse_notifications": "Sciigoj",
+  "settings.auto_collapse_reblogs": "Diskonigoj",
+  "settings.auto_collapse_replies": "Respondoj",
+  "settings.close": "Fermi",
+  "settings.content_warnings": "Content warnings",
+  "settings.content_warnings.regexp": "Regula esprimo",
+  "settings.preferences": "Preferences",
+  "settings.shared_settings_link": "preferoj de uzanto",
+  "settings.side_arm": "Duaranga butono por afiŝi:",
+  "settings.side_arm.none": "Neniu",
+  "settings.status_icons": "Ikonoj sur la afiŝoj",
+  "settings.status_icons_language": "Indikilo de lingvo",
+  "settings.status_icons_media": "Indikilo de aŭdovidaĵojn kaj balotenketo",
+  "settings.status_icons_reply": "Indikilo de respondoj",
+  "settings.status_icons_visibility": "Indikilo de privateco de afiŝo",
+  "web_app_crash.change_your_settings": "Ŝanĝi viajn {settings}",
+  "web_app_crash.reload": "Reŝarĝi",
+  "web_app_crash.reload_page": "{reload} la nunan paĝon",
+  "web_app_crash.settings": "agordojn"
+}
diff --git a/app/javascript/flavours/glitch/locales/es-AR.js b/app/javascript/flavours/glitch/locales/es-AR.js
deleted file mode 100644
index 0dffabcd4..000000000
--- a/app/javascript/flavours/glitch/locales/es-AR.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/es-AR.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/es-AR.json b/app/javascript/flavours/glitch/locales/es-AR.json
new file mode 100644
index 000000000..fc5a2e904
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/es-AR.json
@@ -0,0 +1,95 @@
+{
+  "advanced_options.icon_title": "Opciones avanzadas",
+  "advanced_options.local-only.long": "No publicar a otras instancias",
+  "advanced_options.local-only.short": "Local",
+  "advanced_options.local-only.tooltip": "Este toot es local",
+  "advanced_options.threaded_mode.long": "Al publicar abre automáticamente una respuesta",
+  "advanced_options.threaded_mode.short": "Modo hilo",
+  "advanced_options.threaded_mode.tooltip": "Modo hilo habilitado",
+  "compose.attach": "Adjuntar...",
+  "compose.attach.doodle": "Dibujar algo",
+  "compose.attach.upload": "Subir un archivo",
+  "confirmations.unfilter.author": "Publicado por",
+  "confirmations.unfilter.confirm": "Mostrar",
+  "confirmations.unfilter.edit_filter": "Editar filtro",
+  "confirmations.unfilter.filters": "Coincidencia con {count, plural, one {filtro} other {filtros}}",
+  "favourite_modal.combo": "Puedes presionar {combo} para omitir esto la próxima vez",
+  "getting_started.onboarding": "Paseo inicial",
+  "home.column_settings.show_direct": "Mostrar mensajes directos",
+  "layout.auto": "Automático",
+  "layout.desktop": "Escritorio",
+  "layout.hint.auto": "Seleccionar un diseño automáticamente basado en \"Habilitar interface web avanzada\" y tamaño de pantalla",
+  "layout.hint.desktop": "Utiliza el diseño multi-columna sin importar \"Habilitar interface web avanzada\" o tamaño de pantalla",
+  "layout.hint.single": "Utiliza el diseño de una columna sin importar \"Habilitar interface web avanzada\" o tamaño de pantalla",
+  "media_gallery.sensitive": "Sensible",
+  "navigation_bar.app_settings": "Ajustes de aplicación",
+  "notification.markForDeletion": "Marcar para borrar",
+  "notification_purge.btn_all": "Seleccionar\ntodo",
+  "notification_purge.btn_apply": "Borrar\nselección",
+  "notification_purge.btn_invert": "Invertir\nselección",
+  "notification_purge.btn_none": "Seleccionar\nnada",
+  "notifications.marked_clear": "Limpiar notificaciones seleccionadas",
+  "notifications.marked_clear_confirmation": "¿Deseas borrar permanentemente todas las notificaciones seleccionadas?",
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_one.welcome": "¡Bienvenidx a {domain}!",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.always_show_spoilers_field": "Siempre mostrar el campo de advertencia de contenido",
+  "settings.auto_collapse": "Colapsar automáticamente",
+  "settings.auto_collapse_all": "Todo",
+  "settings.auto_collapse_lengthy": "Toots largos",
+  "settings.auto_collapse_media": "Toots con medios",
+  "settings.auto_collapse_notifications": "Notificaciones",
+  "settings.auto_collapse_reblogs": "Retoots",
+  "settings.auto_collapse_replies": "Respuestas",
+  "settings.close": "Cerrar",
+  "settings.collapsed_statuses": "Toots colapsados",
+  "settings.compose_box_opts": "Cuadro de redacción",
+  "settings.confirm_before_clearing_draft": "Mostrar diálogo de confirmación antes de sobreescribir un mensaje estabas escribiendo",
+  "settings.confirm_boost_missing_media_description": "Mostrar diálogo de confirmación antes de retootear publicaciones con medios sin descripción",
+  "settings.confirm_missing_media_description": "Mostrar diálogo de confirmación antes de publicar toots con medios sin descripción",
+  "settings.content_warnings": "Content warnings",
+  "settings.content_warnings.regexp": "Regexp (expresión regular)",
+  "settings.content_warnings_filter": "No descolapsar estas advertencias de contenido:",
+  "settings.enable_collapsed": "Habilitar toots colapsados",
+  "settings.enable_content_warnings_auto_unfold": "Descolapsar automáticamente advertencias de contenido",
+  "settings.hicolor_privacy_icons": "Íconos de privacidad más visibles",
+  "settings.image_backgrounds": "Fondos de imágenes",
+  "settings.image_backgrounds_media": "Vista previa de medios de toots colapsados",
+  "settings.image_backgrounds_users": "Darle fondo de imagen a toots colapsados",
+  "settings.inline_preview_cards": "Vista previa para enlaces externos",
+  "settings.layout": "Diseño",
+  "settings.layout_opts": "Opciones de diseño",
+  "settings.media": "Medios",
+  "settings.media_fullwidth": "Ancho completo al mostrar medios ",
+  "settings.media_letterbox": "Mantener proporciones al mostrar medios",
+  "settings.media_letterbox_hint": "Escalar medios para que llenen el espacio del contenedor sin cambiar sus proporciones sin recortarlos",
+  "settings.media_reveal_behind_cw": "Siempre mostrar medios sensibles dentro de las advertencias de contenido",
+  "settings.notifications.favicon_badge": "Marcador de notificaciones en el favicon",
+  "settings.notifications.favicon_badge.hint": "Muestra un marcador de notificaciones sin leer en el favicon",
+  "settings.notifications.tab_badge": "Marcador de notificaciones no leídas",
+  "settings.notifications.tab_badge.hint": "Muestra un marcador de notificaciones sin leer en el ícono de notificaciones cuando dicha columna no está abierta",
+  "settings.notifications_opts": "Opciones de notificaciones",
+  "settings.preferences": "Preferences",
+  "settings.prepend_cw_re": "Anteponer \"re: \" a las advertencias de contenido al responder",
+  "settings.preselect_on_reply": "Preseleccionar nombres de usuarix al responder",
+  "settings.preselect_on_reply_hint": "Al responder a conversaciones con múltiples participantes, preselecciona los nombres de usuarix subsecuentes del/la primerx",
+  "settings.rewrite_mentions": "Reescribir menciones in publicaciones mostradas",
+  "settings.rewrite_mentions_acct": "Reescribir con nombre de usuarix y dominio (para cuentas remotas)",
+  "settings.rewrite_mentions_no": "No reescribir menciones",
+  "settings.rewrite_mentions_username": "Reescribir con nombre de usuarix",
+  "settings.show_action_bar": "Mostrar botones de acción en toots colapsados",
+  "settings.show_content_type_choice": "Mostrar selección de tipo de contenido al crear toots",
+  "settings.show_reply_counter": "Mostrar un conteo estimado de respuestas",
+  "settings.side_arm": "Botón secundario:",
+  "settings.side_arm.none": "Ninguno",
+  "settings.side_arm_reply_mode": "Al responder a un toot, el botón de toot secundario debe:",
+  "settings.side_arm_reply_mode.copy": "Copiar opción de privacidad del toot al que estás respondiendo",
+  "settings.side_arm_reply_mode.keep": "Conservar opción de privacidad",
+  "settings.side_arm_reply_mode.restrict": "Restringir la opción de privacidad a la misma del toot al que estás respondiendo",
+  "settings.swipe_to_change_columns": "Permitir deslizar para cambiar columnas (Sólo en móvil)",
+  "settings.tag_misleading_links": "Marcar enlaces engañosos",
+  "settings.tag_misleading_links.hint": "Añadir una indicación visual indicando el destino de los enlace que no los mencionen explícitamente",
+  "settings.wide_view": "Vista amplia (solo modo de escritorio)",
+  "status.collapse": "Colapsar",
+  "status.uncollapse": "Descolapsar"
+}
diff --git a/app/javascript/flavours/glitch/locales/es-MX.js b/app/javascript/flavours/glitch/locales/es-MX.js
deleted file mode 100644
index eaefa20ef..000000000
--- a/app/javascript/flavours/glitch/locales/es-MX.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/es-MX.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/es-MX.json b/app/javascript/flavours/glitch/locales/es-MX.json
new file mode 100644
index 000000000..fc5a2e904
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/es-MX.json
@@ -0,0 +1,95 @@
+{
+  "advanced_options.icon_title": "Opciones avanzadas",
+  "advanced_options.local-only.long": "No publicar a otras instancias",
+  "advanced_options.local-only.short": "Local",
+  "advanced_options.local-only.tooltip": "Este toot es local",
+  "advanced_options.threaded_mode.long": "Al publicar abre automáticamente una respuesta",
+  "advanced_options.threaded_mode.short": "Modo hilo",
+  "advanced_options.threaded_mode.tooltip": "Modo hilo habilitado",
+  "compose.attach": "Adjuntar...",
+  "compose.attach.doodle": "Dibujar algo",
+  "compose.attach.upload": "Subir un archivo",
+  "confirmations.unfilter.author": "Publicado por",
+  "confirmations.unfilter.confirm": "Mostrar",
+  "confirmations.unfilter.edit_filter": "Editar filtro",
+  "confirmations.unfilter.filters": "Coincidencia con {count, plural, one {filtro} other {filtros}}",
+  "favourite_modal.combo": "Puedes presionar {combo} para omitir esto la próxima vez",
+  "getting_started.onboarding": "Paseo inicial",
+  "home.column_settings.show_direct": "Mostrar mensajes directos",
+  "layout.auto": "Automático",
+  "layout.desktop": "Escritorio",
+  "layout.hint.auto": "Seleccionar un diseño automáticamente basado en \"Habilitar interface web avanzada\" y tamaño de pantalla",
+  "layout.hint.desktop": "Utiliza el diseño multi-columna sin importar \"Habilitar interface web avanzada\" o tamaño de pantalla",
+  "layout.hint.single": "Utiliza el diseño de una columna sin importar \"Habilitar interface web avanzada\" o tamaño de pantalla",
+  "media_gallery.sensitive": "Sensible",
+  "navigation_bar.app_settings": "Ajustes de aplicación",
+  "notification.markForDeletion": "Marcar para borrar",
+  "notification_purge.btn_all": "Seleccionar\ntodo",
+  "notification_purge.btn_apply": "Borrar\nselección",
+  "notification_purge.btn_invert": "Invertir\nselección",
+  "notification_purge.btn_none": "Seleccionar\nnada",
+  "notifications.marked_clear": "Limpiar notificaciones seleccionadas",
+  "notifications.marked_clear_confirmation": "¿Deseas borrar permanentemente todas las notificaciones seleccionadas?",
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_one.welcome": "¡Bienvenidx a {domain}!",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.always_show_spoilers_field": "Siempre mostrar el campo de advertencia de contenido",
+  "settings.auto_collapse": "Colapsar automáticamente",
+  "settings.auto_collapse_all": "Todo",
+  "settings.auto_collapse_lengthy": "Toots largos",
+  "settings.auto_collapse_media": "Toots con medios",
+  "settings.auto_collapse_notifications": "Notificaciones",
+  "settings.auto_collapse_reblogs": "Retoots",
+  "settings.auto_collapse_replies": "Respuestas",
+  "settings.close": "Cerrar",
+  "settings.collapsed_statuses": "Toots colapsados",
+  "settings.compose_box_opts": "Cuadro de redacción",
+  "settings.confirm_before_clearing_draft": "Mostrar diálogo de confirmación antes de sobreescribir un mensaje estabas escribiendo",
+  "settings.confirm_boost_missing_media_description": "Mostrar diálogo de confirmación antes de retootear publicaciones con medios sin descripción",
+  "settings.confirm_missing_media_description": "Mostrar diálogo de confirmación antes de publicar toots con medios sin descripción",
+  "settings.content_warnings": "Content warnings",
+  "settings.content_warnings.regexp": "Regexp (expresión regular)",
+  "settings.content_warnings_filter": "No descolapsar estas advertencias de contenido:",
+  "settings.enable_collapsed": "Habilitar toots colapsados",
+  "settings.enable_content_warnings_auto_unfold": "Descolapsar automáticamente advertencias de contenido",
+  "settings.hicolor_privacy_icons": "Íconos de privacidad más visibles",
+  "settings.image_backgrounds": "Fondos de imágenes",
+  "settings.image_backgrounds_media": "Vista previa de medios de toots colapsados",
+  "settings.image_backgrounds_users": "Darle fondo de imagen a toots colapsados",
+  "settings.inline_preview_cards": "Vista previa para enlaces externos",
+  "settings.layout": "Diseño",
+  "settings.layout_opts": "Opciones de diseño",
+  "settings.media": "Medios",
+  "settings.media_fullwidth": "Ancho completo al mostrar medios ",
+  "settings.media_letterbox": "Mantener proporciones al mostrar medios",
+  "settings.media_letterbox_hint": "Escalar medios para que llenen el espacio del contenedor sin cambiar sus proporciones sin recortarlos",
+  "settings.media_reveal_behind_cw": "Siempre mostrar medios sensibles dentro de las advertencias de contenido",
+  "settings.notifications.favicon_badge": "Marcador de notificaciones en el favicon",
+  "settings.notifications.favicon_badge.hint": "Muestra un marcador de notificaciones sin leer en el favicon",
+  "settings.notifications.tab_badge": "Marcador de notificaciones no leídas",
+  "settings.notifications.tab_badge.hint": "Muestra un marcador de notificaciones sin leer en el ícono de notificaciones cuando dicha columna no está abierta",
+  "settings.notifications_opts": "Opciones de notificaciones",
+  "settings.preferences": "Preferences",
+  "settings.prepend_cw_re": "Anteponer \"re: \" a las advertencias de contenido al responder",
+  "settings.preselect_on_reply": "Preseleccionar nombres de usuarix al responder",
+  "settings.preselect_on_reply_hint": "Al responder a conversaciones con múltiples participantes, preselecciona los nombres de usuarix subsecuentes del/la primerx",
+  "settings.rewrite_mentions": "Reescribir menciones in publicaciones mostradas",
+  "settings.rewrite_mentions_acct": "Reescribir con nombre de usuarix y dominio (para cuentas remotas)",
+  "settings.rewrite_mentions_no": "No reescribir menciones",
+  "settings.rewrite_mentions_username": "Reescribir con nombre de usuarix",
+  "settings.show_action_bar": "Mostrar botones de acción en toots colapsados",
+  "settings.show_content_type_choice": "Mostrar selección de tipo de contenido al crear toots",
+  "settings.show_reply_counter": "Mostrar un conteo estimado de respuestas",
+  "settings.side_arm": "Botón secundario:",
+  "settings.side_arm.none": "Ninguno",
+  "settings.side_arm_reply_mode": "Al responder a un toot, el botón de toot secundario debe:",
+  "settings.side_arm_reply_mode.copy": "Copiar opción de privacidad del toot al que estás respondiendo",
+  "settings.side_arm_reply_mode.keep": "Conservar opción de privacidad",
+  "settings.side_arm_reply_mode.restrict": "Restringir la opción de privacidad a la misma del toot al que estás respondiendo",
+  "settings.swipe_to_change_columns": "Permitir deslizar para cambiar columnas (Sólo en móvil)",
+  "settings.tag_misleading_links": "Marcar enlaces engañosos",
+  "settings.tag_misleading_links.hint": "Añadir una indicación visual indicando el destino de los enlace que no los mencionen explícitamente",
+  "settings.wide_view": "Vista amplia (solo modo de escritorio)",
+  "status.collapse": "Colapsar",
+  "status.uncollapse": "Descolapsar"
+}
diff --git a/app/javascript/flavours/glitch/locales/es.js b/app/javascript/flavours/glitch/locales/es.js
deleted file mode 100644
index f22062977..000000000
--- a/app/javascript/flavours/glitch/locales/es.js
+++ /dev/null
@@ -1,119 +0,0 @@
-import inherited from 'mastodon/locales/es.json';
-
-const messages = {
-  'advanced_options.icon_title': 'Opciones avanzadas',
-  'advanced_options.local-only.long': 'No publicar a otras instancias',
-  'advanced_options.local-only.short': 'Local',
-  'advanced_options.local-only.tooltip': 'Este toot es local',
-  'advanced_options.threaded_mode.long': 'Al publicar abre automáticamente una respuesta',
-  'advanced_options.threaded_mode.short': 'Modo hilo',
-  'advanced_options.threaded_mode.tooltip': 'Modo hilo habilitado',
-  'compose.attach.doodle': 'Dibujar algo',
-  'compose.attach.upload': 'Subir un archivo',
-  'compose.attach': 'Adjuntar...',
-  'favourite_modal.combo': 'Puedes presionar {combo} para omitir esto la próxima vez',
-  'getting_started.onboarding': 'Paseo inicial',
-  'getting_started.open_source_notice': 'Glitchsoc es software libre y gratuito bifurcado de {Mastodon}. Puedes contribuir o reportar errores en GitHub en {github}.',
-  'home.column_settings.show_direct': 'Mostrar mensajes directos',
-  'layout.auto': 'Automático',
-  'layout.current_is': 'Tu diseño actual es:',
-  'layout.desktop': 'Escritorio',
-  'layout.hint.auto': 'Seleccionar un diseño automáticamente basado en "Habilitar interface web avanzada" y tamaño de pantalla',
-  'layout.hint.desktop': 'Utiliza el diseño multi-columna sin importar "Habilitar interface web avanzada" o tamaño de pantalla',
-  'layout.hint.single': 'Utiliza el diseño de una columna sin importar "Habilitar interface web avanzada" o tamaño de pantalla',
-  'layout.mobile': 'Móvil',
-  'media_gallery.sensitive': 'Sensible',
-  'navigation_bar.app_settings': 'Ajustes de aplicación',
-  'notification_purge.btn_all': 'Seleccionar\ntodo',
-  'notification_purge.btn_apply': 'Borrar\nselección',
-  'notification_purge.btn_invert': 'Invertir\nselección',
-  'notification_purge.btn_none': 'Seleccionar\nnada',
-  'notification.markForDeletion': 'Marcar para borrar',
-  'notifications.clear': 'Limpiar notificaciones',
-  'notifications.marked_clear_confirmation': '¿Deseas borrar permanentemente todas las notificaciones seleccionadas?',
-  'notifications.marked_clear': 'Limpiar notificaciones seleccionadas',
-  'onboarding.page_one.federation': '{domain} es una "instancia" de Mastodon. Mastodon es una red de servidores independientes que se unen para crear una red social más grande. A estos servidores los llamamos instancias.',
-  'onboarding.page_one.welcome': '¡Bienvenidx a {domain}!',
-  'onboarding.page_six.github': '{domain} usa Glitchsoc. Glitchsoc es una bifurcación {fork} amigable de {Mastodon}, y es compatible con cualquier instancia o aplicación de Mastodon. Glitchsoc es completamente gratuito y de código abierto. Puedes reportar errores, solicitar funciones o contribuir al código en {github}.',
-  'settings.always_show_spoilers_field': 'Siempre mostrar el campo de advertencia de contenido',
-  'settings.auto_collapse_all': 'Todo',
-  'settings.auto_collapse_lengthy': 'Toots largos',
-  'settings.auto_collapse_media': 'Toots con medios',
-  'settings.auto_collapse_notifications': 'Notificaciones',
-  'settings.auto_collapse_reblogs': 'Retoots',
-  'settings.auto_collapse_replies': 'Respuestas',
-  'settings.auto_collapse': 'Colapsar automáticamente',
-  'settings.close': 'Cerrar',
-  'settings.collapsed_statuses': 'Toots colapsados',
-  'settings.compose_box_opts': 'Cuadro de redacción',
-  'settings.confirm_before_clearing_draft': 'Mostrar diálogo de confirmación antes de sobreescribir un mensaje estabas escribiendo',
-  'settings.confirm_boost_missing_media_description': 'Mostrar diálogo de confirmación antes de retootear publicaciones con medios sin descripción',
-  'settings.confirm_missing_media_description': 'Mostrar diálogo de confirmación antes de publicar toots con medios sin descripción',
-  'settings.content_warnings_filter': 'No descolapsar estas advertencias de contenido:',
-  'settings.content_warnings.regexp': 'Regexp (expresión regular)',
-  'settings.content_warnings': 'Advertencias de contenido',
-  'settings.enable_collapsed': 'Habilitar toots colapsados',
-  'settings.enable_content_warnings_auto_unfold': 'Descolapsar automáticamente advertencias de contenido',
-  'settings.filtering_behavior.cw': 'Mostrar el toot y agregar las palabras filtradas a la advertencia de contenido',
-  'settings.filtering_behavior.drop': 'Ocultar toots filtrados por completo',
-  'settings.filtering_behavior.hide': 'Mostrar "Filtrado" y agregar un botón para saber por qué',
-  'settings.filtering_behavior.upstream': 'Mostrar "Filtrado"',
-  'settings.filtering_behavior': 'Configuración de filtros',
-  'settings.filters': 'Filtros',
-  'settings.general': 'General',
-  'settings.hicolor_privacy_icons': 'Íconos de privacidad más visibles',
-  'settings.image_backgrounds_media': 'Vista previa de medios de toots colapsados',
-  'settings.image_backgrounds_users': 'Darle fondo de imagen a toots colapsados',
-  'settings.image_backgrounds': 'Fondos de imágenes',
-  'settings.inline_preview_cards': 'Vista previa para enlaces externos',
-  'settings.layout_opts': 'Opciones de diseño',
-  'settings.layout': 'Diseño',
-  'settings.media_fullwidth': 'Ancho completo al mostrar medios ',
-  'settings.media_letterbox_hint': 'Escalar medios para que llenen el espacio del contenedor sin cambiar sus proporciones sin recortarlos',
-  'settings.media_letterbox': 'Mantener proporciones al mostrar medios',
-  'settings.media_reveal_behind_cw': 'Siempre mostrar medios sensibles dentro de las advertencias de contenido',
-  'settings.media': 'Medios',
-  'settings.navbar_under': 'Barra de navegación en la parte inferior (solo móvil)',
-  'settings.notifications_opts': 'Opciones de notificaciones',
-  'settings.notifications.favicon_badge.hint': 'Muestra un marcador de notificaciones sin leer en el favicon',
-  'settings.notifications.favicon_badge': 'Marcador de notificaciones en el favicon',
-  'settings.notifications.tab_badge.hint': 'Muestra un marcador de notificaciones sin leer en el ícono de notificaciones cuando dicha columna no está abierta',
-  'settings.notifications.tab_badge': 'Marcador de notificaciones no leídas',
-  'settings.preferences': 'Preferencias de usuarix',
-  'settings.prepend_cw_re': 'Anteponer "re: " a las advertencias de contenido al responder',
-  'settings.preselect_on_reply_hint': 'Al responder a conversaciones con múltiples participantes, preselecciona los nombres de usuarix subsecuentes del/la primerx',
-  'settings.preselect_on_reply': 'Preseleccionar nombres de usuarix al responder',
-  'settings.rewrite_mentions_acct': 'Reescribir con nombre de usuarix y dominio (para cuentas remotas)',
-  'settings.rewrite_mentions_no': 'No reescribir menciones',
-  'settings.rewrite_mentions_username': 'Reescribir con nombre de usuarix',
-  'settings.rewrite_mentions': 'Reescribir menciones in publicaciones mostradas',
-  'settings.show_action_bar': 'Mostrar botones de acción en toots colapsados',
-  'settings.show_content_type_choice': 'Mostrar selección de tipo de contenido al crear toots',
-  'settings.show_reply_counter': 'Mostrar un conteo estimado de respuestas',
-  'settings.side_arm_reply_mode.copy': 'Copiar opción de privacidad del toot al que estás respondiendo',
-  'settings.side_arm_reply_mode.keep': 'Conservar opción de privacidad',
-  'settings.side_arm_reply_mode.restrict': 'Restringir la opción de privacidad a la misma del toot al que estás respondiendo',
-  'settings.side_arm_reply_mode': 'Al responder a un toot, el botón de toot secundario debe:',
-  'settings.side_arm.none': 'Ninguno',
-  'settings.side_arm': 'Botón secundario:',
-  'settings.swipe_to_change_columns': 'Permitir deslizar para cambiar columnas (Sólo en móvil)',
-  'settings.tag_misleading_links.hint': 'Añadir una indicación visual indicando el destino de los enlace que no los mencionen explícitamente',
-  'settings.tag_misleading_links': 'Marcar enlaces engañosos',
-  'settings.wide_view': 'Vista amplia (solo modo de escritorio)',
-  'status.collapse': 'Colapsar',
-  'status.uncollapse': 'Descolapsar',
-  'confirmations.unfilter': 'Información del toot filtrado',
-  'confirmations.unfilter.author': 'Publicado por',
-  'confirmations.unfilter.filters': 'Coincidencia con {count, plural, one {filtro} other {filtros}}',
-  'confirmations.unfilter.edit_filter': 'Editar filtro',
-  'confirmations.unfilter.confirm': 'Mostrar',
-  'confirmations.delete.confirm': 'Borrar',
-  'confirmations.delete.message': 'Por favor confirma borrado',
-  'confirmations.redraft.confirm': 'Borrar y volver a borrador',
-  'confirmations.redraft.message': '¿Borrar y volver a borrador? Perderás todas las respuestas, retoots y favoritos asociados, y las respuestas a la publicación original quedarán huérfanos.',
-  'confirmations.reply.confirm': 'Responder',
-  'confirmations.reply.message': 'Responder no sobreescribirá el mensaje que estás escibiendo actualmente. ¿Deseas continuar?',
-  'status.show_filter_reason': '(mostrar por qué)',
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/es.json b/app/javascript/flavours/glitch/locales/es.json
new file mode 100644
index 000000000..07acbf914
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/es.json
@@ -0,0 +1,95 @@
+{
+  "advanced_options.icon_title": "Opciones avanzadas",
+  "advanced_options.local-only.long": "No publicar a otras instancias",
+  "advanced_options.local-only.short": "Local",
+  "advanced_options.local-only.tooltip": "Este toot es local",
+  "advanced_options.threaded_mode.long": "Al publicar abre automáticamente una respuesta",
+  "advanced_options.threaded_mode.short": "Modo hilo",
+  "advanced_options.threaded_mode.tooltip": "Modo hilo habilitado",
+  "compose.attach": "Adjuntar...",
+  "compose.attach.doodle": "Dibujar algo",
+  "compose.attach.upload": "Subir un archivo",
+  "confirmations.unfilter.author": "Publicado por",
+  "confirmations.unfilter.confirm": "Mostrar",
+  "confirmations.unfilter.edit_filter": "Editar filtro",
+  "confirmations.unfilter.filters": "Coincidencia con {count, plural, one {filtro} other {filtros}}",
+  "favourite_modal.combo": "Puedes presionar {combo} para omitir esto la próxima vez",
+  "getting_started.onboarding": "Paseo inicial",
+  "home.column_settings.show_direct": "Mostrar mensajes directos",
+  "layout.auto": "Automático",
+  "layout.desktop": "Escritorio",
+  "layout.hint.auto": "Seleccionar un diseño automáticamente basado en \"Habilitar interface web avanzada\" y tamaño de pantalla",
+  "layout.hint.desktop": "Utiliza el diseño multi-columna sin importar \"Habilitar interface web avanzada\" o tamaño de pantalla",
+  "layout.hint.single": "Utiliza el diseño de una columna sin importar \"Habilitar interface web avanzada\" o tamaño de pantalla",
+  "media_gallery.sensitive": "Sensible",
+  "navigation_bar.app_settings": "Ajustes de aplicación",
+  "notification.markForDeletion": "Marcar para borrar",
+  "notification_purge.btn_all": "Seleccionar\ntodo",
+  "notification_purge.btn_apply": "Borrar\nselección",
+  "notification_purge.btn_invert": "Invertir\nselección",
+  "notification_purge.btn_none": "Seleccionar\nnada",
+  "notifications.marked_clear": "Limpiar notificaciones seleccionadas",
+  "notifications.marked_clear_confirmation": "¿Deseas borrar permanentemente todas las notificaciones seleccionadas?",
+  "onboarding.page_one.federation": "{domain} es una \"instancia\" de Mastodon. Mastodon es una red de servidores independientes que se unen para crear una red social más grande. A estos servidores los llamamos instancias.",
+  "onboarding.page_one.welcome": "¡Bienvenidx a {domain}!",
+  "onboarding.page_six.github": "{domain} usa Glitchsoc. Glitchsoc es una bifurcación {fork} amigable de {Mastodon}, y es compatible con cualquier instancia o aplicación de Mastodon. Glitchsoc es completamente gratuito y de código abierto. Puedes reportar errores, solicitar funciones o contribuir al código en {github}.",
+  "settings.always_show_spoilers_field": "Siempre mostrar el campo de advertencia de contenido",
+  "settings.auto_collapse": "Colapsar automáticamente",
+  "settings.auto_collapse_all": "Todo",
+  "settings.auto_collapse_lengthy": "Toots largos",
+  "settings.auto_collapse_media": "Toots con medios",
+  "settings.auto_collapse_notifications": "Notificaciones",
+  "settings.auto_collapse_reblogs": "Retoots",
+  "settings.auto_collapse_replies": "Respuestas",
+  "settings.close": "Cerrar",
+  "settings.collapsed_statuses": "Toots colapsados",
+  "settings.compose_box_opts": "Cuadro de redacción",
+  "settings.confirm_before_clearing_draft": "Mostrar diálogo de confirmación antes de sobreescribir un mensaje estabas escribiendo",
+  "settings.confirm_boost_missing_media_description": "Mostrar diálogo de confirmación antes de retootear publicaciones con medios sin descripción",
+  "settings.confirm_missing_media_description": "Mostrar diálogo de confirmación antes de publicar toots con medios sin descripción",
+  "settings.content_warnings": "Advertencias de contenido",
+  "settings.content_warnings.regexp": "Regexp (expresión regular)",
+  "settings.content_warnings_filter": "No descolapsar estas advertencias de contenido:",
+  "settings.enable_collapsed": "Habilitar toots colapsados",
+  "settings.enable_content_warnings_auto_unfold": "Descolapsar automáticamente advertencias de contenido",
+  "settings.hicolor_privacy_icons": "Íconos de privacidad más visibles",
+  "settings.image_backgrounds": "Fondos de imágenes",
+  "settings.image_backgrounds_media": "Vista previa de medios de toots colapsados",
+  "settings.image_backgrounds_users": "Darle fondo de imagen a toots colapsados",
+  "settings.inline_preview_cards": "Vista previa para enlaces externos",
+  "settings.layout": "Diseño",
+  "settings.layout_opts": "Opciones de diseño",
+  "settings.media": "Medios",
+  "settings.media_fullwidth": "Ancho completo al mostrar medios ",
+  "settings.media_letterbox": "Mantener proporciones al mostrar medios",
+  "settings.media_letterbox_hint": "Escalar medios para que llenen el espacio del contenedor sin cambiar sus proporciones sin recortarlos",
+  "settings.media_reveal_behind_cw": "Siempre mostrar medios sensibles dentro de las advertencias de contenido",
+  "settings.notifications.favicon_badge": "Marcador de notificaciones en el favicon",
+  "settings.notifications.favicon_badge.hint": "Muestra un marcador de notificaciones sin leer en el favicon",
+  "settings.notifications.tab_badge": "Marcador de notificaciones no leídas",
+  "settings.notifications.tab_badge.hint": "Muestra un marcador de notificaciones sin leer en el ícono de notificaciones cuando dicha columna no está abierta",
+  "settings.notifications_opts": "Opciones de notificaciones",
+  "settings.preferences": "Preferencias de usuarix",
+  "settings.prepend_cw_re": "Anteponer \"re: \" a las advertencias de contenido al responder",
+  "settings.preselect_on_reply": "Preseleccionar nombres de usuarix al responder",
+  "settings.preselect_on_reply_hint": "Al responder a conversaciones con múltiples participantes, preselecciona los nombres de usuarix subsecuentes del/la primerx",
+  "settings.rewrite_mentions": "Reescribir menciones in publicaciones mostradas",
+  "settings.rewrite_mentions_acct": "Reescribir con nombre de usuarix y dominio (para cuentas remotas)",
+  "settings.rewrite_mentions_no": "No reescribir menciones",
+  "settings.rewrite_mentions_username": "Reescribir con nombre de usuarix",
+  "settings.show_action_bar": "Mostrar botones de acción en toots colapsados",
+  "settings.show_content_type_choice": "Mostrar selección de tipo de contenido al crear toots",
+  "settings.show_reply_counter": "Mostrar un conteo estimado de respuestas",
+  "settings.side_arm": "Botón secundario:",
+  "settings.side_arm.none": "Ninguno",
+  "settings.side_arm_reply_mode": "Al responder a un toot, el botón de toot secundario debe:",
+  "settings.side_arm_reply_mode.copy": "Copiar opción de privacidad del toot al que estás respondiendo",
+  "settings.side_arm_reply_mode.keep": "Conservar opción de privacidad",
+  "settings.side_arm_reply_mode.restrict": "Restringir la opción de privacidad a la misma del toot al que estás respondiendo",
+  "settings.swipe_to_change_columns": "Permitir deslizar para cambiar columnas (Sólo en móvil)",
+  "settings.tag_misleading_links": "Marcar enlaces engañosos",
+  "settings.tag_misleading_links.hint": "Añadir una indicación visual indicando el destino de los enlace que no los mencionen explícitamente",
+  "settings.wide_view": "Vista amplia (solo modo de escritorio)",
+  "status.collapse": "Colapsar",
+  "status.uncollapse": "Descolapsar"
+}
diff --git a/app/javascript/flavours/glitch/locales/et.js b/app/javascript/flavours/glitch/locales/et.js
deleted file mode 100644
index e3ea6b2a9..000000000
--- a/app/javascript/flavours/glitch/locales/et.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/et.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/et.json b/app/javascript/flavours/glitch/locales/et.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/et.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/eu.js b/app/javascript/flavours/glitch/locales/eu.js
deleted file mode 100644
index 946410b67..000000000
--- a/app/javascript/flavours/glitch/locales/eu.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/eu.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/eu.json b/app/javascript/flavours/glitch/locales/eu.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/eu.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/fa.js b/app/javascript/flavours/glitch/locales/fa.js
deleted file mode 100644
index d82461a1a..000000000
--- a/app/javascript/flavours/glitch/locales/fa.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/fa.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/fa.json b/app/javascript/flavours/glitch/locales/fa.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/fa.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/fi.js b/app/javascript/flavours/glitch/locales/fi.js
deleted file mode 100644
index 11c3cd082..000000000
--- a/app/javascript/flavours/glitch/locales/fi.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/fi.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/fi.json b/app/javascript/flavours/glitch/locales/fi.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/fi.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/fo.json b/app/javascript/flavours/glitch/locales/fo.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/fo.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/fr-QC.json b/app/javascript/flavours/glitch/locales/fr-QC.json
new file mode 100644
index 000000000..383d933b4
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/fr-QC.json
@@ -0,0 +1,200 @@
+{
+  "about.fork_disclaimer": "Glitch-soc est un logiciel gratuit et open source, fork de Mastodon.",
+  "account.add_account_note": "Ajouter une note pour @{name}",
+  "account.disclaimer_full": "Les informations ci-dessous peuvent être incomplètes.",
+  "account.follows": "Abonnements",
+  "account.joined": "Ici depuis {date}",
+  "account.suspended_disclaimer_full": "Cet utilisateur a été suspendu par un modérateur.",
+  "account.view_full_profile": "Voir le profil complet",
+  "account_note.cancel": "Annuler",
+  "account_note.edit": "Éditer",
+  "account_note.glitch_placeholder": "Aucun commentaire fourni",
+  "account_note.save": "Sauvegarder",
+  "advanced_options.icon_title": "Options avancées",
+  "advanced_options.local-only.long": "Ne pas envoyer aux autres instances",
+  "advanced_options.local-only.short": "Uniquement en local",
+  "advanced_options.local-only.tooltip": "Ce post est uniquement local",
+  "advanced_options.threaded_mode.long": "Ouvre automatiquement une réponse lors de la publication",
+  "advanced_options.threaded_mode.short": "Mode thread",
+  "advanced_options.threaded_mode.tooltip": "Mode thread activé",
+  "boost_modal.missing_description": "Ce post contient des médias sans description",
+  "column.favourited_by": "Ajouté en favori par",
+  "column.heading": "Divers",
+  "column.reblogged_by": "Partagé par",
+  "column.subheading": "Autres options",
+  "column_header.profile": "Profil",
+  "column_subheading.lists": "Listes",
+  "column_subheading.navigation": "Navigation",
+  "community.column_settings.allow_local_only": "Afficher seulement les posts locaux",
+  "compose.attach": "Joindre…",
+  "compose.attach.doodle": "Dessiner quelque chose",
+  "compose.attach.upload": "Téléverser un fichier",
+  "compose.content-type.html": "HTML",
+  "compose.content-type.markdown": "Markdown",
+  "compose.content-type.plain": "Text brut",
+  "compose_form.poll.multiple_choices": "Choix multiples",
+  "compose_form.poll.single_choice": "Choix unique",
+  "compose_form.spoiler": "Cacher le texte derrière un avertissement",
+  "confirmation_modal.do_not_ask_again": "Ne plus demander confirmation",
+  "confirmations.deprecated_settings.confirm": "Utiliser les préférences de Mastodon",
+  "confirmations.deprecated_settings.message": "Certaines {app_settings} de glitch-soc que vous utilisez ont été remplacées par les {preferences} de Mastodon et seront remplacées :",
+  "confirmations.missing_media_description.confirm": "Envoyer quand même",
+  "confirmations.missing_media_description.edit": "Modifier le média",
+  "confirmations.missing_media_description.message": "Au moins un média joint manque d'une description. Pensez à décrire tous les médias attachés pour les malvoyant·e·s avant de publier votre post.",
+  "confirmations.unfilter.author": "Auteur",
+  "confirmations.unfilter.confirm": "Afficher",
+  "confirmations.unfilter.edit_filter": "Modifier le filtre",
+  "confirmations.unfilter.filters": "Correspondance avec {count, plural, one {un filtre} other {plusieurs filtres}}",
+  "content-type.change": "Type de contenu",
+  "direct.group_by_conversations": "Grouper par conversation",
+  "endorsed_accounts_editor.endorsed_accounts": "Comptes mis en avant",
+  "favourite_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci la prochaine fois",
+  "getting_started.onboarding": "Montre-moi les alentours",
+  "home.column_settings.advanced": "Avancé",
+  "home.column_settings.filter_regex": "Filtrer par expression régulière",
+  "home.column_settings.show_direct": "Afficher les MPs",
+  "home.settings": "Paramètres de la colonne",
+  "keyboard_shortcuts.bookmark": "ajouter aux marque-pages",
+  "keyboard_shortcuts.secondary_toot": "Envoyer le post en utilisant les paramètres secondaires de confidentialité",
+  "keyboard_shortcuts.toggle_collapse": "Plier/déplier les posts",
+  "layout.auto": "Auto",
+  "layout.desktop": "Ordinateur",
+  "layout.hint.auto": "Choisir automatiquement la mise en page selon l'option \"Activer l'interface Web avancée\" et la taille d'écran.",
+  "layout.hint.desktop": "Utiliser la mise en page en plusieurs colonnes indépendamment de l'option \"Activer l'interface Web avancée\" ou de la taille d'écran.",
+  "layout.hint.single": "Utiliser la mise en page à colonne unique indépendamment de l'option \"Activer l'interface Web avancée\" ou de la taille d'écran.",
+  "layout.single": "Téléphone",
+  "media_gallery.sensitive": "Sensible",
+  "moved_to_warning": "Ce compte a déménagé vers {moved_to_link} et ne peut donc plus accepter de nouveaux abonné·e·s.",
+  "navigation_bar.app_settings": "Paramètres de l'application",
+  "navigation_bar.featured_users": "Utilisateurs mis en avant",
+  "navigation_bar.info": "Informations détaillées",
+  "navigation_bar.keyboard_shortcuts": "Raccourcis clavier",
+  "navigation_bar.misc": "Autres",
+  "notification.markForDeletion": "Ajouter aux éléments à supprimer",
+  "notification_purge.btn_all": "Sélectionner\ntout",
+  "notification_purge.btn_apply": "Effacer\nla sélection",
+  "notification_purge.btn_invert": "Inverser\nla sélection",
+  "notification_purge.btn_none": "Annuler\nla sélection",
+  "notification_purge.start": "Activer le mode de nettoyage des notifications",
+  "notifications.marked_clear": "Effacer les notifications sélectionnées",
+  "notifications.marked_clear_confirmation": "Voulez-vous vraiment effacer de manière permanente toutes les notifications sélectionnées ?",
+  "onboarding.done": "Terminé",
+  "onboarding.next": "Suivant",
+  "onboarding.page_five.public_timelines": "Le fil local affiche les posts publics de tout le monde sur {domain}. Le fil global affiche les posts publics de tous les comptes que les personnes de {domain} suivent. Ce sont les fils publics, une façon formidable de découvrir de nouvelles personnes.",
+  "onboarding.page_four.home": "L'accueil affiche les posts des personnes que vous suivez.",
+  "onboarding.page_four.notifications": "La colonne de notifications vous montre lorsque quelqu'un interagit avec vous.",
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_one.handle": "Vous êtes sur {domain}, donc votre nom d'utilisateur complet est {handle}",
+  "onboarding.page_one.welcome": "Bievenue sur {domain} !",
+  "onboarding.page_six.admin": "Votre admin d’instance est {admin}.",
+  "onboarding.page_six.almost_done": "C'est bientôt fini...",
+  "onboarding.page_six.appetoot": "Bon appétoot !",
+  "onboarding.page_six.apps_available": "Il y a des {apps} disponibles pour iOS, Android et d'autres plateformes.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "onboarding.page_six.guidelines": "règles de la communauté",
+  "onboarding.page_six.read_guidelines": "Veuillez lire les {guidelines} de {domain} !",
+  "onboarding.page_six.various_app": "applications mobiles",
+  "onboarding.page_three.profile": "Modifiez votre profil pour changer votre avatar, biographie et nom public. Ici, vous trouverez également d'autres options.",
+  "onboarding.page_three.search": "Utilisez la barre de recherche pour trouver des personnes et regarder les hashtags comme {illustration} et {introductions}. Pour chercher une personne n'étant pas sur cette instance, utilisez son nom d'utilisateur complet.",
+  "onboarding.page_two.compose": "Écrivez des posts depuis la colonne de rédaction. Vous pouvez téléverser des images, changer la confidentialité et ajouter des avertissements de contenu avec les boutons ci-dessous.",
+  "onboarding.skip": "Passer",
+  "settings.always_show_spoilers_field": "Toujours activer le champ de rédaction de l'avertissement de contenu",
+  "settings.auto_collapse": "Repliage automatique",
+  "settings.auto_collapse_all": "Tout",
+  "settings.auto_collapse_lengthy": "Posts longs",
+  "settings.auto_collapse_media": "Posts avec média",
+  "settings.auto_collapse_notifications": "Notifications",
+  "settings.auto_collapse_reblogs": "Boosts",
+  "settings.auto_collapse_replies": "Réponses",
+  "settings.close": "Fermer",
+  "settings.collapsed_statuses": "Posts repliés",
+  "settings.compose_box_opts": "Zone de rédaction",
+  "settings.confirm_before_clearing_draft": "Afficher une fenêtre de confirmation avant d'écraser le message en cours de rédaction",
+  "settings.confirm_boost_missing_media_description": "Afficher une fenêtre de confirmation avant de partager des posts manquant de description des médias",
+  "settings.confirm_missing_media_description": "Afficher une fenêtre de confirmation avant de publier des posts manquant de description de média",
+  "settings.content_warnings": "Content warnings",
+  "settings.content_warnings.regexp": "Expression rationnelle",
+  "settings.content_warnings_filter": "Avertissement de contenu à ne pas automatiquement déplier :",
+  "settings.content_warnings_media_outside": "Afficher les médias en dehors des avertissements de contenu",
+  "settings.content_warnings_media_outside_hint": "Reproduit le comportement par défaut de Mastodon, les médias attachés ne sont plus affectés par le bouton d'affichage d'un post avec avertissement",
+  "settings.content_warnings_shared_state": "Affiche/cache le contenu de toutes les copies à la fois",
+  "settings.content_warnings_shared_state_hint": "Reproduit le comportement par défaut de Mastodon, le bouton d'avertissement de contenu affecte toutes les copies d'un post à la fois. Cela empêchera le repliement automatique de n'importe quelle copie d'un post avec un avertissement déplié",
+  "settings.content_warnings_unfold_opts": "Options de dépliement automatique",
+  "settings.deprecated_setting": "Cette option est maintenant définie par les {settings_page_link} de Mastodon",
+  "settings.enable_collapsed": "Activer le repliement des posts",
+  "settings.enable_collapsed_hint": "Les posts repliés ont une partie de leur contenu caché pour libérer de l'espace sur l'écran. C'est une option différente de l'avertissement de contenu",
+  "settings.enable_content_warnings_auto_unfold": "Déplier automatiquement les avertissements de contenu",
+  "settings.general": "Général",
+  "settings.hicolor_privacy_icons": "Indicateurs de confidentialité en couleurs",
+  "settings.hicolor_privacy_icons.hint": "Affiche les indicateurs de confidentialité dans des couleurs facilement distinguables",
+  "settings.image_backgrounds": "Images en arrière-plan",
+  "settings.image_backgrounds_media": "Prévisualiser les médias d'un post replié",
+  "settings.image_backgrounds_media_hint": "Si le post a un média attaché, utiliser le premier comme arrière-plan du post",
+  "settings.image_backgrounds_users": "Donner aux posts repliés une image en arrière-plan",
+  "settings.inline_preview_cards": "Cartes d'aperçu pour les liens externes",
+  "settings.layout": "Mise en page :",
+  "settings.layout_opts": "Mise en page",
+  "settings.media": "Média",
+  "settings.media_fullwidth": "Utiliser toute la largeur pour les aperçus",
+  "settings.media_letterbox": "Afficher les médias en Letterbox",
+  "settings.media_letterbox_hint": "Réduit le média et utilise une letterbox pour afficher l'image entière plutôt que de l'étirer et de la rogner",
+  "settings.media_reveal_behind_cw": "Toujours afficher les médias sensibles avec avertissement",
+  "settings.notifications.favicon_badge": "Badge de notifications non lues dans la favicon",
+  "settings.notifications.favicon_badge.hint": "Ajoute un badge dans la favicon pour alerter d'une notification non lue",
+  "settings.notifications.tab_badge": "Badge de notifications non lues",
+  "settings.notifications.tab_badge.hint": "Affiche un badge de notifications non lues dans les icônes des colonnes quand la colonne n'est pas ouverte",
+  "settings.notifications_opts": "Options des notifications",
+  "settings.pop_in_left": "Gauche",
+  "settings.pop_in_player": "Activer le lecteur pop-in",
+  "settings.pop_in_position": "Position du lecteur pop-in :",
+  "settings.pop_in_right": "Droite",
+  "settings.preferences": "Preferences",
+  "settings.prepend_cw_re": "Préfixer les avertissements avec \"re: \" lors d'une réponse",
+  "settings.preselect_on_reply": "Présélectionner les noms d’utilisateur·rices lors de la réponse",
+  "settings.preselect_on_reply_hint": "Présélectionner les noms d'utilisateurs après le premier lors d'une réponse à une conversation à plusieurs participants",
+  "settings.rewrite_mentions": "Réécrire les mentions dans les posts affichés",
+  "settings.rewrite_mentions_acct": "Réécrire avec le nom d'utilisateur·rice et le domaine (lorsque le compte est distant)",
+  "settings.rewrite_mentions_no": "Ne pas réécrire les mentions",
+  "settings.rewrite_mentions_username": "Réécrire avec le nom d’utilisateur·rice",
+  "settings.shared_settings_link": "préférences de l'utilisateur",
+  "settings.show_action_bar": "Afficher les boutons d'action dans les posts repliés",
+  "settings.show_content_type_choice": "Afficher le choix du type de contenu lors de la création des posts",
+  "settings.show_reply_counter": "Afficher une estimation du nombre de réponses",
+  "settings.side_arm": "Bouton secondaire de publication :",
+  "settings.side_arm.none": "Aucun",
+  "settings.side_arm_reply_mode": "Quand vous répondez à un post, le bouton secondaire de publication devrait :",
+  "settings.side_arm_reply_mode.copy": "Copier la confidentialité du post auquel vous répondez",
+  "settings.side_arm_reply_mode.keep": "Garder la confidentialité établie",
+  "settings.side_arm_reply_mode.restrict": "Restreindre la confidentialité de la réponse à celle du post auquel vous répondez",
+  "settings.status_icons": "Icônes des posts",
+  "settings.status_icons_language": "Indicateur de langue",
+  "settings.status_icons_local_only": "Indicateur de post local",
+  "settings.status_icons_media": "Indicateur de médias et sondage",
+  "settings.status_icons_reply": "Indicateur de réponses",
+  "settings.status_icons_visibility": "Indicateur de la confidentialité du post",
+  "settings.swipe_to_change_columns": "Glissement latéral pour changer de colonne (mobile uniquement)",
+  "settings.tag_misleading_links": "Étiqueter les liens trompeurs",
+  "settings.tag_misleading_links.hint": "Ajouter une indication visuelle avec l'hôte cible du lien à chaque lien ne le mentionnant pas explicitement",
+  "settings.wide_view": "Vue élargie (mode ordinateur uniquement)",
+  "settings.wide_view_hint": "Étire les colonnes pour mieux remplir l'espace disponible.",
+  "status.collapse": "Replier",
+  "status.has_audio": "Contient des fichiers audio attachés",
+  "status.has_pictures": "Contient des images attachées",
+  "status.has_preview_card": "Contient une carte de prévisualisation attachée",
+  "status.has_video": "Contient des vidéos attachées",
+  "status.in_reply_to": "Ce post est une réponse",
+  "status.is_poll": "Ce post est un sondage",
+  "status.local_only": "Visible uniquement depuis votre instance",
+  "status.sensitive_toggle": "Cliquer pour voir",
+  "status.uncollapse": "Déplier",
+  "web_app_crash.change_your_settings": "Changez vos {settings}",
+  "web_app_crash.content": "Voici les différentes options qui s'offrent à vous :",
+  "web_app_crash.debug_info": "Informations de débogage",
+  "web_app_crash.disable_addons": "Désactivez les extensions de votre navigateur, ainsi que les outils de traduction intégrés",
+  "web_app_crash.issue_tracker": "traqueur d'erreurs",
+  "web_app_crash.reload": "Rafraichir",
+  "web_app_crash.reload_page": "{reload} la page actuelle",
+  "web_app_crash.report_issue": "Signalez un bug dans le {issuetracker}",
+  "web_app_crash.settings": "paramètres",
+  "web_app_crash.title": "Nous sommes navrés, mais quelque chose s'est mal passé dans l'application Mastodon."
+}
diff --git a/app/javascript/flavours/glitch/locales/fr.js b/app/javascript/flavours/glitch/locales/fr.js
deleted file mode 100644
index 8562f5594..000000000
--- a/app/javascript/flavours/glitch/locales/fr.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/fr.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/fr.json b/app/javascript/flavours/glitch/locales/fr.json
new file mode 100644
index 000000000..383d933b4
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/fr.json
@@ -0,0 +1,200 @@
+{
+  "about.fork_disclaimer": "Glitch-soc est un logiciel gratuit et open source, fork de Mastodon.",
+  "account.add_account_note": "Ajouter une note pour @{name}",
+  "account.disclaimer_full": "Les informations ci-dessous peuvent être incomplètes.",
+  "account.follows": "Abonnements",
+  "account.joined": "Ici depuis {date}",
+  "account.suspended_disclaimer_full": "Cet utilisateur a été suspendu par un modérateur.",
+  "account.view_full_profile": "Voir le profil complet",
+  "account_note.cancel": "Annuler",
+  "account_note.edit": "Éditer",
+  "account_note.glitch_placeholder": "Aucun commentaire fourni",
+  "account_note.save": "Sauvegarder",
+  "advanced_options.icon_title": "Options avancées",
+  "advanced_options.local-only.long": "Ne pas envoyer aux autres instances",
+  "advanced_options.local-only.short": "Uniquement en local",
+  "advanced_options.local-only.tooltip": "Ce post est uniquement local",
+  "advanced_options.threaded_mode.long": "Ouvre automatiquement une réponse lors de la publication",
+  "advanced_options.threaded_mode.short": "Mode thread",
+  "advanced_options.threaded_mode.tooltip": "Mode thread activé",
+  "boost_modal.missing_description": "Ce post contient des médias sans description",
+  "column.favourited_by": "Ajouté en favori par",
+  "column.heading": "Divers",
+  "column.reblogged_by": "Partagé par",
+  "column.subheading": "Autres options",
+  "column_header.profile": "Profil",
+  "column_subheading.lists": "Listes",
+  "column_subheading.navigation": "Navigation",
+  "community.column_settings.allow_local_only": "Afficher seulement les posts locaux",
+  "compose.attach": "Joindre…",
+  "compose.attach.doodle": "Dessiner quelque chose",
+  "compose.attach.upload": "Téléverser un fichier",
+  "compose.content-type.html": "HTML",
+  "compose.content-type.markdown": "Markdown",
+  "compose.content-type.plain": "Text brut",
+  "compose_form.poll.multiple_choices": "Choix multiples",
+  "compose_form.poll.single_choice": "Choix unique",
+  "compose_form.spoiler": "Cacher le texte derrière un avertissement",
+  "confirmation_modal.do_not_ask_again": "Ne plus demander confirmation",
+  "confirmations.deprecated_settings.confirm": "Utiliser les préférences de Mastodon",
+  "confirmations.deprecated_settings.message": "Certaines {app_settings} de glitch-soc que vous utilisez ont été remplacées par les {preferences} de Mastodon et seront remplacées :",
+  "confirmations.missing_media_description.confirm": "Envoyer quand même",
+  "confirmations.missing_media_description.edit": "Modifier le média",
+  "confirmations.missing_media_description.message": "Au moins un média joint manque d'une description. Pensez à décrire tous les médias attachés pour les malvoyant·e·s avant de publier votre post.",
+  "confirmations.unfilter.author": "Auteur",
+  "confirmations.unfilter.confirm": "Afficher",
+  "confirmations.unfilter.edit_filter": "Modifier le filtre",
+  "confirmations.unfilter.filters": "Correspondance avec {count, plural, one {un filtre} other {plusieurs filtres}}",
+  "content-type.change": "Type de contenu",
+  "direct.group_by_conversations": "Grouper par conversation",
+  "endorsed_accounts_editor.endorsed_accounts": "Comptes mis en avant",
+  "favourite_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci la prochaine fois",
+  "getting_started.onboarding": "Montre-moi les alentours",
+  "home.column_settings.advanced": "Avancé",
+  "home.column_settings.filter_regex": "Filtrer par expression régulière",
+  "home.column_settings.show_direct": "Afficher les MPs",
+  "home.settings": "Paramètres de la colonne",
+  "keyboard_shortcuts.bookmark": "ajouter aux marque-pages",
+  "keyboard_shortcuts.secondary_toot": "Envoyer le post en utilisant les paramètres secondaires de confidentialité",
+  "keyboard_shortcuts.toggle_collapse": "Plier/déplier les posts",
+  "layout.auto": "Auto",
+  "layout.desktop": "Ordinateur",
+  "layout.hint.auto": "Choisir automatiquement la mise en page selon l'option \"Activer l'interface Web avancée\" et la taille d'écran.",
+  "layout.hint.desktop": "Utiliser la mise en page en plusieurs colonnes indépendamment de l'option \"Activer l'interface Web avancée\" ou de la taille d'écran.",
+  "layout.hint.single": "Utiliser la mise en page à colonne unique indépendamment de l'option \"Activer l'interface Web avancée\" ou de la taille d'écran.",
+  "layout.single": "Téléphone",
+  "media_gallery.sensitive": "Sensible",
+  "moved_to_warning": "Ce compte a déménagé vers {moved_to_link} et ne peut donc plus accepter de nouveaux abonné·e·s.",
+  "navigation_bar.app_settings": "Paramètres de l'application",
+  "navigation_bar.featured_users": "Utilisateurs mis en avant",
+  "navigation_bar.info": "Informations détaillées",
+  "navigation_bar.keyboard_shortcuts": "Raccourcis clavier",
+  "navigation_bar.misc": "Autres",
+  "notification.markForDeletion": "Ajouter aux éléments à supprimer",
+  "notification_purge.btn_all": "Sélectionner\ntout",
+  "notification_purge.btn_apply": "Effacer\nla sélection",
+  "notification_purge.btn_invert": "Inverser\nla sélection",
+  "notification_purge.btn_none": "Annuler\nla sélection",
+  "notification_purge.start": "Activer le mode de nettoyage des notifications",
+  "notifications.marked_clear": "Effacer les notifications sélectionnées",
+  "notifications.marked_clear_confirmation": "Voulez-vous vraiment effacer de manière permanente toutes les notifications sélectionnées ?",
+  "onboarding.done": "Terminé",
+  "onboarding.next": "Suivant",
+  "onboarding.page_five.public_timelines": "Le fil local affiche les posts publics de tout le monde sur {domain}. Le fil global affiche les posts publics de tous les comptes que les personnes de {domain} suivent. Ce sont les fils publics, une façon formidable de découvrir de nouvelles personnes.",
+  "onboarding.page_four.home": "L'accueil affiche les posts des personnes que vous suivez.",
+  "onboarding.page_four.notifications": "La colonne de notifications vous montre lorsque quelqu'un interagit avec vous.",
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_one.handle": "Vous êtes sur {domain}, donc votre nom d'utilisateur complet est {handle}",
+  "onboarding.page_one.welcome": "Bievenue sur {domain} !",
+  "onboarding.page_six.admin": "Votre admin d’instance est {admin}.",
+  "onboarding.page_six.almost_done": "C'est bientôt fini...",
+  "onboarding.page_six.appetoot": "Bon appétoot !",
+  "onboarding.page_six.apps_available": "Il y a des {apps} disponibles pour iOS, Android et d'autres plateformes.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "onboarding.page_six.guidelines": "règles de la communauté",
+  "onboarding.page_six.read_guidelines": "Veuillez lire les {guidelines} de {domain} !",
+  "onboarding.page_six.various_app": "applications mobiles",
+  "onboarding.page_three.profile": "Modifiez votre profil pour changer votre avatar, biographie et nom public. Ici, vous trouverez également d'autres options.",
+  "onboarding.page_three.search": "Utilisez la barre de recherche pour trouver des personnes et regarder les hashtags comme {illustration} et {introductions}. Pour chercher une personne n'étant pas sur cette instance, utilisez son nom d'utilisateur complet.",
+  "onboarding.page_two.compose": "Écrivez des posts depuis la colonne de rédaction. Vous pouvez téléverser des images, changer la confidentialité et ajouter des avertissements de contenu avec les boutons ci-dessous.",
+  "onboarding.skip": "Passer",
+  "settings.always_show_spoilers_field": "Toujours activer le champ de rédaction de l'avertissement de contenu",
+  "settings.auto_collapse": "Repliage automatique",
+  "settings.auto_collapse_all": "Tout",
+  "settings.auto_collapse_lengthy": "Posts longs",
+  "settings.auto_collapse_media": "Posts avec média",
+  "settings.auto_collapse_notifications": "Notifications",
+  "settings.auto_collapse_reblogs": "Boosts",
+  "settings.auto_collapse_replies": "Réponses",
+  "settings.close": "Fermer",
+  "settings.collapsed_statuses": "Posts repliés",
+  "settings.compose_box_opts": "Zone de rédaction",
+  "settings.confirm_before_clearing_draft": "Afficher une fenêtre de confirmation avant d'écraser le message en cours de rédaction",
+  "settings.confirm_boost_missing_media_description": "Afficher une fenêtre de confirmation avant de partager des posts manquant de description des médias",
+  "settings.confirm_missing_media_description": "Afficher une fenêtre de confirmation avant de publier des posts manquant de description de média",
+  "settings.content_warnings": "Content warnings",
+  "settings.content_warnings.regexp": "Expression rationnelle",
+  "settings.content_warnings_filter": "Avertissement de contenu à ne pas automatiquement déplier :",
+  "settings.content_warnings_media_outside": "Afficher les médias en dehors des avertissements de contenu",
+  "settings.content_warnings_media_outside_hint": "Reproduit le comportement par défaut de Mastodon, les médias attachés ne sont plus affectés par le bouton d'affichage d'un post avec avertissement",
+  "settings.content_warnings_shared_state": "Affiche/cache le contenu de toutes les copies à la fois",
+  "settings.content_warnings_shared_state_hint": "Reproduit le comportement par défaut de Mastodon, le bouton d'avertissement de contenu affecte toutes les copies d'un post à la fois. Cela empêchera le repliement automatique de n'importe quelle copie d'un post avec un avertissement déplié",
+  "settings.content_warnings_unfold_opts": "Options de dépliement automatique",
+  "settings.deprecated_setting": "Cette option est maintenant définie par les {settings_page_link} de Mastodon",
+  "settings.enable_collapsed": "Activer le repliement des posts",
+  "settings.enable_collapsed_hint": "Les posts repliés ont une partie de leur contenu caché pour libérer de l'espace sur l'écran. C'est une option différente de l'avertissement de contenu",
+  "settings.enable_content_warnings_auto_unfold": "Déplier automatiquement les avertissements de contenu",
+  "settings.general": "Général",
+  "settings.hicolor_privacy_icons": "Indicateurs de confidentialité en couleurs",
+  "settings.hicolor_privacy_icons.hint": "Affiche les indicateurs de confidentialité dans des couleurs facilement distinguables",
+  "settings.image_backgrounds": "Images en arrière-plan",
+  "settings.image_backgrounds_media": "Prévisualiser les médias d'un post replié",
+  "settings.image_backgrounds_media_hint": "Si le post a un média attaché, utiliser le premier comme arrière-plan du post",
+  "settings.image_backgrounds_users": "Donner aux posts repliés une image en arrière-plan",
+  "settings.inline_preview_cards": "Cartes d'aperçu pour les liens externes",
+  "settings.layout": "Mise en page :",
+  "settings.layout_opts": "Mise en page",
+  "settings.media": "Média",
+  "settings.media_fullwidth": "Utiliser toute la largeur pour les aperçus",
+  "settings.media_letterbox": "Afficher les médias en Letterbox",
+  "settings.media_letterbox_hint": "Réduit le média et utilise une letterbox pour afficher l'image entière plutôt que de l'étirer et de la rogner",
+  "settings.media_reveal_behind_cw": "Toujours afficher les médias sensibles avec avertissement",
+  "settings.notifications.favicon_badge": "Badge de notifications non lues dans la favicon",
+  "settings.notifications.favicon_badge.hint": "Ajoute un badge dans la favicon pour alerter d'une notification non lue",
+  "settings.notifications.tab_badge": "Badge de notifications non lues",
+  "settings.notifications.tab_badge.hint": "Affiche un badge de notifications non lues dans les icônes des colonnes quand la colonne n'est pas ouverte",
+  "settings.notifications_opts": "Options des notifications",
+  "settings.pop_in_left": "Gauche",
+  "settings.pop_in_player": "Activer le lecteur pop-in",
+  "settings.pop_in_position": "Position du lecteur pop-in :",
+  "settings.pop_in_right": "Droite",
+  "settings.preferences": "Preferences",
+  "settings.prepend_cw_re": "Préfixer les avertissements avec \"re: \" lors d'une réponse",
+  "settings.preselect_on_reply": "Présélectionner les noms d’utilisateur·rices lors de la réponse",
+  "settings.preselect_on_reply_hint": "Présélectionner les noms d'utilisateurs après le premier lors d'une réponse à une conversation à plusieurs participants",
+  "settings.rewrite_mentions": "Réécrire les mentions dans les posts affichés",
+  "settings.rewrite_mentions_acct": "Réécrire avec le nom d'utilisateur·rice et le domaine (lorsque le compte est distant)",
+  "settings.rewrite_mentions_no": "Ne pas réécrire les mentions",
+  "settings.rewrite_mentions_username": "Réécrire avec le nom d’utilisateur·rice",
+  "settings.shared_settings_link": "préférences de l'utilisateur",
+  "settings.show_action_bar": "Afficher les boutons d'action dans les posts repliés",
+  "settings.show_content_type_choice": "Afficher le choix du type de contenu lors de la création des posts",
+  "settings.show_reply_counter": "Afficher une estimation du nombre de réponses",
+  "settings.side_arm": "Bouton secondaire de publication :",
+  "settings.side_arm.none": "Aucun",
+  "settings.side_arm_reply_mode": "Quand vous répondez à un post, le bouton secondaire de publication devrait :",
+  "settings.side_arm_reply_mode.copy": "Copier la confidentialité du post auquel vous répondez",
+  "settings.side_arm_reply_mode.keep": "Garder la confidentialité établie",
+  "settings.side_arm_reply_mode.restrict": "Restreindre la confidentialité de la réponse à celle du post auquel vous répondez",
+  "settings.status_icons": "Icônes des posts",
+  "settings.status_icons_language": "Indicateur de langue",
+  "settings.status_icons_local_only": "Indicateur de post local",
+  "settings.status_icons_media": "Indicateur de médias et sondage",
+  "settings.status_icons_reply": "Indicateur de réponses",
+  "settings.status_icons_visibility": "Indicateur de la confidentialité du post",
+  "settings.swipe_to_change_columns": "Glissement latéral pour changer de colonne (mobile uniquement)",
+  "settings.tag_misleading_links": "Étiqueter les liens trompeurs",
+  "settings.tag_misleading_links.hint": "Ajouter une indication visuelle avec l'hôte cible du lien à chaque lien ne le mentionnant pas explicitement",
+  "settings.wide_view": "Vue élargie (mode ordinateur uniquement)",
+  "settings.wide_view_hint": "Étire les colonnes pour mieux remplir l'espace disponible.",
+  "status.collapse": "Replier",
+  "status.has_audio": "Contient des fichiers audio attachés",
+  "status.has_pictures": "Contient des images attachées",
+  "status.has_preview_card": "Contient une carte de prévisualisation attachée",
+  "status.has_video": "Contient des vidéos attachées",
+  "status.in_reply_to": "Ce post est une réponse",
+  "status.is_poll": "Ce post est un sondage",
+  "status.local_only": "Visible uniquement depuis votre instance",
+  "status.sensitive_toggle": "Cliquer pour voir",
+  "status.uncollapse": "Déplier",
+  "web_app_crash.change_your_settings": "Changez vos {settings}",
+  "web_app_crash.content": "Voici les différentes options qui s'offrent à vous :",
+  "web_app_crash.debug_info": "Informations de débogage",
+  "web_app_crash.disable_addons": "Désactivez les extensions de votre navigateur, ainsi que les outils de traduction intégrés",
+  "web_app_crash.issue_tracker": "traqueur d'erreurs",
+  "web_app_crash.reload": "Rafraichir",
+  "web_app_crash.reload_page": "{reload} la page actuelle",
+  "web_app_crash.report_issue": "Signalez un bug dans le {issuetracker}",
+  "web_app_crash.settings": "paramètres",
+  "web_app_crash.title": "Nous sommes navrés, mais quelque chose s'est mal passé dans l'application Mastodon."
+}
diff --git a/app/javascript/flavours/glitch/locales/fy.json b/app/javascript/flavours/glitch/locales/fy.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/fy.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/ga.js b/app/javascript/flavours/glitch/locales/ga.js
deleted file mode 100644
index af2846ff8..000000000
--- a/app/javascript/flavours/glitch/locales/ga.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ga.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ga.json b/app/javascript/flavours/glitch/locales/ga.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ga.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/gd.js b/app/javascript/flavours/glitch/locales/gd.js
deleted file mode 100644
index 604ee86dc..000000000
--- a/app/javascript/flavours/glitch/locales/gd.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/gd.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/gd.json b/app/javascript/flavours/glitch/locales/gd.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/gd.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/gl.js b/app/javascript/flavours/glitch/locales/gl.js
deleted file mode 100644
index 6a9140b1a..000000000
--- a/app/javascript/flavours/glitch/locales/gl.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/gl.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/gl.json b/app/javascript/flavours/glitch/locales/gl.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/gl.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/he.js b/app/javascript/flavours/glitch/locales/he.js
deleted file mode 100644
index 99516ee0c..000000000
--- a/app/javascript/flavours/glitch/locales/he.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/he.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/he.json b/app/javascript/flavours/glitch/locales/he.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/he.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/hi.js b/app/javascript/flavours/glitch/locales/hi.js
deleted file mode 100644
index 1a569495f..000000000
--- a/app/javascript/flavours/glitch/locales/hi.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/hi.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/hi.json b/app/javascript/flavours/glitch/locales/hi.json
new file mode 100644
index 000000000..f6eb75f84
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/hi.json
@@ -0,0 +1,18 @@
+{
+  "about.fork_disclaimer": "ग्लिच-सोक एक मुफ्त और ओपन सोर्स सॉफ़्टवेर है जो मैस्टोडॉन से फोर्क किया गया है",
+  "account.add_account_note": "@{name} के लिए कोई नोट लिखें",
+  "account.follows": "फ़ॉलोज़",
+  "account.joined": "ज़ोईन करने की {date}",
+  "account.suspended_disclaimer_full": "यह यूज़र एक मॉडरेटर द्वारा सस्पेंड कर दिया गया है",
+  "account.view_full_profile": "पूरी प्रोफ़ाइल देखें",
+  "account_note.cancel": "कैन्सल",
+  "account_note.edit": "एडिट या सम्पादन करें",
+  "account_note.glitch_placeholder": "कोई कॉमेंट नहीं दिया गया है",
+  "account_note.save": "सेव",
+  "advanced_options.icon_title": "एडवांस्ड ऑप्शन्स",
+  "advanced_options.local-only.long": "दूसरे इंस्टेंसों में पोस्ट ना करें",
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/hr.js b/app/javascript/flavours/glitch/locales/hr.js
deleted file mode 100644
index dbf9b4b9f..000000000
--- a/app/javascript/flavours/glitch/locales/hr.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/hr.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/hr.json b/app/javascript/flavours/glitch/locales/hr.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/hr.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/hu.js b/app/javascript/flavours/glitch/locales/hu.js
deleted file mode 100644
index 1f0849af3..000000000
--- a/app/javascript/flavours/glitch/locales/hu.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/hu.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/hu.json b/app/javascript/flavours/glitch/locales/hu.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/hu.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/hy.js b/app/javascript/flavours/glitch/locales/hy.js
deleted file mode 100644
index 96f6a4d19..000000000
--- a/app/javascript/flavours/glitch/locales/hy.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/hy.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/hy.json b/app/javascript/flavours/glitch/locales/hy.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/hy.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/id.js b/app/javascript/flavours/glitch/locales/id.js
deleted file mode 100644
index 07e5f7e56..000000000
--- a/app/javascript/flavours/glitch/locales/id.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/id.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/id.json b/app/javascript/flavours/glitch/locales/id.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/id.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/ig.json b/app/javascript/flavours/glitch/locales/ig.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ig.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/io.js b/app/javascript/flavours/glitch/locales/io.js
deleted file mode 100644
index 74ea6fae6..000000000
--- a/app/javascript/flavours/glitch/locales/io.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/io.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/io.json b/app/javascript/flavours/glitch/locales/io.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/io.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/is.js b/app/javascript/flavours/glitch/locales/is.js
deleted file mode 100644
index b05a08ad0..000000000
--- a/app/javascript/flavours/glitch/locales/is.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/is.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/is.json b/app/javascript/flavours/glitch/locales/is.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/is.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/it.js b/app/javascript/flavours/glitch/locales/it.js
deleted file mode 100644
index 90f543093..000000000
--- a/app/javascript/flavours/glitch/locales/it.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/it.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/it.json b/app/javascript/flavours/glitch/locales/it.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/it.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/ja.js b/app/javascript/flavours/glitch/locales/ja.js
deleted file mode 100644
index 52aeed3d6..000000000
--- a/app/javascript/flavours/glitch/locales/ja.js
+++ /dev/null
@@ -1,158 +0,0 @@
-import inherited from 'mastodon/locales/ja.json';
-
-const messages = {
-  'getting_started.open_source_notice': 'Glitchsocは{Mastodon}によるフリーなオープンソースソフトウェアです。誰でもGitHub({github})から開発に參加したり、問題を報告したりできます。',
-  'layout.auto': '自動',
-  'layout.current_is': 'あなたの現在のレイアウト:',
-  'layout.desktop': 'デスクトップ',
-  'layout.single': 'モバイル',
-  'navigation_bar.app_settings': 'アプリ設定',
-  'navigation_bar.featured_users': '紹介しているアカウント',
-  'navigation_bar.misc': 'その他',
-  'getting_started.onboarding': '解説を表示',
-  'onboarding.page_one.federation': '{domain}はMastodonのインスタンスです。Mastodonとは、独立したサーバが連携して作るソーシャルネットワークです。これらのサーバーをインスタンスと呼びます。',
-  'onboarding.page_one.welcome': '{domain}へようこそ!',
-  'onboarding.page_six.github': '{domain}はGlitchsocを使用しています。Glitchsocは{Mastodon}のフレンドリーな{fork}で、どんなMastodonアプリやインスタンスとも互換性があります。Glitchsocは完全に無料で、オープンソースです。{github}でバグ報告や機能要望あるいは貢獻をすることが可能です。',
-  'settings.always_show_spoilers_field': '常にコンテンツワーニング設定を表示する(指定がない場合は通常投稿)',
-  'settings.auto_collapse': '自動折りたたみ',
-  'settings.auto_collapse_all': 'すべて',
-  'settings.auto_collapse_lengthy': '長いトゥート',
-  'settings.auto_collapse_media': 'メディア付きトゥート',
-  'settings.auto_collapse_notifications': '通知',
-  'settings.auto_collapse_reblogs': 'ブースト',
-  'settings.auto_collapse_replies': '返信',
-  'settings.close': '閉じる',
-  'settings.collapsed_statuses': 'トゥート折りたたみ',
-  'settings.confirm_missing_media_description': '画像に対する補助記載がないときに投稿前の警告を表示する',
-  'settings.content_warnings': 'コンテンツワーニング',
-  'settings.content_warnings_filter': '説明に指定した文字が含まれているものを自動で展開しないようにする',
-  'settings.content_warnings.regexp': '正規表現',
-  'settings.enable_collapsed': 'トゥート折りたたみを有効にする',
-  'settings.enable_content_warnings_auto_unfold': 'コンテンツワーニング指定されている投稿を常に表示する',
-  'settings.general': '一般',
-  'settings.image_backgrounds': '画像背景',
-  'settings.image_backgrounds_media': '折りたまれたメディア付きトゥートをプレビュー',
-  'settings.image_backgrounds_users': '折りたまれたトゥートの背景を変更する',
-  'settings.media': 'メディア',
-  'settings.media_letterbox': 'メディアをレターボックス式で表示',
-  'settings.media_fullwidth': '全幅メディアプレビュー',
-  'settings.navbar_under': 'ナビを画面下部に移動させる(モバイル レイアウトのみ)',
-  'settings.notifications.favicon_badge': '通知アイコンに未読件数を表示する',
-  'settings.notifications_opts': '通知の設定',
-  'settings.notifications.tab_badge': '未読の通知があるとき、通知アイコンにマークを表示する',
-  'settings.preferences': 'ユーザー設定',
-  'settings.wide_view': 'ワイドビュー(デスクトップ レイアウトのみ)',
-  'settings.compose_box_opts': 'コンポーズボックス設定',
-  'settings.show_reply_counter': '投稿に対するリプライの数を表示する',
-  'settings.side_arm': 'セカンダリートゥートボタン',
-  'settings.side_arm.none': '表示しない',
-  'settings.side_arm_reply_mode': '返信時の投稿範囲',
-  'settings.side_arm_reply_mode.copy': '返信先の投稿範囲を利用する',
-  'settings.side_arm_reply_mode.keep': 'セカンダリートゥートボタンの設定を維持する',
-  'settings.side_arm_reply_mode.restrict': '返信先の投稿範囲に制限する',
-  'settings.layout': 'レイアウト',
-  'settings.layout_opts': 'レイアウトの設定',
-  'status.collapse': '折りたたむ',
-  'status.uncollapse': '折りたたみを解除',
-
-  'confirmations.missing_media_description.message': '少なくとも1つの画像に視覚障害者のための画像説明が付与されていません。すべての画像に対して説明を付与することを望みます。',
-  'confirmations.missing_media_description.confirm': 'このまま投稿',
-  'confirmations.missing_media_description.edit': 'メディアを編集',
-
-  'favourite_modal.combo': '次からは {combo} を押せば、これをスキップできます。',
-
-  'home.column_settings.show_direct': 'DMを表示',
-  'home.column_settings.advanced': '高度',
-  'home.column_settings.filter_regex': '正規表現でフィルター',
-
-  'notification.markForDeletion': '選択',
-  'notifications.clear': '通知を全てクリアする',
-  'notifications.marked_clear_confirmation': '削除した全ての通知を完全に削除してもよろしいですか?',
-  'notifications.marked_clear': '選択した通知を削除する',
-
-  'notification_purge.btn_all': 'すべて\n選択',
-  'notification_purge.btn_none': '選択\n解除',
-  'notification_purge.btn_invert': '選択を\n反転',
-  'notification_purge.btn_apply': '選択したものを\n削除',
-
-  'compose.attach.upload': 'ファイルをアップロード',
-  'compose.attach.doodle': 'お絵描きをする',
-  'compose.attach': '添付...',
-
-  'advanced_options.local-only.short': 'ローカル限定',
-  'advanced_options.local-only.long': '他のインスタンスには投稿されません',
-  'advanced_options.local-only.tooltip': 'この投稿はローカル限定投稿です',
-  'advanced_options.icon_title': '高度な設定',
-  'advanced_options.threaded_mode.short': 'スレッドモード',
-  'advanced_options.threaded_mode.long': '投稿時に自動的に返信するように設定します',
-  'advanced_options.threaded_mode.tooltip': 'スレッドモードを有効にする',
-
-  'navigation_bar.direct': 'ダイレクトメッセージ',
-  'navigation_bar.bookmarks': 'ブックマーク',
-  'column.bookmarks': 'ブックマーク',
-
-  'account.add_account_note': '@{name}のメモを追加',
-  'account.disclaimer_full': 'このユーザー情報は不正確な可能性があります。',
-  'account.follows': 'フォロー',
-  'account.suspended_disclaimer_full': 'このユーザーはモデレータにより停止されました。',
-  'account.view_full_profile': '正確な情報を見る',
-  'account_note.cancel': 'キャンセル',
-  'account_note.edit': '編集',
-  'account_note.glitch_placeholder': 'メモがありません',
-  'account_note.save': '保存',
-  'boost_modal.missing_description': 'このトゥートには少なくとも1つの画像に説明が付与されていません',
-  'community.column_settings.allow_local_only': 'ローカル限定投稿を表示する',
-  'compose.content-type.html': 'HTML',
-  'compose.content-type.markdown': 'マークダウン',
-  'compose.content-type.plain': 'プレーンテキスト',
-  'compose_form.poll.multiple_choices': '複数回答を許可',
-  'compose_form.poll.single_choice': '単一回答を許可',
-  'compose_form.spoiler': '本文は警告の後ろに隠す',
-  'confirmation_modal.do_not_ask_again': 'もう1度尋ねない',
-  'confirmations.discard_edit_media.confirm': '破棄',
-  'confirmations.discard_edit_media.message': 'メディアの説明・プレビューに保存していない変更があります。破棄してもよろしいですか?',
-  'confirmations.unfilter': 'このフィルターされたトゥートについての情報',
-  'confirmations.unfilter.author': '筆者',
-  'confirmations.unfilter.confirm': '見る',
-  'confirmations.unfilter.edit_filter': 'フィルターを編集',
-  'confirmations.unfilter.filters': '適用されたフィルター',
-  'content-type.change': 'コンテンツ形式を変更',
-  'direct.conversations_mode': '会話',
-  'direct.timeline_mode': 'タイムライン',
-  'endorsed_accounts_editor.endorsed_accounts': '紹介しているユーザー',
-  'keyboard_shortcuts.bookmark': 'ブックマーク',
-  'keyboard_shortcuts.secondary_toot': 'セカンダリートゥートの公開範囲でトゥートする',
-  'keyboard_shortcuts.toggle_collapse': '折りたたむ/折りたたみを解除',
-  'moved_to_warning': 'このアカウント{moved_to_link}に引っ越したため、新しいフォロワーを受け入れていません。',
-  'settings.show_action_bar': 'アクションバーを表示',
-  'settings.filtering_behavior': 'フィルターの振る舞い',
-  'settings.filtering_behavior.cw': '警告文にフィルターされた単語を付加して表示します',
-  'settings.filtering_behavior.drop': 'フィルターされたトゥートを完全に隠します',
-  'settings.filtering_behavior.hide': '\'フィルターされました\'とその理由を確認するボタンを表示する',
-  'settings.filtering_behavior.upstream': '\'フィルターされました\'とバニラMastodonと同じように表示する',
-  'settings.filters': 'フィルター',
-  'settings.hicolor_privacy_icons': 'ハイカラーの公開範囲アイコン',
-  'settings.hicolor_privacy_icons.hint': '公開範囲アイコンを明るく表示し見分けやすい色にします',
-  'settings.confirm_boost_missing_media_description': 'メディアの説明が欠けているトゥートをブーストする前に確認ダイアログを表示する',
-  'settings.tag_misleading_links': '誤解を招くリンクにタグをつける',
-  'settings.tag_misleading_links.hint': '明示的に言及していないすべてのリンクに、リンクターゲットホストを含む視覚的な表示を追加します',
-  'settings.rewrite_mentions': '表示されたトゥートの返信先表示を書き換える',
-  'settings.rewrite_mentions_acct': 'ユーザー名とドメイン名(アカウントがリモートの場合)を表示するように書き換える',
-  'settings.rewrite_mentions_no': '書き換えない',
-  'settings.rewrite_mentions_username': 'ユーザー名を表示するように書き換える',
-  'settings.swipe_to_change_columns': 'スワイプでカラムを切り替え可能にする(モバイルのみ)',
-  'settings.prepend_cw_re': '返信するとき警告に "re: "を付加する',
-  'settings.preselect_on_reply': '返信するときユーザー名を事前選択する',
-  'settings.confirm_before_clearing_draft': '作成しているメッセージが上書きされる前に確認ダイアログを表示する',
-  'settings.show_content_type_choice': 'トゥートを書くときコンテンツ形式の選択ボタンを表示する',
-  'settings.inline_preview_cards': '外部リンクに埋め込みプレビューを有効にする',
-  'settings.media_reveal_behind_cw': '既定で警告指定されているトゥートの閲覧注意メディアを表示する',
-  'settings.pop_in_left': '左',
-  'settings.pop_in_player': 'ポップインプレイヤーを有効化する',
-  'settings.pop_in_position': 'ポップインプレーヤーの位置:',
-  'settings.pop_in_right': '右',
-  'status.show_filter_reason': '(理由を見る)',
-
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ja.json b/app/javascript/flavours/glitch/locales/ja.json
new file mode 100644
index 000000000..610cd7525
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ja.json
@@ -0,0 +1,124 @@
+{
+  "account.add_account_note": "@{name}のメモを追加",
+  "account.disclaimer_full": "このユーザー情報は不正確な可能性があります。",
+  "account.follows": "フォロー",
+  "account.suspended_disclaimer_full": "このユーザーはモデレータにより停止されました。",
+  "account.view_full_profile": "正確な情報を見る",
+  "account_note.cancel": "キャンセル",
+  "account_note.edit": "編集",
+  "account_note.glitch_placeholder": "メモがありません",
+  "account_note.save": "保存",
+  "advanced_options.icon_title": "高度な設定",
+  "advanced_options.local-only.long": "他のインスタンスには投稿されません",
+  "advanced_options.local-only.short": "ローカル限定",
+  "advanced_options.local-only.tooltip": "この投稿はローカル限定投稿です",
+  "advanced_options.threaded_mode.long": "投稿時に自動的に返信するように設定します",
+  "advanced_options.threaded_mode.short": "スレッドモード",
+  "advanced_options.threaded_mode.tooltip": "スレッドモードを有効にする",
+  "boost_modal.missing_description": "このトゥートには少なくとも1つの画像に説明が付与されていません",
+  "community.column_settings.allow_local_only": "ローカル限定投稿を表示する",
+  "compose.attach": "添付...",
+  "compose.attach.doodle": "お絵描きをする",
+  "compose.attach.upload": "ファイルをアップロード",
+  "compose.content-type.markdown": "マークダウン",
+  "compose.content-type.plain": "プレーンテキスト",
+  "compose_form.poll.multiple_choices": "複数回答を許可",
+  "compose_form.poll.single_choice": "単一回答を許可",
+  "compose_form.spoiler": "本文は警告の後ろに隠す",
+  "confirmation_modal.do_not_ask_again": "もう1度尋ねない",
+  "confirmations.missing_media_description.confirm": "このまま投稿",
+  "confirmations.missing_media_description.edit": "メディアを編集",
+  "confirmations.missing_media_description.message": "少なくとも1つの画像に視覚障害者のための画像説明が付与されていません。すべての画像に対して説明を付与することを望みます。",
+  "confirmations.unfilter.author": "筆者",
+  "confirmations.unfilter.confirm": "見る",
+  "confirmations.unfilter.edit_filter": "フィルターを編集",
+  "confirmations.unfilter.filters": "適用されたフィルター",
+  "content-type.change": "コンテンツ形式を変更",
+  "endorsed_accounts_editor.endorsed_accounts": "紹介しているユーザー",
+  "favourite_modal.combo": "次からは {combo} を押せば、これをスキップできます。",
+  "getting_started.onboarding": "解説を表示",
+  "home.column_settings.advanced": "高度",
+  "home.column_settings.filter_regex": "正規表現でフィルター",
+  "home.column_settings.show_direct": "DMを表示",
+  "keyboard_shortcuts.bookmark": "ブックマーク",
+  "keyboard_shortcuts.secondary_toot": "セカンダリートゥートの公開範囲でトゥートする",
+  "keyboard_shortcuts.toggle_collapse": "折りたたむ/折りたたみを解除",
+  "layout.auto": "自動",
+  "layout.desktop": "デスクトップ",
+  "layout.single": "モバイル",
+  "moved_to_warning": "このアカウント{moved_to_link}に引っ越したため、新しいフォロワーを受け入れていません。",
+  "navigation_bar.app_settings": "アプリ設定",
+  "navigation_bar.featured_users": "紹介しているアカウント",
+  "navigation_bar.misc": "その他",
+  "notification.markForDeletion": "選択",
+  "notification_purge.btn_all": "すべて\n選択",
+  "notification_purge.btn_apply": "選択したものを\n削除",
+  "notification_purge.btn_invert": "選択を\n反転",
+  "notification_purge.btn_none": "選択\n解除",
+  "notifications.marked_clear": "選択した通知を削除する",
+  "notifications.marked_clear_confirmation": "削除した全ての通知を完全に削除してもよろしいですか?",
+  "onboarding.page_one.federation": "{domain}はMastodonのインスタンスです。Mastodonとは、独立したサーバが連携して作るソーシャルネットワークです。これらのサーバーをインスタンスと呼びます。",
+  "onboarding.page_one.welcome": "{domain}へようこそ!",
+  "onboarding.page_six.github": "{domain}はGlitchsocを使用しています。Glitchsocは{Mastodon}のフレンドリーな{fork}で、どんなMastodonアプリやインスタンスとも互換性があります。Glitchsocは完全に無料で、オープンソースです。{github}でバグ報告や機能要望あるいは貢獻をすることが可能です。",
+  "settings.always_show_spoilers_field": "常にコンテンツワーニング設定を表示する(指定がない場合は通常投稿)",
+  "settings.auto_collapse": "自動折りたたみ",
+  "settings.auto_collapse_all": "すべて",
+  "settings.auto_collapse_lengthy": "長いトゥート",
+  "settings.auto_collapse_media": "メディア付きトゥート",
+  "settings.auto_collapse_notifications": "通知",
+  "settings.auto_collapse_reblogs": "ブースト",
+  "settings.auto_collapse_replies": "返信",
+  "settings.close": "閉じる",
+  "settings.collapsed_statuses": "トゥート折りたたみ",
+  "settings.compose_box_opts": "コンポーズボックス設定",
+  "settings.confirm_before_clearing_draft": "作成しているメッセージが上書きされる前に確認ダイアログを表示する",
+  "settings.confirm_boost_missing_media_description": "メディアの説明が欠けているトゥートをブーストする前に確認ダイアログを表示する",
+  "settings.confirm_missing_media_description": "画像に対する補助記載がないときに投稿前の警告を表示する",
+  "settings.content_warnings": "コンテンツワーニング",
+  "settings.content_warnings.regexp": "正規表現",
+  "settings.content_warnings_filter": "説明に指定した文字が含まれているものを自動で展開しないようにする",
+  "settings.enable_collapsed": "トゥート折りたたみを有効にする",
+  "settings.enable_content_warnings_auto_unfold": "コンテンツワーニング指定されている投稿を常に表示する",
+  "settings.general": "一般",
+  "settings.hicolor_privacy_icons": "ハイカラーの公開範囲アイコン",
+  "settings.hicolor_privacy_icons.hint": "公開範囲アイコンを明るく表示し見分けやすい色にします",
+  "settings.image_backgrounds": "画像背景",
+  "settings.image_backgrounds_media": "折りたまれたメディア付きトゥートをプレビュー",
+  "settings.image_backgrounds_users": "折りたまれたトゥートの背景を変更する",
+  "settings.inline_preview_cards": "外部リンクに埋め込みプレビューを有効にする",
+  "settings.layout": "レイアウト",
+  "settings.layout_opts": "レイアウトの設定",
+  "settings.media": "メディア",
+  "settings.media_fullwidth": "全幅メディアプレビュー",
+  "settings.media_letterbox": "メディアをレターボックス式で表示",
+  "settings.media_reveal_behind_cw": "既定で警告指定されているトゥートの閲覧注意メディアを表示する",
+  "settings.notifications.favicon_badge": "通知アイコンに未読件数を表示する",
+  "settings.notifications.tab_badge": "未読の通知があるとき、通知アイコンにマークを表示する",
+  "settings.notifications_opts": "通知の設定",
+  "settings.pop_in_left": "左",
+  "settings.pop_in_player": "ポップインプレイヤーを有効化する",
+  "settings.pop_in_position": "ポップインプレーヤーの位置:",
+  "settings.pop_in_right": "右",
+  "settings.preferences": "ユーザー設定",
+  "settings.prepend_cw_re": "返信するとき警告に \"re: \"を付加する",
+  "settings.preselect_on_reply": "返信するときユーザー名を事前選択する",
+  "settings.rewrite_mentions": "表示されたトゥートの返信先表示を書き換える",
+  "settings.rewrite_mentions_acct": "ユーザー名とドメイン名(アカウントがリモートの場合)を表示するように書き換える",
+  "settings.rewrite_mentions_no": "書き換えない",
+  "settings.rewrite_mentions_username": "ユーザー名を表示するように書き換える",
+  "settings.show_action_bar": "アクションバーを表示",
+  "settings.show_content_type_choice": "トゥートを書くときコンテンツ形式の選択ボタンを表示する",
+  "settings.show_reply_counter": "投稿に対するリプライの数を表示する",
+  "settings.side_arm": "セカンダリートゥートボタン",
+  "settings.side_arm.none": "表示しない",
+  "settings.side_arm_reply_mode": "返信時の投稿範囲",
+  "settings.side_arm_reply_mode.copy": "返信先の投稿範囲を利用する",
+  "settings.side_arm_reply_mode.keep": "セカンダリートゥートボタンの設定を維持する",
+  "settings.side_arm_reply_mode.restrict": "返信先の投稿範囲に制限する",
+  "settings.swipe_to_change_columns": "スワイプでカラムを切り替え可能にする(モバイルのみ)",
+  "settings.tag_misleading_links": "誤解を招くリンクにタグをつける",
+  "settings.tag_misleading_links.hint": "明示的に言及していないすべてのリンクに、リンクターゲットホストを含む視覚的な表示を追加します",
+  "settings.wide_view": "ワイドビュー(デスクトップ レイアウトのみ)",
+  "status.collapse": "折りたたむ",
+  "status.uncollapse": "折りたたみを解除"
+}
diff --git a/app/javascript/flavours/glitch/locales/ka.js b/app/javascript/flavours/glitch/locales/ka.js
deleted file mode 100644
index 3e06f4282..000000000
--- a/app/javascript/flavours/glitch/locales/ka.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ka.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ka.json b/app/javascript/flavours/glitch/locales/ka.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ka.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/kab.js b/app/javascript/flavours/glitch/locales/kab.js
deleted file mode 100644
index 5ed1156ef..000000000
--- a/app/javascript/flavours/glitch/locales/kab.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/kab.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/kab.json b/app/javascript/flavours/glitch/locales/kab.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/kab.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/kk.js b/app/javascript/flavours/glitch/locales/kk.js
deleted file mode 100644
index 8d00fb035..000000000
--- a/app/javascript/flavours/glitch/locales/kk.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/kk.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/kk.json b/app/javascript/flavours/glitch/locales/kk.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/kk.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/kn.js b/app/javascript/flavours/glitch/locales/kn.js
deleted file mode 100644
index 1c50e3628..000000000
--- a/app/javascript/flavours/glitch/locales/kn.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/kn.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/kn.json b/app/javascript/flavours/glitch/locales/kn.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/kn.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/ko.js b/app/javascript/flavours/glitch/locales/ko.js
deleted file mode 100644
index a817044c1..000000000
--- a/app/javascript/flavours/glitch/locales/ko.js
+++ /dev/null
@@ -1,208 +0,0 @@
-import inherited from 'mastodon/locales/ko.json';
-
-const messages = {
-  'account.add_account_note': '@{name} 님에 대한 메모 추가',
-  'account.disclaimer_full': '아래에 있는 정보들은 사용자의 프로필을 완벽하게 나타내지 못하고 있을 수도 있습니다.',
-  'account.follows': '팔로우',
-  'account.suspended_disclaimer_full': '이 사용자는 중재자에 의해 정지되었습니다.',
-  'account.view_full_profile': '전체 프로필 보기',
-  'account_note.cancel': '취소',
-  'account_note.edit': '편집',
-  'account_note.glitch_placeholder': '코멘트가 없습니다',
-  'account_note.save': '저장',
-  'advanced_options.icon_title': '고급 옵션',
-  'advanced_options.local-only.long': '다른 서버에 게시하지 않기',
-  'advanced_options.local-only.short': '로컬 전용',
-  'advanced_options.local-only.tooltip': '이 게시물은 로컬 전용입니다',
-  'advanced_options.threaded_mode.long': '글을 작성하고 자동으로 답글 열기',
-  'advanced_options.threaded_mode.short': '글타래 모드',
-  'advanced_options.threaded_mode.tooltip': '글타래 모드 활성화됨',
-  'boost_modal.missing_description': '이 게시물은 설명이 없는 미디어를 포함하고 있습니다',
-  'column.favourited_by': '즐겨찾기 한 사람',
-  'column.heading': '기타',
-  'column.reblogged_by': '부스트 한 사람',
-  'column.subheading': '다양한 옵션',
-  'column.toot': '게시물과 답글',
-  'column_header.profile': '프로필',
-  'column_subheading.lists': '리스트',
-  'column_subheading.navigation': '탐색',
-  'community.column_settings.allow_local_only': '로컬 전용 글 보기',
-  'compose.attach': '첨부…',
-  'compose.attach.doodle': '뭔가 그려보세요',
-  'compose.attach.upload': '파일 업로드',
-  'compose.content-type.html': 'HTML',
-  'compose.content-type.markdown': '마크다운',
-  'compose.content-type.plain': '일반 텍스트',
-  'compose_form.poll.multiple_choices': '여러 개 선택 가능',
-  'compose_form.poll.single_choice': '하나만 선택 가능',
-  'compose_form.spoiler': '경고 메시지로 숨기기',
-  'confirmation_modal.do_not_ask_again': '다음부터 확인창을 띄우지 않기',
-  'confirmations.discard_edit_media.message': '저장하지 않은 미디어 설명이나 미리보기가 있습니다, 그냥 닫을까요?',
-  'confirmations.missing_media_description.confirm': '그냥 보내기',
-  'confirmations.missing_media_description.edit': '미디어 편집',
-  'confirmations.missing_media_description.message': '하나 이상의 미디어에 대해 설명을 작성하지 않았습니다. 시각장애인을 위해 모든 미디어에 설명을 추가하는 것을 고려해주세요.',
-  'confirmations.unfilter': '이 필터링 된 글에 대한 정보',
-  'confirmations.unfilter.author': '작성자',
-  'confirmations.unfilter.confirm': '보기',
-  'confirmations.unfilter.edit_filter': '필터 편집',
-  'confirmations.unfilter.filters': '적용된 {count, plural, one {필터} other {필터들}}',
-  'content-type.change': '콘텐트 타입',
-  'direct.conversations_mode': '대화',
-  'direct.timeline_mode': '타임라인',
-  'endorsed_accounts_editor.endorsed_accounts': '추천하는 계정들',
-  'favourite_modal.combo': '다음엔 {combo}를 눌러 건너뛸 수 있습니다',
-  'getting_started.onboarding': '둘러보기',
-  'getting_started.open_source_notice': '글리치는 {Mastodon}의 자유 오픈소스 포크버전입니다. {github}에서 문제를 리포팅 하거나 기여를 할 수 있습니다.',
-  'home.column_settings.advanced': '고급',
-  'home.column_settings.filter_regex': '정규표현식으로 필터',
-  'home.column_settings.show_direct': 'DM 보여주기',
-  'home.settings': '컬럼 설정',
-  'keyboard_shortcuts.bookmark': '북마크',
-  'keyboard_shortcuts.secondary_toot': '보조 프라이버시 설정으로 글 보내기',
-  'keyboard_shortcuts.toggle_collapse': '글 접거나 펼치기',
-  'layout.auto': '자동',
-  'layout.current_is': '현재 레이아웃:',
-  'layout.desktop': '데스크탑',
-  'layout.hint.auto': '“고급 웹 인터페이스 활성화” 설정과 화면 크기에 따라 자동으로 레이아웃을 고릅니다.',
-  'layout.hint.desktop': '“고급 웹 인터페이스 활성화” 설정이나 화면 크기에 관계 없이 멀티 컬럼 레이아웃을 사용합니다.',
-  'layout.hint.single': '“고급 웹 인터페이스 활성화” 설정이나 화면 크기에 관계 없이 싱글 컬럼 레이아웃을 사용합니다.',
-  'layout.single': '모바일',
-  'media_gallery.sensitive': '민감함',
-  'moved_to_warning': '이 계정은 {moved_to_link}로 이동한 것으로 표시되었고, 새 팔로우를 받지 않는 것 같습니다.',
-  'navigation_bar.app_settings': '앱 설정',
-  'navigation_bar.featured_users': '추천된 계정들',
-  'navigation_bar.misc': '다양한 옵션들',
-  'notification.markForDeletion': '삭제하기 위해 표시',
-  'notification_purge.btn_all': '전체선택',
-  'notification_purge.btn_apply': '선택된 알림 삭제',
-  'notification_purge.btn_invert': '선택반전',
-  'notification_purge.btn_none': '전체선택해제',
-  'notification_purge.start': '알림 삭제모드로 들어가기',
-  'notifications.clear': '내 알림 모두 지우기',
-  'notifications.marked_clear': '선택된 알림 모두 삭제',
-  'notifications.marked_clear_confirmation': '정말로 선택된 알림들을 영구적으로 삭제할까요?',
-  'onboarding.done': '완료',
-  'onboarding.next': '다음',
-  'onboarding.page_five.public_timelines': '로컬 타임라인은 {domain}에 있는 모든 사람의 공개글을 보여줍니다. 연합 타임라인은 {domain}에 있는 사람들이 팔로우 하는 모든 사람의 공개글을 보여줍니다. 이것들은 공개 타임라인이라고 불리며, 새로운 사람들을 발견할 수 있는 좋은 방법입니다.',
-  'onboarding.page_four.home': '홈 타임라인은 당신이 팔로우 한 사람들의 글을 보여줍니다.',
-  'onboarding.page_four.notifications': '알림 컬럼은 누군가가 당신과 상호작용한 것들을 보여줍니다.',
-  'onboarding.page_one.federation': '{domain}은 마스토돈의 \'인스턴스\'입니다. 마스토돈은 하나의 거대한 소셜 네트워크를 만들기 위해 참여한 서버들의 네트워크입니다. 우린 이 서버들을 인스턴스라고 부릅니다.',
-  'onboarding.page_one.handle': '당신은 {domain}에 속해 있으며, 전체 핸들은 {handle} 입니다.',
-  'onboarding.page_one.welcome': '{domain}에 오신 것을 환영합니다!',
-  'onboarding.page_six.admin': '우리 서버의 관리자는 {admin} 님입니다.',
-  'onboarding.page_six.almost_done': '거의 다 되었습니다…',
-  'onboarding.page_six.appetoot': '본 아페툿!',
-  'onboarding.page_six.apps_available': 'iOS, 안드로이드, 그리고 다른 플랫폼들을 위한 {apps}이 존재합니다.',
-  'onboarding.page_six.github': '{domain}은 글리치를 통해 구동 됩니다. 글리치는 {Mastodon}의 {fork}입니다, 그리고 어떤 마스토돈 인스턴스나 앱과도 호환 됩니다. 글리치는 완전한 자유 오픈소스입니다. {github}에서 버그를 리포팅 하거나, 기능을 제안하거나, 코드를 기여할 수 있습니다.',
-  'onboarding.page_six.guidelines': '커뮤니티 가이드라인',
-  'onboarding.page_six.read_guidelines': '{domain}의 {guidelines}을 읽어주세요!',
-  'onboarding.page_six.various_app': '모바일 앱',
-  'onboarding.page_three.profile': '프로필을 수정해 아바타, 바이오, 표시되는 이름을 설정하세요. 거기에서 다른 설정들도 찾을 수 있습니다.',
-  'onboarding.page_three.search': '검색창을 사용해 사람들과 해시태그를 찾아보세요. 예를 들면 {illustration}이라든지 {introcustions} 같은 것으로요. 이 인스턴스에 있지 않은 사람을 찾으려면, 전체 핸들을 사용하세요.',
-  'onboarding.page_two.compose': '작성 컬럼에서 게시물을 작성하세요. 그림을 업로드 할 수 있고, 공개설정을 바꿀 수도 있으며, 아래 아이콘을 통해 열람주의 텍스트를 설정할 수 있습니다.',
-  'onboarding.skip': '건너뛰기',
-  'settings.always_show_spoilers_field': '열람주의 항목을 언제나 활성화',
-  'settings.auto_collapse': '자동으로 접기',
-  'settings.auto_collapse_all': '모두',
-  'settings.auto_collapse_lengthy': '긴 글',
-  'settings.auto_collapse_media': '미디어 포함 글',
-  'settings.auto_collapse_notifications': '알림',
-  'settings.auto_collapse_reblogs': '부스트',
-  'settings.auto_collapse_replies': '답글',
-  'settings.close': '닫기',
-  'settings.collapsed_statuses': '접힌 글',
-  'settings.compose_box_opts': '작성 상자',
-  'settings.confirm_before_clearing_draft': '작성 중인 메시지를 덮어씌우기 전에 확인창을 보여주기',
-  'settings.confirm_boost_missing_media_description': '미디어 설명이 없는 글을 부스트하려 할 때 확인창을 보여주기',
-  'settings.confirm_missing_media_description': '미디어 설명이 없는 글을 작성하려 할 때 확인창을 보여주기',
-  'settings.content_warnings': '열람주의',
-  'settings.content_warnings.regexp': '정규표현식',
-  'settings.content_warnings_filter': '자동으로 펼치지 않을 열람주의 문구:',
-  'settings.deprecated_setting': '이 설정은 마스토돈의 {settings_page_link}에서 관리됩니다',
-  'settings.enable_collapsed': '접힌 글 활성화',
-  'settings.enable_content_warnings_auto_unfold': '자동으로 열람주의 펼치기',
-  'settings.filtering_behavior': '필터링 동작',
-  'settings.filtering_behavior.cw': '게시물을 보여주되, 필터된 단어를 열람주의에 추가합니다',
-  'settings.filtering_behavior.drop': '완전히 숨깁니다',
-  'settings.filtering_behavior.hide': '\'필터됨\'이라고 표시하고 이유를 표시하는 버튼을 추가합니다',
-  'settings.filtering_behavior.upstream': '\'필터됨\'이라고 일반 마스토돈처럼 표시합니다',
-  'settings.filters': '필터',
-  'settings.general': '일반',
-  'settings.hicolor_privacy_icons': '높은 채도의 공개설정 아이콘',
-  'settings.hicolor_privacy_icons.hint': '공개설정 아이콘들을 밝고 구분하기 쉬운 색으로 표시합니다',
-  'settings.image_backgrounds': '이미지 배경',
-  'settings.image_backgrounds_media': '접힌 글의 미디어 미리보기',
-  'settings.image_backgrounds_users': '접힌 글에 이미지 배경 주기',
-  'settings.inline_preview_cards': '외부 링크에 대한 미리보기 카드를 같이 표시',
-  'settings.layout': '레이아웃:',
-  'settings.layout_opts': '레이아웃 옵션',
-  'settings.media': '미디어',
-  'settings.media_fullwidth': '최대폭 미디어 미리보기',
-  'settings.media_letterbox': '레터박스 미디어',
-  'settings.media_letterbox_hint': '확대하고 자르는 대신 축소하고 레터박스에 넣어 이미지를 보여줍니다',
-  'settings.media_reveal_behind_cw': '열람주의로 가려진 미디어를 기본으로 펼쳐 둡니다',
-  'settings.navbar_under': '내비바를 하단에 (모바일 전용)',
-  'settings.notifications.favicon_badge': '읽지 않은 알림 파비콘 배지',
-  'settings.notifications.favicon_badge.hint': '읽지 않은 알림 배지를 파비콘에 추가합니다',
-  'settings.notifications.tab_badge': '읽지 않은 알림 배지',
-  'settings.notifications.tab_badge.hint': '알림 컬럼이 열려 있지 않을 때 알림 컬럼에 알림이 있다는 배지를 표시합니다',
-  'settings.notifications_opts': '알림 옵션',
-  'settings.pop_in_left': '왼쪽',
-  'settings.pop_in_player': '떠있는 재생기 활성화',
-  'settings.pop_in_position': '떠있는 재생기 위치:',
-  'settings.pop_in_right': '오른쪽',
-  'settings.preferences': '사용자 설정',
-  'settings.prepend_cw_re': '열람주의가 달린 글에 답장을 할 때 열람주의 문구 앞에 “re: ”를 추가합니다',
-  'settings.preselect_on_reply': '답글 달 때 사용자명 미리 선택',
-  'settings.preselect_on_reply_hint': '답글을 달 때 이미 멘션 된 사람의 사용자명을 미리 블럭으로 설정해 놓습니다',
-  'settings.rewrite_mentions': '표시되는 게시물의 멘션 표시 바꾸기',
-  'settings.rewrite_mentions_acct': '사용자명과 도메인으로 바꾸기(계정이 원격일 때)',
-  'settings.rewrite_mentions_no': '멘션을 그대로 두기',
-  'settings.rewrite_mentions_username': '사용자명으로 바꾸기',
-  'settings.shared_settings_link': '사용자 설정',
-  'settings.show_action_bar': '접힌 글에 액션 버튼들 보이기',
-  'settings.show_content_type_choice': '글을 작성할 때 콘텐트 타입을 고를 수 있도록 합니다',
-  'settings.show_reply_counter': '대략적인 답글 개수를 표시합니다',
-  'settings.side_arm': '보조 작성 버튼:',
-  'settings.side_arm.none': '없음',
-  'settings.side_arm_reply_mode': '답글을 작성할 때:',
-  'settings.side_arm_reply_mode.copy': '답글을 달려는 글의 공개설정을 복사합니다',
-  'settings.side_arm_reply_mode.keep': '보조 작성 버튼의 공개설정을 유지합니다',
-  'settings.side_arm_reply_mode.restrict': '답글을 달려는 글의 공개설정에 맞게 제한합니다',
-  'settings.status_icons': '게시물 아이콘',
-  'settings.status_icons_language': '언어 표시',
-  'settings.status_icons_local_only': '로컬 전용 표시',
-  'settings.status_icons_media': '미디어와 투표 표시',
-  'settings.status_icons_reply': '답글 표시',
-  'settings.status_icons_visibility': '툿 공개설정 표시',
-  'settings.swipe_to_change_columns': '스와이프하여 컬럼간 전환을 허용합니다 (모바일 전용)',
-  'settings.tag_misleading_links': '오해의 소지가 있는 링크를 표시합니다',
-  'settings.tag_misleading_links.hint': '링크에 명시적으로 주소가 없는 경우엔 대상 호스트를 보이도록 표시합니다',
-  'settings.wide_view': '넓은 뷰 (데스크탑 모드 전용)',
-  'settings.wide_view_hint': '컬럼들을 늘려서 활용 가능한 공간을 사용합니다.',
-  'status.collapse': '접기',
-  'status.has_audio': '소리 파일이 첨부되어 있습니다',
-  'status.has_pictures': '그림 파일이 첨부되어 있습니다',
-  'status.has_preview_card': '미리보기 카드가 첨부되어 있습니다',
-  'status.has_video': '영상이 첨부되어 있습니다',
-  'status.hide': '글 가리기',
-  'status.in_reply_to': '이 글은 답글입니다',
-  'status.is_poll': '이 글은 설문입니다',
-  'status.local_only': '당신의 서버에서만 보입니다',
-  'status.sensitive_toggle': '클릭해서 보기',
-  'status.show_filter_reason': '(이유 보기)',
-  'status.uncollapse': '펼치기',
-  'upload_modal.applying': '적용중…',
-  'web_app_crash.change_your_settings': '{settings}을 바꾸세요',
-  'web_app_crash.content': '이것들을 시도해 볼 수 있습니다:',
-  'web_app_crash.debug_info': '디버그 정보',
-  'web_app_crash.disable_addons': '브라우저 애드온이나 기본 번역 도구를 비활성화 합니다',
-  'web_app_crash.issue_tracker': '이슈 트래커',
-  'web_app_crash.reload': '새로고침',
-  'web_app_crash.reload_page': '이 페이지를 {reload}',
-  'web_app_crash.report_issue': '{issuetracker}에 버그 제보',
-  'web_app_crash.settings': '설정',
-  'web_app_crash.title': '죄송합니다, 하지만 마스토돈 앱이 뭔가 잘못되었습니다.',
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ko.json b/app/javascript/flavours/glitch/locales/ko.json
new file mode 100644
index 000000000..f17f32a9d
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ko.json
@@ -0,0 +1,200 @@
+{
+  "about.fork_disclaimer": "글리치는 마스토돈에서 포크한 자유 오픈소스 소프트웨어입니다.",
+  "account.add_account_note": "@{name} 님에 대한 메모 추가",
+  "account.disclaimer_full": "아래에 있는 정보들은 사용자의 프로필을 완벽하게 나타내지 못하고 있을 수도 있습니다.",
+  "account.follows": "팔로우",
+  "account.joined": "{date}에 가입함",
+  "account.suspended_disclaimer_full": "이 사용자는 중재자에 의해 정지되었습니다.",
+  "account.view_full_profile": "전체 프로필 보기",
+  "account_note.cancel": "취소",
+  "account_note.edit": "편집",
+  "account_note.glitch_placeholder": "코멘트가 없습니다",
+  "account_note.save": "저장",
+  "advanced_options.icon_title": "고급 옵션",
+  "advanced_options.local-only.long": "다른 서버에 게시하지 않기",
+  "advanced_options.local-only.short": "로컬 전용",
+  "advanced_options.local-only.tooltip": "이 게시물은 로컬 전용입니다",
+  "advanced_options.threaded_mode.long": "글을 작성하고 자동으로 답글 열기",
+  "advanced_options.threaded_mode.short": "글타래 모드",
+  "advanced_options.threaded_mode.tooltip": "글타래 모드 활성화됨",
+  "boost_modal.missing_description": "이 게시물은 설명이 없는 미디어를 포함하고 있습니다",
+  "column.favourited_by": "즐겨찾기 한 사람",
+  "column.heading": "기타",
+  "column.reblogged_by": "부스트 한 사람",
+  "column.subheading": "다양한 옵션",
+  "column_header.profile": "프로필",
+  "column_subheading.lists": "리스트",
+  "column_subheading.navigation": "탐색",
+  "community.column_settings.allow_local_only": "로컬 전용 글 보기",
+  "compose.attach": "첨부…",
+  "compose.attach.doodle": "뭔가 그려보세요",
+  "compose.attach.upload": "파일 업로드",
+  "compose.content-type.html": "HTML",
+  "compose.content-type.markdown": "마크다운",
+  "compose.content-type.plain": "일반 텍스트",
+  "compose_form.poll.multiple_choices": "여러 개 선택 가능",
+  "compose_form.poll.single_choice": "하나만 선택 가능",
+  "compose_form.spoiler": "경고 메시지로 숨기기",
+  "confirmation_modal.do_not_ask_again": "다음부터 확인창을 띄우지 않기",
+  "confirmations.deprecated_settings.confirm": "마스토돈 설정 사용",
+  "confirmations.deprecated_settings.message": "사용하던 몇몇 기기별 글리치 {app_settings}은 마스토돈 {preferences}으로 대체되었습니다:",
+  "confirmations.missing_media_description.confirm": "그냥 보내기",
+  "confirmations.missing_media_description.edit": "미디어 편집",
+  "confirmations.missing_media_description.message": "하나 이상의 미디어에 대해 설명을 작성하지 않았습니다. 시각장애인을 위해 모든 미디어에 설명을 추가하는 것을 고려해주세요.",
+  "confirmations.unfilter.author": "작성자",
+  "confirmations.unfilter.confirm": "보기",
+  "confirmations.unfilter.edit_filter": "필터 편집",
+  "confirmations.unfilter.filters": "적용된 {count, plural, one {필터} other {필터들}}",
+  "content-type.change": "콘텐트 타입",
+  "direct.group_by_conversations": "대화별로 묶기",
+  "endorsed_accounts_editor.endorsed_accounts": "추천하는 계정들",
+  "favourite_modal.combo": "다음엔 {combo}를 눌러 건너뛸 수 있습니다",
+  "getting_started.onboarding": "둘러보기",
+  "home.column_settings.advanced": "고급",
+  "home.column_settings.filter_regex": "정규표현식으로 필터",
+  "home.column_settings.show_direct": "DM 보여주기",
+  "home.settings": "컬럼 설정",
+  "keyboard_shortcuts.bookmark": "북마크",
+  "keyboard_shortcuts.secondary_toot": "보조 프라이버시 설정으로 글 보내기",
+  "keyboard_shortcuts.toggle_collapse": "글 접거나 펼치기",
+  "layout.auto": "자동",
+  "layout.desktop": "데스크탑",
+  "layout.hint.auto": "“고급 웹 인터페이스 활성화” 설정과 화면 크기에 따라 자동으로 레이아웃을 고릅니다.",
+  "layout.hint.desktop": "“고급 웹 인터페이스 활성화” 설정이나 화면 크기에 관계 없이 멀티 컬럼 레이아웃을 사용합니다.",
+  "layout.hint.single": "“고급 웹 인터페이스 활성화” 설정이나 화면 크기에 관계 없이 싱글 컬럼 레이아웃을 사용합니다.",
+  "layout.single": "모바일",
+  "media_gallery.sensitive": "민감함",
+  "moved_to_warning": "이 계정은 {moved_to_link}로 이동한 것으로 표시되었고, 새 팔로우를 받지 않는 것 같습니다.",
+  "navigation_bar.app_settings": "앱 설정",
+  "navigation_bar.featured_users": "추천된 계정들",
+  "navigation_bar.info": "추가 정보",
+  "navigation_bar.keyboard_shortcuts": "키보드 단축기",
+  "navigation_bar.misc": "다양한 옵션들",
+  "notification.markForDeletion": "삭제하기 위해 표시",
+  "notification_purge.btn_all": "전체선택",
+  "notification_purge.btn_apply": "선택된 알림 삭제",
+  "notification_purge.btn_invert": "선택반전",
+  "notification_purge.btn_none": "전체선택해제",
+  "notification_purge.start": "알림 삭제모드로 들어가기",
+  "notifications.marked_clear": "선택된 알림 모두 삭제",
+  "notifications.marked_clear_confirmation": "정말로 선택된 알림들을 영구적으로 삭제할까요?",
+  "onboarding.done": "완료",
+  "onboarding.next": "다음",
+  "onboarding.page_five.public_timelines": "로컬 타임라인은 {domain}에 있는 모든 사람의 공개글을 보여줍니다. 연합 타임라인은 {domain}에 있는 사람들이 팔로우 하는 모든 사람의 공개글을 보여줍니다. 이것들은 공개 타임라인이라고 불리며, 새로운 사람들을 발견할 수 있는 좋은 방법입니다.",
+  "onboarding.page_four.home": "홈 타임라인은 당신이 팔로우 한 사람들의 글을 보여줍니다.",
+  "onboarding.page_four.notifications": "알림 컬럼은 누군가가 당신과 상호작용한 것들을 보여줍니다.",
+  "onboarding.page_one.federation": "{domain}은 마스토돈의 '인스턴스'입니다. 마스토돈은 하나의 거대한 소셜 네트워크를 만들기 위해 참여한 서버들의 네트워크입니다. 우린 이 서버들을 인스턴스라고 부릅니다.",
+  "onboarding.page_one.handle": "당신은 {domain}에 속해 있으며, 전체 핸들은 {handle} 입니다.",
+  "onboarding.page_one.welcome": "{domain}에 오신 것을 환영합니다!",
+  "onboarding.page_six.admin": "우리 서버의 관리자는 {admin} 님입니다.",
+  "onboarding.page_six.almost_done": "거의 다 되었습니다…",
+  "onboarding.page_six.appetoot": "본 아페툿!",
+  "onboarding.page_six.apps_available": "iOS, 안드로이드, 그리고 다른 플랫폼들을 위한 {apps}이 존재합니다.",
+  "onboarding.page_six.github": "{domain}은 글리치를 통해 구동 됩니다. 글리치는 {Mastodon}의 {fork}입니다, 그리고 어떤 마스토돈 인스턴스나 앱과도 호환 됩니다. 글리치는 완전한 자유 오픈소스입니다. {github}에서 버그를 리포팅 하거나, 기능을 제안하거나, 코드를 기여할 수 있습니다.",
+  "onboarding.page_six.guidelines": "커뮤니티 가이드라인",
+  "onboarding.page_six.read_guidelines": "{domain}의 {guidelines}을 읽어주세요!",
+  "onboarding.page_six.various_app": "모바일 앱",
+  "onboarding.page_three.profile": "프로필을 수정해 아바타, 바이오, 표시되는 이름을 설정하세요. 거기에서 다른 설정들도 찾을 수 있습니다.",
+  "onboarding.page_three.search": "검색창을 사용해 사람들과 해시태그를 찾아보세요. 예를 들면 {illustration}이라든지 {introcustions} 같은 것으로요. 이 인스턴스에 있지 않은 사람을 찾으려면, 전체 핸들을 사용하세요.",
+  "onboarding.page_two.compose": "작성 컬럼에서 게시물을 작성하세요. 그림을 업로드 할 수 있고, 공개설정을 바꿀 수도 있으며, 아래 아이콘을 통해 열람주의 텍스트를 설정할 수 있습니다.",
+  "onboarding.skip": "건너뛰기",
+  "settings.always_show_spoilers_field": "열람주의 항목을 언제나 활성화",
+  "settings.auto_collapse": "자동으로 접기",
+  "settings.auto_collapse_all": "모두",
+  "settings.auto_collapse_lengthy": "긴 글",
+  "settings.auto_collapse_media": "미디어 포함 글",
+  "settings.auto_collapse_notifications": "알림",
+  "settings.auto_collapse_reblogs": "부스트",
+  "settings.auto_collapse_replies": "답글",
+  "settings.close": "닫기",
+  "settings.collapsed_statuses": "접힌 글",
+  "settings.compose_box_opts": "작성 상자",
+  "settings.confirm_before_clearing_draft": "작성 중인 메시지를 덮어씌우기 전에 확인창을 보여주기",
+  "settings.confirm_boost_missing_media_description": "미디어 설명이 없는 글을 부스트하려 할 때 확인창을 보여주기",
+  "settings.confirm_missing_media_description": "미디어 설명이 없는 글을 작성하려 할 때 확인창을 보여주기",
+  "settings.content_warnings": "열람주의",
+  "settings.content_warnings.regexp": "정규표현식",
+  "settings.content_warnings_filter": "자동으로 펼치지 않을 열람주의 문구:",
+  "settings.content_warnings_media_outside": "미디어 첨부를 열람주의 바깥에 보이기",
+  "settings.content_warnings_media_outside_hint": "마스토돈 원본처럼 열람주의 토글이 미디어 첨부에는 영향을 미치지 않게 합니다",
+  "settings.content_warnings_shared_state": "동일한 글의 열람주의를 한번에 열고 닫기",
+  "settings.content_warnings_shared_state_hint": "마스토돈 원본처럼 열람주의 버튼이 동일한 모든 글에 대해 영향을 미치게 합니다. 펼쳐진 열람주의 글이 자동으로 다시 접히는 것을 방지합니다",
+  "settings.content_warnings_unfold_opts": "자동 펼치기 옵션",
+  "settings.deprecated_setting": "이 설정은 마스토돈의 {settings_page_link}에서 관리됩니다",
+  "settings.enable_collapsed": "접힌 글 활성화",
+  "settings.enable_collapsed_hint": "접힌 게시물을 콘텐츠의 일부분을 가려서 공간을 적게 차지합니다. 열람주의 기능과는 다릅니다",
+  "settings.enable_content_warnings_auto_unfold": "자동으로 열람주의 펼치기",
+  "settings.general": "일반",
+  "settings.hicolor_privacy_icons": "높은 채도의 공개설정 아이콘",
+  "settings.hicolor_privacy_icons.hint": "공개설정 아이콘들을 밝고 구분하기 쉬운 색으로 표시합니다",
+  "settings.image_backgrounds": "이미지 배경",
+  "settings.image_backgrounds_media": "접힌 글의 미디어 미리보기",
+  "settings.image_backgrounds_media_hint": "게시물이 미디어 첨부를 포함한다면, 첫번째를 배경으로 사용합니다",
+  "settings.image_backgrounds_users": "접힌 글에 이미지 배경 주기",
+  "settings.inline_preview_cards": "외부 링크에 대한 미리보기 카드를 같이 표시",
+  "settings.layout": "레이아웃:",
+  "settings.layout_opts": "레이아웃 옵션",
+  "settings.media": "미디어",
+  "settings.media_fullwidth": "최대폭 미디어 미리보기",
+  "settings.media_letterbox": "레터박스 미디어",
+  "settings.media_letterbox_hint": "확대하고 자르는 대신 축소하고 레터박스에 넣어 이미지를 보여줍니다",
+  "settings.media_reveal_behind_cw": "열람주의로 가려진 미디어를 기본으로 펼쳐 둡니다",
+  "settings.notifications.favicon_badge": "읽지 않은 알림 파비콘 배지",
+  "settings.notifications.favicon_badge.hint": "읽지 않은 알림 배지를 파비콘에 추가합니다",
+  "settings.notifications.tab_badge": "읽지 않은 알림 배지",
+  "settings.notifications.tab_badge.hint": "알림 컬럼이 열려 있지 않을 때 알림 컬럼에 알림이 있다는 배지를 표시합니다",
+  "settings.notifications_opts": "알림 옵션",
+  "settings.pop_in_left": "왼쪽",
+  "settings.pop_in_player": "떠있는 재생기 활성화",
+  "settings.pop_in_position": "떠있는 재생기 위치:",
+  "settings.pop_in_right": "오른쪽",
+  "settings.preferences": "사용자 설정",
+  "settings.prepend_cw_re": "열람주의가 달린 글에 답장을 할 때 열람주의 문구 앞에 “re: ”를 추가합니다",
+  "settings.preselect_on_reply": "답글 달 때 사용자명 미리 선택",
+  "settings.preselect_on_reply_hint": "답글을 달 때 이미 멘션 된 사람의 사용자명을 미리 블럭으로 설정해 놓습니다",
+  "settings.rewrite_mentions": "표시되는 게시물의 멘션 표시 바꾸기",
+  "settings.rewrite_mentions_acct": "사용자명과 도메인으로 바꾸기(계정이 원격일 때)",
+  "settings.rewrite_mentions_no": "멘션을 그대로 두기",
+  "settings.rewrite_mentions_username": "사용자명으로 바꾸기",
+  "settings.shared_settings_link": "사용자 설정",
+  "settings.show_action_bar": "접힌 글에 액션 버튼들 보이기",
+  "settings.show_content_type_choice": "글을 작성할 때 콘텐트 타입을 고를 수 있도록 합니다",
+  "settings.show_reply_counter": "대략적인 답글 개수를 표시합니다",
+  "settings.side_arm": "보조 작성 버튼:",
+  "settings.side_arm.none": "없음",
+  "settings.side_arm_reply_mode": "답글을 작성할 때:",
+  "settings.side_arm_reply_mode.copy": "답글을 달려는 글의 공개설정을 복사합니다",
+  "settings.side_arm_reply_mode.keep": "보조 작성 버튼의 공개설정을 유지합니다",
+  "settings.side_arm_reply_mode.restrict": "답글을 달려는 글의 공개설정에 맞게 제한합니다",
+  "settings.status_icons": "게시물 아이콘",
+  "settings.status_icons_language": "언어 표시",
+  "settings.status_icons_local_only": "로컬 전용 표시",
+  "settings.status_icons_media": "미디어와 투표 표시",
+  "settings.status_icons_reply": "답글 표시",
+  "settings.status_icons_visibility": "툿 공개설정 표시",
+  "settings.swipe_to_change_columns": "스와이프하여 컬럼간 전환을 허용합니다 (모바일 전용)",
+  "settings.tag_misleading_links": "오해의 소지가 있는 링크를 표시합니다",
+  "settings.tag_misleading_links.hint": "링크에 명시적으로 주소가 없는 경우엔 대상 호스트를 보이도록 표시합니다",
+  "settings.wide_view": "넓은 뷰 (데스크탑 모드 전용)",
+  "settings.wide_view_hint": "컬럼들을 늘려서 활용 가능한 공간을 사용합니다.",
+  "status.collapse": "접기",
+  "status.has_audio": "소리 파일이 첨부되어 있습니다",
+  "status.has_pictures": "그림 파일이 첨부되어 있습니다",
+  "status.has_preview_card": "미리보기 카드가 첨부되어 있습니다",
+  "status.has_video": "영상이 첨부되어 있습니다",
+  "status.in_reply_to": "이 글은 답글입니다",
+  "status.is_poll": "이 글은 설문입니다",
+  "status.local_only": "당신의 서버에서만 보입니다",
+  "status.sensitive_toggle": "클릭해서 보기",
+  "status.uncollapse": "펼치기",
+  "web_app_crash.change_your_settings": "{settings}을 바꾸세요",
+  "web_app_crash.content": "이것들을 시도해 볼 수 있습니다:",
+  "web_app_crash.debug_info": "디버그 정보",
+  "web_app_crash.disable_addons": "브라우저 애드온이나 기본 번역 도구를 비활성화 합니다",
+  "web_app_crash.issue_tracker": "이슈 트래커",
+  "web_app_crash.reload": "새로고침",
+  "web_app_crash.reload_page": "이 페이지를 {reload}",
+  "web_app_crash.report_issue": "{issuetracker}에 버그 제보",
+  "web_app_crash.settings": "설정",
+  "web_app_crash.title": "죄송합니다, 하지만 마스토돈 앱이 뭔가 잘못되었습니다."
+}
diff --git a/app/javascript/flavours/glitch/locales/ku.js b/app/javascript/flavours/glitch/locales/ku.js
deleted file mode 100644
index 19e0e95aa..000000000
--- a/app/javascript/flavours/glitch/locales/ku.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ku.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ku.json b/app/javascript/flavours/glitch/locales/ku.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ku.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/kw.js b/app/javascript/flavours/glitch/locales/kw.js
deleted file mode 100644
index 1325ca825..000000000
--- a/app/javascript/flavours/glitch/locales/kw.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/kw.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/kw.json b/app/javascript/flavours/glitch/locales/kw.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/kw.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/la.json b/app/javascript/flavours/glitch/locales/la.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/la.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/lt.js b/app/javascript/flavours/glitch/locales/lt.js
deleted file mode 100644
index 47453aeeb..000000000
--- a/app/javascript/flavours/glitch/locales/lt.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/lt.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/lt.json b/app/javascript/flavours/glitch/locales/lt.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/lt.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/lv.js b/app/javascript/flavours/glitch/locales/lv.js
deleted file mode 100644
index cdbcdf799..000000000
--- a/app/javascript/flavours/glitch/locales/lv.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/lv.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/lv.json b/app/javascript/flavours/glitch/locales/lv.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/lv.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/mk.js b/app/javascript/flavours/glitch/locales/mk.js
deleted file mode 100644
index 55e510b59..000000000
--- a/app/javascript/flavours/glitch/locales/mk.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/mk.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/mk.json b/app/javascript/flavours/glitch/locales/mk.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/mk.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/ml.js b/app/javascript/flavours/glitch/locales/ml.js
deleted file mode 100644
index d00331a1a..000000000
--- a/app/javascript/flavours/glitch/locales/ml.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ml.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ml.json b/app/javascript/flavours/glitch/locales/ml.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ml.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/mr.js b/app/javascript/flavours/glitch/locales/mr.js
deleted file mode 100644
index fb3cde92a..000000000
--- a/app/javascript/flavours/glitch/locales/mr.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/mr.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/mr.json b/app/javascript/flavours/glitch/locales/mr.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/mr.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/ms.js b/app/javascript/flavours/glitch/locales/ms.js
deleted file mode 100644
index 61033c521..000000000
--- a/app/javascript/flavours/glitch/locales/ms.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ms.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ms.json b/app/javascript/flavours/glitch/locales/ms.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ms.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/my.json b/app/javascript/flavours/glitch/locales/my.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/my.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/nl.js b/app/javascript/flavours/glitch/locales/nl.js
deleted file mode 100644
index 17c371c58..000000000
--- a/app/javascript/flavours/glitch/locales/nl.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/nl.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/nl.json b/app/javascript/flavours/glitch/locales/nl.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/nl.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/nn.js b/app/javascript/flavours/glitch/locales/nn.js
deleted file mode 100644
index 4c42368cb..000000000
--- a/app/javascript/flavours/glitch/locales/nn.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/nn.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/nn.json b/app/javascript/flavours/glitch/locales/nn.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/nn.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/no.js b/app/javascript/flavours/glitch/locales/no.js
deleted file mode 100644
index 794b1da25..000000000
--- a/app/javascript/flavours/glitch/locales/no.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/no.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/no.json b/app/javascript/flavours/glitch/locales/no.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/no.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/oc.js b/app/javascript/flavours/glitch/locales/oc.js
deleted file mode 100644
index 8f161fd8c..000000000
--- a/app/javascript/flavours/glitch/locales/oc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/oc.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/oc.json b/app/javascript/flavours/glitch/locales/oc.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/oc.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/pa.js b/app/javascript/flavours/glitch/locales/pa.js
deleted file mode 100644
index c3e0e2b84..000000000
--- a/app/javascript/flavours/glitch/locales/pa.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/pa.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/pa.json b/app/javascript/flavours/glitch/locales/pa.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/pa.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/pl.js b/app/javascript/flavours/glitch/locales/pl.js
deleted file mode 100644
index f430bf577..000000000
--- a/app/javascript/flavours/glitch/locales/pl.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import inherited from 'mastodon/locales/pl.json';
-
-const messages = {
-  'getting_started.open_source_notice': 'Glitchsoc jest wolnym i otwartoźródłowym forkiem oprogramowania {Mastodon}. Możesz współtworzyć projekt lub zgłaszać błędy na GitHubie pod adresem {github}.',
-  'layout.auto': 'Automatyczny',
-  'layout.current_is': 'Twój obecny układ to:',
-  'layout.desktop': 'Desktopowy',
-  'layout.mobile': 'Mobilny',
-  'navigation_bar.app_settings': 'Ustawienia aplikacji',
-  'navigation_bar.bookmarks': 'Zakładki',
-  'getting_started.onboarding': 'Rozejrzyj się',
-  'onboarding.page_one.federation': '{domain} jest \'instancją\' Mastodona. Mastodon to sieć działających niezależnie serwerów tworzących jedną sieć społecznościową. Te serwery nazywane są instancjami.',
-  'onboarding.page_one.welcome': 'Witamy na {domain}!',
-  'onboarding.page_six.github': '{domain} jest oparty na Glitchsoc. Glitchsoc jest {forkiem} {Mastodon}a kompatybilnym z każdym klientem i aplikacją Mastodona. Glitchsoc jest całkowicie wolnym i otwartoźródłowym oprogramowaniem. Możesz zgłaszać błędy i sugestie funkcji oraz współtworzyć projekt na {github}.',
-  'settings.auto_collapse': 'Automatyczne zwijanie',
-  'settings.auto_collapse_all': 'Wszystko',
-  'settings.auto_collapse_lengthy': 'Długie wpisy',
-  'settings.auto_collapse_media': 'Wpisy z zawartością multimedialną',
-  'settings.auto_collapse_notifications': 'Powiadomienia',
-  'settings.auto_collapse_reblogs': 'Podbicia',
-  'settings.auto_collapse_replies': 'Odpowiedzi',
-  'settings.close': 'Zamknij',
-  'settings.collapsed_statuses': 'Zwijanie wpisów',
-  'settings.enable_collapsed': 'Włącz zwijanie wpisów',
-  'settings.general': 'Ogólne',
-  'settings.image_backgrounds': 'Obrazy w tle',
-  'settings.image_backgrounds_media': 'Wyświetlaj zawartość multimedialną zwiniętych wpisów',
-  'settings.image_backgrounds_users': 'Nadaj tło zwiniętym wpisom',
-  'settings.layout': 'Układ',
-  'settings.media': 'Zawartość multimedialna',
-  'settings.media_letterbox': 'Letterbox media',
-  'settings.media_fullwidth': 'Podgląd zawartości multimedialnej o pełnej szerokości',
-  'settings.navbar_under': 'Pasek nawigacji na dole (tylko w trybie mobilnym)',
-  'settings.preferences': 'Preferencje użytkownika',
-  'settings.side_arm': 'Drugi przycisk wysyłania',
-  'settings.side_arm.none': 'Żaden',
-  'settings.wide_view': 'Szeroki widok (tylko w trybie desktopowym)',
-  'status.bookmark': 'Dodaj do zakładek',
-  'status.collapse': 'Zwiń',
-  'status.uncollapse': 'Rozwiń',
-
-  'media_gallery.sensitive': 'Zawartość wrażliwa',
-
-  'favourite_modal.combo': 'Możesz nacisnąć {combo}, aby pominąć to następnym razem',
-
-  'home.column_settings.show_direct': 'Pokaż wiadomości bezpośrednie',
-
-  'notification.markForDeletion': 'Oznacz do usunięcia',
-  'notifications.clear': 'Wyczyść wszystkie powiadomienia',
-  'notifications.marked_clear_confirmation': 'Czy na pewno chcesz bezpowrtonie usunąć wszystkie powiadomienia?',
-  'notifications.marked_clear': 'Usuń zaznaczone powiadomienia',
-
-  'notification_purge.btn_all': 'Zaznacz\nwszystkie',
-  'notification_purge.btn_none': 'Odznacz\nwszystkie',
-  'notification_purge.btn_invert': 'Odwróć\nzaznaczenie',
-  'notification_purge.btn_apply': 'Usuń\nzaznaczone',
-  'notification_purge.start': 'Przejdź do trybu usuwania powiadomień',
-
-  'compose.attach.upload': 'Wyślij plik',
-  'compose.attach.doodle': 'Narysuj coś',
-  'compose.attach': 'Załącz coś',
-
-  'advanced_options.local-only.short': 'Tylko lokalnie',
-  'advanced_options.local-only.long': 'Nie wysyłaj na inne instancje',
-  'advanced_options.local-only.tooltip': 'Ten wpis jest widoczny tylko lokalnie',
-  'advanced_options.icon_title': 'Ustawienia zaawansowane',
-  'advanced_options.threaded_mode.short': 'Tryb wątków',
-  'advanced_options.threaded_mode.long': 'Przechodzi do tworzenia odpowiedzi po publikacji wpisu',
-  'advanced_options.threaded_mode.tooltip': 'Włączono tryb wątków',
-  
-  'column.bookmarks': 'Zakładki',
-  'compose_form.sensitive': 'Oznacz zawartość multimedialną jako wrażliwą',
-  'compose_form.spoiler': 'Ukryj tekst za ostrzeżeniem',
-  'favourite_modal.combo': 'Możesz nacisnąć {combo}, aby pominąć to następnym razem',
-  'tabs_bar.compose': 'Napisz',
-  
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/pl.json b/app/javascript/flavours/glitch/locales/pl.json
new file mode 100644
index 000000000..09acd098e
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/pl.json
@@ -0,0 +1,55 @@
+{
+  "advanced_options.icon_title": "Ustawienia zaawansowane",
+  "advanced_options.local-only.long": "Nie wysyłaj na inne instancje",
+  "advanced_options.local-only.short": "Tylko lokalnie",
+  "advanced_options.local-only.tooltip": "Ten wpis jest widoczny tylko lokalnie",
+  "advanced_options.threaded_mode.long": "Przechodzi do tworzenia odpowiedzi po publikacji wpisu",
+  "advanced_options.threaded_mode.short": "Tryb wątków",
+  "advanced_options.threaded_mode.tooltip": "Włączono tryb wątków",
+  "compose.attach": "Załącz coś",
+  "compose.attach.doodle": "Narysuj coś",
+  "compose.attach.upload": "Wyślij plik",
+  "compose_form.spoiler": "Ukryj tekst za ostrzeżeniem",
+  "favourite_modal.combo": "Możesz nacisnąć {combo}, aby pominąć to następnym razem",
+  "getting_started.onboarding": "Rozejrzyj się",
+  "home.column_settings.show_direct": "Pokaż wiadomości bezpośrednie",
+  "layout.auto": "Automatyczny",
+  "layout.desktop": "Desktopowy",
+  "media_gallery.sensitive": "Zawartość wrażliwa",
+  "navigation_bar.app_settings": "Ustawienia aplikacji",
+  "notification.markForDeletion": "Oznacz do usunięcia",
+  "notification_purge.btn_all": "Zaznacz\nwszystkie",
+  "notification_purge.btn_apply": "Usuń\nzaznaczone",
+  "notification_purge.btn_invert": "Odwróć\nzaznaczenie",
+  "notification_purge.btn_none": "Odznacz\nwszystkie",
+  "notification_purge.start": "Przejdź do trybu usuwania powiadomień",
+  "notifications.marked_clear": "Usuń zaznaczone powiadomienia",
+  "notifications.marked_clear_confirmation": "Czy na pewno chcesz bezpowrtonie usunąć wszystkie powiadomienia?",
+  "onboarding.page_one.federation": "{domain} jest 'instancją' Mastodona. Mastodon to sieć działających niezależnie serwerów tworzących jedną sieć społecznościową. Te serwery nazywane są instancjami.",
+  "onboarding.page_one.welcome": "Witamy na {domain}!",
+  "onboarding.page_six.github": "{domain} jest oparty na Glitchsoc. Glitchsoc jest {forkiem} {Mastodon}a kompatybilnym z każdym klientem i aplikacją Mastodona. Glitchsoc jest całkowicie wolnym i otwartoźródłowym oprogramowaniem. Możesz zgłaszać błędy i sugestie funkcji oraz współtworzyć projekt na {github}.",
+  "settings.auto_collapse": "Automatyczne zwijanie",
+  "settings.auto_collapse_all": "Wszystko",
+  "settings.auto_collapse_lengthy": "Długie wpisy",
+  "settings.auto_collapse_media": "Wpisy z zawartością multimedialną",
+  "settings.auto_collapse_notifications": "Powiadomienia",
+  "settings.auto_collapse_reblogs": "Podbicia",
+  "settings.auto_collapse_replies": "Odpowiedzi",
+  "settings.close": "Zamknij",
+  "settings.collapsed_statuses": "Zwijanie wpisów",
+  "settings.content_warnings": "Content warnings",
+  "settings.enable_collapsed": "Włącz zwijanie wpisów",
+  "settings.general": "Ogólne",
+  "settings.image_backgrounds": "Obrazy w tle",
+  "settings.image_backgrounds_media": "Wyświetlaj zawartość multimedialną zwiniętych wpisów",
+  "settings.image_backgrounds_users": "Nadaj tło zwiniętym wpisom",
+  "settings.layout": "Układ",
+  "settings.media": "Zawartość multimedialna",
+  "settings.media_fullwidth": "Podgląd zawartości multimedialnej o pełnej szerokości",
+  "settings.preferences": "Preferencje użytkownika",
+  "settings.side_arm": "Drugi przycisk wysyłania",
+  "settings.side_arm.none": "Żaden",
+  "settings.wide_view": "Szeroki widok (tylko w trybie desktopowym)",
+  "status.collapse": "Zwiń",
+  "status.uncollapse": "Rozwiń"
+}
diff --git a/app/javascript/flavours/glitch/locales/pt-BR.js b/app/javascript/flavours/glitch/locales/pt-BR.js
deleted file mode 100644
index 6fed635f8..000000000
--- a/app/javascript/flavours/glitch/locales/pt-BR.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/pt-BR.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/pt-BR.json b/app/javascript/flavours/glitch/locales/pt-BR.json
new file mode 100644
index 000000000..0bc0d2bea
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/pt-BR.json
@@ -0,0 +1,200 @@
+{
+  "about.fork_disclaimer": "O Glitch-soc é um software gratuito de código aberto bifurcado a partir do Mastodon.",
+  "account.add_account_note": "Adicionar nota para @{name}",
+  "account.disclaimer_full": "As informações abaixo podem refletir o perfil do usuário de forma incompleta.",
+  "account.follows": "Seguidores",
+  "account.joined": "Entrou em {date}",
+  "account.suspended_disclaimer_full": "Este usuário foi suspenso por um moderador.",
+  "account.view_full_profile": "Ver o perfil completo",
+  "account_note.cancel": "Cancelar",
+  "account_note.edit": "Editar",
+  "account_note.glitch_placeholder": "Nenhum comentário fornecido",
+  "account_note.save": "Salvar",
+  "advanced_options.icon_title": "Opções avançadas",
+  "advanced_options.local-only.long": "Não publicar em outras instâncias",
+  "advanced_options.local-only.short": "Apenas localmente",
+  "advanced_options.local-only.tooltip": "Este post é somente local",
+  "advanced_options.threaded_mode.long": "Abrir automaticamente uma resposta ao postar",
+  "advanced_options.threaded_mode.short": "Modo de discussão",
+  "advanced_options.threaded_mode.tooltip": "Modo de discussão ativado",
+  "boost_modal.missing_description": "Este toot contém algumas mídias sem descrição",
+  "column.favourited_by": "Favoritado por",
+  "column.heading": "Diversos",
+  "column.reblogged_by": "Inpulsionado por",
+  "column.subheading": "Opções diversas",
+  "column_header.profile": "Perfil",
+  "column_subheading.lists": "Listas",
+  "column_subheading.navigation": "Navegação",
+  "community.column_settings.allow_local_only": "Mostrar os toots apenas locais",
+  "compose.attach": "Anexar...",
+  "compose.attach.doodle": "Desenhe algo",
+  "compose.attach.upload": "Enviar um arquivo",
+  "compose.content-type.html": "HTML",
+  "compose.content-type.markdown": "Markdown",
+  "compose.content-type.plain": "Texto sem formatação",
+  "compose_form.poll.multiple_choices": "Permitir múltipla escolha",
+  "compose_form.poll.single_choice": "Permitir uma escolha",
+  "compose_form.spoiler": "Ocultar texto atrás do aviso",
+  "confirmation_modal.do_not_ask_again": "Não pedir confirmação novamente",
+  "confirmations.deprecated_settings.confirm": "Usar preferências do Mastodon",
+  "confirmations.deprecated_settings.message": "Alguns dos {app_settings} específicos do dispositivo que você está usando foram substituídos por Mastodon {preferences} e serão substituídos:",
+  "confirmations.missing_media_description.confirm": "Enviar mesmo assim",
+  "confirmations.missing_media_description.edit": "Editar mídia",
+  "confirmations.missing_media_description.message": "Pelo menos um anexo de mídia não tem uma descrição. Considere descrever todos os anexos de mídia para deficientes visuais antes de enviar seu toot.",
+  "confirmations.unfilter.author": "Autor",
+  "confirmations.unfilter.confirm": "Exibir",
+  "confirmations.unfilter.edit_filter": "Editar filtro",
+  "confirmations.unfilter.filters": "Correspondência de {count, plural, one {filtro} other {filtros}}",
+  "content-type.change": "Tipo de conteúdo",
+  "direct.group_by_conversations": "Agrupar por conversa",
+  "endorsed_accounts_editor.endorsed_accounts": "Contas em destaque",
+  "favourite_modal.combo": "Você pode pressionar {combo} para pular isso da próxima vez",
+  "getting_started.onboarding": "Mostre-me ao redor",
+  "home.column_settings.advanced": "Avançado",
+  "home.column_settings.filter_regex": "Filtrar com uma expressão regular",
+  "home.column_settings.show_direct": "Mostrar DMs",
+  "home.settings": "Configurações da coluna",
+  "keyboard_shortcuts.bookmark": "para marcar",
+  "keyboard_shortcuts.secondary_toot": "para enviar toot usando a configuração de privacidade secundária",
+  "keyboard_shortcuts.toggle_collapse": "para recolher/mostrar toots",
+  "layout.auto": "Automático",
+  "layout.desktop": "Área de trabalho",
+  "layout.hint.auto": "Escolher automaticamente o layout baseado na configuração \"Habilitar interface web avançada\" e o tamanho da tela.",
+  "layout.hint.desktop": "Use o layout de várias colunas independentemente da configuração \"Habilitar interface web avançada\" ou do tamanho da tela.",
+  "layout.hint.single": "Use o layout de uma coluna independentemente da configuração \"Habilitar interface web avançada\" ou do tamanho da tela.",
+  "layout.single": "Celular",
+  "media_gallery.sensitive": "Sensível",
+  "moved_to_warning": "Esta conta foi como movida para {moved_to_link} e, portanto, pode não aceitar novos seguidores.",
+  "navigation_bar.app_settings": "Configurações do aplicativo",
+  "navigation_bar.featured_users": "Usuários em destaque",
+  "navigation_bar.info": "Informação estendida",
+  "navigation_bar.keyboard_shortcuts": "Atalhos de teclado",
+  "navigation_bar.misc": "Diversos",
+  "notification.markForDeletion": "Marcar para exclusão",
+  "notification_purge.btn_all": "Selecionar\ntudo",
+  "notification_purge.btn_apply": "Limpar\nselecionados",
+  "notification_purge.btn_invert": "Inverter\nseleção",
+  "notification_purge.btn_none": "Selecionar\nnenhum",
+  "notification_purge.start": "Entrar no modo de limpeza de notificação",
+  "notifications.marked_clear": "Limpar as notificações selecionadas",
+  "notifications.marked_clear_confirmation": "Tem certeza que deseja limpar todas as notificações selecionadas permanentemente?",
+  "onboarding.done": "Feito",
+  "onboarding.next": "Próximo",
+  "onboarding.page_five.public_timelines": "A linha do tempo local mostra publicações públicas de todos em {domain}. A linha do tempo federada mostra publicações públicas de todos que as pessoas seguem em {domain}. Estas são as linhas do tempo públicas, uma ótima maneira de descobrir novas pessoas.",
+  "onboarding.page_four.home": "A linha do tempo da casa mostra publicações de pessoas que você segue.",
+  "onboarding.page_four.notifications": "A coluna de notificações mostra quando alguém interage com você.",
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_one.handle": "Você está em {domain}, então o seu identificador completo é {handle}",
+  "onboarding.page_one.welcome": "Bem-vindo ao {domain}!",
+  "onboarding.page_six.admin": "O administrador da sua instância é {admin}.",
+  "onboarding.page_six.almost_done": "Quase pronto...",
+  "onboarding.page_six.appetoot": "Bom Appetoot!",
+  "onboarding.page_six.apps_available": "Há {apps} disponíveis para iOS, Android e outras plataformas.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "onboarding.page_six.guidelines": "diretrizes da comunidade",
+  "onboarding.page_six.read_guidelines": "Por favor, leia {domain} {guidelines}!",
+  "onboarding.page_six.various_app": "aplicativos móveis",
+  "onboarding.page_three.profile": "Edite seu perfil para alterar seu avatar, bio e nome de exibição. Lá você também encontrará outras preferências.",
+  "onboarding.page_three.search": "Use a barra de busca para encontrar pessoas e procure hashtags, tais como {illustration} e {introductions}. Para procurar uma pessoa que não esteja neste caso, use o identificador completo.",
+  "onboarding.page_two.compose": "Escreva as postagens a partir da coluna de composição. Você pode enviar imagens, alterar as configurações de privacidade e adicionar avisos de conteúdo com os ícones abaixo.",
+  "onboarding.skip": "Pular",
+  "settings.always_show_spoilers_field": "Sempre ativar o campo Aviso de Conteúdo",
+  "settings.auto_collapse": "Colapso automático",
+  "settings.auto_collapse_all": "Tudo",
+  "settings.auto_collapse_lengthy": "Toots longos",
+  "settings.auto_collapse_media": "Toots com mídia",
+  "settings.auto_collapse_notifications": "Notificações",
+  "settings.auto_collapse_reblogs": "Impulsos",
+  "settings.auto_collapse_replies": "Respostas",
+  "settings.close": "Fechar",
+  "settings.collapsed_statuses": "Toots recolhidos",
+  "settings.compose_box_opts": "Caixa de composição",
+  "settings.confirm_before_clearing_draft": "Mostrar diálogo de confirmação antes de sobrescrever a mensagem que está sendo composta",
+  "settings.confirm_boost_missing_media_description": "Mostrar diálogo antes de inpulsionar os toots sem descrições de mídia",
+  "settings.confirm_missing_media_description": "Mostrar diálogo antes de enviar toots sem descrições de mídia",
+  "settings.content_warnings": "Content warnings",
+  "settings.content_warnings.regexp": "Expressão regular",
+  "settings.content_warnings_filter": "Avisos de conteúdo para não revelar automaticamente:",
+  "settings.content_warnings_media_outside": "Exibir anexos de mídia fora avisos de conteúdo",
+  "settings.content_warnings_media_outside_hint": "Reproduzir o comportamento do Mastodonte, fazendo com que a alternância do Aviso de Conteúdo não afete os anexos de mídia",
+  "settings.content_warnings_shared_state": "Mostrar/ocultar o conteúdo de todas as cópias de uma só vez",
+  "settings.content_warnings_shared_state_hint": "Reproduzir o comportamento do Mastodonte fazendo com que o botão de Aviso de Conteúdo afete todas as cópias de um post de uma só vez. Isto evitará o colapso automático de qualquer cópia de um toon com Aviso de Conteúdo revelado",
+  "settings.content_warnings_unfold_opts": "Opções de auto-revelar",
+  "settings.deprecated_setting": "Essa configuração agora é controlada pelo {settings_page_link} do Mastodon",
+  "settings.enable_collapsed": "Habilitar toots recolhidos",
+  "settings.enable_collapsed_hint": "Posts recolhidos têm partes dos seus conteúdos ocultos para ocupar menos espaço na tela. Isto é diferente do recurso 'Aviso de Conteúdo'",
+  "settings.enable_content_warnings_auto_unfold": "Revelar automaticamente os avisos de conteúdo",
+  "settings.general": "Geral",
+  "settings.hicolor_privacy_icons": "Ícones de privacidade com cores de alto contraste",
+  "settings.hicolor_privacy_icons.hint": "Exibir ícones de privacidade em cores brilhantes e facilmente distinguíveis",
+  "settings.image_backgrounds": "Fundos de imagem",
+  "settings.image_backgrounds_media": "Pré-visualização da mídia de toots colapsados",
+  "settings.image_backgrounds_media_hint": "Se o post tiver algum anexo de mídia, use o primeiro em um plano de fundo",
+  "settings.image_backgrounds_users": "Dar a toots recolhidos uma imagem de fundo",
+  "settings.inline_preview_cards": "Cartões de pré-visualização em linha para links externos",
+  "settings.layout": "Layout:",
+  "settings.layout_opts": "Opções de layout",
+  "settings.media": "Mídia",
+  "settings.media_fullwidth": "Pré-visualização da mídia em largura total",
+  "settings.media_letterbox": "Caixa de mensagens",
+  "settings.media_letterbox_hint": "Escala para baixo para encher os recipientes de imagem em vez de esticá-los e cortá-los",
+  "settings.media_reveal_behind_cw": "Revelar mídia sensível por trás de um Aviso de Conteúdo por padrão",
+  "settings.notifications.favicon_badge": "Notificações não lidas como emblema do favicon",
+  "settings.notifications.favicon_badge.hint": "Adicionar um emblema para notificações não lidas ao favicon",
+  "settings.notifications.tab_badge": "Emblema de notificações não lidas",
+  "settings.notifications.tab_badge.hint": "Exibir um emblema para notificações não lidas nos ícones de coluna quando a coluna de notificações não estiver aberta",
+  "settings.notifications_opts": "Opções de notificações",
+  "settings.pop_in_left": "Esquerda",
+  "settings.pop_in_player": "Ativar player pop-in",
+  "settings.pop_in_position": "Posição do player:",
+  "settings.pop_in_right": "Direita",
+  "settings.preferences": "Preferences",
+  "settings.prepend_cw_re": "Preparar \"re: \" para avisos de conteúdo quando responder",
+  "settings.preselect_on_reply": "Nome de usuário pré-selecionado na resposta",
+  "settings.preselect_on_reply_hint": "Ao responder a uma conversa com vários participantes, pré-selecionar nomes de usuários após o primeiro",
+  "settings.rewrite_mentions": "Reescrever as menções nos status exibidos",
+  "settings.rewrite_mentions_acct": "Reescrever com nome de usuário e domínio (quando a conta for remota)",
+  "settings.rewrite_mentions_no": "Não reescrever menções",
+  "settings.rewrite_mentions_username": "Reescreva com nome de usuário",
+  "settings.shared_settings_link": "preferências do usuário",
+  "settings.show_action_bar": "Mostrar botões de ação em toots recolhidos",
+  "settings.show_content_type_choice": "Exibir opção do tipo de conteúdo ao autorar toots",
+  "settings.show_reply_counter": "Exibir uma estimativa da contagem de respostas",
+  "settings.side_arm": "Botão de toot secundário:",
+  "settings.side_arm.none": "Nenhum",
+  "settings.side_arm_reply_mode": "Ao responder a um toot, o botão secundário de toot deve:",
+  "settings.side_arm_reply_mode.copy": "Copiar configuração de privacidade do toot sendo respondido a",
+  "settings.side_arm_reply_mode.keep": "Mantenha sua privacidade definida",
+  "settings.side_arm_reply_mode.restrict": "Restringir configuração de privacidade ao toot sendo respondido a",
+  "settings.status_icons": "Ícones de toot",
+  "settings.status_icons_language": "Indicador de idioma",
+  "settings.status_icons_local_only": "Indicador somente local",
+  "settings.status_icons_media": "Indicadores de mídia e enquete",
+  "settings.status_icons_reply": "Indicador de resposta",
+  "settings.status_icons_visibility": "Indicador de privacidade",
+  "settings.swipe_to_change_columns": "Permitir deslizar para alterar colunas (apenas celular)",
+  "settings.tag_misleading_links": "Marcar links enganosos",
+  "settings.tag_misleading_links.hint": "Acrescentar uma indicação visual com o link hospedeiro alvo a cada link que não o mencione explicitamente",
+  "settings.wide_view": "Visualização ampla (apenas no Modo desktop)",
+  "settings.wide_view_hint": "Estica as colunas para preencher melhor o espaço disponível.",
+  "status.collapse": "Recolher",
+  "status.has_audio": "Possui um arquivo de áudio anexado",
+  "status.has_pictures": "Possui uma imagem anexada",
+  "status.has_preview_card": "Possui uma pré-visualização anexada",
+  "status.has_video": "Possui um vídeo anexado",
+  "status.in_reply_to": "Este toot é uma resposta",
+  "status.is_poll": "Este toot é uma enquete",
+  "status.local_only": "Visível apenas em sua instância",
+  "status.sensitive_toggle": "Clique para ver",
+  "status.uncollapse": "Revelar",
+  "web_app_crash.change_your_settings": "Altere suas {settings}",
+  "web_app_crash.content": "Você poderia tentar qualquer uma das seguintes opções:",
+  "web_app_crash.debug_info": "Informações de depuração",
+  "web_app_crash.disable_addons": "Desativar complementos do navegador ou ferramentas de tradução integradas",
+  "web_app_crash.issue_tracker": "rastreador de problemas",
+  "web_app_crash.reload": "Recarregar",
+  "web_app_crash.reload_page": "{reload} a página atual",
+  "web_app_crash.report_issue": "Relatar um erro no {issuetracker}",
+  "web_app_crash.settings": "configurações",
+  "web_app_crash.title": "Desculpe, mas algo deu errado com o aplicativo Mastodon."
+}
diff --git a/app/javascript/flavours/glitch/locales/pt-PT.js b/app/javascript/flavours/glitch/locales/pt-PT.js
deleted file mode 100644
index cf7afd17a..000000000
--- a/app/javascript/flavours/glitch/locales/pt-PT.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/pt-PT.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/pt-PT.json b/app/javascript/flavours/glitch/locales/pt-PT.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/pt-PT.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/ro.js b/app/javascript/flavours/glitch/locales/ro.js
deleted file mode 100644
index a16446c6a..000000000
--- a/app/javascript/flavours/glitch/locales/ro.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ro.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ro.json b/app/javascript/flavours/glitch/locales/ro.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ro.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/ru.js b/app/javascript/flavours/glitch/locales/ru.js
deleted file mode 100644
index 0e9f1de71..000000000
--- a/app/javascript/flavours/glitch/locales/ru.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ru.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ru.json b/app/javascript/flavours/glitch/locales/ru.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ru.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/sa.js b/app/javascript/flavours/glitch/locales/sa.js
deleted file mode 100644
index 4cade0a07..000000000
--- a/app/javascript/flavours/glitch/locales/sa.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/sa.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/sa.json b/app/javascript/flavours/glitch/locales/sa.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/sa.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/sc.js b/app/javascript/flavours/glitch/locales/sc.js
deleted file mode 100644
index 88a83aa53..000000000
--- a/app/javascript/flavours/glitch/locales/sc.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/sc.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/sc.json b/app/javascript/flavours/glitch/locales/sc.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/sc.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/sco.json b/app/javascript/flavours/glitch/locales/sco.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/sco.json
@@ -0,0 +1 @@
+{}
diff --git a/app/javascript/flavours/glitch/locales/si.js b/app/javascript/flavours/glitch/locales/si.js
deleted file mode 100644
index d43266254..000000000
--- a/app/javascript/flavours/glitch/locales/si.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/si.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/si.json b/app/javascript/flavours/glitch/locales/si.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/si.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/sk.js b/app/javascript/flavours/glitch/locales/sk.js
deleted file mode 100644
index 5fba6ab97..000000000
--- a/app/javascript/flavours/glitch/locales/sk.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/sk.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/sk.json b/app/javascript/flavours/glitch/locales/sk.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/sk.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/sl.js b/app/javascript/flavours/glitch/locales/sl.js
deleted file mode 100644
index c53c1bae8..000000000
--- a/app/javascript/flavours/glitch/locales/sl.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/sl.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/sl.json b/app/javascript/flavours/glitch/locales/sl.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/sl.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/sq.js b/app/javascript/flavours/glitch/locales/sq.js
deleted file mode 100644
index 2fb7a2973..000000000
--- a/app/javascript/flavours/glitch/locales/sq.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/sq.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/sq.json b/app/javascript/flavours/glitch/locales/sq.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/sq.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/sr-Latn.js b/app/javascript/flavours/glitch/locales/sr-Latn.js
deleted file mode 100644
index b42d5eaaf..000000000
--- a/app/javascript/flavours/glitch/locales/sr-Latn.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/sr-Latn.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/sr-Latn.json b/app/javascript/flavours/glitch/locales/sr-Latn.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/sr-Latn.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/sr.js b/app/javascript/flavours/glitch/locales/sr.js
deleted file mode 100644
index 8793d8d1e..000000000
--- a/app/javascript/flavours/glitch/locales/sr.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/sr.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/sr.json b/app/javascript/flavours/glitch/locales/sr.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/sr.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/sv.js b/app/javascript/flavours/glitch/locales/sv.js
deleted file mode 100644
index b62c353fe..000000000
--- a/app/javascript/flavours/glitch/locales/sv.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/sv.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/sv.json b/app/javascript/flavours/glitch/locales/sv.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/sv.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/szl.js b/app/javascript/flavours/glitch/locales/szl.js
deleted file mode 100644
index 0b50afe45..000000000
--- a/app/javascript/flavours/glitch/locales/szl.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/szl.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/szl.json b/app/javascript/flavours/glitch/locales/szl.json
new file mode 100644
index 000000000..807ed8207
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/szl.json
@@ -0,0 +1,201 @@
+{
+  "about.fork_disclaimer": "Glitch-soc is free open source software forked from Mastodon.",
+  "account.add_account_note": "Add note for @{name}",
+  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
+  "account.follows": "Follows",
+  "account.joined": "Joined {date}",
+  "account.suspended_disclaimer_full": "This user has been suspended by a moderator.",
+  "account.view_full_profile": "View full profile",
+  "account_note.cancel": "Cancel",
+  "account_note.edit": "Edit",
+  "account_note.glitch_placeholder": "No comment provided",
+  "account_note.save": "Save",
+  "advanced_options.icon_title": "Advanced options",
+  "advanced_options.local-only.long": "Do not post to other instances",
+  "advanced_options.local-only.short": "Local-only",
+  "advanced_options.local-only.tooltip": "This post is local-only",
+  "advanced_options.threaded_mode.long": "Automatically opens a reply on posting",
+  "advanced_options.threaded_mode.short": "Threaded mode",
+  "advanced_options.threaded_mode.tooltip": "Threaded mode enabled",
+  "boost_modal.missing_description": "This toot contains some media without description",
+  "column.favourited_by": "Favourited by",
+  "column.heading": "Misc",
+  "column.reblogged_by": "Boosted by",
+  "column.subheading": "Miscellaneous options",
+  "column_header.profile": "Profile",
+  "column_subheading.lists": "Lists",
+  "column_subheading.navigation": "Navigation",
+  "community.column_settings.allow_local_only": "Show local-only toots",
+  "compose.attach": "Attach...",
+  "compose.attach.doodle": "Draw something",
+  "compose.attach.upload": "Upload a file",
+  "compose.content-type.html": "HTML",
+  "compose.content-type.markdown": "Markdown",
+  "compose.content-type.plain": "Plain text",
+  "compose_form.poll.multiple_choices": "Allow multiple choices",
+  "compose_form.poll.single_choice": "Allow one choice",
+  "compose_form.spoiler": "Hide text behind warning",
+  "confirmation_modal.do_not_ask_again": "Do not ask for confirmation again",
+  "confirmations.deprecated_settings.confirm": "Use Mastodon preferences",
+  "confirmations.deprecated_settings.message": "Some of the glitch-soc device-specific {app_settings} you are using have been replaced by Mastodon {preferences} and will be overriden:",
+  "confirmations.missing_media_description.confirm": "Send anyway",
+  "confirmations.missing_media_description.edit": "Edit media",
+  "confirmations.missing_media_description.message": "At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.",
+  "confirmations.unfilter.author": "Author",
+  "confirmations.unfilter.confirm": "Show",
+  "confirmations.unfilter.edit_filter": "Edit filter",
+  "confirmations.unfilter.filters": "Matching {count, plural, one {filter} other {filters}}",
+  "content-type.change": "Content type",
+  "direct.group_by_conversations": "Group by conversation",
+  "endorsed_accounts_editor.endorsed_accounts": "Featured accounts",
+  "favourite_modal.combo": "You can press {combo} to skip this next time",
+  "getting_started.onboarding": "Show me around",
+  "home.column_settings.advanced": "Advanced",
+  "home.column_settings.filter_regex": "Filter out by regular expressions",
+  "home.column_settings.show_direct": "Show DMs",
+  "home.settings": "Column settings",
+  "keyboard_shortcuts.bookmark": "to bookmark",
+  "keyboard_shortcuts.secondary_toot": "to send toot using secondary privacy setting",
+  "keyboard_shortcuts.toggle_collapse": "to collapse/uncollapse toots",
+  "layout.auto": "Auto",
+  "layout.desktop": "Desktop",
+  "layout.hint.auto": "Automatically chose layout based on “Enable advanced web interface” setting and screen size.",
+  "layout.hint.desktop": "Use multiple-column layout regardless of the “Enable advanced web interface” setting or screen size.",
+  "layout.hint.single": "Use single-column layout regardless of the “Enable advanced web interface” setting or screen size.",
+  "layout.single": "Mobile",
+  "media_gallery.sensitive": "Sensitive",
+  "moved_to_warning": "This account is marked as moved to {moved_to_link}, and may thus not accept new follows.",
+  "navigation_bar.app_settings": "App settings",
+  "navigation_bar.featured_users": "Featured users",
+  "navigation_bar.info": "Extended information",
+  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
+  "navigation_bar.misc": "Misc",
+  "notification.markForDeletion": "Mark for deletion",
+  "notification_purge.btn_all": "Select\nall",
+  "notification_purge.btn_apply": "Clear\nselected",
+  "notification_purge.btn_invert": "Invert\nselection",
+  "notification_purge.btn_none": "Select\nnone",
+  "notification_purge.start": "Enter notification cleaning mode",
+  "notifications.marked_clear": "Clear selected notifications",
+  "notifications.marked_clear_confirmation": "Are you sure you want to permanently clear all selected notifications?",
+  "onboarding.done": "Done",
+  "onboarding.next": "Next",
+  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
+  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
+  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_one.handle": "You are on {domain}, so your full handle is {handle}",
+  "onboarding.page_one.welcome": "Welcome to {domain}!",
+  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
+  "onboarding.page_six.almost_done": "Almost done...",
+  "onboarding.page_six.appetoot": "Bon Appetoot!",
+  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "onboarding.page_six.guidelines": "community guidelines",
+  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
+  "onboarding.page_six.various_app": "mobile apps",
+  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
+  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
+  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
+  "onboarding.skip": "Skip",
+  "settings.always_show_spoilers_field": "Always enable the Content Warning field",
+  "settings.auto_collapse": "Automatic collapsing",
+  "settings.auto_collapse_all": "Everything",
+  "settings.auto_collapse_lengthy": "Lengthy toots",
+  "settings.auto_collapse_media": "Toots with media",
+  "settings.auto_collapse_notifications": "Notifications",
+  "settings.auto_collapse_reblogs": "Boosts",
+  "settings.auto_collapse_replies": "Replies",
+  "settings.close": "Close",
+  "settings.collapsed_statuses": "Collapsed toots",
+  "settings.compose_box_opts": "Compose box",
+  "settings.confirm_before_clearing_draft": "Show confirmation dialog before overwriting the message being composed",
+  "settings.confirm_boost_missing_media_description": "Show confirmation dialog before boosting toots lacking media descriptions",
+  "settings.confirm_missing_media_description": "Show confirmation dialog before sending toots lacking media descriptions",
+  "settings.content_warnings": "Content warnings",
+  "settings.content_warnings.regexp": "Regular expression",
+  "settings.content_warnings_filter": "Content warnings to not automatically unfold:",
+  "settings.content_warnings_media_outside": "Display media attachments outside content warnings",
+  "settings.content_warnings_media_outside_hint": "Reproduce upstream Mastodon behavior by having the Content Warning toggle not affect media attachments",
+  "settings.content_warnings_shared_state": "Show/hide content of all copies at once",
+  "settings.content_warnings_shared_state_hint": "Reproduce upstream Mastodon behavior by having the Content Warning button affect all copies of a post at once. This will prevent automatic collapsing of any copy of a toot with unfolded CW",
+  "settings.content_warnings_unfold_opts": "Auto-unfolding options",
+  "settings.deprecated_setting": "This setting is now controlled from Mastodon's {settings_page_link}",
+  "settings.enable_collapsed": "Enable collapsed toots",
+  "settings.enable_collapsed_hint": "Collapsed posts have parts of their contents hidden to take up less screen space. This is distinct from the Content Warning feature",
+  "settings.enable_content_warnings_auto_unfold": "Automatically unfold content-warnings",
+  "settings.filters": "Filters",
+  "settings.general": "General",
+  "settings.hicolor_privacy_icons": "High color privacy icons",
+  "settings.hicolor_privacy_icons.hint": "Display privacy icons in bright and easily distinguishable colors",
+  "settings.image_backgrounds": "Image backgrounds",
+  "settings.image_backgrounds_media": "Preview collapsed toot media",
+  "settings.image_backgrounds_media_hint": "If the post has any media attachment, use the first one as a background",
+  "settings.image_backgrounds_users": "Give collapsed toots an image background",
+  "settings.inline_preview_cards": "Inline preview cards for external links",
+  "settings.layout": "Layout:",
+  "settings.layout_opts": "Layout options",
+  "settings.media": "Media",
+  "settings.media_fullwidth": "Full-width media previews",
+  "settings.media_letterbox": "Letterbox media",
+  "settings.media_letterbox_hint": "Scale down and letterbox media to fill the image containers instead of stretching and cropping them",
+  "settings.media_reveal_behind_cw": "Reveal sensitive media behind a CW by default",
+  "settings.notifications.favicon_badge": "Unread notifications favicon badge",
+  "settings.notifications.favicon_badge.hint": "Add a badge for unread notifications to the favicon",
+  "settings.notifications.tab_badge": "Unread notifications badge",
+  "settings.notifications.tab_badge.hint": "Display a badge for unread notifications in the column icons when the notifications column isn't open",
+  "settings.notifications_opts": "Notifications options",
+  "settings.pop_in_left": "Left",
+  "settings.pop_in_player": "Enable pop-in player",
+  "settings.pop_in_position": "Pop-in player position:",
+  "settings.pop_in_right": "Right",
+  "settings.preferences": "Preferences",
+  "settings.prepend_cw_re": "Prepend “re: ” to content warnings when replying",
+  "settings.preselect_on_reply": "Pre-select usernames on reply",
+  "settings.preselect_on_reply_hint": "When replying to a conversation with multiple participants, pre-select usernames past the first",
+  "settings.rewrite_mentions": "Rewrite mentions in displayed statuses",
+  "settings.rewrite_mentions_acct": "Rewrite with username and domain (when the account is remote)",
+  "settings.rewrite_mentions_no": "Do not rewrite mentions",
+  "settings.rewrite_mentions_username": "Rewrite with username",
+  "settings.shared_settings_link": "user preferences",
+  "settings.show_action_bar": "Show action buttons in collapsed toots",
+  "settings.show_content_type_choice": "Show content-type choice when authoring toots",
+  "settings.show_reply_counter": "Display an estimate of the reply count",
+  "settings.side_arm": "Secondary toot button:",
+  "settings.side_arm.none": "None",
+  "settings.side_arm_reply_mode": "When replying to a toot, the secondary toot button should:",
+  "settings.side_arm_reply_mode.copy": "Copy privacy setting of the toot being replied to",
+  "settings.side_arm_reply_mode.keep": "Keep its set privacy",
+  "settings.side_arm_reply_mode.restrict": "Restrict privacy setting to that of the toot being replied to",
+  "settings.status_icons": "Toot icons",
+  "settings.status_icons_language": "Language indicator",
+  "settings.status_icons_local_only": "Local-only indicator",
+  "settings.status_icons_media": "Media and poll indicators",
+  "settings.status_icons_reply": "Reply indicator",
+  "settings.status_icons_visibility": "Toot privacy indicator",
+  "settings.swipe_to_change_columns": "Allow swiping to change columns (Mobile only)",
+  "settings.tag_misleading_links": "Tag misleading links",
+  "settings.tag_misleading_links.hint": "Add a visual indication with the link target host to every link not mentioning it explicitly",
+  "settings.wide_view": "Wide view (Desktop mode only)",
+  "settings.wide_view_hint": "Stretches columns to better fill the available space.",
+  "status.collapse": "Collapse",
+  "status.has_audio": "Features attached audio files",
+  "status.has_pictures": "Features attached pictures",
+  "status.has_preview_card": "Features an attached preview card",
+  "status.has_video": "Features attached videos",
+  "status.in_reply_to": "This toot is a reply",
+  "status.is_poll": "This toot is a poll",
+  "status.local_only": "Only visible from your instance",
+  "status.sensitive_toggle": "Click to view",
+  "status.uncollapse": "Uncollapse",
+  "web_app_crash.change_your_settings": "Change your {settings}",
+  "web_app_crash.content": "You could try any of the following:",
+  "web_app_crash.debug_info": "Debug information",
+  "web_app_crash.disable_addons": "Disable browser add-ons or built-in translation tools",
+  "web_app_crash.issue_tracker": "issue tracker",
+  "web_app_crash.reload": "Reload",
+  "web_app_crash.reload_page": "{reload} the current page",
+  "web_app_crash.report_issue": "Report a bug in the {issuetracker}",
+  "web_app_crash.settings": "settings",
+  "web_app_crash.title": "We're sorry, but something went wrong with the Mastodon app."
+}
diff --git a/app/javascript/flavours/glitch/locales/ta.js b/app/javascript/flavours/glitch/locales/ta.js
deleted file mode 100644
index d6ecdcb1b..000000000
--- a/app/javascript/flavours/glitch/locales/ta.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ta.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ta.json b/app/javascript/flavours/glitch/locales/ta.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ta.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/tai.js b/app/javascript/flavours/glitch/locales/tai.js
deleted file mode 100644
index f26cec5bd..000000000
--- a/app/javascript/flavours/glitch/locales/tai.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/tai.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/tai.json b/app/javascript/flavours/glitch/locales/tai.json
new file mode 100644
index 000000000..807ed8207
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/tai.json
@@ -0,0 +1,201 @@
+{
+  "about.fork_disclaimer": "Glitch-soc is free open source software forked from Mastodon.",
+  "account.add_account_note": "Add note for @{name}",
+  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
+  "account.follows": "Follows",
+  "account.joined": "Joined {date}",
+  "account.suspended_disclaimer_full": "This user has been suspended by a moderator.",
+  "account.view_full_profile": "View full profile",
+  "account_note.cancel": "Cancel",
+  "account_note.edit": "Edit",
+  "account_note.glitch_placeholder": "No comment provided",
+  "account_note.save": "Save",
+  "advanced_options.icon_title": "Advanced options",
+  "advanced_options.local-only.long": "Do not post to other instances",
+  "advanced_options.local-only.short": "Local-only",
+  "advanced_options.local-only.tooltip": "This post is local-only",
+  "advanced_options.threaded_mode.long": "Automatically opens a reply on posting",
+  "advanced_options.threaded_mode.short": "Threaded mode",
+  "advanced_options.threaded_mode.tooltip": "Threaded mode enabled",
+  "boost_modal.missing_description": "This toot contains some media without description",
+  "column.favourited_by": "Favourited by",
+  "column.heading": "Misc",
+  "column.reblogged_by": "Boosted by",
+  "column.subheading": "Miscellaneous options",
+  "column_header.profile": "Profile",
+  "column_subheading.lists": "Lists",
+  "column_subheading.navigation": "Navigation",
+  "community.column_settings.allow_local_only": "Show local-only toots",
+  "compose.attach": "Attach...",
+  "compose.attach.doodle": "Draw something",
+  "compose.attach.upload": "Upload a file",
+  "compose.content-type.html": "HTML",
+  "compose.content-type.markdown": "Markdown",
+  "compose.content-type.plain": "Plain text",
+  "compose_form.poll.multiple_choices": "Allow multiple choices",
+  "compose_form.poll.single_choice": "Allow one choice",
+  "compose_form.spoiler": "Hide text behind warning",
+  "confirmation_modal.do_not_ask_again": "Do not ask for confirmation again",
+  "confirmations.deprecated_settings.confirm": "Use Mastodon preferences",
+  "confirmations.deprecated_settings.message": "Some of the glitch-soc device-specific {app_settings} you are using have been replaced by Mastodon {preferences} and will be overriden:",
+  "confirmations.missing_media_description.confirm": "Send anyway",
+  "confirmations.missing_media_description.edit": "Edit media",
+  "confirmations.missing_media_description.message": "At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.",
+  "confirmations.unfilter.author": "Author",
+  "confirmations.unfilter.confirm": "Show",
+  "confirmations.unfilter.edit_filter": "Edit filter",
+  "confirmations.unfilter.filters": "Matching {count, plural, one {filter} other {filters}}",
+  "content-type.change": "Content type",
+  "direct.group_by_conversations": "Group by conversation",
+  "endorsed_accounts_editor.endorsed_accounts": "Featured accounts",
+  "favourite_modal.combo": "You can press {combo} to skip this next time",
+  "getting_started.onboarding": "Show me around",
+  "home.column_settings.advanced": "Advanced",
+  "home.column_settings.filter_regex": "Filter out by regular expressions",
+  "home.column_settings.show_direct": "Show DMs",
+  "home.settings": "Column settings",
+  "keyboard_shortcuts.bookmark": "to bookmark",
+  "keyboard_shortcuts.secondary_toot": "to send toot using secondary privacy setting",
+  "keyboard_shortcuts.toggle_collapse": "to collapse/uncollapse toots",
+  "layout.auto": "Auto",
+  "layout.desktop": "Desktop",
+  "layout.hint.auto": "Automatically chose layout based on “Enable advanced web interface” setting and screen size.",
+  "layout.hint.desktop": "Use multiple-column layout regardless of the “Enable advanced web interface” setting or screen size.",
+  "layout.hint.single": "Use single-column layout regardless of the “Enable advanced web interface” setting or screen size.",
+  "layout.single": "Mobile",
+  "media_gallery.sensitive": "Sensitive",
+  "moved_to_warning": "This account is marked as moved to {moved_to_link}, and may thus not accept new follows.",
+  "navigation_bar.app_settings": "App settings",
+  "navigation_bar.featured_users": "Featured users",
+  "navigation_bar.info": "Extended information",
+  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
+  "navigation_bar.misc": "Misc",
+  "notification.markForDeletion": "Mark for deletion",
+  "notification_purge.btn_all": "Select\nall",
+  "notification_purge.btn_apply": "Clear\nselected",
+  "notification_purge.btn_invert": "Invert\nselection",
+  "notification_purge.btn_none": "Select\nnone",
+  "notification_purge.start": "Enter notification cleaning mode",
+  "notifications.marked_clear": "Clear selected notifications",
+  "notifications.marked_clear_confirmation": "Are you sure you want to permanently clear all selected notifications?",
+  "onboarding.done": "Done",
+  "onboarding.next": "Next",
+  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
+  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
+  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_one.handle": "You are on {domain}, so your full handle is {handle}",
+  "onboarding.page_one.welcome": "Welcome to {domain}!",
+  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
+  "onboarding.page_six.almost_done": "Almost done...",
+  "onboarding.page_six.appetoot": "Bon Appetoot!",
+  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "onboarding.page_six.guidelines": "community guidelines",
+  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
+  "onboarding.page_six.various_app": "mobile apps",
+  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
+  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
+  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
+  "onboarding.skip": "Skip",
+  "settings.always_show_spoilers_field": "Always enable the Content Warning field",
+  "settings.auto_collapse": "Automatic collapsing",
+  "settings.auto_collapse_all": "Everything",
+  "settings.auto_collapse_lengthy": "Lengthy toots",
+  "settings.auto_collapse_media": "Toots with media",
+  "settings.auto_collapse_notifications": "Notifications",
+  "settings.auto_collapse_reblogs": "Boosts",
+  "settings.auto_collapse_replies": "Replies",
+  "settings.close": "Close",
+  "settings.collapsed_statuses": "Collapsed toots",
+  "settings.compose_box_opts": "Compose box",
+  "settings.confirm_before_clearing_draft": "Show confirmation dialog before overwriting the message being composed",
+  "settings.confirm_boost_missing_media_description": "Show confirmation dialog before boosting toots lacking media descriptions",
+  "settings.confirm_missing_media_description": "Show confirmation dialog before sending toots lacking media descriptions",
+  "settings.content_warnings": "Content warnings",
+  "settings.content_warnings.regexp": "Regular expression",
+  "settings.content_warnings_filter": "Content warnings to not automatically unfold:",
+  "settings.content_warnings_media_outside": "Display media attachments outside content warnings",
+  "settings.content_warnings_media_outside_hint": "Reproduce upstream Mastodon behavior by having the Content Warning toggle not affect media attachments",
+  "settings.content_warnings_shared_state": "Show/hide content of all copies at once",
+  "settings.content_warnings_shared_state_hint": "Reproduce upstream Mastodon behavior by having the Content Warning button affect all copies of a post at once. This will prevent automatic collapsing of any copy of a toot with unfolded CW",
+  "settings.content_warnings_unfold_opts": "Auto-unfolding options",
+  "settings.deprecated_setting": "This setting is now controlled from Mastodon's {settings_page_link}",
+  "settings.enable_collapsed": "Enable collapsed toots",
+  "settings.enable_collapsed_hint": "Collapsed posts have parts of their contents hidden to take up less screen space. This is distinct from the Content Warning feature",
+  "settings.enable_content_warnings_auto_unfold": "Automatically unfold content-warnings",
+  "settings.filters": "Filters",
+  "settings.general": "General",
+  "settings.hicolor_privacy_icons": "High color privacy icons",
+  "settings.hicolor_privacy_icons.hint": "Display privacy icons in bright and easily distinguishable colors",
+  "settings.image_backgrounds": "Image backgrounds",
+  "settings.image_backgrounds_media": "Preview collapsed toot media",
+  "settings.image_backgrounds_media_hint": "If the post has any media attachment, use the first one as a background",
+  "settings.image_backgrounds_users": "Give collapsed toots an image background",
+  "settings.inline_preview_cards": "Inline preview cards for external links",
+  "settings.layout": "Layout:",
+  "settings.layout_opts": "Layout options",
+  "settings.media": "Media",
+  "settings.media_fullwidth": "Full-width media previews",
+  "settings.media_letterbox": "Letterbox media",
+  "settings.media_letterbox_hint": "Scale down and letterbox media to fill the image containers instead of stretching and cropping them",
+  "settings.media_reveal_behind_cw": "Reveal sensitive media behind a CW by default",
+  "settings.notifications.favicon_badge": "Unread notifications favicon badge",
+  "settings.notifications.favicon_badge.hint": "Add a badge for unread notifications to the favicon",
+  "settings.notifications.tab_badge": "Unread notifications badge",
+  "settings.notifications.tab_badge.hint": "Display a badge for unread notifications in the column icons when the notifications column isn't open",
+  "settings.notifications_opts": "Notifications options",
+  "settings.pop_in_left": "Left",
+  "settings.pop_in_player": "Enable pop-in player",
+  "settings.pop_in_position": "Pop-in player position:",
+  "settings.pop_in_right": "Right",
+  "settings.preferences": "Preferences",
+  "settings.prepend_cw_re": "Prepend “re: ” to content warnings when replying",
+  "settings.preselect_on_reply": "Pre-select usernames on reply",
+  "settings.preselect_on_reply_hint": "When replying to a conversation with multiple participants, pre-select usernames past the first",
+  "settings.rewrite_mentions": "Rewrite mentions in displayed statuses",
+  "settings.rewrite_mentions_acct": "Rewrite with username and domain (when the account is remote)",
+  "settings.rewrite_mentions_no": "Do not rewrite mentions",
+  "settings.rewrite_mentions_username": "Rewrite with username",
+  "settings.shared_settings_link": "user preferences",
+  "settings.show_action_bar": "Show action buttons in collapsed toots",
+  "settings.show_content_type_choice": "Show content-type choice when authoring toots",
+  "settings.show_reply_counter": "Display an estimate of the reply count",
+  "settings.side_arm": "Secondary toot button:",
+  "settings.side_arm.none": "None",
+  "settings.side_arm_reply_mode": "When replying to a toot, the secondary toot button should:",
+  "settings.side_arm_reply_mode.copy": "Copy privacy setting of the toot being replied to",
+  "settings.side_arm_reply_mode.keep": "Keep its set privacy",
+  "settings.side_arm_reply_mode.restrict": "Restrict privacy setting to that of the toot being replied to",
+  "settings.status_icons": "Toot icons",
+  "settings.status_icons_language": "Language indicator",
+  "settings.status_icons_local_only": "Local-only indicator",
+  "settings.status_icons_media": "Media and poll indicators",
+  "settings.status_icons_reply": "Reply indicator",
+  "settings.status_icons_visibility": "Toot privacy indicator",
+  "settings.swipe_to_change_columns": "Allow swiping to change columns (Mobile only)",
+  "settings.tag_misleading_links": "Tag misleading links",
+  "settings.tag_misleading_links.hint": "Add a visual indication with the link target host to every link not mentioning it explicitly",
+  "settings.wide_view": "Wide view (Desktop mode only)",
+  "settings.wide_view_hint": "Stretches columns to better fill the available space.",
+  "status.collapse": "Collapse",
+  "status.has_audio": "Features attached audio files",
+  "status.has_pictures": "Features attached pictures",
+  "status.has_preview_card": "Features an attached preview card",
+  "status.has_video": "Features attached videos",
+  "status.in_reply_to": "This toot is a reply",
+  "status.is_poll": "This toot is a poll",
+  "status.local_only": "Only visible from your instance",
+  "status.sensitive_toggle": "Click to view",
+  "status.uncollapse": "Uncollapse",
+  "web_app_crash.change_your_settings": "Change your {settings}",
+  "web_app_crash.content": "You could try any of the following:",
+  "web_app_crash.debug_info": "Debug information",
+  "web_app_crash.disable_addons": "Disable browser add-ons or built-in translation tools",
+  "web_app_crash.issue_tracker": "issue tracker",
+  "web_app_crash.reload": "Reload",
+  "web_app_crash.reload_page": "{reload} the current page",
+  "web_app_crash.report_issue": "Report a bug in the {issuetracker}",
+  "web_app_crash.settings": "settings",
+  "web_app_crash.title": "We're sorry, but something went wrong with the Mastodon app."
+}
diff --git a/app/javascript/flavours/glitch/locales/te.js b/app/javascript/flavours/glitch/locales/te.js
deleted file mode 100644
index afd6e4f7b..000000000
--- a/app/javascript/flavours/glitch/locales/te.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/te.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/te.json b/app/javascript/flavours/glitch/locales/te.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/te.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/th.js b/app/javascript/flavours/glitch/locales/th.js
deleted file mode 100644
index e939f8631..000000000
--- a/app/javascript/flavours/glitch/locales/th.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/th.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/th.json b/app/javascript/flavours/glitch/locales/th.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/th.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/tr.js b/app/javascript/flavours/glitch/locales/tr.js
deleted file mode 100644
index c2b740617..000000000
--- a/app/javascript/flavours/glitch/locales/tr.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/tr.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/tr.json b/app/javascript/flavours/glitch/locales/tr.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/tr.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/tt.js b/app/javascript/flavours/glitch/locales/tt.js
deleted file mode 100644
index ff74f6c29..000000000
--- a/app/javascript/flavours/glitch/locales/tt.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/tt.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/tt.json b/app/javascript/flavours/glitch/locales/tt.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/tt.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/ug.js b/app/javascript/flavours/glitch/locales/ug.js
deleted file mode 100644
index ab7ee0761..000000000
--- a/app/javascript/flavours/glitch/locales/ug.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ug.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ug.json b/app/javascript/flavours/glitch/locales/ug.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ug.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/uk.js b/app/javascript/flavours/glitch/locales/uk.js
deleted file mode 100644
index ab6d9a7dc..000000000
--- a/app/javascript/flavours/glitch/locales/uk.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/uk.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/uk.json b/app/javascript/flavours/glitch/locales/uk.json
new file mode 100644
index 000000000..b21584659
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/uk.json
@@ -0,0 +1,48 @@
+{
+  "advanced_options.local-only.long": "Не дмухати це на інші сервери",
+  "advanced_options.local-only.short": "Лише локальне",
+  "advanced_options.local-only.tooltip": "Цей дмух лише локальний",
+  "compose.attach": "Вкласти...",
+  "compose.attach.doodle": "Помалювати",
+  "compose.attach.upload": "Завантажити сюди файл",
+  "favourite_modal.combo": "Ви можете натиснути {combo}, щоб пропустити це наступного разу",
+  "getting_started.onboarding": "Шо тут",
+  "home.column_settings.show_direct": "Показати прямі повідомлення",
+  "layout.auto": "Автоматичний",
+  "layout.desktop": "Настільний",
+  "media_gallery.sensitive": "Чутливі",
+  "navigation_bar.app_settings": "Налаштування програми",
+  "notification.markForDeletion": "Позначити для видалення",
+  "notification_purge.btn_all": "Вибрати\nвсе",
+  "notification_purge.btn_apply": "Очистити\nвибір",
+  "notification_purge.btn_invert": "Інвертувати\nвибір",
+  "notification_purge.btn_none": "Вибрати\nнічого",
+  "notifications.marked_clear": "Очистити вибрані сповіщення",
+  "notifications.marked_clear_confirmation": "Ви впевнені, що хочете незворотньо очистити всі вибрані сповіщення?",
+  "onboarding.page_one.federation": "{domain} є сервером of Mastodon. Mastodon — мережа незалежних серверів, які працюють разом великою соціяльною мережою. Сервери Mastodon також називають „інстансами“.",
+  "onboarding.page_one.welcome": "Ласкаво просимо до {domain}!",
+  "onboarding.page_six.github": "{domain} використовує Glitchsoc. Glitchsoc — дружній {fork} {Mastodon}, сумісний з будь-яким сервером Mastodon або програмою для нього. Glitchsoc повністю вільний та відкритий. Повідомляти про баги, просити фічі, або працювати з кодом можна на {github}.",
+  "settings.auto_collapse": "Автоматичне згортання",
+  "settings.auto_collapse_all": "Все",
+  "settings.auto_collapse_lengthy": "Довгі дмухи",
+  "settings.auto_collapse_media": "Дмухи з медіафайлами",
+  "settings.auto_collapse_notifications": "Сповіщення",
+  "settings.auto_collapse_reblogs": "Передмухи",
+  "settings.auto_collapse_replies": "Відповіді",
+  "settings.close": "Закрити",
+  "settings.collapsed_statuses": "Згорнуті дмухи",
+  "settings.content_warnings": "Content warnings",
+  "settings.enable_collapsed": "Увімкути згорнутання дмухів",
+  "settings.general": "Основне",
+  "settings.image_backgrounds": "Картинки на тлі",
+  "settings.image_backgrounds_media": "Підглядати медіа зі схованих дмухів",
+  "settings.image_backgrounds_users": "Давати схованим дмухам тло-картинку",
+  "settings.media": "Медіа",
+  "settings.media_fullwidth": "Показувати медіа повною шириною",
+  "settings.media_letterbox": "Обрізати медіа",
+  "settings.preferences": "Користувацькі налаштування",
+  "settings.show_action_bar": "Показувати кнопки у згорнутих дмухах",
+  "settings.wide_view": "Широкий вид (тільки в режимі для комп'ютерів)",
+  "status.collapse": "Згорнути",
+  "status.uncollapse": "Розгорнути"
+}
diff --git a/app/javascript/flavours/glitch/locales/ur.js b/app/javascript/flavours/glitch/locales/ur.js
deleted file mode 100644
index 97ba291b0..000000000
--- a/app/javascript/flavours/glitch/locales/ur.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/ur.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/ur.json b/app/javascript/flavours/glitch/locales/ur.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/ur.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/vi.js b/app/javascript/flavours/glitch/locales/vi.js
deleted file mode 100644
index 499a96727..000000000
--- a/app/javascript/flavours/glitch/locales/vi.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/vi.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/vi.json b/app/javascript/flavours/glitch/locales/vi.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/vi.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/whitelist_af.json b/app/javascript/flavours/glitch/locales/whitelist_af.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_af.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ar.json b/app/javascript/flavours/glitch/locales/whitelist_ar.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ar.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ast.json b/app/javascript/flavours/glitch/locales/whitelist_ast.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ast.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_bg.json b/app/javascript/flavours/glitch/locales/whitelist_bg.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_bg.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_bn.json b/app/javascript/flavours/glitch/locales/whitelist_bn.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_bn.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_br.json b/app/javascript/flavours/glitch/locales/whitelist_br.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_br.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ca.json b/app/javascript/flavours/glitch/locales/whitelist_ca.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ca.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ckb.json b/app/javascript/flavours/glitch/locales/whitelist_ckb.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ckb.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_co.json b/app/javascript/flavours/glitch/locales/whitelist_co.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_co.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_cs.json b/app/javascript/flavours/glitch/locales/whitelist_cs.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_cs.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_cy.json b/app/javascript/flavours/glitch/locales/whitelist_cy.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_cy.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_da.json b/app/javascript/flavours/glitch/locales/whitelist_da.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_da.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_de.json b/app/javascript/flavours/glitch/locales/whitelist_de.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_de.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_el.json b/app/javascript/flavours/glitch/locales/whitelist_el.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_el.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_en.json b/app/javascript/flavours/glitch/locales/whitelist_en.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_en.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_eo.json b/app/javascript/flavours/glitch/locales/whitelist_eo.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_eo.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_es-AR.json b/app/javascript/flavours/glitch/locales/whitelist_es-AR.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_es-AR.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_es-MX.json b/app/javascript/flavours/glitch/locales/whitelist_es-MX.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_es-MX.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_es.json b/app/javascript/flavours/glitch/locales/whitelist_es.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_es.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_et.json b/app/javascript/flavours/glitch/locales/whitelist_et.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_et.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_eu.json b/app/javascript/flavours/glitch/locales/whitelist_eu.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_eu.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_fa.json b/app/javascript/flavours/glitch/locales/whitelist_fa.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_fa.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_fi.json b/app/javascript/flavours/glitch/locales/whitelist_fi.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_fi.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_fr.json b/app/javascript/flavours/glitch/locales/whitelist_fr.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_fr.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ga.json b/app/javascript/flavours/glitch/locales/whitelist_ga.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ga.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_gd.json b/app/javascript/flavours/glitch/locales/whitelist_gd.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_gd.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_gl.json b/app/javascript/flavours/glitch/locales/whitelist_gl.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_gl.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_he.json b/app/javascript/flavours/glitch/locales/whitelist_he.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_he.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_hi.json b/app/javascript/flavours/glitch/locales/whitelist_hi.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_hi.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_hr.json b/app/javascript/flavours/glitch/locales/whitelist_hr.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_hr.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_hu.json b/app/javascript/flavours/glitch/locales/whitelist_hu.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_hu.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_hy.json b/app/javascript/flavours/glitch/locales/whitelist_hy.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_hy.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_id.json b/app/javascript/flavours/glitch/locales/whitelist_id.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_id.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_io.json b/app/javascript/flavours/glitch/locales/whitelist_io.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_io.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_is.json b/app/javascript/flavours/glitch/locales/whitelist_is.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_is.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_it.json b/app/javascript/flavours/glitch/locales/whitelist_it.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_it.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ja.json b/app/javascript/flavours/glitch/locales/whitelist_ja.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ja.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ka.json b/app/javascript/flavours/glitch/locales/whitelist_ka.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ka.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_kab.json b/app/javascript/flavours/glitch/locales/whitelist_kab.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_kab.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_kk.json b/app/javascript/flavours/glitch/locales/whitelist_kk.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_kk.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_kn.json b/app/javascript/flavours/glitch/locales/whitelist_kn.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_kn.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ko.json b/app/javascript/flavours/glitch/locales/whitelist_ko.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ko.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ku.json b/app/javascript/flavours/glitch/locales/whitelist_ku.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ku.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_kw.json b/app/javascript/flavours/glitch/locales/whitelist_kw.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_kw.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_lt.json b/app/javascript/flavours/glitch/locales/whitelist_lt.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_lt.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_lv.json b/app/javascript/flavours/glitch/locales/whitelist_lv.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_lv.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_mk.json b/app/javascript/flavours/glitch/locales/whitelist_mk.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_mk.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ml.json b/app/javascript/flavours/glitch/locales/whitelist_ml.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ml.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_mr.json b/app/javascript/flavours/glitch/locales/whitelist_mr.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_mr.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ms.json b/app/javascript/flavours/glitch/locales/whitelist_ms.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ms.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_nl.json b/app/javascript/flavours/glitch/locales/whitelist_nl.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_nl.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_nn.json b/app/javascript/flavours/glitch/locales/whitelist_nn.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_nn.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_no.json b/app/javascript/flavours/glitch/locales/whitelist_no.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_no.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_oc.json b/app/javascript/flavours/glitch/locales/whitelist_oc.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_oc.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_pa.json b/app/javascript/flavours/glitch/locales/whitelist_pa.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_pa.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_pl.json b/app/javascript/flavours/glitch/locales/whitelist_pl.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_pl.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_pt-BR.json b/app/javascript/flavours/glitch/locales/whitelist_pt-BR.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_pt-BR.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_pt-PT.json b/app/javascript/flavours/glitch/locales/whitelist_pt-PT.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_pt-PT.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ro.json b/app/javascript/flavours/glitch/locales/whitelist_ro.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ro.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ru.json b/app/javascript/flavours/glitch/locales/whitelist_ru.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ru.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_sa.json b/app/javascript/flavours/glitch/locales/whitelist_sa.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_sa.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_sc.json b/app/javascript/flavours/glitch/locales/whitelist_sc.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_sc.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_si.json b/app/javascript/flavours/glitch/locales/whitelist_si.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_si.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_sk.json b/app/javascript/flavours/glitch/locales/whitelist_sk.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_sk.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_sl.json b/app/javascript/flavours/glitch/locales/whitelist_sl.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_sl.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_sq.json b/app/javascript/flavours/glitch/locales/whitelist_sq.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_sq.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_sr-Latn.json b/app/javascript/flavours/glitch/locales/whitelist_sr-Latn.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_sr-Latn.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_sr.json b/app/javascript/flavours/glitch/locales/whitelist_sr.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_sr.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_sv.json b/app/javascript/flavours/glitch/locales/whitelist_sv.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_sv.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_szl.json b/app/javascript/flavours/glitch/locales/whitelist_szl.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_szl.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ta.json b/app/javascript/flavours/glitch/locales/whitelist_ta.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ta.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_tai.json b/app/javascript/flavours/glitch/locales/whitelist_tai.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_tai.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_te.json b/app/javascript/flavours/glitch/locales/whitelist_te.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_te.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_th.json b/app/javascript/flavours/glitch/locales/whitelist_th.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_th.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_tr.json b/app/javascript/flavours/glitch/locales/whitelist_tr.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_tr.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_tt.json b/app/javascript/flavours/glitch/locales/whitelist_tt.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_tt.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ug.json b/app/javascript/flavours/glitch/locales/whitelist_ug.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ug.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_uk.json b/app/javascript/flavours/glitch/locales/whitelist_uk.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_uk.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_ur.json b/app/javascript/flavours/glitch/locales/whitelist_ur.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_ur.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_vi.json b/app/javascript/flavours/glitch/locales/whitelist_vi.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_vi.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_zgh.json b/app/javascript/flavours/glitch/locales/whitelist_zgh.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_zgh.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_zh-CN.json b/app/javascript/flavours/glitch/locales/whitelist_zh-CN.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_zh-CN.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_zh-HK.json b/app/javascript/flavours/glitch/locales/whitelist_zh-HK.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_zh-HK.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/whitelist_zh-TW.json b/app/javascript/flavours/glitch/locales/whitelist_zh-TW.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/whitelist_zh-TW.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/flavours/glitch/locales/zgh.js b/app/javascript/flavours/glitch/locales/zgh.js
deleted file mode 100644
index f2f15b1a4..000000000
--- a/app/javascript/flavours/glitch/locales/zgh.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/zgh.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/zgh.json b/app/javascript/flavours/glitch/locales/zgh.json
new file mode 100644
index 000000000..807ed8207
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/zgh.json
@@ -0,0 +1,201 @@
+{
+  "about.fork_disclaimer": "Glitch-soc is free open source software forked from Mastodon.",
+  "account.add_account_note": "Add note for @{name}",
+  "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
+  "account.follows": "Follows",
+  "account.joined": "Joined {date}",
+  "account.suspended_disclaimer_full": "This user has been suspended by a moderator.",
+  "account.view_full_profile": "View full profile",
+  "account_note.cancel": "Cancel",
+  "account_note.edit": "Edit",
+  "account_note.glitch_placeholder": "No comment provided",
+  "account_note.save": "Save",
+  "advanced_options.icon_title": "Advanced options",
+  "advanced_options.local-only.long": "Do not post to other instances",
+  "advanced_options.local-only.short": "Local-only",
+  "advanced_options.local-only.tooltip": "This post is local-only",
+  "advanced_options.threaded_mode.long": "Automatically opens a reply on posting",
+  "advanced_options.threaded_mode.short": "Threaded mode",
+  "advanced_options.threaded_mode.tooltip": "Threaded mode enabled",
+  "boost_modal.missing_description": "This toot contains some media without description",
+  "column.favourited_by": "Favourited by",
+  "column.heading": "Misc",
+  "column.reblogged_by": "Boosted by",
+  "column.subheading": "Miscellaneous options",
+  "column_header.profile": "Profile",
+  "column_subheading.lists": "Lists",
+  "column_subheading.navigation": "Navigation",
+  "community.column_settings.allow_local_only": "Show local-only toots",
+  "compose.attach": "Attach...",
+  "compose.attach.doodle": "Draw something",
+  "compose.attach.upload": "Upload a file",
+  "compose.content-type.html": "HTML",
+  "compose.content-type.markdown": "Markdown",
+  "compose.content-type.plain": "Plain text",
+  "compose_form.poll.multiple_choices": "Allow multiple choices",
+  "compose_form.poll.single_choice": "Allow one choice",
+  "compose_form.spoiler": "Hide text behind warning",
+  "confirmation_modal.do_not_ask_again": "Do not ask for confirmation again",
+  "confirmations.deprecated_settings.confirm": "Use Mastodon preferences",
+  "confirmations.deprecated_settings.message": "Some of the glitch-soc device-specific {app_settings} you are using have been replaced by Mastodon {preferences} and will be overriden:",
+  "confirmations.missing_media_description.confirm": "Send anyway",
+  "confirmations.missing_media_description.edit": "Edit media",
+  "confirmations.missing_media_description.message": "At least one media attachment is lacking a description. Consider describing all media attachments for the visually impaired before sending your toot.",
+  "confirmations.unfilter.author": "Author",
+  "confirmations.unfilter.confirm": "Show",
+  "confirmations.unfilter.edit_filter": "Edit filter",
+  "confirmations.unfilter.filters": "Matching {count, plural, one {filter} other {filters}}",
+  "content-type.change": "Content type",
+  "direct.group_by_conversations": "Group by conversation",
+  "endorsed_accounts_editor.endorsed_accounts": "Featured accounts",
+  "favourite_modal.combo": "You can press {combo} to skip this next time",
+  "getting_started.onboarding": "Show me around",
+  "home.column_settings.advanced": "Advanced",
+  "home.column_settings.filter_regex": "Filter out by regular expressions",
+  "home.column_settings.show_direct": "Show DMs",
+  "home.settings": "Column settings",
+  "keyboard_shortcuts.bookmark": "to bookmark",
+  "keyboard_shortcuts.secondary_toot": "to send toot using secondary privacy setting",
+  "keyboard_shortcuts.toggle_collapse": "to collapse/uncollapse toots",
+  "layout.auto": "Auto",
+  "layout.desktop": "Desktop",
+  "layout.hint.auto": "Automatically chose layout based on “Enable advanced web interface” setting and screen size.",
+  "layout.hint.desktop": "Use multiple-column layout regardless of the “Enable advanced web interface” setting or screen size.",
+  "layout.hint.single": "Use single-column layout regardless of the “Enable advanced web interface” setting or screen size.",
+  "layout.single": "Mobile",
+  "media_gallery.sensitive": "Sensitive",
+  "moved_to_warning": "This account is marked as moved to {moved_to_link}, and may thus not accept new follows.",
+  "navigation_bar.app_settings": "App settings",
+  "navigation_bar.featured_users": "Featured users",
+  "navigation_bar.info": "Extended information",
+  "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
+  "navigation_bar.misc": "Misc",
+  "notification.markForDeletion": "Mark for deletion",
+  "notification_purge.btn_all": "Select\nall",
+  "notification_purge.btn_apply": "Clear\nselected",
+  "notification_purge.btn_invert": "Invert\nselection",
+  "notification_purge.btn_none": "Select\nnone",
+  "notification_purge.start": "Enter notification cleaning mode",
+  "notifications.marked_clear": "Clear selected notifications",
+  "notifications.marked_clear_confirmation": "Are you sure you want to permanently clear all selected notifications?",
+  "onboarding.done": "Done",
+  "onboarding.next": "Next",
+  "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
+  "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
+  "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_one.handle": "You are on {domain}, so your full handle is {handle}",
+  "onboarding.page_one.welcome": "Welcome to {domain}!",
+  "onboarding.page_six.admin": "Your instance's admin is {admin}.",
+  "onboarding.page_six.almost_done": "Almost done...",
+  "onboarding.page_six.appetoot": "Bon Appetoot!",
+  "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "onboarding.page_six.guidelines": "community guidelines",
+  "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
+  "onboarding.page_six.various_app": "mobile apps",
+  "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
+  "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
+  "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
+  "onboarding.skip": "Skip",
+  "settings.always_show_spoilers_field": "Always enable the Content Warning field",
+  "settings.auto_collapse": "Automatic collapsing",
+  "settings.auto_collapse_all": "Everything",
+  "settings.auto_collapse_lengthy": "Lengthy toots",
+  "settings.auto_collapse_media": "Toots with media",
+  "settings.auto_collapse_notifications": "Notifications",
+  "settings.auto_collapse_reblogs": "Boosts",
+  "settings.auto_collapse_replies": "Replies",
+  "settings.close": "Close",
+  "settings.collapsed_statuses": "Collapsed toots",
+  "settings.compose_box_opts": "Compose box",
+  "settings.confirm_before_clearing_draft": "Show confirmation dialog before overwriting the message being composed",
+  "settings.confirm_boost_missing_media_description": "Show confirmation dialog before boosting toots lacking media descriptions",
+  "settings.confirm_missing_media_description": "Show confirmation dialog before sending toots lacking media descriptions",
+  "settings.content_warnings": "Content warnings",
+  "settings.content_warnings.regexp": "Regular expression",
+  "settings.content_warnings_filter": "Content warnings to not automatically unfold:",
+  "settings.content_warnings_media_outside": "Display media attachments outside content warnings",
+  "settings.content_warnings_media_outside_hint": "Reproduce upstream Mastodon behavior by having the Content Warning toggle not affect media attachments",
+  "settings.content_warnings_shared_state": "Show/hide content of all copies at once",
+  "settings.content_warnings_shared_state_hint": "Reproduce upstream Mastodon behavior by having the Content Warning button affect all copies of a post at once. This will prevent automatic collapsing of any copy of a toot with unfolded CW",
+  "settings.content_warnings_unfold_opts": "Auto-unfolding options",
+  "settings.deprecated_setting": "This setting is now controlled from Mastodon's {settings_page_link}",
+  "settings.enable_collapsed": "Enable collapsed toots",
+  "settings.enable_collapsed_hint": "Collapsed posts have parts of their contents hidden to take up less screen space. This is distinct from the Content Warning feature",
+  "settings.enable_content_warnings_auto_unfold": "Automatically unfold content-warnings",
+  "settings.filters": "Filters",
+  "settings.general": "General",
+  "settings.hicolor_privacy_icons": "High color privacy icons",
+  "settings.hicolor_privacy_icons.hint": "Display privacy icons in bright and easily distinguishable colors",
+  "settings.image_backgrounds": "Image backgrounds",
+  "settings.image_backgrounds_media": "Preview collapsed toot media",
+  "settings.image_backgrounds_media_hint": "If the post has any media attachment, use the first one as a background",
+  "settings.image_backgrounds_users": "Give collapsed toots an image background",
+  "settings.inline_preview_cards": "Inline preview cards for external links",
+  "settings.layout": "Layout:",
+  "settings.layout_opts": "Layout options",
+  "settings.media": "Media",
+  "settings.media_fullwidth": "Full-width media previews",
+  "settings.media_letterbox": "Letterbox media",
+  "settings.media_letterbox_hint": "Scale down and letterbox media to fill the image containers instead of stretching and cropping them",
+  "settings.media_reveal_behind_cw": "Reveal sensitive media behind a CW by default",
+  "settings.notifications.favicon_badge": "Unread notifications favicon badge",
+  "settings.notifications.favicon_badge.hint": "Add a badge for unread notifications to the favicon",
+  "settings.notifications.tab_badge": "Unread notifications badge",
+  "settings.notifications.tab_badge.hint": "Display a badge for unread notifications in the column icons when the notifications column isn't open",
+  "settings.notifications_opts": "Notifications options",
+  "settings.pop_in_left": "Left",
+  "settings.pop_in_player": "Enable pop-in player",
+  "settings.pop_in_position": "Pop-in player position:",
+  "settings.pop_in_right": "Right",
+  "settings.preferences": "Preferences",
+  "settings.prepend_cw_re": "Prepend “re: ” to content warnings when replying",
+  "settings.preselect_on_reply": "Pre-select usernames on reply",
+  "settings.preselect_on_reply_hint": "When replying to a conversation with multiple participants, pre-select usernames past the first",
+  "settings.rewrite_mentions": "Rewrite mentions in displayed statuses",
+  "settings.rewrite_mentions_acct": "Rewrite with username and domain (when the account is remote)",
+  "settings.rewrite_mentions_no": "Do not rewrite mentions",
+  "settings.rewrite_mentions_username": "Rewrite with username",
+  "settings.shared_settings_link": "user preferences",
+  "settings.show_action_bar": "Show action buttons in collapsed toots",
+  "settings.show_content_type_choice": "Show content-type choice when authoring toots",
+  "settings.show_reply_counter": "Display an estimate of the reply count",
+  "settings.side_arm": "Secondary toot button:",
+  "settings.side_arm.none": "None",
+  "settings.side_arm_reply_mode": "When replying to a toot, the secondary toot button should:",
+  "settings.side_arm_reply_mode.copy": "Copy privacy setting of the toot being replied to",
+  "settings.side_arm_reply_mode.keep": "Keep its set privacy",
+  "settings.side_arm_reply_mode.restrict": "Restrict privacy setting to that of the toot being replied to",
+  "settings.status_icons": "Toot icons",
+  "settings.status_icons_language": "Language indicator",
+  "settings.status_icons_local_only": "Local-only indicator",
+  "settings.status_icons_media": "Media and poll indicators",
+  "settings.status_icons_reply": "Reply indicator",
+  "settings.status_icons_visibility": "Toot privacy indicator",
+  "settings.swipe_to_change_columns": "Allow swiping to change columns (Mobile only)",
+  "settings.tag_misleading_links": "Tag misleading links",
+  "settings.tag_misleading_links.hint": "Add a visual indication with the link target host to every link not mentioning it explicitly",
+  "settings.wide_view": "Wide view (Desktop mode only)",
+  "settings.wide_view_hint": "Stretches columns to better fill the available space.",
+  "status.collapse": "Collapse",
+  "status.has_audio": "Features attached audio files",
+  "status.has_pictures": "Features attached pictures",
+  "status.has_preview_card": "Features an attached preview card",
+  "status.has_video": "Features attached videos",
+  "status.in_reply_to": "This toot is a reply",
+  "status.is_poll": "This toot is a poll",
+  "status.local_only": "Only visible from your instance",
+  "status.sensitive_toggle": "Click to view",
+  "status.uncollapse": "Uncollapse",
+  "web_app_crash.change_your_settings": "Change your {settings}",
+  "web_app_crash.content": "You could try any of the following:",
+  "web_app_crash.debug_info": "Debug information",
+  "web_app_crash.disable_addons": "Disable browser add-ons or built-in translation tools",
+  "web_app_crash.issue_tracker": "issue tracker",
+  "web_app_crash.reload": "Reload",
+  "web_app_crash.reload_page": "{reload} the current page",
+  "web_app_crash.report_issue": "Report a bug in the {issuetracker}",
+  "web_app_crash.settings": "settings",
+  "web_app_crash.title": "We're sorry, but something went wrong with the Mastodon app."
+}
diff --git a/app/javascript/flavours/glitch/locales/zh-CN.js b/app/javascript/flavours/glitch/locales/zh-CN.js
deleted file mode 100644
index 21a68fc01..000000000
--- a/app/javascript/flavours/glitch/locales/zh-CN.js
+++ /dev/null
@@ -1,201 +0,0 @@
-import inherited from 'mastodon/locales/zh-CN.json';
-
-const messages = {
-  'account.add_account_note': '为 @{name} 添加备注',
-  'account.disclaimer_full': '以下信息可能无法完整代表你的个人资料。',
-  'account.follows': '正在关注',
-  'account.suspended_disclaimer_full': '该用户已被封禁。',
-  'account.view_full_profile': '查看完整资料',
-  'account_note.cancel': '取消',
-  'account_note.edit': '编辑',
-  'account_note.glitch_placeholder': '暂无备注',
-  'account_note.save': '保存',
-  'advanced_options.icon_title': '高级选项',
-  'advanced_options.local-only.long': '不要发布嘟文到其他实例',
-  'advanced_options.local-only.short': '本地模式',
-  'advanced_options.local-only.tooltip': '这条嘟文仅限于本实例',
-  'advanced_options.threaded_mode.long': '发嘟时自动打开回复',
-  'advanced_options.threaded_mode.short': '线程模式',
-  'advanced_options.threaded_mode.tooltip': '线程模式已启用',
-  'boost_modal.missing_description': '这条嘟文未包含媒体描述',
-  'column.favourited_by': '喜欢',
-  'column.heading': '标题',
-  'column.reblogged_by': '转嘟',
-  'column.subheading': '其他选项',
-  'column.toot': '嘟文和回复',
-  'column_header.profile': '个人资料',
-  'column_subheading.lists': '列表',
-  'column_subheading.navigation': '导航',
-  'community.column_settings.allow_local_only': '只显示本地模式嘟文',
-  'compose.attach': '附上...',
-  'compose.attach.doodle': '画点什么',
-  'compose.attach.upload': '上传文件',
-  'compose.content-type.html': 'HTML',
-  'compose.content-type.markdown': 'Markdown',
-  'compose.content-type.plain': '纯文本',
-  'compose_form.poll.multiple_choices': '允许多选',
-  'compose_form.poll.single_choice': '允许单选',
-  'compose_form.spoiler': '隐藏为内容警告',
-  'confirmation_modal.do_not_ask_again': '下次不显示确认窗口',
-  'confirmations.discard_edit_media.confirm': '确认',
-  'confirmations.discard_edit_media.message': '有未保存的媒体描述或预览,确认要关闭?',
-  'confirmations.missing_media_description.confirm': '确认',
-  'confirmations.missing_media_description.edit': '编辑',
-  'confirmations.missing_media_description.message': '你没有为一种或多种媒体撰写描述。请考虑为视障人士添加描述。',
-  'confirmations.unfilter': '关于此过滤后嘟文的信息',
-  'confirmations.unfilter.author': '作者',
-  'confirmations.unfilter.confirm': '查看',
-  'confirmations.unfilter.edit_filter': '编辑过滤器',
-  'confirmations.unfilter.filters': '应用 {count, plural, one {过滤器} other {过滤器}}',
-  'content-type.change': '内容类型 ',
-  'direct.conversations_mode': '对话模式',
-  'direct.timeline_mode': '时间线模式',
-  'endorsed_accounts_editor.endorsed_accounts': '推荐用户',
-  'favourite_modal.combo': '下次你可以按 {combo} 跳过这个',
-  'getting_started.onboarding': '参观一下',
-  'getting_started.open_source_notice': 'Glitchsoc 是由 {Mastodon} 分叉出来的免费开源软件。你可以在 GitHub 上贡献或报告问题,地址是 {github}。',
-  'home.column_settings.advanced': '高级',
-  'home.column_settings.filter_regex': '按正则表达式过滤',
-  'home.column_settings.show_direct': '显示私信',
-  'home.settings': '列表设置',
-  'keyboard_shortcuts.bookmark': '书签',
-  'keyboard_shortcuts.secondary_toot': '使用二级隐私设置发送嘟文',
-  'keyboard_shortcuts.toggle_collapse': '折叠或展开嘟文',
-  'layout.auto': '自动模式',
-  'layout.current_is': '你目前的布局是:',
-  'layout.desktop': '桌面模式',
-  'layout.hint.auto': '根据“启用高级 Web 界面”设置和屏幕大小自动选择布局。',
-  'layout.hint.desktop': '“使用多列布局,无论“启用高级 Web 界面”设置和屏幕大小如何。',
-  'layout.hint.single': '使用单列布局,无论“启用高级 Web 界面”设置和屏幕大小如何。',
-  'layout.single': '移动模式',
-  'media_gallery.sensitive': '敏感内容',
-  'moved_to_warning': '此帐户已被标记为移至 {moved_to_link},并且似乎没有收到新关注者。',
-  'navigation_bar.app_settings': '应用选项',
-  'navigation_bar.featured_users': '推荐用户',
-  'navigation_bar.misc': '杂项',
-  'notification.markForDeletion': '标记以删除',
-  'notification_purge.btn_all': '全选',
-  'notification_purge.btn_apply': '清除已选',
-  'notification_purge.btn_invert': '反向选择',
-  'notification_purge.btn_none': '取消全选',
-  'notification_purge.start': '进入通知清除模式',
-  'notifications.clear': '清除所有通知',
-  'notifications.marked_clear': '清除选择的通知',
-  'notifications.marked_clear_confirmation': '你确定要永久清除所有选择的通知吗?',
-  'onboarding.done': '完成',
-  'onboarding.next': '下一个',
-  'onboarding.page_five.public_timelines': '本地时间线显示来自 {domain} 中所有人的公开嘟文。跨站时间线显示了 {domain} 用户关注的每个人的公开嘟文。这些被称为公共时间线,是发现新朋友的好方法。',
-  'onboarding.page_four.home': '你的主页时间线会显示你关注的人的嘟文。',
-  'onboarding.page_four.notifications': '通知栏显示某人与你互动的内容。',
-  'onboarding.page_one.federation': '{domain} 是 Mastodon 的一个“实例”。Mastodon 是一个由独立服务器组成的,通过不断联合形成的社交网络。我们称这些服务器为实例。',
-  'onboarding.page_one.handle': '你位于 {domain},因此你的完整用户名是 {handle} 。',
-  'onboarding.page_one.welcome': '欢迎来到 {domain}!',
-  'onboarding.page_six.admin': '实例的管理员是 {admin}。',
-  'onboarding.page_six.almost_done': '就快完成了...',
-  'onboarding.page_six.appetoot': '尽情享用吧!',
-  'onboarding.page_six.apps_available': '有适用于 iOS、Android 和其他平台的应用程序。',
-  'onboarding.page_six.github': '{domain} 在 Glitchsoc 上运行。Glitchsoc 是 {Mastodon} 的一个友好 {fork},与任何 Mastodon 实例或应用兼容。Glitchsoc 是完全免费和开源的。你可以在 {github} 上报告错误、请求功能或贡献代码。',
-  'onboarding.page_six.guidelines': '社区准则',
-  'onboarding.page_six.read_guidelines': '请阅读 {domain} 的 {guidelines}!',
-  'onboarding.page_six.various_app': '应用程序',
-  'onboarding.page_three.profile': '编辑你的个人资料,更改你的头像、个人简介和昵称。在那里,你还会发现其他设置。',
-  'onboarding.page_three.search': '使用搜索栏查找用户并查看标签,例如 #illustration 和 #introductions。要查找不在此实例中的用户,请使用他们的完整用户名。',
-  'onboarding.page_two.compose': '在撰写框中撰写嘟文。你可以使用下方图标上传图像、更改隐私设置和添加内容警告。',
-  'onboarding.skip': '跳过',
-  'settings.always_show_spoilers_field': '始终显示内容警告框',
-  'settings.auto_collapse': '自动折叠',
-  'settings.auto_collapse_all': '所有',
-  'settings.auto_collapse_lengthy': '长嘟文',
-  'settings.auto_collapse_media': '带媒体文件的嘟文',
-  'settings.auto_collapse_notifications': '通知',
-  'settings.auto_collapse_reblogs': '转嘟',
-  'settings.auto_collapse_replies': '回复',
-  'settings.close': '关闭',
-  'settings.collapsed_statuses': '折叠嘟文',
-  'settings.compose_box_opts': '撰写框',
-  'settings.confirm_before_clearing_draft': '在覆盖正在写入的嘟文之前显示确认对话框',
-  'settings.confirm_boost_missing_media_description': '在转嘟缺少媒体描述的嘟文之前显示确认对话框',
-  'settings.confirm_missing_media_description': '在发送缺少媒体描述的嘟文之前显示确认对话框',
-  'settings.content_warnings': '内容警告',
-  'settings.content_warnings.regexp': '正则表达式',
-  'settings.content_warnings_filter': '不会自动展开的内容警告:',
-  'settings.enable_collapsed': '启用折叠嘟文',
-  'settings.enable_content_warnings_auto_unfold': '自动展开内容警告',
-  'settings.filtering_behavior': '过滤器行为',
-  'settings.filtering_behavior.cw': '仍然显示嘟文,并在内容警告中添加过滤词',
-  'settings.filtering_behavior.drop': '完全隐藏过滤的嘟文',
-  'settings.filtering_behavior.hide': '显示“已过滤”并添加一个按钮来显示原因',
-  'settings.filtering_behavior.upstream': '像原版 Mastodon 一样显示“已过滤”',
-  'settings.filters': '过滤器',
-  'settings.general': '一般',
-  'settings.hicolor_privacy_icons': '彩色隐私图标 ',
-  'settings.hicolor_privacy_icons.hint': '以明亮且易于区分的颜色显示隐私图标',
-  'settings.image_backgrounds': '图片背景',
-  'settings.image_backgrounds_media': '预览折叠嘟文的媒体文件',
-  'settings.image_backgrounds_users': '为折叠嘟文附加图片背景',
-  'settings.inline_preview_cards': '外部链接的内嵌预览卡片',
-  'settings.layout': '布局:',
-  'settings.layout_opts': '布局选项',
-  'settings.media': '媒体',
-  'settings.media_fullwidth': '全宽媒体预览',
-  'settings.media_letterbox': '信箱媒体',
-  'settings.media_letterbox_hint': '缩小媒体以填充图像容器而不是拉伸和裁剪它们',
-  'settings.media_reveal_behind_cw': '默认显示内容警告后的敏感媒体',
-  'settings.navbar_under': '底部导航栏(仅限于移动模式)',
-  'settings.notifications.favicon_badge': '未读通知网站图标',
-  'settings.notifications.favicon_badge.hint': '将未读通知添加到网站图标',
-  'settings.notifications.tab_badge': '未读通知图标',
-  'settings.notifications.tab_badge.hint': '当通知栏未打开时,显示未读通知图标',
-  'settings.notifications_opts': '通知选项',
-  'settings.pop_in_left': '左边',
-  'settings.pop_in_player': '启用悬浮播放器',
-  'settings.pop_in_position': '悬浮播放器位置:',
-  'settings.pop_in_right': '右边',
-  'settings.preferences': '用户选项',
-  'settings.prepend_cw_re': '回复时在内容警告前加上“re:”',
-  'settings.preselect_on_reply': '回复时预先选择用户名',
-  'settings.preselect_on_reply_hint': '回复与多个参与者的对话时,预先选择第一个用户名',
-  'settings.rewrite_mentions': '重写嘟文中的提及',
-  'settings.rewrite_mentions_acct': '重写为用户名和域名(当帐户为远程时)',
-  'settings.rewrite_mentions_no': '不要重写',
-  'settings.rewrite_mentions_username': '重写为用户名',
-  'settings.show_action_bar': '在折叠的嘟文中显示操作按钮',
-  'settings.show_content_type_choice': '允许你在撰写嘟文时选择格式类型',
-  'settings.show_reply_counter': '显示回复的大致数量',
-  'settings.side_arm': '辅助发嘟按钮:',
-  'settings.side_arm.none': '无',
-  'settings.side_arm_reply_mode': '当回复嘟文时:',
-  'settings.side_arm_reply_mode.copy': '复制被回复嘟文的隐私设置',
-  'settings.side_arm_reply_mode.keep': '保留辅助发嘟按钮以设置隐私',
-  'settings.side_arm_reply_mode.restrict': '将隐私设置限制为正在回复的那条嘟文',
-  'settings.swipe_to_change_columns': '允许滑动以在列之间切换(仅限移动模式)',
-  'settings.tag_misleading_links': '标记误导性链接',
-  'settings.tag_misleading_links.hint': '将带有目标网页链接的视觉指示添加到每个未明确的链接',
-  'settings.wide_view': '宽视图(仅限于桌面模式)',
-  'settings.wide_view_hint': '拉伸列宽以更好地填充可用空间。',
-  'status.collapse': '折叠',
-  'status.has_audio': '附带音频文件',
-  'status.has_pictures': '附带图片文件',
-  'status.has_preview_card': '附带预览卡片',
-  'status.has_video': '附带视频文件',
-  'status.hide': '隐藏内容',
-  'status.in_reply_to': '此嘟文是回复',
-  'status.is_poll': '此嘟文是投票',
-  'status.local_only': '此嘟文仅本实例可见',
-  'status.sensitive_toggle': '点击查看',
-  'status.show_filter_reason': '(显示原因)',
-  'status.uncollapse': '不折叠',
-  'upload_modal.applying': '正在应用...',
-  'web_app_crash.change_your_settings': '更改 {settings}',
-  'web_app_crash.content': '你可以尝试这些:',
-  'web_app_crash.debug_info': '调试信息',
-  'web_app_crash.disable_addons': '禁用浏览器插件或本地翻译工具',
-  'web_app_crash.issue_tracker': '问题追踪器',
-  'web_app_crash.reload': '刷新',
-  'web_app_crash.reload_page': '{reload} 此页面',
-  'web_app_crash.report_issue': '将错误报告给 {issuetracker}',
-  'web_app_crash.settings': '设置',
-  'web_app_crash.title': '抱歉,Mastodon 出了点问题。',
-};
-
-export default Object.assign({}, inherited, messages);
\ No newline at end of file
diff --git a/app/javascript/flavours/glitch/locales/zh-CN.json b/app/javascript/flavours/glitch/locales/zh-CN.json
new file mode 100644
index 000000000..9b5a7713f
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/zh-CN.json
@@ -0,0 +1,176 @@
+{
+  "account.add_account_note": "为 @{name} 添加备注",
+  "account.disclaimer_full": "以下信息可能无法完整代表你的个人资料。",
+  "account.follows": "正在关注",
+  "account.suspended_disclaimer_full": "该用户已被封禁。",
+  "account.view_full_profile": "查看完整资料",
+  "account_note.cancel": "取消",
+  "account_note.edit": "编辑",
+  "account_note.glitch_placeholder": "暂无备注",
+  "account_note.save": "保存",
+  "advanced_options.icon_title": "高级选项",
+  "advanced_options.local-only.long": "不要发布嘟文到其他实例",
+  "advanced_options.local-only.short": "本地模式",
+  "advanced_options.local-only.tooltip": "这条嘟文仅限于本实例",
+  "advanced_options.threaded_mode.long": "发嘟时自动打开回复",
+  "advanced_options.threaded_mode.short": "线程模式",
+  "advanced_options.threaded_mode.tooltip": "线程模式已启用",
+  "boost_modal.missing_description": "这条嘟文未包含媒体描述",
+  "column.favourited_by": "喜欢",
+  "column.heading": "标题",
+  "column.reblogged_by": "转嘟",
+  "column.subheading": "其他选项",
+  "column_header.profile": "个人资料",
+  "column_subheading.lists": "列表",
+  "column_subheading.navigation": "导航",
+  "community.column_settings.allow_local_only": "只显示本地模式嘟文",
+  "compose.attach": "附上...",
+  "compose.attach.doodle": "画点什么",
+  "compose.attach.upload": "上传文件",
+  "compose.content-type.plain": "纯文本",
+  "compose_form.poll.multiple_choices": "允许多选",
+  "compose_form.poll.single_choice": "允许单选",
+  "compose_form.spoiler": "隐藏为内容警告",
+  "confirmation_modal.do_not_ask_again": "下次不显示确认窗口",
+  "confirmations.missing_media_description.confirm": "确认",
+  "confirmations.missing_media_description.edit": "编辑",
+  "confirmations.missing_media_description.message": "你没有为一种或多种媒体撰写描述。请考虑为视障人士添加描述。",
+  "confirmations.unfilter.author": "作者",
+  "confirmations.unfilter.confirm": "查看",
+  "confirmations.unfilter.edit_filter": "编辑过滤器",
+  "confirmations.unfilter.filters": "应用 {count, plural, one {过滤器} other {过滤器}}",
+  "content-type.change": "内容类型 ",
+  "endorsed_accounts_editor.endorsed_accounts": "推荐用户",
+  "favourite_modal.combo": "下次你可以按 {combo} 跳过这个",
+  "getting_started.onboarding": "参观一下",
+  "home.column_settings.advanced": "高级",
+  "home.column_settings.filter_regex": "按正则表达式过滤",
+  "home.column_settings.show_direct": "显示私信",
+  "home.settings": "列表设置",
+  "keyboard_shortcuts.bookmark": "书签",
+  "keyboard_shortcuts.secondary_toot": "使用二级隐私设置发送嘟文",
+  "keyboard_shortcuts.toggle_collapse": "折叠或展开嘟文",
+  "layout.auto": "自动模式",
+  "layout.desktop": "桌面模式",
+  "layout.hint.auto": "根据“启用高级 Web 界面”设置和屏幕大小自动选择布局。",
+  "layout.hint.desktop": "“使用多列布局,无论“启用高级 Web 界面”设置和屏幕大小如何。",
+  "layout.hint.single": "使用单列布局,无论“启用高级 Web 界面”设置和屏幕大小如何。",
+  "layout.single": "移动模式",
+  "media_gallery.sensitive": "敏感内容",
+  "moved_to_warning": "此帐户已被标记为移至 {moved_to_link},并且似乎没有收到新关注者。",
+  "navigation_bar.app_settings": "应用选项",
+  "navigation_bar.featured_users": "推荐用户",
+  "navigation_bar.misc": "杂项",
+  "notification.markForDeletion": "标记以删除",
+  "notification_purge.btn_all": "全选",
+  "notification_purge.btn_apply": "清除已选",
+  "notification_purge.btn_invert": "反向选择",
+  "notification_purge.btn_none": "取消全选",
+  "notification_purge.start": "进入通知清除模式",
+  "notifications.marked_clear": "清除选择的通知",
+  "notifications.marked_clear_confirmation": "你确定要永久清除所有选择的通知吗?",
+  "onboarding.done": "完成",
+  "onboarding.next": "下一个",
+  "onboarding.page_five.public_timelines": "本地时间线显示来自 {domain} 中所有人的公开嘟文。跨站时间线显示了 {domain} 用户关注的每个人的公开嘟文。这些被称为公共时间线,是发现新朋友的好方法。",
+  "onboarding.page_four.home": "你的主页时间线会显示你关注的人的嘟文。",
+  "onboarding.page_four.notifications": "通知栏显示某人与你互动的内容。",
+  "onboarding.page_one.federation": "{domain} 是 Mastodon 的一个“实例”。Mastodon 是一个由独立服务器组成的,通过不断联合形成的社交网络。我们称这些服务器为实例。",
+  "onboarding.page_one.handle": "你位于 {domain},因此你的完整用户名是 {handle} 。",
+  "onboarding.page_one.welcome": "欢迎来到 {domain}!",
+  "onboarding.page_six.admin": "实例的管理员是 {admin}。",
+  "onboarding.page_six.almost_done": "就快完成了...",
+  "onboarding.page_six.appetoot": "尽情享用吧!",
+  "onboarding.page_six.apps_available": "有适用于 iOS、Android 和其他平台的应用程序。",
+  "onboarding.page_six.github": "{domain} 在 Glitchsoc 上运行。Glitchsoc 是 {Mastodon} 的一个友好 {fork},与任何 Mastodon 实例或应用兼容。Glitchsoc 是完全免费和开源的。你可以在 {github} 上报告错误、请求功能或贡献代码。",
+  "onboarding.page_six.guidelines": "社区准则",
+  "onboarding.page_six.read_guidelines": "请阅读 {domain} 的 {guidelines}!",
+  "onboarding.page_six.various_app": "应用程序",
+  "onboarding.page_three.profile": "编辑你的个人资料,更改你的头像、个人简介和昵称。在那里,你还会发现其他设置。",
+  "onboarding.page_three.search": "使用搜索栏查找用户并查看标签,例如 #illustration 和 #introductions。要查找不在此实例中的用户,请使用他们的完整用户名。",
+  "onboarding.page_two.compose": "在撰写框中撰写嘟文。你可以使用下方图标上传图像、更改隐私设置和添加内容警告。",
+  "onboarding.skip": "跳过",
+  "settings.always_show_spoilers_field": "始终显示内容警告框",
+  "settings.auto_collapse": "自动折叠",
+  "settings.auto_collapse_all": "所有",
+  "settings.auto_collapse_lengthy": "长嘟文",
+  "settings.auto_collapse_media": "带媒体文件的嘟文",
+  "settings.auto_collapse_notifications": "通知",
+  "settings.auto_collapse_reblogs": "转嘟",
+  "settings.auto_collapse_replies": "回复",
+  "settings.close": "关闭",
+  "settings.collapsed_statuses": "折叠嘟文",
+  "settings.compose_box_opts": "撰写框",
+  "settings.confirm_before_clearing_draft": "在覆盖正在写入的嘟文之前显示确认对话框",
+  "settings.confirm_boost_missing_media_description": "在转嘟缺少媒体描述的嘟文之前显示确认对话框",
+  "settings.confirm_missing_media_description": "在发送缺少媒体描述的嘟文之前显示确认对话框",
+  "settings.content_warnings": "内容警告",
+  "settings.content_warnings.regexp": "正则表达式",
+  "settings.content_warnings_filter": "不会自动展开的内容警告:",
+  "settings.enable_collapsed": "启用折叠嘟文",
+  "settings.enable_content_warnings_auto_unfold": "自动展开内容警告",
+  "settings.general": "一般",
+  "settings.hicolor_privacy_icons": "彩色隐私图标 ",
+  "settings.hicolor_privacy_icons.hint": "以明亮且易于区分的颜色显示隐私图标",
+  "settings.image_backgrounds": "图片背景",
+  "settings.image_backgrounds_media": "预览折叠嘟文的媒体文件",
+  "settings.image_backgrounds_users": "为折叠嘟文附加图片背景",
+  "settings.inline_preview_cards": "外部链接的内嵌预览卡片",
+  "settings.layout": "布局:",
+  "settings.layout_opts": "布局选项",
+  "settings.media": "媒体",
+  "settings.media_fullwidth": "全宽媒体预览",
+  "settings.media_letterbox": "信箱媒体",
+  "settings.media_letterbox_hint": "缩小媒体以填充图像容器而不是拉伸和裁剪它们",
+  "settings.media_reveal_behind_cw": "默认显示内容警告后的敏感媒体",
+  "settings.notifications.favicon_badge": "未读通知网站图标",
+  "settings.notifications.favicon_badge.hint": "将未读通知添加到网站图标",
+  "settings.notifications.tab_badge": "未读通知图标",
+  "settings.notifications.tab_badge.hint": "当通知栏未打开时,显示未读通知图标",
+  "settings.notifications_opts": "通知选项",
+  "settings.pop_in_left": "左边",
+  "settings.pop_in_player": "启用悬浮播放器",
+  "settings.pop_in_position": "悬浮播放器位置:",
+  "settings.pop_in_right": "右边",
+  "settings.preferences": "用户选项",
+  "settings.prepend_cw_re": "回复时在内容警告前加上“re:”",
+  "settings.preselect_on_reply": "回复时预先选择用户名",
+  "settings.preselect_on_reply_hint": "回复与多个参与者的对话时,预先选择第一个用户名",
+  "settings.rewrite_mentions": "重写嘟文中的提及",
+  "settings.rewrite_mentions_acct": "重写为用户名和域名(当帐户为远程时)",
+  "settings.rewrite_mentions_no": "不要重写",
+  "settings.rewrite_mentions_username": "重写为用户名",
+  "settings.show_action_bar": "在折叠的嘟文中显示操作按钮",
+  "settings.show_content_type_choice": "允许你在撰写嘟文时选择格式类型",
+  "settings.show_reply_counter": "显示回复的大致数量",
+  "settings.side_arm": "辅助发嘟按钮:",
+  "settings.side_arm.none": "无",
+  "settings.side_arm_reply_mode": "当回复嘟文时:",
+  "settings.side_arm_reply_mode.copy": "复制被回复嘟文的隐私设置",
+  "settings.side_arm_reply_mode.keep": "保留辅助发嘟按钮以设置隐私",
+  "settings.side_arm_reply_mode.restrict": "将隐私设置限制为正在回复的那条嘟文",
+  "settings.swipe_to_change_columns": "允许滑动以在列之间切换(仅限移动模式)",
+  "settings.tag_misleading_links": "标记误导性链接",
+  "settings.tag_misleading_links.hint": "将带有目标网页链接的视觉指示添加到每个未明确的链接",
+  "settings.wide_view": "宽视图(仅限于桌面模式)",
+  "settings.wide_view_hint": "拉伸列宽以更好地填充可用空间。",
+  "status.collapse": "折叠",
+  "status.has_audio": "附带音频文件",
+  "status.has_pictures": "附带图片文件",
+  "status.has_preview_card": "附带预览卡片",
+  "status.has_video": "附带视频文件",
+  "status.in_reply_to": "此嘟文是回复",
+  "status.is_poll": "此嘟文是投票",
+  "status.local_only": "此嘟文仅本实例可见",
+  "status.sensitive_toggle": "点击查看",
+  "status.uncollapse": "不折叠",
+  "web_app_crash.change_your_settings": "更改 {settings}",
+  "web_app_crash.content": "你可以尝试这些:",
+  "web_app_crash.debug_info": "调试信息",
+  "web_app_crash.disable_addons": "禁用浏览器插件或本地翻译工具",
+  "web_app_crash.issue_tracker": "问题追踪器",
+  "web_app_crash.reload": "刷新",
+  "web_app_crash.reload_page": "{reload} 此页面",
+  "web_app_crash.report_issue": "将错误报告给 {issuetracker}",
+  "web_app_crash.settings": "设置",
+  "web_app_crash.title": "抱歉,Mastodon 出了点问题。"
+}
diff --git a/app/javascript/flavours/glitch/locales/zh-HK.js b/app/javascript/flavours/glitch/locales/zh-HK.js
deleted file mode 100644
index b71c81f2b..000000000
--- a/app/javascript/flavours/glitch/locales/zh-HK.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/zh-HK.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/zh-HK.json b/app/javascript/flavours/glitch/locales/zh-HK.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/zh-HK.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/locales/zh-TW.js b/app/javascript/flavours/glitch/locales/zh-TW.js
deleted file mode 100644
index de2b7769c..000000000
--- a/app/javascript/flavours/glitch/locales/zh-TW.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import inherited from 'mastodon/locales/zh-TW.json';
-
-const messages = {
-  //  No translations available.
-};
-
-export default Object.assign({}, inherited, messages);
diff --git a/app/javascript/flavours/glitch/locales/zh-TW.json b/app/javascript/flavours/glitch/locales/zh-TW.json
new file mode 100644
index 000000000..4d243f94c
--- /dev/null
+++ b/app/javascript/flavours/glitch/locales/zh-TW.json
@@ -0,0 +1,6 @@
+{
+  "onboarding.page_one.federation": "{domain} is an \"instance\" of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
+  "onboarding.page_six.github": "{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}. Glitchsoc is fully compatible with all Mastodon apps and instances. Glitchsoc is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
+  "settings.content_warnings": "Content warnings",
+  "settings.preferences": "Preferences"
+}
diff --git a/app/javascript/flavours/glitch/packs/public.js b/app/javascript/flavours/glitch/packs/public.js
index 843fd5163..b256fdbd5 100644
--- a/app/javascript/flavours/glitch/packs/public.js
+++ b/app/javascript/flavours/glitch/packs/public.js
@@ -42,6 +42,18 @@ function main() {
       minute: 'numeric',
     });
 
+    const dateFormat = new Intl.DateTimeFormat(locale, {
+      year: 'numeric',
+      month: 'short',
+      day: 'numeric',
+      timeFormat: false,
+    });
+
+    const timeFormat = new Intl.DateTimeFormat(locale, {
+      timeStyle: 'short',
+      hour12: false,
+    });
+
     [].forEach.call(document.querySelectorAll('.emojify'), (content) => {
       content.innerHTML = emojify(content.innerHTML);
     });
@@ -54,6 +66,32 @@ function main() {
       content.textContent = formattedDate;
     });
 
+    const isToday = date => {
+      const today = new Date();
+
+      return date.getDate() === today.getDate() &&
+        date.getMonth() === today.getMonth() &&
+        date.getFullYear() === today.getFullYear();
+    };
+    const todayFormat = new IntlMessageFormat(messages['relative_format.today'] || 'Today at {time}', locale);
+
+    [].forEach.call(document.querySelectorAll('time.relative-formatted'), (content) => {
+      const datetime = new Date(content.getAttribute('datetime'));
+
+      let formattedContent;
+
+      if (isToday(datetime)) {
+        const formattedTime = timeFormat.format(datetime);
+
+        formattedContent = todayFormat.format({ time: formattedTime });
+      } else {
+        formattedContent = dateFormat.format(datetime);
+      }
+
+      content.title = formattedContent;
+      content.textContent = formattedContent;
+    });
+
     [].forEach.call(document.querySelectorAll('time.time-ago'), (content) => {
       const datetime = new Date(content.getAttribute('datetime'));
       const now      = new Date();
diff --git a/app/javascript/flavours/glitch/permissions.js b/app/javascript/flavours/glitch/permissions.js
index 752ddd6c5..9ea149e5f 100644
--- a/app/javascript/flavours/glitch/permissions.js
+++ b/app/javascript/flavours/glitch/permissions.js
@@ -1,3 +1,4 @@
-export const PERMISSION_INVITE_USERS   = 0x0000000000010000;
-export const PERMISSION_MANAGE_USERS   = 0x0000000000000400;
-export const PERMISSION_MANAGE_REPORTS = 0x0000000000000010;
+export const PERMISSION_INVITE_USERS      = 0x0000000000010000;
+export const PERMISSION_MANAGE_USERS      = 0x0000000000000400;
+export const PERMISSION_MANAGE_FEDERATION = 0x0000000000000020;
+export const PERMISSION_MANAGE_REPORTS    = 0x0000000000000010;
diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js
index 9b50ec23a..814b6a1a7 100644
--- a/app/javascript/flavours/glitch/reducers/compose.js
+++ b/app/javascript/flavours/glitch/reducers/compose.js
@@ -421,8 +421,10 @@ export default function compose(state = initialState, action) {
       map.set('preselectDate', new Date());
       map.set('idempotencyKey', uuid());
 
-      if (action.status.get('language')) {
+      if (action.status.get('language') && !action.status.has('translation')) {
         map.set('language', action.status.get('language'));
+      } else {
+        map.set('language', state.get('default_language'));
       }
 
       if (action.status.get('spoiler_text').length > 0) {
@@ -536,6 +538,8 @@ export default function compose(state = initialState, action) {
   case TIMELINE_DELETE:
     if (action.id === state.get('in_reply_to')) {
       return state.set('in_reply_to', null);
+    } else if (action.id === state.get('id')) {
+      return state.set('id', null);
     } else {
       return state;
     }
diff --git a/app/javascript/flavours/glitch/reducers/dropdown_menu.js b/app/javascript/flavours/glitch/reducers/dropdown_menu.js
index a78a11acc..51bf9375b 100644
--- a/app/javascript/flavours/glitch/reducers/dropdown_menu.js
+++ b/app/javascript/flavours/glitch/reducers/dropdown_menu.js
@@ -4,12 +4,12 @@ import {
   DROPDOWN_MENU_CLOSE,
 } from '../actions/dropdown_menu';
 
-const initialState = Immutable.Map({ openId: null, placement: null, keyboard: false, scroll_key: null });
+const initialState = Immutable.Map({ openId: null, keyboard: false, scroll_key: null });
 
 export default function dropdownMenu(state = initialState, action) {
   switch (action.type) {
   case DROPDOWN_MENU_OPEN:
-    return state.merge({ openId: action.id, placement: action.placement, keyboard: action.keyboard, scroll_key: action.scroll_key });
+    return state.merge({ openId: action.id, keyboard: action.keyboard, scroll_key: action.scroll_key });
   case DROPDOWN_MENU_CLOSE:
     return state.get('openId') === action.id ? state.set('openId', null).set('scroll_key', null) : state;
   default:
diff --git a/app/javascript/flavours/glitch/reducers/relationships.js b/app/javascript/flavours/glitch/reducers/relationships.js
index 49dd77ef5..e4b9acea2 100644
--- a/app/javascript/flavours/glitch/reducers/relationships.js
+++ b/app/javascript/flavours/glitch/reducers/relationships.js
@@ -1,4 +1,7 @@
 import {
+  NOTIFICATIONS_UPDATE,
+} from '../actions/notifications';
+import {
   ACCOUNT_FOLLOW_SUCCESS,
   ACCOUNT_FOLLOW_REQUEST,
   ACCOUNT_FOLLOW_FAIL,
@@ -12,6 +15,8 @@ import {
   ACCOUNT_PIN_SUCCESS,
   ACCOUNT_UNPIN_SUCCESS,
   RELATIONSHIPS_FETCH_SUCCESS,
+  FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
+  FOLLOW_REQUEST_REJECT_SUCCESS,
 } from 'flavours/glitch/actions/accounts';
 import {
   DOMAIN_BLOCK_SUCCESS,
@@ -44,6 +49,12 @@ const initialState = ImmutableMap();
 
 export default function relationships(state = initialState, action) {
   switch(action.type) {
+  case FOLLOW_REQUEST_AUTHORIZE_SUCCESS:
+    return state.setIn([action.id, 'followed_by'], true).setIn([action.id, 'requested_by'], false);
+  case FOLLOW_REQUEST_REJECT_SUCCESS:
+    return state.setIn([action.id, 'followed_by'], false).setIn([action.id, 'requested_by'], false);
+  case NOTIFICATIONS_UPDATE:
+    return action.notification.type === 'follow_request' ? state.setIn([action.notification.account.id, 'requested_by'], true) : state;
   case ACCOUNT_FOLLOW_REQUEST:
     return state.getIn([action.id, 'following']) ? state : state.setIn([action.id, action.locked ? 'requested' : 'following'], true);
   case ACCOUNT_FOLLOW_FAIL:
diff --git a/app/javascript/flavours/glitch/selectors/index.js b/app/javascript/flavours/glitch/selectors/index.js
index df46b58a8..83f8783d9 100644
--- a/app/javascript/flavours/glitch/selectors/index.js
+++ b/app/javascript/flavours/glitch/selectors/index.js
@@ -1,6 +1,6 @@
 import escapeTextContentForBrowser from 'escape-html';
 import { createSelector } from 'reselect';
-import { List as ImmutableList } from 'immutable';
+import { List as ImmutableList, Map as ImmutableMap, is } from 'immutable';
 import { toServerSideType } from 'flavours/glitch/utils/filters';
 import { me } from 'flavours/glitch/initial_state';
 
@@ -74,6 +74,16 @@ export const makeGetStatus = () => {
   );
 };
 
+export const makeGetPictureInPicture = () => {
+  return createSelector([
+    (state, { id }) => state.get('picture_in_picture').statusId === id,
+    (state) => state.getIn(['meta', 'layout']) !== 'mobile',
+  ], (inUse, available) => ImmutableMap({
+    inUse: inUse && available,
+    available,
+  }));
+};
+
 const getAlertsBase = state => state.get('alerts');
 
 export const getAlerts = createSelector([getAlertsBase], (base) => {
diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss
index c2426944b..8ddf815c3 100644
--- a/app/javascript/flavours/glitch/styles/admin.scss
+++ b/app/javascript/flavours/glitch/styles/admin.scss
@@ -254,10 +254,8 @@ $content-width: 840px;
 
       &__actions {
         display: inline-flex;
-
-        & > :not(:first-child) {
-          margin-left: 5px;
-        }
+        flex-flow: wrap;
+        gap: 5px;
       }
 
       h2 small {
@@ -1681,6 +1679,15 @@ a.sparkline {
   box-sizing: border-box;
   min-height: 100%;
 
+  a {
+    color: $highlight-text-color;
+    text-decoration: none;
+
+    &:hover {
+      text-decoration: underline;
+    }
+  }
+
   p {
     margin-bottom: 20px;
     unicode-bidi: plaintext;
diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss
index ac2d642a8..5b3e1db1b 100644
--- a/app/javascript/flavours/glitch/styles/components/accounts.scss
+++ b/app/javascript/flavours/glitch/styles/components/accounts.scss
@@ -523,7 +523,6 @@
       display: block;
       flex: 0 0 auto;
       width: 94px;
-      margin-left: -2px;
 
       .account__avatar {
         background: darken($ui-base-color, 8%);
@@ -540,6 +539,7 @@
     margin-top: -55px;
     gap: 8px;
     overflow: hidden;
+    margin-left: -2px; // aligns the pfp with content below
 
     &__buttons {
       display: flex;
@@ -593,6 +593,10 @@
           font-weight: 400;
           overflow: hidden;
           text-overflow: ellipsis;
+
+          span {
+            user-select: all;
+          }
         }
       }
     }
@@ -752,3 +756,37 @@
     }
   }
 }
+
+.moved-account-banner,
+.follow-request-banner {
+  padding: 20px;
+  background: lighten($ui-base-color, 4%);
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+  &__message {
+    color: $darker-text-color;
+    padding: 8px 0;
+    padding-top: 0;
+    padding-bottom: 4px;
+    font-size: 14px;
+    font-weight: 500;
+    text-align: center;
+    margin-bottom: 16px;
+  }
+  &__action {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    gap: 15px;
+    width: 100%;
+  }
+
+  .detailed-status__display-name {
+    margin-bottom: 0;
+  }
+}
+
+.follow-request-banner .button {
+  width: 100%;
+}
diff --git a/app/javascript/flavours/glitch/styles/components/compose_form.scss b/app/javascript/flavours/glitch/styles/components/compose_form.scss
index 72d3aad1d..aa2d52ed0 100644
--- a/app/javascript/flavours/glitch/styles/components/compose_form.scss
+++ b/app/javascript/flavours/glitch/styles/components/compose_form.scss
@@ -586,7 +586,6 @@
 }
 
 .privacy-dropdown__dropdown {
-  position: absolute;
   border-radius: 4px;
   box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
   background: $simple-background-color;
@@ -653,7 +652,6 @@
 
 .language-dropdown {
   &__dropdown {
-    position: absolute;
     background: $simple-background-color;
     box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
     border-radius: 4px;
diff --git a/app/javascript/flavours/glitch/styles/components/emoji.scss b/app/javascript/flavours/glitch/styles/components/emoji.scss
index 9dfee346a..c037e03f9 100644
--- a/app/javascript/flavours/glitch/styles/components/emoji.scss
+++ b/app/javascript/flavours/glitch/styles/components/emoji.scss
@@ -13,7 +13,7 @@
 
 .emoji-picker-dropdown__menu {
   background: $simple-background-color;
-  position: absolute;
+  position: relative;
   box-shadow: 4px 4px 6px rgba($base-shadow-color, 0.4);
   border-radius: 4px;
   margin-top: 5px;
diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss
index 84aca2ebc..d50316366 100644
--- a/app/javascript/flavours/glitch/styles/components/index.scss
+++ b/app/javascript/flavours/glitch/styles/components/index.scss
@@ -141,6 +141,30 @@
     &:disabled {
       opacity: 0.5;
     }
+
+    &.button--confirmation {
+      color: $valid-value-color;
+      border-color: $valid-value-color;
+
+      &:active,
+      &:focus,
+      &:hover {
+        background: $valid-value-color;
+        color: $primary-text-color;
+      }
+    }
+
+    &.button--destructive {
+      color: $error-value-color;
+      border-color: $error-value-color;
+
+      &:active,
+      &:focus,
+      &:hover {
+        background: $error-value-color;
+        color: $primary-text-color;
+      }
+    }
   }
 
   &.button--block {
@@ -322,9 +346,8 @@
   }
 }
 
-.dropdown-menu {
-  position: absolute;
-  transform-origin: 50% 0;
+body > [data-popper-placement] {
+  z-index: 3;
 }
 
 .invisible {
@@ -508,6 +531,42 @@
   }
 }
 
+.dropdown-animation {
+  animation: dropdown 300ms cubic-bezier(0.1, 0.7, 0.1, 1);
+
+  @keyframes dropdown {
+    from {
+      opacity: 0;
+      transform: scaleX(0.85) scaleY(0.75);
+    }
+
+    to {
+      opacity: 1;
+      transform: scaleX(1) scaleY(1);
+    }
+  }
+
+  &.top {
+    transform-origin: bottom;
+  }
+
+  &.right {
+    transform-origin: left;
+  }
+
+  &.bottom {
+    transform-origin: top;
+  }
+
+  &.left {
+    transform-origin: right;
+  }
+
+  .reduce-motion & {
+    animation: none;
+  }
+}
+
 .dropdown {
   display: inline-block;
 }
@@ -576,36 +635,42 @@
 
 .dropdown-menu__arrow {
   position: absolute;
-  width: 0;
-  height: 0;
-  border: 0 solid transparent;
 
-  &.left {
-    right: -5px;
-    margin-top: -5px;
-    border-width: 5px 0 5px 5px;
-    border-left-color: $ui-secondary-color;
+  &::before {
+    content: '';
+    display: block;
+    width: 14px;
+    height: 5px;
+    background-color: $ui-secondary-color;
+    mask-image: url("data:image/svg+xml;utf8,<svg width='14' height='5' xmlns='http://www.w3.org/2000/svg'><path d='M7 0L0 5h14L7 0z' fill='white'/></svg>");
   }
 
   &.top {
     bottom: -5px;
-    margin-left: -7px;
-    border-width: 5px 7px 0;
-    border-top-color: $ui-secondary-color;
+
+    &::before {
+      transform: rotate(180deg);
+    }
+  }
+
+  &.right {
+    left: -9px;
+
+    &::before {
+      transform: rotate(-90deg);
+    }
   }
 
   &.bottom {
     top: -5px;
-    margin-left: -7px;
-    border-width: 0 7px 5px;
-    border-bottom-color: $ui-secondary-color;
   }
 
-  &.right {
-    left: -5px;
-    margin-top: -5px;
-    border-width: 5px 5px 5px 0;
-    border-right-color: $ui-secondary-color;
+  &.left {
+    right: -9px;
+
+    &::before {
+      transform: rotate(90deg);
+    }
   }
 }
 
diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss
index 8ba8bec10..972e01e7d 100644
--- a/app/javascript/flavours/glitch/styles/components/modal.scss
+++ b/app/javascript/flavours/glitch/styles/components/modal.scss
@@ -37,7 +37,6 @@
 .modal-root__modal {
   pointer-events: auto;
   display: flex;
-  z-index: 9999;
 }
 
 .media-modal__zoom-button {
diff --git a/app/javascript/flavours/glitch/styles/components/search.scss b/app/javascript/flavours/glitch/styles/components/search.scss
index 70af0f651..b8078bdb6 100644
--- a/app/javascript/flavours/glitch/styles/components/search.scss
+++ b/app/javascript/flavours/glitch/styles/components/search.scss
@@ -1,4 +1,5 @@
 .search {
+  margin-bottom: 10px;
   position: relative;
 }
 
diff --git a/app/javascript/flavours/glitch/styles/components/single_column.scss b/app/javascript/flavours/glitch/styles/components/single_column.scss
index 45d57aedd..74e5d0884 100644
--- a/app/javascript/flavours/glitch/styles/components/single_column.scss
+++ b/app/javascript/flavours/glitch/styles/components/single_column.scss
@@ -227,8 +227,7 @@
     height: calc(100% - 10px) !important;
   }
 
-  .getting-started__wrapper,
-  .search {
+  .getting-started__wrapper {
     margin-bottom: 10px;
   }
 
@@ -281,7 +280,7 @@
     }
   }
 
-  .ui__header {
+  .layout-single-column .ui__header {
     display: flex;
     background: $ui-base-color;
     border-bottom: 1px solid lighten($ui-base-color, 8%);
diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss
index 64dbc3cf0..a46fb94b2 100644
--- a/app/javascript/flavours/glitch/styles/components/status.scss
+++ b/app/javascript/flavours/glitch/styles/components/status.scss
@@ -448,7 +448,6 @@
 
 .status__relative-time {
   display: inline-block;
-  flex-grow: 1;
   color: $dark-text-color;
   font-size: 14px;
   text-align: right;
@@ -598,6 +597,10 @@
   width: 23.15px;
 }
 
+.status__action-bar-spacer {
+  flex-grow: 1;
+}
+
 .detailed-status__action-bar-dropdown {
   flex: 1 1 auto;
   display: flex;
@@ -1075,7 +1078,7 @@ a.status-card.compact:hover {
       pointer-events: 0;
       width: 100%;
       height: 100%;
-      border-left: 2px solid $highlight-text-color;
+      border-left: 4px solid $highlight-text-color;
       pointer-events: none;
     }
   }
diff --git a/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss b/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss
index 9fc1aed2a..2ec2da833 100644
--- a/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss
+++ b/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss
@@ -285,22 +285,8 @@ html {
 .dropdown-menu {
   background: $white;
 
-  &__arrow {
-    &.left {
-      border-left-color: $white;
-    }
-
-    &.top {
-      border-top-color: $white;
-    }
-
-    &.bottom {
-      border-bottom-color: $white;
-    }
-
-    &.right {
-      border-right-color: $white;
-    }
+  &__arrow::before {
+    background-color: $white;
   }
 
   &__item {
diff --git a/app/javascript/flavours/glitch/styles/modal.scss b/app/javascript/flavours/glitch/styles/modal.scss
index 6c6de4206..a333926dd 100644
--- a/app/javascript/flavours/glitch/styles/modal.scss
+++ b/app/javascript/flavours/glitch/styles/modal.scss
@@ -1,5 +1,5 @@
 .modal-layout {
-  background: $ui-base-color url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-lighter-color)}"/></svg>') repeat-x bottom fixed;
+  background: $ui-base-color url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-lighter-color)}33"/></svg>') repeat-x bottom fixed;
   display: flex;
   flex-direction: column;
   height: 100vh;
diff --git a/app/javascript/flavours/glitch/styles/polls.scss b/app/javascript/flavours/glitch/styles/polls.scss
index 0847c8f4c..43924829d 100644
--- a/app/javascript/flavours/glitch/styles/polls.scss
+++ b/app/javascript/flavours/glitch/styles/polls.scss
@@ -289,10 +289,10 @@
   color: $dark-text-color;
 
   &__chart {
-    background: rgba(darken($ui-primary-color, 14%), 0.2);
+    background: rgba(darken($ui-primary-color, 14%), 0.7);
 
     &.leading {
-      background: rgba($ui-highlight-color, 0.2);
+      background: rgba($ui-highlight-color, 0.5);
     }
   }
 }
diff --git a/app/javascript/flavours/glitch/theme.yml b/app/javascript/flavours/glitch/theme.yml
index e85dd74e1..2a2cf30b5 100644
--- a/app/javascript/flavours/glitch/theme.yml
+++ b/app/javascript/flavours/glitch/theme.yml
@@ -12,10 +12,10 @@ pack:
   home:
     filename: packs/home.js
     preload:
-    - flavours/glitch/async/compose
-    - flavours/glitch/async/getting_started
-    - flavours/glitch/async/home_timeline
-    - flavours/glitch/async/notifications
+      - flavours/glitch/async/compose
+      - flavours/glitch/async/getting_started
+      - flavours/glitch/async/home_timeline
+      - flavours/glitch/async/notifications
   mailer:
   modal:
   public: packs/public.js
@@ -24,10 +24,13 @@ pack:
 
 #  (OPTIONAL) The directory which contains localization files for
 #  the flavour, relative to this directory. The contents of this
-#  directory must be `.js` or `.json` files whose names correspond to
+#  directory must be `.json` files whose names correspond to
 #  language tags and whose default exports are a messages object.
 locales: locales
 
+#  (OPTIONAL) Which flavour to inherit locales from
+inherit_locales: vanilla
+
 #  (OPTIONAL) A file to use as the preview screenshot for the flavour,
 #  or an array thereof. These are the full path from `app/javascript/`.
 screenshot: flavours/glitch/images/glitch-preview.jpg
diff --git a/app/javascript/flavours/vanilla/theme.yml b/app/javascript/flavours/vanilla/theme.yml
index 5cb76b721..3f0b27899 100644
--- a/app/javascript/flavours/vanilla/theme.yml
+++ b/app/javascript/flavours/vanilla/theme.yml
@@ -12,10 +12,10 @@ pack:
   home:
     filename: application.js
     preload:
-    - features/getting_started
-    - features/compose
-    - features/home_timeline
-    - features/notifications
+      - features/getting_started
+      - features/compose
+      - features/home_timeline
+      - features/notifications
   mailer:
   modal:
   public: public.js
diff --git a/app/javascript/images/logo-symbol-icon.svg b/app/javascript/images/logo-symbol-icon.svg
index 56cf03921..c4c14f098 100644
--- a/app/javascript/images/logo-symbol-icon.svg
+++ b/app/javascript/images/logo-symbol-icon.svg
@@ -1,2 +1,2 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="79" height="79" viewBox="0 0 79 75"><symbol id="logo-symbol-icon"><path d="M74.7135 16.6043C73.6199 8.54587 66.5351 2.19527 58.1366 0.964691C56.7196 0.756754 51.351 0 38.9148 0H38.822C26.3824 0 23.7135 0.756754 22.2966 0.964691C14.1319 2.16118 6.67571 7.86752 4.86669 16.0214C3.99657 20.0369 3.90371 24.4888 4.06535 28.5726C4.29578 34.4289 4.34049 40.275 4.877 46.1075C5.24791 49.9817 5.89495 53.8251 6.81328 57.6088C8.53288 64.5968 15.4938 70.4122 22.3138 72.7848C29.6155 75.259 37.468 75.6697 44.9919 73.971C45.8196 73.7801 46.6381 73.5586 47.4475 73.3063C49.2737 72.7302 51.4164 72.086 52.9915 70.9542C53.0131 70.9384 53.0308 70.9178 53.0433 70.8942C53.0558 70.8706 53.0628 70.8445 53.0637 70.8179V65.1661C53.0634 65.1412 53.0574 65.1167 53.0462 65.0944C53.035 65.0721 53.0189 65.0525 52.9992 65.0371C52.9794 65.0218 52.9564 65.011 52.9318 65.0056C52.9073 65.0002 52.8819 65.0003 52.8574 65.0059C48.0369 66.1472 43.0971 66.7193 38.141 66.7103C29.6118 66.7103 27.3178 62.6981 26.6609 61.0278C26.1329 59.5842 25.7976 58.0784 25.6636 56.5486C25.6622 56.5229 25.667 56.4973 25.6775 56.4738C25.688 56.4502 25.7039 56.4295 25.724 56.4132C25.7441 56.397 25.7678 56.3856 25.7931 56.3801C25.8185 56.3746 25.8448 56.3751 25.8699 56.3816C30.6101 57.5151 35.4693 58.0873 40.3455 58.086C41.5183 58.086 42.6876 58.086 43.8604 58.0553C48.7647 57.919 53.9339 57.6701 58.7591 56.7361C58.8794 56.7123 58.9998 56.6918 59.103 56.6611C66.7139 55.2124 73.9569 50.665 74.6929 39.1501C74.7204 38.6967 74.7892 34.4016 74.7892 33.9312C74.7926 32.3325 75.3085 22.5901 74.7135 16.6043ZM62.9996 45.3371H54.9966V25.9069C54.9966 21.8163 53.277 19.7302 49.7793 19.7302C45.9343 19.7302 44.0083 22.1981 44.0083 27.0727V37.7082H36.0534V27.0727C36.0534 22.1981 34.124 19.7302 30.279 19.7302C26.8019 19.7302 25.0651 21.8163 25.0617 25.9069V45.3371H17.0656V25.3172C17.0656 21.2266 18.1191 17.9769 20.2262 15.568C22.3998 13.1648 25.2509 11.9308 28.7898 11.9308C32.8859 11.9308 35.9812 13.492 38.0447 16.6111L40.036 19.9245L42.0308 16.6111C44.0943 13.492 47.1896 11.9308 51.2788 11.9308C54.8143 11.9308 57.6654 13.1648 59.8459 15.568C61.9529 17.9746 63.0065 21.2243 63.0065 25.3172L62.9996 45.3371Z" fill="currentColor"/></symbol><use xlink:href="#logo-symbol-icon" style="color:#fff" /></svg>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="79" height="79" viewBox="0 0 79 75"><symbol id="logo-symbol-icon"><path d="M74.7135 16.6043C73.6199 8.54587 66.5351 2.19527 58.1366 0.964691C56.7196 0.756754 51.351 0 38.9148 0H38.822C26.3824 0 23.7135 0.756754 22.2966 0.964691C14.1319 2.16118 6.67571 7.86752 4.86669 16.0214C3.99657 20.0369 3.90371 24.4888 4.06535 28.5726C4.29578 34.4289 4.34049 40.275 4.877 46.1075C5.24791 49.9817 5.89495 53.8251 6.81328 57.6088C8.53288 64.5968 15.4938 70.4122 22.3138 72.7848C29.6155 75.259 37.468 75.6697 44.9919 73.971C45.8196 73.7801 46.6381 73.5586 47.4475 73.3063C49.2737 72.7302 51.4164 72.086 52.9915 70.9542C53.0131 70.9384 53.0308 70.9178 53.0433 70.8942C53.0558 70.8706 53.0628 70.8445 53.0637 70.8179V65.1661C53.0634 65.1412 53.0574 65.1167 53.0462 65.0944C53.035 65.0721 53.0189 65.0525 52.9992 65.0371C52.9794 65.0218 52.9564 65.011 52.9318 65.0056C52.9073 65.0002 52.8819 65.0003 52.8574 65.0059C48.0369 66.1472 43.0971 66.7193 38.141 66.7103C29.6118 66.7103 27.3178 62.6981 26.6609 61.0278C26.1329 59.5842 25.7976 58.0784 25.6636 56.5486C25.6622 56.5229 25.667 56.4973 25.6775 56.4738C25.688 56.4502 25.7039 56.4295 25.724 56.4132C25.7441 56.397 25.7678 56.3856 25.7931 56.3801C25.8185 56.3746 25.8448 56.3751 25.8699 56.3816C30.6101 57.5151 35.4693 58.0873 40.3455 58.086C41.5183 58.086 42.6876 58.086 43.8604 58.0553C48.7647 57.919 53.9339 57.6701 58.7591 56.7361C58.8794 56.7123 58.9998 56.6918 59.103 56.6611C66.7139 55.2124 73.9569 50.665 74.6929 39.1501C74.7204 38.6967 74.7892 34.4016 74.7892 33.9312C74.7926 32.3325 75.3085 22.5901 74.7135 16.6043ZM62.9996 45.3371H54.9966V25.9069C54.9966 21.8163 53.277 19.7302 49.7793 19.7302C45.9343 19.7302 44.0083 22.1981 44.0083 27.0727V37.7082H36.0534V27.0727C36.0534 22.1981 34.124 19.7302 30.279 19.7302C26.8019 19.7302 25.0651 21.8163 25.0617 25.9069V45.3371H17.0656V25.3172C17.0656 21.2266 18.1191 17.9769 20.2262 15.568C22.3998 13.1648 25.2509 11.9308 28.7898 11.9308C32.8859 11.9308 35.9812 13.492 38.0447 16.6111L40.036 19.9245L42.0308 16.6111C44.0943 13.492 47.1896 11.9308 51.2788 11.9308C54.8143 11.9308 57.6654 13.1648 59.8459 15.568C61.9529 17.9746 63.0065 21.2243 63.0065 25.3172L62.9996 45.3371Z" fill="currentColor"/></symbol><use xlink:href="#logo-symbol-icon"/></svg>
 
diff --git a/app/javascript/images/logo-symbol-wordmark.svg b/app/javascript/images/logo-symbol-wordmark.svg
index 7e7f7b087..ee0b636d9 100644
--- a/app/javascript/images/logo-symbol-wordmark.svg
+++ b/app/javascript/images/logo-symbol-wordmark.svg
@@ -7,5 +7,5 @@
 <stop stop-color="#6364FF"/>
 <stop offset="1" stop-color="#563ACC"/>
 </linearGradient>
-</defs></symbol><use xlink:href="#logo-symbol-wordmark" style="color:#fff"/>
+</defs></symbol><use xlink:href="#logo-symbol-wordmark"/>
 </svg>
diff --git a/app/javascript/mastodon/actions/account_notes.js b/app/javascript/mastodon/actions/account_notes.js
index d17441000..72b943300 100644
--- a/app/javascript/mastodon/actions/account_notes.js
+++ b/app/javascript/mastodon/actions/account_notes.js
@@ -14,24 +14,24 @@ export function submitAccountNote(id, value) {
       dispatch(submitAccountNoteSuccess(response.data));
     }).catch(error => dispatch(submitAccountNoteFail(error)));
   };
-};
+}
 
 export function submitAccountNoteRequest() {
   return {
     type: ACCOUNT_NOTE_SUBMIT_REQUEST,
   };
-};
+}
 
 export function submitAccountNoteSuccess(relationship) {
   return {
     type: ACCOUNT_NOTE_SUBMIT_SUCCESS,
     relationship,
   };
-};
+}
 
 export function submitAccountNoteFail(error) {
   return {
     type: ACCOUNT_NOTE_SUBMIT_FAIL,
     error,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/accounts.js b/app/javascript/mastodon/actions/accounts.js
index f61f06e40..88407ae6c 100644
--- a/app/javascript/mastodon/actions/accounts.js
+++ b/app/javascript/mastodon/actions/accounts.js
@@ -91,7 +91,7 @@ export function fetchAccount(id) {
       dispatch(fetchAccountFail(id, error));
     });
   };
-};
+}
 
 export const lookupAccount = acct => (dispatch, getState) => {
   dispatch(lookupAccountRequest(acct));
@@ -126,13 +126,13 @@ export function fetchAccountRequest(id) {
     type: ACCOUNT_FETCH_REQUEST,
     id,
   };
-};
+}
 
 export function fetchAccountSuccess() {
   return {
     type: ACCOUNT_FETCH_SUCCESS,
   };
-};
+}
 
 export function fetchAccountFail(id, error) {
   return {
@@ -141,7 +141,7 @@ export function fetchAccountFail(id, error) {
     error,
     skipAlert: true,
   };
-};
+}
 
 export function followAccount(id, options = { reblogs: true }) {
   return (dispatch, getState) => {
@@ -156,7 +156,7 @@ export function followAccount(id, options = { reblogs: true }) {
       dispatch(followAccountFail(error, locked));
     });
   };
-};
+}
 
 export function unfollowAccount(id) {
   return (dispatch, getState) => {
@@ -168,7 +168,7 @@ export function unfollowAccount(id) {
       dispatch(unfollowAccountFail(error));
     });
   };
-};
+}
 
 export function followAccountRequest(id, locked) {
   return {
@@ -177,7 +177,7 @@ export function followAccountRequest(id, locked) {
     locked,
     skipLoading: true,
   };
-};
+}
 
 export function followAccountSuccess(relationship, alreadyFollowing) {
   return {
@@ -186,7 +186,7 @@ export function followAccountSuccess(relationship, alreadyFollowing) {
     alreadyFollowing,
     skipLoading: true,
   };
-};
+}
 
 export function followAccountFail(error, locked) {
   return {
@@ -195,7 +195,7 @@ export function followAccountFail(error, locked) {
     locked,
     skipLoading: true,
   };
-};
+}
 
 export function unfollowAccountRequest(id) {
   return {
@@ -203,7 +203,7 @@ export function unfollowAccountRequest(id) {
     id,
     skipLoading: true,
   };
-};
+}
 
 export function unfollowAccountSuccess(relationship, statuses) {
   return {
@@ -212,7 +212,7 @@ export function unfollowAccountSuccess(relationship, statuses) {
     statuses,
     skipLoading: true,
   };
-};
+}
 
 export function unfollowAccountFail(error) {
   return {
@@ -220,7 +220,7 @@ export function unfollowAccountFail(error) {
     error,
     skipLoading: true,
   };
-};
+}
 
 export function blockAccount(id) {
   return (dispatch, getState) => {
@@ -233,7 +233,7 @@ export function blockAccount(id) {
       dispatch(blockAccountFail(id, error));
     });
   };
-};
+}
 
 export function unblockAccount(id) {
   return (dispatch, getState) => {
@@ -245,14 +245,14 @@ export function unblockAccount(id) {
       dispatch(unblockAccountFail(id, error));
     });
   };
-};
+}
 
 export function blockAccountRequest(id) {
   return {
     type: ACCOUNT_BLOCK_REQUEST,
     id,
   };
-};
+}
 
 export function blockAccountSuccess(relationship, statuses) {
   return {
@@ -260,35 +260,35 @@ export function blockAccountSuccess(relationship, statuses) {
     relationship,
     statuses,
   };
-};
+}
 
 export function blockAccountFail(error) {
   return {
     type: ACCOUNT_BLOCK_FAIL,
     error,
   };
-};
+}
 
 export function unblockAccountRequest(id) {
   return {
     type: ACCOUNT_UNBLOCK_REQUEST,
     id,
   };
-};
+}
 
 export function unblockAccountSuccess(relationship) {
   return {
     type: ACCOUNT_UNBLOCK_SUCCESS,
     relationship,
   };
-};
+}
 
 export function unblockAccountFail(error) {
   return {
     type: ACCOUNT_UNBLOCK_FAIL,
     error,
   };
-};
+}
 
 
 export function muteAccount(id, notifications, duration=0) {
@@ -302,7 +302,7 @@ export function muteAccount(id, notifications, duration=0) {
       dispatch(muteAccountFail(id, error));
     });
   };
-};
+}
 
 export function unmuteAccount(id) {
   return (dispatch, getState) => {
@@ -314,14 +314,14 @@ export function unmuteAccount(id) {
       dispatch(unmuteAccountFail(id, error));
     });
   };
-};
+}
 
 export function muteAccountRequest(id) {
   return {
     type: ACCOUNT_MUTE_REQUEST,
     id,
   };
-};
+}
 
 export function muteAccountSuccess(relationship, statuses) {
   return {
@@ -329,35 +329,35 @@ export function muteAccountSuccess(relationship, statuses) {
     relationship,
     statuses,
   };
-};
+}
 
 export function muteAccountFail(error) {
   return {
     type: ACCOUNT_MUTE_FAIL,
     error,
   };
-};
+}
 
 export function unmuteAccountRequest(id) {
   return {
     type: ACCOUNT_UNMUTE_REQUEST,
     id,
   };
-};
+}
 
 export function unmuteAccountSuccess(relationship) {
   return {
     type: ACCOUNT_UNMUTE_SUCCESS,
     relationship,
   };
-};
+}
 
 export function unmuteAccountFail(error) {
   return {
     type: ACCOUNT_UNMUTE_FAIL,
     error,
   };
-};
+}
 
 
 export function fetchFollowers(id) {
@@ -374,14 +374,14 @@ export function fetchFollowers(id) {
       dispatch(fetchFollowersFail(id, error));
     });
   };
-};
+}
 
 export function fetchFollowersRequest(id) {
   return {
     type: FOLLOWERS_FETCH_REQUEST,
     id,
   };
-};
+}
 
 export function fetchFollowersSuccess(id, accounts, next) {
   return {
@@ -390,7 +390,7 @@ export function fetchFollowersSuccess(id, accounts, next) {
     accounts,
     next,
   };
-};
+}
 
 export function fetchFollowersFail(id, error) {
   return {
@@ -399,7 +399,7 @@ export function fetchFollowersFail(id, error) {
     error,
     skipNotFound: true,
   };
-};
+}
 
 export function expandFollowers(id) {
   return (dispatch, getState) => {
@@ -421,14 +421,14 @@ export function expandFollowers(id) {
       dispatch(expandFollowersFail(id, error));
     });
   };
-};
+}
 
 export function expandFollowersRequest(id) {
   return {
     type: FOLLOWERS_EXPAND_REQUEST,
     id,
   };
-};
+}
 
 export function expandFollowersSuccess(id, accounts, next) {
   return {
@@ -437,7 +437,7 @@ export function expandFollowersSuccess(id, accounts, next) {
     accounts,
     next,
   };
-};
+}
 
 export function expandFollowersFail(id, error) {
   return {
@@ -445,7 +445,7 @@ export function expandFollowersFail(id, error) {
     id,
     error,
   };
-};
+}
 
 export function fetchFollowing(id) {
   return (dispatch, getState) => {
@@ -461,14 +461,14 @@ export function fetchFollowing(id) {
       dispatch(fetchFollowingFail(id, error));
     });
   };
-};
+}
 
 export function fetchFollowingRequest(id) {
   return {
     type: FOLLOWING_FETCH_REQUEST,
     id,
   };
-};
+}
 
 export function fetchFollowingSuccess(id, accounts, next) {
   return {
@@ -477,7 +477,7 @@ export function fetchFollowingSuccess(id, accounts, next) {
     accounts,
     next,
   };
-};
+}
 
 export function fetchFollowingFail(id, error) {
   return {
@@ -486,7 +486,7 @@ export function fetchFollowingFail(id, error) {
     error,
     skipNotFound: true,
   };
-};
+}
 
 export function expandFollowing(id) {
   return (dispatch, getState) => {
@@ -508,14 +508,14 @@ export function expandFollowing(id) {
       dispatch(expandFollowingFail(id, error));
     });
   };
-};
+}
 
 export function expandFollowingRequest(id) {
   return {
     type: FOLLOWING_EXPAND_REQUEST,
     id,
   };
-};
+}
 
 export function expandFollowingSuccess(id, accounts, next) {
   return {
@@ -524,7 +524,7 @@ export function expandFollowingSuccess(id, accounts, next) {
     accounts,
     next,
   };
-};
+}
 
 export function expandFollowingFail(id, error) {
   return {
@@ -532,7 +532,7 @@ export function expandFollowingFail(id, error) {
     id,
     error,
   };
-};
+}
 
 export function fetchRelationships(accountIds) {
   return (dispatch, getState) => {
@@ -553,7 +553,7 @@ export function fetchRelationships(accountIds) {
       dispatch(fetchRelationshipsFail(error));
     });
   };
-};
+}
 
 export function fetchRelationshipsRequest(ids) {
   return {
@@ -561,7 +561,7 @@ export function fetchRelationshipsRequest(ids) {
     ids,
     skipLoading: true,
   };
-};
+}
 
 export function fetchRelationshipsSuccess(relationships) {
   return {
@@ -569,7 +569,7 @@ export function fetchRelationshipsSuccess(relationships) {
     relationships,
     skipLoading: true,
   };
-};
+}
 
 export function fetchRelationshipsFail(error) {
   return {
@@ -578,7 +578,7 @@ export function fetchRelationshipsFail(error) {
     skipLoading: true,
     skipNotFound: true,
   };
-};
+}
 
 export function fetchFollowRequests() {
   return (dispatch, getState) => {
@@ -590,13 +590,13 @@ export function fetchFollowRequests() {
       dispatch(fetchFollowRequestsSuccess(response.data, next ? next.uri : null));
     }).catch(error => dispatch(fetchFollowRequestsFail(error)));
   };
-};
+}
 
 export function fetchFollowRequestsRequest() {
   return {
     type: FOLLOW_REQUESTS_FETCH_REQUEST,
   };
-};
+}
 
 export function fetchFollowRequestsSuccess(accounts, next) {
   return {
@@ -604,14 +604,14 @@ export function fetchFollowRequestsSuccess(accounts, next) {
     accounts,
     next,
   };
-};
+}
 
 export function fetchFollowRequestsFail(error) {
   return {
     type: FOLLOW_REQUESTS_FETCH_FAIL,
     error,
   };
-};
+}
 
 export function expandFollowRequests() {
   return (dispatch, getState) => {
@@ -629,13 +629,13 @@ export function expandFollowRequests() {
       dispatch(expandFollowRequestsSuccess(response.data, next ? next.uri : null));
     }).catch(error => dispatch(expandFollowRequestsFail(error)));
   };
-};
+}
 
 export function expandFollowRequestsRequest() {
   return {
     type: FOLLOW_REQUESTS_EXPAND_REQUEST,
   };
-};
+}
 
 export function expandFollowRequestsSuccess(accounts, next) {
   return {
@@ -643,14 +643,14 @@ export function expandFollowRequestsSuccess(accounts, next) {
     accounts,
     next,
   };
-};
+}
 
 export function expandFollowRequestsFail(error) {
   return {
     type: FOLLOW_REQUESTS_EXPAND_FAIL,
     error,
   };
-};
+}
 
 export function authorizeFollowRequest(id) {
   return (dispatch, getState) => {
@@ -661,21 +661,21 @@ export function authorizeFollowRequest(id) {
       .then(() => dispatch(authorizeFollowRequestSuccess(id)))
       .catch(error => dispatch(authorizeFollowRequestFail(id, error)));
   };
-};
+}
 
 export function authorizeFollowRequestRequest(id) {
   return {
     type: FOLLOW_REQUEST_AUTHORIZE_REQUEST,
     id,
   };
-};
+}
 
 export function authorizeFollowRequestSuccess(id) {
   return {
     type: FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
     id,
   };
-};
+}
 
 export function authorizeFollowRequestFail(id, error) {
   return {
@@ -683,7 +683,7 @@ export function authorizeFollowRequestFail(id, error) {
     id,
     error,
   };
-};
+}
 
 
 export function rejectFollowRequest(id) {
@@ -695,21 +695,21 @@ export function rejectFollowRequest(id) {
       .then(() => dispatch(rejectFollowRequestSuccess(id)))
       .catch(error => dispatch(rejectFollowRequestFail(id, error)));
   };
-};
+}
 
 export function rejectFollowRequestRequest(id) {
   return {
     type: FOLLOW_REQUEST_REJECT_REQUEST,
     id,
   };
-};
+}
 
 export function rejectFollowRequestSuccess(id) {
   return {
     type: FOLLOW_REQUEST_REJECT_SUCCESS,
     id,
   };
-};
+}
 
 export function rejectFollowRequestFail(id, error) {
   return {
@@ -717,7 +717,7 @@ export function rejectFollowRequestFail(id, error) {
     id,
     error,
   };
-};
+}
 
 export function pinAccount(id) {
   return (dispatch, getState) => {
@@ -729,7 +729,7 @@ export function pinAccount(id) {
       dispatch(pinAccountFail(error));
     });
   };
-};
+}
 
 export function unpinAccount(id) {
   return (dispatch, getState) => {
@@ -741,49 +741,49 @@ export function unpinAccount(id) {
       dispatch(unpinAccountFail(error));
     });
   };
-};
+}
 
 export function pinAccountRequest(id) {
   return {
     type: ACCOUNT_PIN_REQUEST,
     id,
   };
-};
+}
 
 export function pinAccountSuccess(relationship) {
   return {
     type: ACCOUNT_PIN_SUCCESS,
     relationship,
   };
-};
+}
 
 export function pinAccountFail(error) {
   return {
     type: ACCOUNT_PIN_FAIL,
     error,
   };
-};
+}
 
 export function unpinAccountRequest(id) {
   return {
     type: ACCOUNT_UNPIN_REQUEST,
     id,
   };
-};
+}
 
 export function unpinAccountSuccess(relationship) {
   return {
     type: ACCOUNT_UNPIN_SUCCESS,
     relationship,
   };
-};
+}
 
 export function unpinAccountFail(error) {
   return {
     type: ACCOUNT_UNPIN_FAIL,
     error,
   };
-};
+}
 
 export const revealAccount = id => ({
   type: ACCOUNT_REVEAL,
diff --git a/app/javascript/mastodon/actions/alerts.js b/app/javascript/mastodon/actions/alerts.js
index 1670f9c10..0220b0af5 100644
--- a/app/javascript/mastodon/actions/alerts.js
+++ b/app/javascript/mastodon/actions/alerts.js
@@ -17,13 +17,13 @@ export function dismissAlert(alert) {
     type: ALERT_DISMISS,
     alert,
   };
-};
+}
 
 export function clearAlert() {
   return {
     type: ALERT_CLEAR,
   };
-};
+}
 
 export function showAlert(title = messages.unexpectedTitle, message = messages.unexpectedMessage, message_values = undefined) {
   return {
@@ -32,7 +32,7 @@ export function showAlert(title = messages.unexpectedTitle, message = messages.u
     message,
     message_values,
   };
-};
+}
 
 export function showAlertForError(error, skipNotFound = false) {
   if (error.response) {
diff --git a/app/javascript/mastodon/actions/announcements.js b/app/javascript/mastodon/actions/announcements.js
index 1bdea909f..586dcfd33 100644
--- a/app/javascript/mastodon/actions/announcements.js
+++ b/app/javascript/mastodon/actions/announcements.js
@@ -102,7 +102,7 @@ export const addReaction = (announcementId, name) => (dispatch, getState) => {
     dispatch(addReactionRequest(announcementId, name, alreadyAdded));
   }
 
-  api(getState).put(`/api/v1/announcements/${announcementId}/reactions/${name}`).then(() => {
+  api(getState).put(`/api/v1/announcements/${announcementId}/reactions/${encodeURIComponent(name)}`).then(() => {
     dispatch(addReactionSuccess(announcementId, name, alreadyAdded));
   }).catch(err => {
     if (!alreadyAdded) {
@@ -136,7 +136,7 @@ export const addReactionFail = (announcementId, name, error) => ({
 export const removeReaction = (announcementId, name) => (dispatch, getState) => {
   dispatch(removeReactionRequest(announcementId, name));
 
-  api(getState).delete(`/api/v1/announcements/${announcementId}/reactions/${name}`).then(() => {
+  api(getState).delete(`/api/v1/announcements/${announcementId}/reactions/${encodeURIComponent(name)}`).then(() => {
     dispatch(removeReactionSuccess(announcementId, name));
   }).catch(err => {
     dispatch(removeReactionFail(announcementId, name, err));
diff --git a/app/javascript/mastodon/actions/blocks.js b/app/javascript/mastodon/actions/blocks.js
index fd9881302..192aa3ce4 100644
--- a/app/javascript/mastodon/actions/blocks.js
+++ b/app/javascript/mastodon/actions/blocks.js
@@ -24,13 +24,13 @@ export function fetchBlocks() {
       dispatch(fetchRelationships(response.data.map(item => item.id)));
     }).catch(error => dispatch(fetchBlocksFail(error)));
   };
-};
+}
 
 export function fetchBlocksRequest() {
   return {
     type: BLOCKS_FETCH_REQUEST,
   };
-};
+}
 
 export function fetchBlocksSuccess(accounts, next) {
   return {
@@ -38,14 +38,14 @@ export function fetchBlocksSuccess(accounts, next) {
     accounts,
     next,
   };
-};
+}
 
 export function fetchBlocksFail(error) {
   return {
     type: BLOCKS_FETCH_FAIL,
     error,
   };
-};
+}
 
 export function expandBlocks() {
   return (dispatch, getState) => {
@@ -64,13 +64,13 @@ export function expandBlocks() {
       dispatch(fetchRelationships(response.data.map(item => item.id)));
     }).catch(error => dispatch(expandBlocksFail(error)));
   };
-};
+}
 
 export function expandBlocksRequest() {
   return {
     type: BLOCKS_EXPAND_REQUEST,
   };
-};
+}
 
 export function expandBlocksSuccess(accounts, next) {
   return {
@@ -78,14 +78,14 @@ export function expandBlocksSuccess(accounts, next) {
     accounts,
     next,
   };
-};
+}
 
 export function expandBlocksFail(error) {
   return {
     type: BLOCKS_EXPAND_FAIL,
     error,
   };
-};
+}
 
 export function initBlockModal(account) {
   return dispatch => {
diff --git a/app/javascript/mastodon/actions/bookmarks.js b/app/javascript/mastodon/actions/bookmarks.js
index 544ed2ff2..3c8eec546 100644
--- a/app/javascript/mastodon/actions/bookmarks.js
+++ b/app/javascript/mastodon/actions/bookmarks.js
@@ -25,13 +25,13 @@ export function fetchBookmarkedStatuses() {
       dispatch(fetchBookmarkedStatusesFail(error));
     });
   };
-};
+}
 
 export function fetchBookmarkedStatusesRequest() {
   return {
     type: BOOKMARKED_STATUSES_FETCH_REQUEST,
   };
-};
+}
 
 export function fetchBookmarkedStatusesSuccess(statuses, next) {
   return {
@@ -39,14 +39,14 @@ export function fetchBookmarkedStatusesSuccess(statuses, next) {
     statuses,
     next,
   };
-};
+}
 
 export function fetchBookmarkedStatusesFail(error) {
   return {
     type: BOOKMARKED_STATUSES_FETCH_FAIL,
     error,
   };
-};
+}
 
 export function expandBookmarkedStatuses() {
   return (dispatch, getState) => {
@@ -66,13 +66,13 @@ export function expandBookmarkedStatuses() {
       dispatch(expandBookmarkedStatusesFail(error));
     });
   };
-};
+}
 
 export function expandBookmarkedStatusesRequest() {
   return {
     type: BOOKMARKED_STATUSES_EXPAND_REQUEST,
   };
-};
+}
 
 export function expandBookmarkedStatusesSuccess(statuses, next) {
   return {
@@ -80,11 +80,11 @@ export function expandBookmarkedStatusesSuccess(statuses, next) {
     statuses,
     next,
   };
-};
+}
 
 export function expandBookmarkedStatusesFail(error) {
   return {
     type: BOOKMARKED_STATUSES_EXPAND_FAIL,
     error,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/columns.js b/app/javascript/mastodon/actions/columns.js
index 9b87415fb..302c3f0f9 100644
--- a/app/javascript/mastodon/actions/columns.js
+++ b/app/javascript/mastodon/actions/columns.js
@@ -15,7 +15,7 @@ export function addColumn(id, params) {
 
     dispatch(saveSettings());
   };
-};
+}
 
 export function removeColumn(uuid) {
   return dispatch => {
@@ -26,7 +26,7 @@ export function removeColumn(uuid) {
 
     dispatch(saveSettings());
   };
-};
+}
 
 export function moveColumn(uuid, direction) {
   return dispatch => {
@@ -38,7 +38,7 @@ export function moveColumn(uuid, direction) {
 
     dispatch(saveSettings());
   };
-};
+}
 
 export function changeColumnParams(uuid, path, value) {
   return dispatch => {
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index 26d389648..12d25490b 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -94,14 +94,14 @@ export function setComposeToStatus(status, text, spoiler_text) {
     text,
     spoiler_text,
   };
-};
+}
 
 export function changeCompose(text) {
   return {
     type: COMPOSE_CHANGE,
     text: text,
   };
-};
+}
 
 export function replyCompose(status, routerHistory) {
   return (dispatch, getState) => {
@@ -112,19 +112,19 @@ export function replyCompose(status, routerHistory) {
 
     ensureComposeIsVisible(getState, routerHistory);
   };
-};
+}
 
 export function cancelReplyCompose() {
   return {
     type: COMPOSE_REPLY_CANCEL,
   };
-};
+}
 
 export function resetCompose() {
   return {
     type: COMPOSE_RESET,
   };
-};
+}
 
 export function mentionCompose(account, routerHistory) {
   return (dispatch, getState) => {
@@ -135,7 +135,7 @@ export function mentionCompose(account, routerHistory) {
 
     ensureComposeIsVisible(getState, routerHistory);
   };
-};
+}
 
 export function directCompose(account, routerHistory) {
   return (dispatch, getState) => {
@@ -146,7 +146,7 @@ export function directCompose(account, routerHistory) {
 
     ensureComposeIsVisible(getState, routerHistory);
   };
-};
+}
 
 export function submitCompose(routerHistory) {
   return function (dispatch, getState) {
@@ -213,27 +213,27 @@ export function submitCompose(routerHistory) {
       dispatch(submitComposeFail(error));
     });
   };
-};
+}
 
 export function submitComposeRequest() {
   return {
     type: COMPOSE_SUBMIT_REQUEST,
   };
-};
+}
 
 export function submitComposeSuccess(status) {
   return {
     type: COMPOSE_SUBMIT_SUCCESS,
     status: status,
   };
-};
+}
 
 export function submitComposeFail(error) {
   return {
     type: COMPOSE_SUBMIT_FAIL,
     error: error,
   };
-};
+}
 
 export function uploadCompose(files) {
   return function (dispatch, getState) {
@@ -296,9 +296,9 @@ export function uploadCompose(files) {
           }
         });
       }).catch(error => dispatch(uploadComposeFail(error)));
-    };
+    }
   };
-};
+}
 
 export const uploadComposeProcessing = () => ({
   type: COMPOSE_UPLOAD_PROCESSING,
@@ -356,14 +356,14 @@ export function initMediaEditModal(id) {
 
     dispatch(openModal('FOCAL_POINT', { id }));
   };
-};
+}
 
 export function onChangeMediaDescription(description) {
   return {
     type: COMPOSE_CHANGE_MEDIA_DESCRIPTION,
     description,
   };
-};
+}
 
 export function onChangeMediaFocus(focusX, focusY) {
   return {
@@ -371,7 +371,7 @@ export function onChangeMediaFocus(focusX, focusY) {
     focusX,
     focusY,
   };
-};
+}
 
 export function changeUploadCompose(id, params) {
   return (dispatch, getState) => {
@@ -383,14 +383,14 @@ export function changeUploadCompose(id, params) {
       dispatch(changeUploadComposeFail(id, error));
     });
   };
-};
+}
 
 export function changeUploadComposeRequest() {
   return {
     type: COMPOSE_UPLOAD_CHANGE_REQUEST,
     skipLoading: true,
   };
-};
+}
 
 export function changeUploadComposeSuccess(media) {
   return {
@@ -398,7 +398,7 @@ export function changeUploadComposeSuccess(media) {
     media: media,
     skipLoading: true,
   };
-};
+}
 
 export function changeUploadComposeFail(error) {
   return {
@@ -406,14 +406,14 @@ export function changeUploadComposeFail(error) {
     error: error,
     skipLoading: true,
   };
-};
+}
 
 export function uploadComposeRequest() {
   return {
     type: COMPOSE_UPLOAD_REQUEST,
     skipLoading: true,
   };
-};
+}
 
 export function uploadComposeProgress(loaded, total) {
   return {
@@ -421,7 +421,7 @@ export function uploadComposeProgress(loaded, total) {
     loaded: loaded,
     total: total,
   };
-};
+}
 
 export function uploadComposeSuccess(media, file) {
   return {
@@ -430,7 +430,7 @@ export function uploadComposeSuccess(media, file) {
     file: file,
     skipLoading: true,
   };
-};
+}
 
 export function uploadComposeFail(error) {
   return {
@@ -438,14 +438,14 @@ export function uploadComposeFail(error) {
     error: error,
     skipLoading: true,
   };
-};
+}
 
 export function undoUploadCompose(media_id) {
   return {
     type: COMPOSE_UPLOAD_UNDO,
     media_id: media_id,
   };
-};
+}
 
 export function clearComposeSuggestions() {
   if (fetchComposeSuggestionsAccountsController) {
@@ -454,7 +454,7 @@ export function clearComposeSuggestions() {
   return {
     type: COMPOSE_SUGGESTIONS_CLEAR,
   };
-};
+}
 
 const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) => {
   if (fetchComposeSuggestionsAccountsController) {
@@ -532,7 +532,7 @@ export function fetchComposeSuggestions(token) {
       break;
     }
   };
-};
+}
 
 export function readyComposeSuggestionsEmojis(token, emojis) {
   return {
@@ -540,7 +540,7 @@ export function readyComposeSuggestionsEmojis(token, emojis) {
     token,
     emojis,
   };
-};
+}
 
 export function readyComposeSuggestionsAccounts(token, accounts) {
   return {
@@ -548,7 +548,7 @@ export function readyComposeSuggestionsAccounts(token, accounts) {
     token,
     accounts,
   };
-};
+}
 
 export const readyComposeSuggestionsTags = (token, tags) => ({
   type: COMPOSE_SUGGESTIONS_READY,
@@ -593,7 +593,7 @@ export function selectComposeSuggestion(position, token, suggestion, path) {
       });
     }
   };
-};
+}
 
 export function updateSuggestionTags(token) {
   return {
@@ -654,19 +654,19 @@ export function mountCompose() {
   return {
     type: COMPOSE_MOUNT,
   };
-};
+}
 
 export function unmountCompose() {
   return {
     type: COMPOSE_UNMOUNT,
   };
-};
+}
 
 export function changeComposeSensitivity() {
   return {
     type: COMPOSE_SENSITIVITY_CHANGE,
   };
-};
+}
 
 export const changeComposeLanguage = language => ({
   type: COMPOSE_LANGUAGE_CHANGE,
@@ -677,21 +677,21 @@ export function changeComposeSpoilerness() {
   return {
     type: COMPOSE_SPOILERNESS_CHANGE,
   };
-};
+}
 
 export function changeComposeSpoilerText(text) {
   return {
     type: COMPOSE_SPOILER_TEXT_CHANGE,
     text,
   };
-};
+}
 
 export function changeComposeVisibility(value) {
   return {
     type: COMPOSE_VISIBILITY_CHANGE,
     value,
   };
-};
+}
 
 export function insertEmojiCompose(position, emoji, needsSpace) {
   return {
@@ -700,33 +700,33 @@ export function insertEmojiCompose(position, emoji, needsSpace) {
     emoji,
     needsSpace,
   };
-};
+}
 
 export function changeComposing(value) {
   return {
     type: COMPOSE_COMPOSING_CHANGE,
     value,
   };
-};
+}
 
 export function addPoll() {
   return {
     type: COMPOSE_POLL_ADD,
   };
-};
+}
 
 export function removePoll() {
   return {
     type: COMPOSE_POLL_REMOVE,
   };
-};
+}
 
 export function addPollOption(title) {
   return {
     type: COMPOSE_POLL_OPTION_ADD,
     title,
   };
-};
+}
 
 export function changePollOption(index, title) {
   return {
@@ -734,14 +734,14 @@ export function changePollOption(index, title) {
     index,
     title,
   };
-};
+}
 
 export function removePollOption(index) {
   return {
     type: COMPOSE_POLL_OPTION_REMOVE,
     index,
   };
-};
+}
 
 export function changePollSettings(expiresIn, isMultiple) {
   return {
@@ -749,4 +749,4 @@ export function changePollSettings(expiresIn, isMultiple) {
     expiresIn,
     isMultiple,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/custom_emojis.js b/app/javascript/mastodon/actions/custom_emojis.js
index 7b7d0091b..9ec8156b1 100644
--- a/app/javascript/mastodon/actions/custom_emojis.js
+++ b/app/javascript/mastodon/actions/custom_emojis.js
@@ -14,14 +14,14 @@ export function fetchCustomEmojis() {
       dispatch(fetchCustomEmojisFail(error));
     });
   };
-};
+}
 
 export function fetchCustomEmojisRequest() {
   return {
     type: CUSTOM_EMOJIS_FETCH_REQUEST,
     skipLoading: true,
   };
-};
+}
 
 export function fetchCustomEmojisSuccess(custom_emojis) {
   return {
@@ -29,7 +29,7 @@ export function fetchCustomEmojisSuccess(custom_emojis) {
     custom_emojis,
     skipLoading: true,
   };
-};
+}
 
 export function fetchCustomEmojisFail(error) {
   return {
@@ -37,4 +37,4 @@ export function fetchCustomEmojisFail(error) {
     error,
     skipLoading: true,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/domain_blocks.js b/app/javascript/mastodon/actions/domain_blocks.js
index 34a33a654..d06de20a2 100644
--- a/app/javascript/mastodon/actions/domain_blocks.js
+++ b/app/javascript/mastodon/actions/domain_blocks.js
@@ -29,14 +29,14 @@ export function blockDomain(domain) {
       dispatch(blockDomainFail(domain, err));
     });
   };
-};
+}
 
 export function blockDomainRequest(domain) {
   return {
     type: DOMAIN_BLOCK_REQUEST,
     domain,
   };
-};
+}
 
 export function blockDomainSuccess(domain, accounts) {
   return {
@@ -44,7 +44,7 @@ export function blockDomainSuccess(domain, accounts) {
     domain,
     accounts,
   };
-};
+}
 
 export function blockDomainFail(domain, error) {
   return {
@@ -52,7 +52,7 @@ export function blockDomainFail(domain, error) {
     domain,
     error,
   };
-};
+}
 
 export function unblockDomain(domain) {
   return (dispatch, getState) => {
@@ -66,14 +66,14 @@ export function unblockDomain(domain) {
       dispatch(unblockDomainFail(domain, err));
     });
   };
-};
+}
 
 export function unblockDomainRequest(domain) {
   return {
     type: DOMAIN_UNBLOCK_REQUEST,
     domain,
   };
-};
+}
 
 export function unblockDomainSuccess(domain, accounts) {
   return {
@@ -81,7 +81,7 @@ export function unblockDomainSuccess(domain, accounts) {
     domain,
     accounts,
   };
-};
+}
 
 export function unblockDomainFail(domain, error) {
   return {
@@ -89,7 +89,7 @@ export function unblockDomainFail(domain, error) {
     domain,
     error,
   };
-};
+}
 
 export function fetchDomainBlocks() {
   return (dispatch, getState) => {
@@ -102,13 +102,13 @@ export function fetchDomainBlocks() {
       dispatch(fetchDomainBlocksFail(err));
     });
   };
-};
+}
 
 export function fetchDomainBlocksRequest() {
   return {
     type: DOMAIN_BLOCKS_FETCH_REQUEST,
   };
-};
+}
 
 export function fetchDomainBlocksSuccess(domains, next) {
   return {
@@ -116,14 +116,14 @@ export function fetchDomainBlocksSuccess(domains, next) {
     domains,
     next,
   };
-};
+}
 
 export function fetchDomainBlocksFail(error) {
   return {
     type: DOMAIN_BLOCKS_FETCH_FAIL,
     error,
   };
-};
+}
 
 export function expandDomainBlocks() {
   return (dispatch, getState) => {
@@ -142,13 +142,13 @@ export function expandDomainBlocks() {
       dispatch(expandDomainBlocksFail(err));
     });
   };
-};
+}
 
 export function expandDomainBlocksRequest() {
   return {
     type: DOMAIN_BLOCKS_EXPAND_REQUEST,
   };
-};
+}
 
 export function expandDomainBlocksSuccess(domains, next) {
   return {
@@ -156,11 +156,11 @@ export function expandDomainBlocksSuccess(domains, next) {
     domains,
     next,
   };
-};
+}
 
 export function expandDomainBlocksFail(error) {
   return {
     type: DOMAIN_BLOCKS_EXPAND_FAIL,
     error,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/dropdown_menu.js b/app/javascript/mastodon/actions/dropdown_menu.js
index fb6e55612..023151d4b 100644
--- a/app/javascript/mastodon/actions/dropdown_menu.js
+++ b/app/javascript/mastodon/actions/dropdown_menu.js
@@ -1,8 +1,8 @@
 export const DROPDOWN_MENU_OPEN = 'DROPDOWN_MENU_OPEN';
 export const DROPDOWN_MENU_CLOSE = 'DROPDOWN_MENU_CLOSE';
 
-export function openDropdownMenu(id, placement, keyboard, scroll_key) {
-  return { type: DROPDOWN_MENU_OPEN, id, placement, keyboard, scroll_key };
+export function openDropdownMenu(id, keyboard, scroll_key) {
+  return { type: DROPDOWN_MENU_OPEN, id, keyboard, scroll_key };
 }
 
 export function closeDropdownMenu(id) {
diff --git a/app/javascript/mastodon/actions/emojis.js b/app/javascript/mastodon/actions/emojis.js
index 7cd9d4b7b..3b5d53996 100644
--- a/app/javascript/mastodon/actions/emojis.js
+++ b/app/javascript/mastodon/actions/emojis.js
@@ -11,4 +11,4 @@ export function useEmoji(emoji) {
 
     dispatch(saveSettings());
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/favourites.js b/app/javascript/mastodon/actions/favourites.js
index 9448b1efe..7388e0c58 100644
--- a/app/javascript/mastodon/actions/favourites.js
+++ b/app/javascript/mastodon/actions/favourites.js
@@ -25,14 +25,14 @@ export function fetchFavouritedStatuses() {
       dispatch(fetchFavouritedStatusesFail(error));
     });
   };
-};
+}
 
 export function fetchFavouritedStatusesRequest() {
   return {
     type: FAVOURITED_STATUSES_FETCH_REQUEST,
     skipLoading: true,
   };
-};
+}
 
 export function fetchFavouritedStatusesSuccess(statuses, next) {
   return {
@@ -41,7 +41,7 @@ export function fetchFavouritedStatusesSuccess(statuses, next) {
     next,
     skipLoading: true,
   };
-};
+}
 
 export function fetchFavouritedStatusesFail(error) {
   return {
@@ -49,7 +49,7 @@ export function fetchFavouritedStatusesFail(error) {
     error,
     skipLoading: true,
   };
-};
+}
 
 export function expandFavouritedStatuses() {
   return (dispatch, getState) => {
@@ -69,13 +69,13 @@ export function expandFavouritedStatuses() {
       dispatch(expandFavouritedStatusesFail(error));
     });
   };
-};
+}
 
 export function expandFavouritedStatusesRequest() {
   return {
     type: FAVOURITED_STATUSES_EXPAND_REQUEST,
   };
-};
+}
 
 export function expandFavouritedStatusesSuccess(statuses, next) {
   return {
@@ -83,11 +83,11 @@ export function expandFavouritedStatusesSuccess(statuses, next) {
     statuses,
     next,
   };
-};
+}
 
 export function expandFavouritedStatusesFail(error) {
   return {
     type: FAVOURITED_STATUSES_EXPAND_FAIL,
     error,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/height_cache.js b/app/javascript/mastodon/actions/height_cache.js
index 4c752993f..a8645410c 100644
--- a/app/javascript/mastodon/actions/height_cache.js
+++ b/app/javascript/mastodon/actions/height_cache.js
@@ -8,10 +8,10 @@ export function setHeight (key, id, height) {
     id,
     height,
   };
-};
+}
 
 export function clearHeight () {
   return {
     type: HEIGHT_CACHE_CLEAR,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/interactions.js b/app/javascript/mastodon/actions/interactions.js
index d60ccc1fb..bc35736ff 100644
--- a/app/javascript/mastodon/actions/interactions.js
+++ b/app/javascript/mastodon/actions/interactions.js
@@ -54,7 +54,7 @@ export function reblog(status, visibility) {
       dispatch(reblogFail(status, error));
     });
   };
-};
+}
 
 export function unreblog(status) {
   return (dispatch, getState) => {
@@ -67,7 +67,7 @@ export function unreblog(status) {
       dispatch(unreblogFail(status, error));
     });
   };
-};
+}
 
 export function reblogRequest(status) {
   return {
@@ -75,7 +75,7 @@ export function reblogRequest(status) {
     status: status,
     skipLoading: true,
   };
-};
+}
 
 export function reblogSuccess(status) {
   return {
@@ -83,7 +83,7 @@ export function reblogSuccess(status) {
     status: status,
     skipLoading: true,
   };
-};
+}
 
 export function reblogFail(status, error) {
   return {
@@ -92,7 +92,7 @@ export function reblogFail(status, error) {
     error: error,
     skipLoading: true,
   };
-};
+}
 
 export function unreblogRequest(status) {
   return {
@@ -100,7 +100,7 @@ export function unreblogRequest(status) {
     status: status,
     skipLoading: true,
   };
-};
+}
 
 export function unreblogSuccess(status) {
   return {
@@ -108,7 +108,7 @@ export function unreblogSuccess(status) {
     status: status,
     skipLoading: true,
   };
-};
+}
 
 export function unreblogFail(status, error) {
   return {
@@ -117,7 +117,7 @@ export function unreblogFail(status, error) {
     error: error,
     skipLoading: true,
   };
-};
+}
 
 export function favourite(status) {
   return function (dispatch, getState) {
@@ -130,7 +130,7 @@ export function favourite(status) {
       dispatch(favouriteFail(status, error));
     });
   };
-};
+}
 
 export function unfavourite(status) {
   return (dispatch, getState) => {
@@ -143,7 +143,7 @@ export function unfavourite(status) {
       dispatch(unfavouriteFail(status, error));
     });
   };
-};
+}
 
 export function favouriteRequest(status) {
   return {
@@ -151,7 +151,7 @@ export function favouriteRequest(status) {
     status: status,
     skipLoading: true,
   };
-};
+}
 
 export function favouriteSuccess(status) {
   return {
@@ -159,7 +159,7 @@ export function favouriteSuccess(status) {
     status: status,
     skipLoading: true,
   };
-};
+}
 
 export function favouriteFail(status, error) {
   return {
@@ -168,7 +168,7 @@ export function favouriteFail(status, error) {
     error: error,
     skipLoading: true,
   };
-};
+}
 
 export function unfavouriteRequest(status) {
   return {
@@ -176,7 +176,7 @@ export function unfavouriteRequest(status) {
     status: status,
     skipLoading: true,
   };
-};
+}
 
 export function unfavouriteSuccess(status) {
   return {
@@ -184,7 +184,7 @@ export function unfavouriteSuccess(status) {
     status: status,
     skipLoading: true,
   };
-};
+}
 
 export function unfavouriteFail(status, error) {
   return {
@@ -193,7 +193,7 @@ export function unfavouriteFail(status, error) {
     error: error,
     skipLoading: true,
   };
-};
+}
 
 export function bookmark(status) {
   return function (dispatch, getState) {
@@ -206,7 +206,7 @@ export function bookmark(status) {
       dispatch(bookmarkFail(status, error));
     });
   };
-};
+}
 
 export function unbookmark(status) {
   return (dispatch, getState) => {
@@ -219,14 +219,14 @@ export function unbookmark(status) {
       dispatch(unbookmarkFail(status, error));
     });
   };
-};
+}
 
 export function bookmarkRequest(status) {
   return {
     type: BOOKMARK_REQUEST,
     status: status,
   };
-};
+}
 
 export function bookmarkSuccess(status, response) {
   return {
@@ -234,7 +234,7 @@ export function bookmarkSuccess(status, response) {
     status: status,
     response: response,
   };
-};
+}
 
 export function bookmarkFail(status, error) {
   return {
@@ -242,14 +242,14 @@ export function bookmarkFail(status, error) {
     status: status,
     error: error,
   };
-};
+}
 
 export function unbookmarkRequest(status) {
   return {
     type: UNBOOKMARK_REQUEST,
     status: status,
   };
-};
+}
 
 export function unbookmarkSuccess(status, response) {
   return {
@@ -257,7 +257,7 @@ export function unbookmarkSuccess(status, response) {
     status: status,
     response: response,
   };
-};
+}
 
 export function unbookmarkFail(status, error) {
   return {
@@ -265,7 +265,7 @@ export function unbookmarkFail(status, error) {
     status: status,
     error: error,
   };
-};
+}
 
 export function fetchReblogs(id) {
   return (dispatch, getState) => {
@@ -278,14 +278,14 @@ export function fetchReblogs(id) {
       dispatch(fetchReblogsFail(id, error));
     });
   };
-};
+}
 
 export function fetchReblogsRequest(id) {
   return {
     type: REBLOGS_FETCH_REQUEST,
     id,
   };
-};
+}
 
 export function fetchReblogsSuccess(id, accounts) {
   return {
@@ -293,14 +293,14 @@ export function fetchReblogsSuccess(id, accounts) {
     id,
     accounts,
   };
-};
+}
 
 export function fetchReblogsFail(id, error) {
   return {
     type: REBLOGS_FETCH_FAIL,
     error,
   };
-};
+}
 
 export function fetchFavourites(id) {
   return (dispatch, getState) => {
@@ -313,14 +313,14 @@ export function fetchFavourites(id) {
       dispatch(fetchFavouritesFail(id, error));
     });
   };
-};
+}
 
 export function fetchFavouritesRequest(id) {
   return {
     type: FAVOURITES_FETCH_REQUEST,
     id,
   };
-};
+}
 
 export function fetchFavouritesSuccess(id, accounts) {
   return {
@@ -328,14 +328,14 @@ export function fetchFavouritesSuccess(id, accounts) {
     id,
     accounts,
   };
-};
+}
 
 export function fetchFavouritesFail(id, error) {
   return {
     type: FAVOURITES_FETCH_FAIL,
     error,
   };
-};
+}
 
 export function pin(status) {
   return (dispatch, getState) => {
@@ -348,7 +348,7 @@ export function pin(status) {
       dispatch(pinFail(status, error));
     });
   };
-};
+}
 
 export function pinRequest(status) {
   return {
@@ -356,7 +356,7 @@ export function pinRequest(status) {
     status,
     skipLoading: true,
   };
-};
+}
 
 export function pinSuccess(status) {
   return {
@@ -364,7 +364,7 @@ export function pinSuccess(status) {
     status,
     skipLoading: true,
   };
-};
+}
 
 export function pinFail(status, error) {
   return {
@@ -373,7 +373,7 @@ export function pinFail(status, error) {
     error,
     skipLoading: true,
   };
-};
+}
 
 export function unpin (status) {
   return (dispatch, getState) => {
@@ -386,7 +386,7 @@ export function unpin (status) {
       dispatch(unpinFail(status, error));
     });
   };
-};
+}
 
 export function unpinRequest(status) {
   return {
@@ -394,7 +394,7 @@ export function unpinRequest(status) {
     status,
     skipLoading: true,
   };
-};
+}
 
 export function unpinSuccess(status) {
   return {
@@ -402,7 +402,7 @@ export function unpinSuccess(status) {
     status,
     skipLoading: true,
   };
-};
+}
 
 export function unpinFail(status, error) {
   return {
@@ -411,4 +411,4 @@ export function unpinFail(status, error) {
     error,
     skipLoading: true,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/markers.js b/app/javascript/mastodon/actions/markers.js
index b7f406cb8..16ec7fe77 100644
--- a/app/javascript/mastodon/actions/markers.js
+++ b/app/javascript/mastodon/actions/markers.js
@@ -101,7 +101,7 @@ export function submitMarkersSuccess({ home, notifications }) {
     home: (home || {}).last_read_id,
     notifications: (notifications || {}).last_read_id,
   };
-};
+}
 
 export function submitMarkers(params = {}) {
   const result = (dispatch, getState) => debouncedSubmitMarkers(dispatch, getState);
@@ -111,7 +111,7 @@ export function submitMarkers(params = {}) {
   }
 
   return result;
-};
+}
 
 export const fetchMarkers = () => (dispatch, getState) => {
   const params = { timeline: ['notifications'] };
@@ -130,7 +130,7 @@ export function fetchMarkersRequest() {
     type: MARKERS_FETCH_REQUEST,
     skipLoading: true,
   };
-};
+}
 
 export function fetchMarkersSuccess(markers) {
   return {
@@ -138,7 +138,7 @@ export function fetchMarkersSuccess(markers) {
     markers,
     skipLoading: true,
   };
-};
+}
 
 export function fetchMarkersFail(error) {
   return {
@@ -147,4 +147,4 @@ export function fetchMarkersFail(error) {
     skipLoading: true,
     skipAlert: true,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/modal.js b/app/javascript/mastodon/actions/modal.js
index 3e576fab8..ef2ae0e4c 100644
--- a/app/javascript/mastodon/actions/modal.js
+++ b/app/javascript/mastodon/actions/modal.js
@@ -7,7 +7,7 @@ export function openModal(type, props) {
     modalType: type,
     modalProps: props,
   };
-};
+}
 
 export function closeModal(type, options = { ignoreFocus: false }) {
   return {
@@ -15,4 +15,4 @@ export function closeModal(type, options = { ignoreFocus: false }) {
     modalType: type,
     ignoreFocus: options.ignoreFocus,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/mutes.js b/app/javascript/mastodon/actions/mutes.js
index d8874f353..cbc42a67e 100644
--- a/app/javascript/mastodon/actions/mutes.js
+++ b/app/javascript/mastodon/actions/mutes.js
@@ -26,13 +26,13 @@ export function fetchMutes() {
       dispatch(fetchRelationships(response.data.map(item => item.id)));
     }).catch(error => dispatch(fetchMutesFail(error)));
   };
-};
+}
 
 export function fetchMutesRequest() {
   return {
     type: MUTES_FETCH_REQUEST,
   };
-};
+}
 
 export function fetchMutesSuccess(accounts, next) {
   return {
@@ -40,14 +40,14 @@ export function fetchMutesSuccess(accounts, next) {
     accounts,
     next,
   };
-};
+}
 
 export function fetchMutesFail(error) {
   return {
     type: MUTES_FETCH_FAIL,
     error,
   };
-};
+}
 
 export function expandMutes() {
   return (dispatch, getState) => {
@@ -66,13 +66,13 @@ export function expandMutes() {
       dispatch(fetchRelationships(response.data.map(item => item.id)));
     }).catch(error => dispatch(expandMutesFail(error)));
   };
-};
+}
 
 export function expandMutesRequest() {
   return {
     type: MUTES_EXPAND_REQUEST,
   };
-};
+}
 
 export function expandMutesSuccess(accounts, next) {
   return {
@@ -80,14 +80,14 @@ export function expandMutesSuccess(accounts, next) {
     accounts,
     next,
   };
-};
+}
 
 export function expandMutesFail(error) {
   return {
     type: MUTES_EXPAND_FAIL,
     error,
   };
-};
+}
 
 export function initMuteModal(account) {
   return dispatch => {
diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js
index d4588db2c..93588d3c0 100644
--- a/app/javascript/mastodon/actions/notifications.js
+++ b/app/javascript/mastodon/actions/notifications.js
@@ -118,7 +118,7 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
       });
     }
   };
-};
+}
 
 const excludeTypesFromSettings = state => state.getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS();
 
@@ -197,14 +197,14 @@ export function expandNotifications({ maxId, forceLoad } = {}, done = noOp) {
       done();
     });
   };
-};
+}
 
 export function expandNotificationsRequest(isLoadingMore) {
   return {
     type: NOTIFICATIONS_EXPAND_REQUEST,
     skipLoading: !isLoadingMore,
   };
-};
+}
 
 export function expandNotificationsSuccess(notifications, next, isLoadingMore, isLoadingRecent, usePendingItems) {
   return {
@@ -215,7 +215,7 @@ export function expandNotificationsSuccess(notifications, next, isLoadingMore, i
     usePendingItems,
     skipLoading: !isLoadingMore,
   };
-};
+}
 
 export function expandNotificationsFail(error, isLoadingMore) {
   return {
@@ -224,7 +224,7 @@ export function expandNotificationsFail(error, isLoadingMore) {
     skipLoading: !isLoadingMore,
     skipAlert: !isLoadingMore || error.name === 'AbortError',
   };
-};
+}
 
 export function clearNotifications() {
   return (dispatch, getState) => {
@@ -234,14 +234,14 @@ export function clearNotifications() {
 
     api(getState).post('/api/v1/notifications/clear');
   };
-};
+}
 
 export function scrollTopNotifications(top) {
   return {
     type: NOTIFICATIONS_SCROLL_TOP,
     top,
   };
-};
+}
 
 export function setFilter (filterType) {
   return dispatch => {
@@ -253,7 +253,7 @@ export function setFilter (filterType) {
     dispatch(expandNotifications({ forceLoad: true }));
     dispatch(saveSettings());
   };
-};
+}
 
 export const mountNotifications = () => ({
   type: NOTIFICATIONS_MOUNT,
@@ -291,7 +291,7 @@ export function requestBrowserPermission(callback = noOp) {
       callback(permission);
     });
   };
-};
+}
 
 export function setBrowserSupport (value) {
   return {
diff --git a/app/javascript/mastodon/actions/pin_statuses.js b/app/javascript/mastodon/actions/pin_statuses.js
index 77abba7b5..e2de98ca9 100644
--- a/app/javascript/mastodon/actions/pin_statuses.js
+++ b/app/javascript/mastodon/actions/pin_statuses.js
@@ -18,13 +18,13 @@ export function fetchPinnedStatuses() {
       dispatch(fetchPinnedStatusesFail(error));
     });
   };
-};
+}
 
 export function fetchPinnedStatusesRequest() {
   return {
     type: PINNED_STATUSES_FETCH_REQUEST,
   };
-};
+}
 
 export function fetchPinnedStatusesSuccess(statuses, next) {
   return {
@@ -32,11 +32,11 @@ export function fetchPinnedStatusesSuccess(statuses, next) {
     statuses,
     next,
   };
-};
+}
 
 export function fetchPinnedStatusesFail(error) {
   return {
     type: PINNED_STATUSES_FETCH_FAIL,
     error,
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/search.js b/app/javascript/mastodon/actions/search.js
index e333c0ea7..666c6c223 100644
--- a/app/javascript/mastodon/actions/search.js
+++ b/app/javascript/mastodon/actions/search.js
@@ -19,13 +19,13 @@ export function changeSearch(value) {
     type: SEARCH_CHANGE,
     value,
   };
-};
+}
 
 export function clearSearch() {
   return {
     type: SEARCH_CLEAR,
   };
-};
+}
 
 export function submitSearch() {
   return (dispatch, getState) => {
@@ -60,13 +60,13 @@ export function submitSearch() {
       dispatch(fetchSearchFail(error));
     });
   };
-};
+}
 
 export function fetchSearchRequest() {
   return {
     type: SEARCH_FETCH_REQUEST,
   };
-};
+}
 
 export function fetchSearchSuccess(results, searchTerm) {
   return {
@@ -74,14 +74,14 @@ export function fetchSearchSuccess(results, searchTerm) {
     results,
     searchTerm,
   };
-};
+}
 
 export function fetchSearchFail(error) {
   return {
     type: SEARCH_FETCH_FAIL,
     error,
   };
-};
+}
 
 export const expandSearch = type => (dispatch, getState) => {
   const value  = getState().getIn(['search', 'value']);
diff --git a/app/javascript/mastodon/actions/settings.js b/app/javascript/mastodon/actions/settings.js
index 6bf85e464..6ae001b6f 100644
--- a/app/javascript/mastodon/actions/settings.js
+++ b/app/javascript/mastodon/actions/settings.js
@@ -15,7 +15,7 @@ export function changeSetting(path, value) {
 
     dispatch(saveSettings());
   };
-};
+}
 
 const debouncedSave = debounce((dispatch, getState) => {
   if (getState().getIn(['settings', 'saved'])) {
@@ -31,4 +31,4 @@ const debouncedSave = debounce((dispatch, getState) => {
 
 export function saveSettings() {
   return (dispatch, getState) => debouncedSave(dispatch, getState);
-};
+}
diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js
index 4ae1b21e0..275280a53 100644
--- a/app/javascript/mastodon/actions/statuses.js
+++ b/app/javascript/mastodon/actions/statuses.js
@@ -45,7 +45,7 @@ export function fetchStatusRequest(id, skipLoading) {
     id,
     skipLoading,
   };
-};
+}
 
 export function fetchStatus(id, forceFetch = false) {
   return (dispatch, getState) => {
@@ -66,14 +66,14 @@ export function fetchStatus(id, forceFetch = false) {
       dispatch(fetchStatusFail(id, error, skipLoading));
     });
   };
-};
+}
 
 export function fetchStatusSuccess(skipLoading) {
   return {
     type: STATUS_FETCH_SUCCESS,
     skipLoading,
   };
-};
+}
 
 export function fetchStatusFail(id, error, skipLoading) {
   return {
@@ -83,7 +83,7 @@ export function fetchStatusFail(id, error, skipLoading) {
     skipLoading,
     skipAlert: true,
   };
-};
+}
 
 export function redraft(status, raw_text) {
   return {
@@ -91,7 +91,7 @@ export function redraft(status, raw_text) {
     status,
     raw_text,
   };
-};
+}
 
 export const editStatus = (id, routerHistory) => (dispatch, getState) => {
   let status = getState().getIn(['statuses', id]);
@@ -147,21 +147,21 @@ export function deleteStatus(id, routerHistory, withRedraft = false) {
       dispatch(deleteStatusFail(id, error));
     });
   };
-};
+}
 
 export function deleteStatusRequest(id) {
   return {
     type: STATUS_DELETE_REQUEST,
     id: id,
   };
-};
+}
 
 export function deleteStatusSuccess(id) {
   return {
     type: STATUS_DELETE_SUCCESS,
     id: id,
   };
-};
+}
 
 export function deleteStatusFail(id, error) {
   return {
@@ -169,7 +169,7 @@ export function deleteStatusFail(id, error) {
     id: id,
     error: error,
   };
-};
+}
 
 export const updateStatus = status => dispatch =>
   dispatch(importFetchedStatus(status));
@@ -190,14 +190,14 @@ export function fetchContext(id) {
       dispatch(fetchContextFail(id, error));
     });
   };
-};
+}
 
 export function fetchContextRequest(id) {
   return {
     type: CONTEXT_FETCH_REQUEST,
     id,
   };
-};
+}
 
 export function fetchContextSuccess(id, ancestors, descendants) {
   return {
@@ -207,7 +207,7 @@ export function fetchContextSuccess(id, ancestors, descendants) {
     descendants,
     statuses: ancestors.concat(descendants),
   };
-};
+}
 
 export function fetchContextFail(id, error) {
   return {
@@ -216,7 +216,7 @@ export function fetchContextFail(id, error) {
     error,
     skipAlert: true,
   };
-};
+}
 
 export function muteStatus(id) {
   return (dispatch, getState) => {
@@ -228,21 +228,21 @@ export function muteStatus(id) {
       dispatch(muteStatusFail(id, error));
     });
   };
-};
+}
 
 export function muteStatusRequest(id) {
   return {
     type: STATUS_MUTE_REQUEST,
     id,
   };
-};
+}
 
 export function muteStatusSuccess(id) {
   return {
     type: STATUS_MUTE_SUCCESS,
     id,
   };
-};
+}
 
 export function muteStatusFail(id, error) {
   return {
@@ -250,7 +250,7 @@ export function muteStatusFail(id, error) {
     id,
     error,
   };
-};
+}
 
 export function unmuteStatus(id) {
   return (dispatch, getState) => {
@@ -262,21 +262,21 @@ export function unmuteStatus(id) {
       dispatch(unmuteStatusFail(id, error));
     });
   };
-};
+}
 
 export function unmuteStatusRequest(id) {
   return {
     type: STATUS_UNMUTE_REQUEST,
     id,
   };
-};
+}
 
 export function unmuteStatusSuccess(id) {
   return {
     type: STATUS_UNMUTE_SUCCESS,
     id,
   };
-};
+}
 
 export function unmuteStatusFail(id, error) {
   return {
@@ -284,7 +284,7 @@ export function unmuteStatusFail(id, error) {
     id,
     error,
   };
-};
+}
 
 export function hideStatus(ids) {
   if (!Array.isArray(ids)) {
@@ -295,7 +295,7 @@ export function hideStatus(ids) {
     type: STATUS_HIDE,
     ids,
   };
-};
+}
 
 export function revealStatus(ids) {
   if (!Array.isArray(ids)) {
@@ -306,7 +306,7 @@ export function revealStatus(ids) {
     type: STATUS_REVEAL,
     ids,
   };
-};
+}
 
 export function toggleStatusCollapse(id, isCollapsed) {
   return {
@@ -314,7 +314,7 @@ export function toggleStatusCollapse(id, isCollapsed) {
     id,
     isCollapsed,
   };
-};
+}
 
 export const translateStatus = id => (dispatch, getState) => {
   dispatch(translateStatusRequest(id));
diff --git a/app/javascript/mastodon/actions/store.js b/app/javascript/mastodon/actions/store.js
index 34dcafc51..b3030467b 100644
--- a/app/javascript/mastodon/actions/store.js
+++ b/app/javascript/mastodon/actions/store.js
@@ -21,4 +21,4 @@ export function hydrateStore(rawState) {
     dispatch(hydrateCompose());
     dispatch(importFetchedAccounts(Object.values(rawState.accounts)));
   };
-};
+}
diff --git a/app/javascript/mastodon/actions/suggestions.js b/app/javascript/mastodon/actions/suggestions.js
index 1f1116e75..9e8cd1ea4 100644
--- a/app/javascript/mastodon/actions/suggestions.js
+++ b/app/javascript/mastodon/actions/suggestions.js
@@ -21,14 +21,14 @@ export function fetchSuggestions(withRelationships = false) {
       }
     }).catch(error => dispatch(fetchSuggestionsFail(error)));
   };
-};
+}
 
 export function fetchSuggestionsRequest() {
   return {
     type: SUGGESTIONS_FETCH_REQUEST,
     skipLoading: true,
   };
-};
+}
 
 export function fetchSuggestionsSuccess(suggestions) {
   return {
@@ -36,7 +36,7 @@ export function fetchSuggestionsSuccess(suggestions) {
     suggestions,
     skipLoading: true,
   };
-};
+}
 
 export function fetchSuggestionsFail(error) {
   return {
@@ -45,7 +45,7 @@ export function fetchSuggestionsFail(error) {
     skipLoading: true,
     skipAlert: true,
   };
-};
+}
 
 export const dismissSuggestion = accountId => (dispatch, getState) => {
   dispatch({
diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js
index a3434908f..4f772a55f 100644
--- a/app/javascript/mastodon/actions/timelines.js
+++ b/app/javascript/mastodon/actions/timelines.js
@@ -51,7 +51,7 @@ export function updateTimeline(timeline, status, accept) {
       dispatch(submitMarkers());
     }
   };
-};
+}
 
 export function deleteFromTimelines(id) {
   return (dispatch, getState) => {
@@ -67,13 +67,13 @@ export function deleteFromTimelines(id) {
       reblogOf,
     });
   };
-};
+}
 
 export function clearTimeline(timeline) {
   return (dispatch) => {
     dispatch({ type: TIMELINE_CLEAR, timeline });
   };
-};
+}
 
 const noOp = () => {};
 
@@ -122,7 +122,7 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
       done();
     });
   };
-};
+}
 
 export function fillTimelineGaps(timelineId, path, params = {}, done = noOp) {
   return (dispatch, getState) => {
@@ -168,7 +168,7 @@ export function expandTimelineRequest(timeline, isLoadingMore) {
     timeline,
     skipLoading: !isLoadingMore,
   };
-};
+}
 
 export function expandTimelineSuccess(timeline, statuses, next, partial, isLoadingRecent, isLoadingMore, usePendingItems) {
   return {
@@ -181,7 +181,7 @@ export function expandTimelineSuccess(timeline, statuses, next, partial, isLoadi
     usePendingItems,
     skipLoading: !isLoadingMore,
   };
-};
+}
 
 export function expandTimelineFail(timeline, error, isLoadingMore) {
   return {
@@ -191,7 +191,7 @@ export function expandTimelineFail(timeline, error, isLoadingMore) {
     skipLoading: !isLoadingMore,
     skipNotFound: timeline.startsWith('account:'),
   };
-};
+}
 
 export function scrollTopTimeline(timeline, top) {
   return {
@@ -199,7 +199,7 @@ export function scrollTopTimeline(timeline, top) {
     timeline,
     top,
   };
-};
+}
 
 export function connectTimeline(timeline) {
   return {
@@ -207,7 +207,7 @@ export function connectTimeline(timeline) {
     timeline,
     usePendingItems: preferPendingItems,
   };
-};
+}
 
 export const disconnectTimeline = timeline => ({
   type: TIMELINE_DISCONNECT,
diff --git a/app/javascript/mastodon/common.js b/app/javascript/mastodon/common.js
index 6818aa5d5..8f3505303 100644
--- a/app/javascript/mastodon/common.js
+++ b/app/javascript/mastodon/common.js
@@ -9,4 +9,4 @@ export function start() {
   } catch (e) {
     // If called twice
   }
-};
+}
diff --git a/app/javascript/mastodon/compare_id.js b/app/javascript/mastodon/compare_id.js
index 66cf51c4b..d2bd74f44 100644
--- a/app/javascript/mastodon/compare_id.js
+++ b/app/javascript/mastodon/compare_id.js
@@ -8,4 +8,4 @@ export default function compareId (id1, id2) {
   } else {
     return id1.length > id2.length ? 1 : -1;
   }
-};
+}
diff --git a/app/javascript/mastodon/components/admin/Retention.js b/app/javascript/mastodon/components/admin/Retention.js
index 47c9e7151..f312a45eb 100644
--- a/app/javascript/mastodon/components/admin/Retention.js
+++ b/app/javascript/mastodon/components/admin/Retention.js
@@ -137,7 +137,7 @@ export default class Retention extends React.PureComponent {
       break;
     default:
       title = <FormattedMessage id='admin.dashboard.monthly_retention' defaultMessage='User retention rate by month after sign-up' />;
-    };
+    }
 
     return (
       <div className='retention'>
diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js
index 4b4ad8355..5897aada8 100644
--- a/app/javascript/mastodon/components/dropdown_menu.js
+++ b/app/javascript/mastodon/components/dropdown_menu.js
@@ -2,9 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import IconButton from './icon_button';
-import Overlay from 'react-overlays/lib/Overlay';
-import Motion from '../features/ui/util/optional_motion';
-import spring from 'react-motion/lib/spring';
+import Overlay from 'react-overlays/Overlay';
 import { supportsPassiveEvents } from 'detect-passive-events';
 import classNames from 'classnames';
 import { CircularProgress } from 'mastodon/components/loading_indicator';
@@ -24,9 +22,6 @@ class DropdownMenu extends React.PureComponent {
     scrollable: PropTypes.bool,
     onClose: PropTypes.func.isRequired,
     style: PropTypes.object,
-    placement: PropTypes.string,
-    arrowOffsetLeft: PropTypes.string,
-    arrowOffsetTop: PropTypes.string,
     openedViaKeyboard: PropTypes.bool,
     renderItem: PropTypes.func,
     renderHeader: PropTypes.func,
@@ -35,11 +30,6 @@ class DropdownMenu extends React.PureComponent {
 
   static defaultProps = {
     style: {},
-    placement: 'bottom',
-  };
-
-  state = {
-    mounted: false,
   };
 
   handleDocumentClick = e => {
@@ -56,8 +46,6 @@ class DropdownMenu extends React.PureComponent {
     if (this.focusedItem && this.props.openedViaKeyboard) {
       this.focusedItem.focus({ preventScroll: true });
     }
-
-    this.setState({ mounted: true });
   }
 
   componentWillUnmount () {
@@ -139,40 +127,28 @@ class DropdownMenu extends React.PureComponent {
   }
 
   render () {
-    const { items, style, placement, arrowOffsetLeft, arrowOffsetTop, scrollable, renderHeader, loading } = this.props;
-    const { mounted } = this.state;
+    const { items, scrollable, renderHeader, loading } = this.props;
 
     let renderItem = this.props.renderItem || this.renderItem;
 
     return (
-      <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
-        {({ opacity, scaleX, scaleY }) => (
-          // It should not be transformed when mounting because the resulting
-          // size will be used to determine the coordinate of the menu by
-          // react-overlays
-          <div className={`dropdown-menu ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}>
-            <div className={`dropdown-menu__arrow ${placement}`} style={{ left: arrowOffsetLeft, top: arrowOffsetTop }} />
-
-            <div className={classNames('dropdown-menu__container', { 'dropdown-menu__container--loading': loading })}>
-              {loading && (
-                <CircularProgress size={30} strokeWidth={3.5} />
-              )}
-
-              {!loading && renderHeader && (
-                <div className='dropdown-menu__container__header'>
-                  {renderHeader(items)}
-                </div>
-              )}
-
-              {!loading && (
-                <ul className={classNames('dropdown-menu__container__list', { 'dropdown-menu__container__list--scrollable': scrollable })}>
-                  {items.map((option, i) => renderItem(option, i, { onClick: this.handleClick, onKeyPress: this.handleItemKeyPress }))}
-                </ul>
-              )}
-            </div>
+      <div className={classNames('dropdown-menu__container', { 'dropdown-menu__container--loading': loading })} ref={this.setRef}>
+        {loading && (
+          <CircularProgress size={30} strokeWidth={3.5} />
+        )}
+
+        {!loading && renderHeader && (
+          <div className='dropdown-menu__container__header'>
+            {renderHeader(items)}
           </div>
         )}
-      </Motion>
+
+        {!loading && (
+          <ul className={classNames('dropdown-menu__container__list', { 'dropdown-menu__container__list--scrollable': scrollable })}>
+            {items.map((option, i) => renderItem(option, i, { onClick: this.handleClick, onKeyPress: this.handleItemKeyPress }))}
+          </ul>
+        )}
+      </div>
     );
   }
 
@@ -197,7 +173,6 @@ export default class Dropdown extends React.PureComponent {
     isUserTouching: PropTypes.func,
     onOpen: PropTypes.func.isRequired,
     onClose: PropTypes.func.isRequired,
-    dropdownPlacement: PropTypes.string,
     openDropdownId: PropTypes.number,
     openedViaKeyboard: PropTypes.bool,
     renderItem: PropTypes.func,
@@ -213,13 +188,11 @@ export default class Dropdown extends React.PureComponent {
     id: id++,
   };
 
-  handleClick = ({ target, type }) => {
+  handleClick = ({ type }) => {
     if (this.state.id === this.props.openDropdownId) {
       this.handleClose();
     } else {
-      const { top } = target.getBoundingClientRect();
-      const placement = top * 2 < innerHeight ? 'bottom' : 'top';
-      this.props.onOpen(this.state.id, this.handleItemClick, placement, type !== 'click');
+      this.props.onOpen(this.state.id, this.handleItemClick, type !== 'click');
     }
   }
 
@@ -303,7 +276,6 @@ export default class Dropdown extends React.PureComponent {
       disabled,
       loading,
       scrollable,
-      dropdownPlacement,
       openDropdownId,
       openedViaKeyboard,
       children,
@@ -314,7 +286,6 @@ export default class Dropdown extends React.PureComponent {
     const open = this.state.id === openDropdownId;
 
     const button = children ? React.cloneElement(React.Children.only(children), {
-      ref: this.setTargetRef,
       onClick: this.handleClick,
       onMouseDown: this.handleMouseDown,
       onKeyDown: this.handleButtonKeyDown,
@@ -326,7 +297,6 @@ export default class Dropdown extends React.PureComponent {
         active={open}
         disabled={disabled}
         size={size}
-        ref={this.setTargetRef}
         onClick={this.handleClick}
         onMouseDown={this.handleMouseDown}
         onKeyDown={this.handleButtonKeyDown}
@@ -336,19 +306,27 @@ export default class Dropdown extends React.PureComponent {
 
     return (
       <React.Fragment>
-        {button}
-
-        <Overlay show={open} placement={dropdownPlacement} target={this.findTarget}>
-          <DropdownMenu
-            items={items}
-            loading={loading}
-            scrollable={scrollable}
-            onClose={this.handleClose}
-            openedViaKeyboard={openedViaKeyboard}
-            renderItem={renderItem}
-            renderHeader={renderHeader}
-            onItemClick={this.handleItemClick}
-          />
+        <span ref={this.setTargetRef}>
+          {button}
+        </span>
+        <Overlay show={open} offset={[5, 5]} placement={'bottom'} flip target={this.findTarget} popperConfig={{ strategy: 'fixed' }}>
+          {({ props, arrowProps, placement }) => (
+            <div {...props}>
+              <div className={`dropdown-animation dropdown-menu ${placement}`}>
+                <div className={`dropdown-menu__arrow ${placement}`} {...arrowProps} />
+                <DropdownMenu
+                  items={items}
+                  loading={loading}
+                  scrollable={scrollable}
+                  onClose={this.handleClose}
+                  openedViaKeyboard={openedViaKeyboard}
+                  renderItem={renderItem}
+                  renderHeader={renderHeader}
+                  onItemClick={this.handleItemClick}
+                />
+              </div>
+            </div>
+          )}
         </Overlay>
       </React.Fragment>
     );
diff --git a/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js b/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js
index e30c18372..16fe77a73 100644
--- a/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js
+++ b/app/javascript/mastodon/components/edited_timestamp/containers/dropdown_menu_container.js
@@ -4,7 +4,6 @@ import { fetchHistory } from 'mastodon/actions/history';
 import DropdownMenu from 'mastodon/components/dropdown_menu';
 
 const mapStateToProps = (state, { statusId }) => ({
-  dropdownPlacement: state.getIn(['dropdown_menu', 'placement']),
   openDropdownId: state.getIn(['dropdown_menu', 'openId']),
   openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']),
   items: state.getIn(['history', statusId, 'items']),
@@ -13,9 +12,9 @@ const mapStateToProps = (state, { statusId }) => ({
 
 const mapDispatchToProps = (dispatch, { statusId }) => ({
 
-  onOpen (id, onItemClick, dropdownPlacement, keyboard) {
+  onOpen (id, onItemClick, keyboard) {
     dispatch(fetchHistory(statusId));
-    dispatch(openDropdownMenu(id, dropdownPlacement, keyboard));
+    dispatch(openDropdownMenu(id, keyboard));
   },
 
   onClose (id) {
diff --git a/app/javascript/mastodon/components/icon_button.js b/app/javascript/mastodon/components/icon_button.js
index 49858f2e2..b7daf82a4 100644
--- a/app/javascript/mastodon/components/icon_button.js
+++ b/app/javascript/mastodon/components/icon_button.js
@@ -27,6 +27,7 @@ export default class IconButton extends React.PureComponent {
     counter: PropTypes.number,
     obfuscateCount: PropTypes.bool,
     href: PropTypes.string,
+    ariaHidden: PropTypes.bool,
   };
 
   static defaultProps = {
@@ -36,6 +37,7 @@ export default class IconButton extends React.PureComponent {
     animate: false,
     overlay: false,
     tabIndex: '0',
+    ariaHidden: false,
   };
 
   state = {
@@ -102,6 +104,7 @@ export default class IconButton extends React.PureComponent {
       counter,
       obfuscateCount,
       href,
+      ariaHidden,
     } = this.props;
 
     const {
@@ -142,6 +145,7 @@ export default class IconButton extends React.PureComponent {
         type='button'
         aria-label={title}
         aria-expanded={expanded}
+        aria-hidden={ariaHidden}
         title={title}
         className={classes}
         onClick={this.handleClick}
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
index bf7982cea..e4a8be338 100644
--- a/app/javascript/mastodon/components/media_gallery.js
+++ b/app/javascript/mastodon/components/media_gallery.js
@@ -345,7 +345,7 @@ class MediaGallery extends React.PureComponent {
         </button>
       );
     } else if (visible) {
-      spoilerButton = <IconButton title={intl.formatMessage(messages.toggle_visible, { number: size })} icon='eye-slash' overlay onClick={this.handleOpen} />;
+      spoilerButton = <IconButton title={intl.formatMessage(messages.toggle_visible, { number: size })} icon='eye-slash' overlay onClick={this.handleOpen} ariaHidden />;
     } else {
       spoilerButton = (
         <button type='button' onClick={this.handleOpen} className='spoiler-button__overlay'>
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js
index 2a1fedb93..00fc94358 100644
--- a/app/javascript/mastodon/components/status_action_bar.js
+++ b/app/javascript/mastodon/components/status_action_bar.js
@@ -8,7 +8,7 @@ import { defineMessages, injectIntl } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { me } from '../initial_state';
 import classNames from 'classnames';
-import { PERMISSION_MANAGE_USERS } from 'mastodon/permissions';
+import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
 
 const messages = defineMessages({
   delete: { id: 'status.delete', defaultMessage: 'Delete' },
@@ -37,9 +37,10 @@ const messages = defineMessages({
   unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
   embed: { id: 'status.embed', defaultMessage: 'Embed' },
   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
-  admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
-  copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
-  hide: { id: 'status.hide', defaultMessage: 'Hide toot' },
+  admin_status: { id: 'status.admin_status', defaultMessage: 'Open this post in the moderation interface' },
+  admin_domain: { id: 'status.admin_domain', defaultMessage: 'Open moderation interface for {domain}' },
+  copy: { id: 'status.copy', defaultMessage: 'Copy link to post' },
+  hide: { id: 'status.hide', defaultMessage: 'Hide post' },
   blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
   unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
   unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
@@ -232,7 +233,7 @@ class StatusActionBar extends ImmutablePureComponent {
 
   render () {
     const { status, relationship, intl, withDismiss, withCounters, scrollKey } = this.props;
-    const { signedIn } = this.context.identity;
+    const { signedIn, permissions } = this.context.identity;
 
     const anonymousAccess    = !signedIn;
     const publicStatus       = ['public', 'unlisted'].includes(status.get('visibility'));
@@ -246,12 +247,13 @@ class StatusActionBar extends ImmutablePureComponent {
 
     menu.push({ text: intl.formatMessage(messages.open), action: this.handleOpen });
 
-    if (publicStatus) {
-      if (isRemote) {
-        menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: status.get('url') });
-      }
+    if (publicStatus && isRemote) {
+      menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: status.get('url') });
+    }
 
-      menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
+    menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
+
+    if (publicStatus) {
       menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
     }
 
@@ -311,10 +313,16 @@ class StatusActionBar extends ImmutablePureComponent {
         }
       }
 
-      if ((this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
+      if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS || (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION)) {
         menu.push(null);
-        menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
-        menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
+        if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
+          menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
+          menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
+        }
+        if (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION) {
+          const domain = account.get('acct').split('@')[1];
+          menu.push({ text: intl.formatMessage(messages.admin_domain, { domain: domain }), href: `/admin/instances/${domain}` });
+        }
       }
     }
 
diff --git a/app/javascript/mastodon/containers/dropdown_menu_container.js b/app/javascript/mastodon/containers/dropdown_menu_container.js
index c45bab40b..bedd1c63f 100644
--- a/app/javascript/mastodon/containers/dropdown_menu_container.js
+++ b/app/javascript/mastodon/containers/dropdown_menu_container.js
@@ -6,13 +6,12 @@ import DropdownMenu from '../components/dropdown_menu';
 import { isUserTouching } from '../is_mobile';
 
 const mapStateToProps = state => ({
-  dropdownPlacement: state.getIn(['dropdown_menu', 'placement']),
   openDropdownId: state.getIn(['dropdown_menu', 'openId']),
   openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']),
 });
 
 const mapDispatchToProps = (dispatch, { status, items, scrollKey }) => ({
-  onOpen(id, onItemClick, dropdownPlacement, keyboard) {
+  onOpen(id, onItemClick, keyboard) {
     if (status) {
       dispatch(fetchRelationships([status.getIn(['account', 'id'])]));
     }
@@ -21,7 +20,7 @@ const mapDispatchToProps = (dispatch, { status, items, scrollKey }) => ({
       status,
       actions: items,
       onClick: onItemClick,
-    }) : openDropdownMenu(id, dropdownPlacement, keyboard, scrollKey));
+    }) : openDropdownMenu(id, keyboard, scrollKey));
   },
 
   onClose(id) {
diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js
index 724719f74..002b71e93 100644
--- a/app/javascript/mastodon/containers/mastodon.js
+++ b/app/javascript/mastodon/containers/mastodon.js
@@ -23,7 +23,9 @@ export const store = configureStore();
 const hydrateAction = hydrateStore(initialState);
 
 store.dispatch(hydrateAction);
-store.dispatch(fetchCustomEmojis());
+if (initialState.meta.me) {
+  store.dispatch(fetchCustomEmojis());
+}
 
 const createIdentityContext = state => ({
   signedIn: !!state.meta.me,
diff --git a/app/javascript/mastodon/extra_polyfills.js b/app/javascript/mastodon/extra_polyfills.js
index 395f1ed05..6e8004f07 100644
--- a/app/javascript/mastodon/extra_polyfills.js
+++ b/app/javascript/mastodon/extra_polyfills.js
@@ -1,6 +1,3 @@
 import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';
 import 'intersection-observer';
 import 'requestidlecallback';
-import objectFitImages from 'object-fit-images';
-
-objectFitImages();
diff --git a/app/javascript/mastodon/features/account/components/follow_request_note.js b/app/javascript/mastodon/features/account/components/follow_request_note.js
new file mode 100644
index 000000000..300ae4266
--- /dev/null
+++ b/app/javascript/mastodon/features/account/components/follow_request_note.js
@@ -0,0 +1,37 @@
+import React from 'react';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { FormattedMessage } from 'react-intl';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import Icon from 'mastodon/components/icon';
+
+export default class FollowRequestNote extends ImmutablePureComponent {
+
+  static propTypes = {
+    account: ImmutablePropTypes.map.isRequired,
+  };
+
+  render () {
+    const { account, onAuthorize, onReject } = this.props;
+
+    return (
+      <div className='follow-request-banner'>
+        <div className='follow-request-banner__message'>
+          <FormattedMessage id='account.requested_follow' defaultMessage='{name} has requested to follow you' values={{ name: <bdi><strong dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} /></bdi> }} />
+        </div>
+
+        <div className='follow-request-banner__action'>
+          <button type='button' className='button button-tertiary button--confirmation' onClick={onAuthorize}>
+            <Icon id='check' fixedWidth />
+            <FormattedMessage id='follow_request.authorize' defaultMessage='Authorize' />
+          </button>
+
+          <button type='button' className='button button-tertiary button--destructive' onClick={onReject}>
+            <Icon id='times' fixedWidth />
+            <FormattedMessage id='follow_request.reject' defaultMessage='Reject' />
+          </button>
+        </div>
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index 5eb89c0ea..2481e4783 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -14,7 +14,8 @@ import ShortNumber from 'mastodon/components/short_number';
 import { NavLink } from 'react-router-dom';
 import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
 import AccountNoteContainer from '../containers/account_note_container';
-import { PERMISSION_MANAGE_USERS } from 'mastodon/permissions';
+import FollowRequestNoteContainer from '../containers/follow_request_note_container';
+import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
 import { Helmet } from 'react-helmet';
 
 const messages = defineMessages({
@@ -52,6 +53,7 @@ const messages = defineMessages({
   unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
   add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
+  admin_domain: { id: 'status.admin_domain', defaultMessage: 'Open moderation interface for {domain}' },
   languages: { id: 'account.languages', defaultMessage: 'Change subscribed languages' },
   openOriginalPage: { id: 'account.open_original_page', defaultMessage: 'Open original page' },
 });
@@ -162,7 +164,7 @@ class Header extends ImmutablePureComponent {
 
   render () {
     const { account, hidden, intl, domain } = this.props;
-    const { signedIn } = this.context.identity;
+    const { signedIn, permissions } = this.context.identity;
 
     if (!account) {
       return null;
@@ -287,9 +289,14 @@ class Header extends ImmutablePureComponent {
       }
     }
 
-    if (account.get('id') !== me && (this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
+    if ((account.get('id') !== me && (permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) || (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION)) {
       menu.push(null);
-      menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${account.get('id')}` });
+      if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
+        menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${account.get('id')}` });
+      }
+        if (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION) {
+          menu.push({ text: intl.formatMessage(messages.admin_domain, { domain: remoteDomain }), href: `/admin/instances/${remoteDomain}` });
+        }
     }
 
     const content         = { __html: account.get('note_emojified') };
@@ -311,6 +318,8 @@ class Header extends ImmutablePureComponent {
 
     return (
       <div className={classNames('account__header', { inactive: !!account.get('moved') })} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
+        {!(suspended || hidden || account.get('moved')) && account.getIn(['relationship', 'requested_by']) && <FollowRequestNoteContainer account={account} />}
+
         <div className='account__header__image'>
           <div className='account__header__info'>
             {!suspended && info}
@@ -342,7 +351,9 @@ class Header extends ImmutablePureComponent {
           <div className='account__header__tabs__name'>
             <h1>
               <span dangerouslySetInnerHTML={displayNameHtml} /> {badge}
-              <small>@{acct} {lockedIcon}</small>
+              <small>
+                <span>@{acct}</span> {lockedIcon}
+              </small>
             </h1>
           </div>
 
diff --git a/app/javascript/mastodon/features/account/containers/follow_request_note_container.js b/app/javascript/mastodon/features/account/containers/follow_request_note_container.js
new file mode 100644
index 000000000..c33c3de59
--- /dev/null
+++ b/app/javascript/mastodon/features/account/containers/follow_request_note_container.js
@@ -0,0 +1,15 @@
+import { connect } from 'react-redux';
+import FollowRequestNote from '../components/follow_request_note';
+import { authorizeFollowRequest, rejectFollowRequest } from 'mastodon/actions/accounts';
+
+const mapDispatchToProps = (dispatch, { account }) => ({
+  onAuthorize () {
+    dispatch(authorizeFollowRequest(account.get('id')));
+  },
+
+  onReject () {
+    dispatch(rejectFollowRequest(account.get('id')));
+  },
+});
+
+export default connect(null, mapDispatchToProps)(FollowRequestNote);
diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js
index f16fe07f1..13fd7fe03 100644
--- a/app/javascript/mastodon/features/account_gallery/components/media_item.js
+++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js
@@ -104,6 +104,7 @@ export default class MediaItem extends ImmutablePureComponent {
           <video
             className='media-gallery__item-gifv-thumbnail'
             aria-label={attachment.get('description')}
+            title={attachment.get('description')}
             role='application'
             src={attachment.get('url')}
             onMouseEnter={this.handleMouseEnter}
diff --git a/app/javascript/mastodon/features/closed_registrations_modal/index.js b/app/javascript/mastodon/features/closed_registrations_modal/index.js
index 275bd50aa..e6540e825 100644
--- a/app/javascript/mastodon/features/closed_registrations_modal/index.js
+++ b/app/javascript/mastodon/features/closed_registrations_modal/index.js
@@ -72,4 +72,4 @@ class ClosedRegistrationsModal extends ImmutablePureComponent {
     );
   }
 
-};
+}
diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js
index 55ffecb49..ebdd55d33 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.js
+++ b/app/javascript/mastodon/features/compose/components/compose_form.js
@@ -16,7 +16,6 @@ import PollFormContainer from '../containers/poll_form_container';
 import UploadFormContainer from '../containers/upload_form_container';
 import WarningContainer from '../containers/warning_container';
 import LanguageDropdown from '../containers/language_dropdown_container';
-import { isMobile } from '../../../is_mobile';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { length } from 'stringz';
 import { countableText } from '../util/counter';
@@ -62,14 +61,14 @@ class ComposeForm extends ImmutablePureComponent {
     onChangeSpoilerText: PropTypes.func.isRequired,
     onPaste: PropTypes.func.isRequired,
     onPickEmoji: PropTypes.func.isRequired,
-    showSearch: PropTypes.bool,
+    autoFocus: PropTypes.bool,
     anyMedia: PropTypes.bool,
     isInReply: PropTypes.bool,
     singleColumn: PropTypes.bool,
   };
 
   static defaultProps = {
-    showSearch: false,
+    autoFocus: false,
   };
 
   handleChange = (e) => {
@@ -155,7 +154,7 @@ class ComposeForm extends ImmutablePureComponent {
     //     - Replying to zero or one users, places the cursor at the end of the textbox.
     //     - Replying to more than one user, selects any usernames past the first;
     //       this provides a convenient shortcut to drop everyone else from the conversation.
-    if (this.props.focusDate !== prevProps.focusDate) {
+    if (this.props.focusDate && this.props.focusDate !== prevProps.focusDate) {
       let selectionEnd, selectionStart;
 
       if (this.props.preselectDate !== prevProps.preselectDate && this.props.isInReply) {
@@ -181,7 +180,7 @@ class ComposeForm extends ImmutablePureComponent {
     } else if (this.props.spoiler !== prevProps.spoiler) {
       if (this.props.spoiler) {
         this.spoilerText.input.focus();
-      } else {
+      } else if (prevProps.spoiler) {
         this.autosuggestTextarea.textarea.focus();
       }
     }
@@ -208,7 +207,7 @@ class ComposeForm extends ImmutablePureComponent {
   }
 
   render () {
-    const { intl, onPaste, showSearch } = this.props;
+    const { intl, onPaste, autoFocus } = this.props;
     const disabled = this.props.isSubmitting;
 
     let publishText = '';
@@ -227,7 +226,7 @@ class ComposeForm extends ImmutablePureComponent {
 
         <ReplyIndicatorContainer />
 
-        <div className={`spoiler-input ${this.props.spoiler ? 'spoiler-input--visible' : ''}`} ref={this.setRef}>
+        <div className={`spoiler-input ${this.props.spoiler ? 'spoiler-input--visible' : ''}`} ref={this.setRef} aria-hidden={!this.props.spoiler}>
           <AutosuggestInput
             placeholder={intl.formatMessage(messages.spoiler_placeholder)}
             value={this.props.spoilerText}
@@ -258,7 +257,7 @@ class ComposeForm extends ImmutablePureComponent {
           onSuggestionsClearRequested={this.onSuggestionsClearRequested}
           onSuggestionSelected={this.onSuggestionSelected}
           onPaste={onPaste}
-          autoFocus={!showSearch && !isMobile(window.innerWidth)}
+          autoFocus={autoFocus}
         >
           <EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} />
 
diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
index 8cca8af2a..76c9cda81 100644
--- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import { EmojiPicker as EmojiPickerAsync } from '../../ui/util/async-components';
-import Overlay from 'react-overlays/lib/Overlay';
+import Overlay from 'react-overlays/Overlay';
 import classNames from 'classnames';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import { supportsPassiveEvents } from 'detect-passive-events';
@@ -154,9 +154,6 @@ class EmojiPickerMenu extends React.PureComponent {
     onClose: PropTypes.func.isRequired,
     onPick: PropTypes.func.isRequired,
     style: PropTypes.object,
-    placement: PropTypes.string,
-    arrowOffsetLeft: PropTypes.string,
-    arrowOffsetTop: PropTypes.string,
     intl: PropTypes.object.isRequired,
     skinTone: PropTypes.number.isRequired,
     onSkinTone: PropTypes.func.isRequired,
@@ -324,14 +321,13 @@ class EmojiPickerDropdown extends React.PureComponent {
   state = {
     active: false,
     loading: false,
-    placement: null,
   };
 
   setRef = (c) => {
     this.dropdown = c;
   }
 
-  onShowDropdown = ({ target }) => {
+  onShowDropdown = () => {
     this.setState({ active: true });
 
     if (!EmojiPicker) {
@@ -346,9 +342,6 @@ class EmojiPickerDropdown extends React.PureComponent {
         this.setState({ loading: false, active: false });
       });
     }
-
-    const { top } = target.getBoundingClientRect();
-    this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
   }
 
   onHideDropdown = () => {
@@ -382,7 +375,7 @@ class EmojiPickerDropdown extends React.PureComponent {
   render () {
     const { intl, onPickEmoji, onSkinTone, skinTone, frequentlyUsedEmojis, button } = this.props;
     const title = intl.formatMessage(messages.emoji);
-    const { active, loading, placement } = this.state;
+    const { active, loading } = this.state;
 
     return (
       <div className='emoji-picker-dropdown' onKeyDown={this.handleKeyDown}>
@@ -394,16 +387,22 @@ class EmojiPickerDropdown extends React.PureComponent {
           />}
         </div>
 
-        <Overlay show={active} placement={placement} target={this.findTarget}>
-          <EmojiPickerMenu
-            custom_emojis={this.props.custom_emojis}
-            loading={loading}
-            onClose={this.onHideDropdown}
-            onPick={onPickEmoji}
-            onSkinTone={onSkinTone}
-            skinTone={skinTone}
-            frequentlyUsedEmojis={frequentlyUsedEmojis}
-          />
+        <Overlay show={active} placement={'bottom'} target={this.findTarget} popperConfig={{ strategy: 'fixed' }}>
+          {({ props, placement })=> (
+            <div {...props} style={{ ...props.style, width: 299 }}>
+              <div className={`dropdown-animation ${placement}`}>
+                <EmojiPickerMenu
+                  custom_emojis={this.props.custom_emojis}
+                  loading={loading}
+                  onClose={this.onHideDropdown}
+                  onPick={onPickEmoji}
+                  onSkinTone={onSkinTone}
+                  skinTone={skinTone}
+                  frequentlyUsedEmojis={frequentlyUsedEmojis}
+                />
+              </div>
+            </div>
+          )}
         </Overlay>
       </div>
     );
diff --git a/app/javascript/mastodon/features/compose/components/language_dropdown.js b/app/javascript/mastodon/features/compose/components/language_dropdown.js
index bf56fd0fa..2dd406b4b 100644
--- a/app/javascript/mastodon/features/compose/components/language_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/language_dropdown.js
@@ -2,9 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { injectIntl, defineMessages } from 'react-intl';
 import TextIconButton from './text_icon_button';
-import Overlay from 'react-overlays/lib/Overlay';
-import Motion from 'mastodon/features/ui/util/optional_motion';
-import spring from 'react-motion/lib/spring';
+import Overlay from 'react-overlays/Overlay';
 import { supportsPassiveEvents } from 'detect-passive-events';
 import classNames from 'classnames';
 import { languages as preloadedLanguages } from 'mastodon/initial_state';
@@ -22,10 +20,8 @@ const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
 class LanguageDropdownMenu extends React.PureComponent {
 
   static propTypes = {
-    style: PropTypes.object,
     value: PropTypes.string.isRequired,
     frequentlyUsedLanguages: PropTypes.arrayOf(PropTypes.string).isRequired,
-    placement: PropTypes.string.isRequired,
     onClose: PropTypes.func.isRequired,
     onChange: PropTypes.func.isRequired,
     languages: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)),
@@ -37,7 +33,6 @@ class LanguageDropdownMenu extends React.PureComponent {
   };
 
   state = {
-    mounted: false,
     searchValue: '',
   };
 
@@ -50,7 +45,6 @@ class LanguageDropdownMenu extends React.PureComponent {
   componentDidMount () {
     document.addEventListener('click', this.handleDocumentClick, false);
     document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
-    this.setState({ mounted: true });
 
     // Because of https://github.com/react-bootstrap/react-bootstrap/issues/2614 we need
     // to wait for a frame before focusing
@@ -222,29 +216,22 @@ class LanguageDropdownMenu extends React.PureComponent {
   }
 
   render () {
-    const { style, placement, intl } = this.props;
-    const { mounted, searchValue } = this.state;
+    const { intl } = this.props;
+    const { searchValue } = this.state;
     const isSearching = searchValue !== '';
     const results = this.search();
 
     return (
-      <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
-        {({ opacity, scaleX, scaleY }) => (
-          // It should not be transformed when mounting because the resulting
-          // size will be used to determine the coordinate of the menu by
-          // react-overlays
-          <div className={`language-dropdown__dropdown ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} ref={this.setRef}>
-            <div className='emoji-mart-search'>
-              <input type='search' value={searchValue} onChange={this.handleSearchChange} onKeyDown={this.handleSearchKeyDown} placeholder={intl.formatMessage(messages.search)} />
-              <button type='button' className='emoji-mart-search-icon' disabled={!isSearching} aria-label={intl.formatMessage(messages.clear)} onClick={this.handleClear}>{!isSearching ? loupeIcon : deleteIcon}</button>
-            </div>
+      <div ref={this.setRef}>
+        <div className='emoji-mart-search'>
+          <input type='search' value={searchValue} onChange={this.handleSearchChange} onKeyDown={this.handleSearchKeyDown} placeholder={intl.formatMessage(messages.search)} />
+          <button type='button' className='emoji-mart-search-icon' disabled={!isSearching} aria-label={intl.formatMessage(messages.clear)} onClick={this.handleClear}>{!isSearching ? loupeIcon : deleteIcon}</button>
+        </div>
 
-            <div className='language-dropdown__dropdown__results emoji-mart-scroll' role='listbox' ref={this.setListRef}>
-              {results.map(this.renderItem)}
-            </div>
-          </div>
-        )}
-      </Motion>
+        <div className='language-dropdown__dropdown__results emoji-mart-scroll' role='listbox' ref={this.setListRef}>
+          {results.map(this.renderItem)}
+        </div>
+      </div>
     );
   }
 
@@ -266,14 +253,11 @@ class LanguageDropdown extends React.PureComponent {
     placement: 'bottom',
   };
 
-  handleToggle = ({ target }) => {
-    const { top } = target.getBoundingClientRect();
-
+  handleToggle = () => {
     if (this.state.open && this.activeElement) {
       this.activeElement.focus({ preventScroll: true });
     }
 
-    this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
     this.setState({ open: !this.state.open });
   }
 
@@ -293,13 +277,25 @@ class LanguageDropdown extends React.PureComponent {
     onChange(value);
   }
 
+  setTargetRef = c => {
+    this.target = c;
+  }
+
+  findTarget = () => {
+    return this.target;
+  }
+
+  handleOverlayEnter = (state) => {
+    this.setState({ placement: state.placement });
+  }
+
   render () {
     const { value, intl, frequentlyUsedLanguages } = this.props;
     const { open, placement } = this.state;
 
     return (
-      <div className={classNames('privacy-dropdown', { active: open })}>
-        <div className='privacy-dropdown__value'>
+      <div className={classNames('privacy-dropdown', placement, { active: open })}>
+        <div className='privacy-dropdown__value' ref={this.setTargetRef} >
           <TextIconButton
             className='privacy-dropdown__value-icon'
             label={value && value.toUpperCase()}
@@ -309,15 +305,20 @@ class LanguageDropdown extends React.PureComponent {
           />
         </div>
 
-        <Overlay show={open} placement={placement} target={this}>
-          <LanguageDropdownMenu
-            value={value}
-            frequentlyUsedLanguages={frequentlyUsedLanguages}
-            onClose={this.handleClose}
-            onChange={this.handleChange}
-            placement={placement}
-            intl={intl}
-          />
+        <Overlay show={open} placement={'bottom'} flip target={this.findTarget} popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}>
+          {({ props, placement }) => (
+            <div {...props}>
+              <div className={`dropdown-animation language-dropdown__dropdown ${placement}`} >
+                <LanguageDropdownMenu
+                  value={value}
+                  frequentlyUsedLanguages={frequentlyUsedLanguages}
+                  onClose={this.handleClose}
+                  onChange={this.handleChange}
+                  intl={intl}
+                />
+              </div>
+            </div>
+          )}
         </Overlay>
       </div>
     );
diff --git a/app/javascript/mastodon/features/compose/components/poll_form.js b/app/javascript/mastodon/features/compose/components/poll_form.js
index 47ba2fdc3..3aa527161 100644
--- a/app/javascript/mastodon/features/compose/components/poll_form.js
+++ b/app/javascript/mastodon/features/compose/components/poll_form.js
@@ -165,6 +165,7 @@ class PollForm extends ImmutablePureComponent {
             <option value={1800}>{intl.formatMessage(messages.minutes, { number: 30 })}</option>
             <option value={3600}>{intl.formatMessage(messages.hours, { number: 1 })}</option>
             <option value={21600}>{intl.formatMessage(messages.hours, { number: 6 })}</option>
+            <option value={43200}>{intl.formatMessage(messages.hours, { number: 12 })}</option>
             <option value={86400}>{intl.formatMessage(messages.days, { number: 1 })}</option>
             <option value={259200}>{intl.formatMessage(messages.days, { number: 3 })}</option>
             <option value={604800}>{intl.formatMessage(messages.days, { number: 7 })}</option>
diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
index 1f0e998d3..545b67eda 100644
--- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
@@ -2,9 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { injectIntl, defineMessages } from 'react-intl';
 import IconButton from '../../../components/icon_button';
-import Overlay from 'react-overlays/lib/Overlay';
-import Motion from '../../ui/util/optional_motion';
-import spring from 'react-motion/lib/spring';
+import Overlay from 'react-overlays/Overlay';
 import { supportsPassiveEvents } from 'detect-passive-events';
 import classNames from 'classnames';
 import Icon from 'mastodon/components/icon';
@@ -29,15 +27,10 @@ class PrivacyDropdownMenu extends React.PureComponent {
     style: PropTypes.object,
     items: PropTypes.array.isRequired,
     value: PropTypes.string.isRequired,
-    placement: PropTypes.string.isRequired,
     onClose: PropTypes.func.isRequired,
     onChange: PropTypes.func.isRequired,
   };
 
-  state = {
-    mounted: false,
-  };
-
   handleDocumentClick = e => {
     if (this.node && !this.node.contains(e.target)) {
       this.props.onClose();
@@ -101,7 +94,6 @@ class PrivacyDropdownMenu extends React.PureComponent {
     document.addEventListener('click', this.handleDocumentClick, false);
     document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
     if (this.focusedItem) this.focusedItem.focus({ preventScroll: true });
-    this.setState({ mounted: true });
   }
 
   componentWillUnmount () {
@@ -118,31 +110,23 @@ class PrivacyDropdownMenu extends React.PureComponent {
   }
 
   render () {
-    const { mounted } = this.state;
-    const { style, items, placement, value } = this.props;
+    const { style, items, value } = this.props;
 
     return (
-      <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
-        {({ opacity, scaleX, scaleY }) => (
-          // It should not be transformed when mounting because the resulting
-          // size will be used to determine the coordinate of the menu by
-          // react-overlays
-          <div className={`privacy-dropdown__dropdown ${placement}`} style={{ ...style, opacity: opacity, transform: mounted ? `scale(${scaleX}, ${scaleY})` : null }} role='listbox' ref={this.setRef}>
-            {items.map(item => (
-              <div role='option' tabIndex='0' key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}>
-                <div className='privacy-dropdown__option__icon'>
-                  <Icon id={item.icon} fixedWidth />
-                </div>
-
-                <div className='privacy-dropdown__option__content'>
-                  <strong>{item.text}</strong>
-                  {item.meta}
-                </div>
-              </div>
-            ))}
+      <div style={{ ...style }} role='listbox' ref={this.setRef}>
+        {items.map(item => (
+          <div role='option' tabIndex='0' key={item.value} data-index={item.value} onKeyDown={this.handleKeyDown} onClick={this.handleClick} className={classNames('privacy-dropdown__option', { active: item.value === value })} aria-selected={item.value === value} ref={item.value === value ? this.setFocusRef : null}>
+            <div className='privacy-dropdown__option__icon'>
+              <Icon id={item.icon} fixedWidth />
+            </div>
+
+            <div className='privacy-dropdown__option__content'>
+              <strong>{item.text}</strong>
+              {item.meta}
+            </div>
           </div>
-        )}
-      </Motion>
+        ))}
+      </div>
     );
   }
 
@@ -168,7 +152,7 @@ class PrivacyDropdown extends React.PureComponent {
     placement: 'bottom',
   };
 
-  handleToggle = ({ target }) => {
+  handleToggle = () => {
     if (this.props.isUserTouching && this.props.isUserTouching()) {
       if (this.state.open) {
         this.props.onModalClose();
@@ -179,11 +163,9 @@ class PrivacyDropdown extends React.PureComponent {
         });
       }
     } else {
-      const { top } = target.getBoundingClientRect();
       if (this.state.open && this.activeElement) {
         this.activeElement.focus({ preventScroll: true });
       }
-      this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' });
       this.setState({ open: !this.state.open });
     }
   }
@@ -247,6 +229,18 @@ class PrivacyDropdown extends React.PureComponent {
     }
   }
 
+  setTargetRef = c => {
+    this.target = c;
+  }
+
+  findTarget = () => {
+    return this.target;
+  }
+
+  handleOverlayEnter = (state) => {
+    this.setState({ placement: state.placement });
+  }
+
   render () {
     const { value, container, disabled, intl } = this.props;
     const { open, placement } = this.state;
@@ -255,7 +249,7 @@ class PrivacyDropdown extends React.PureComponent {
 
     return (
       <div className={classNames('privacy-dropdown', placement, { active: open })} onKeyDown={this.handleKeyDown}>
-        <div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === (placement === 'bottom' ? 0 : (this.options.length - 1)) })}>
+        <div className={classNames('privacy-dropdown__value', { active: this.options.indexOf(valueOption) === (placement === 'bottom' ? 0 : (this.options.length - 1)) })} ref={this.setTargetRef}>
           <IconButton
             className='privacy-dropdown__value-icon'
             icon={valueOption.icon}
@@ -272,14 +266,19 @@ class PrivacyDropdown extends React.PureComponent {
           />
         </div>
 
-        <Overlay show={open} placement={placement} target={this} container={container}>
-          <PrivacyDropdownMenu
-            items={this.options}
-            value={value}
-            onClose={this.handleClose}
-            onChange={this.handleChange}
-            placement={placement}
-          />
+        <Overlay show={open} placement={'bottom'} flip target={this.findTarget} container={container} popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}>
+          {({ props, placement }) => (
+            <div {...props}>
+              <div className={`dropdown-animation privacy-dropdown__dropdown ${placement}`}>
+                <PrivacyDropdownMenu
+                  items={this.options}
+                  value={value}
+                  onClose={this.handleClose}
+                  onChange={this.handleChange}
+                />
+              </div>
+            </div>
+          )}
         </Overlay>
       </div>
     );
diff --git a/app/javascript/mastodon/features/compose/components/search.js b/app/javascript/mastodon/features/compose/components/search.js
index ebb23d92f..5820f8ca2 100644
--- a/app/javascript/mastodon/features/compose/components/search.js
+++ b/app/javascript/mastodon/features/compose/components/search.js
@@ -1,9 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import Overlay from 'react-overlays/lib/Overlay';
-import Motion from '../../ui/util/optional_motion';
-import spring from 'react-motion/lib/spring';
+import Overlay from 'react-overlays/Overlay';
 import { searchEnabled } from '../../../initial_state';
 import Icon from 'mastodon/components/icon';
 
@@ -14,31 +12,20 @@ const messages = defineMessages({
 
 class SearchPopout extends React.PureComponent {
 
-  static propTypes = {
-    style: PropTypes.object,
-  };
-
   render () {
-    const { style } = this.props;
     const extraInformation = searchEnabled ? <FormattedMessage id='search_popout.tips.full_text' defaultMessage='Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.' /> : <FormattedMessage id='search_popout.tips.text' defaultMessage='Simple text returns matching display names, usernames and hashtags' />;
     return (
-      <div style={{ ...style, position: 'absolute', width: 285, zIndex: 2 }}>
-        <Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
-          {({ opacity, scaleX, scaleY }) => (
-            <div className='search-popout' style={{ opacity: opacity, transform: `scale(${scaleX}, ${scaleY})` }}>
-              <h4><FormattedMessage id='search_popout.search_format' defaultMessage='Advanced search format' /></h4>
-
-              <ul>
-                <li><em>#example</em> <FormattedMessage id='search_popout.tips.hashtag' defaultMessage='hashtag' /></li>
-                <li><em>@username@domain</em> <FormattedMessage id='search_popout.tips.user' defaultMessage='user' /></li>
-                <li><em>URL</em> <FormattedMessage id='search_popout.tips.user' defaultMessage='user' /></li>
-                <li><em>URL</em> <FormattedMessage id='search_popout.tips.status' defaultMessage='status' /></li>
-              </ul>
-
-              {extraInformation}
-            </div>
-          )}
-        </Motion>
+      <div className='search-popout'>
+        <h4><FormattedMessage id='search_popout.search_format' defaultMessage='Advanced search format' /></h4>
+
+        <ul>
+          <li><em>#example</em> <FormattedMessage id='search_popout.tips.hashtag' defaultMessage='hashtag' /></li>
+          <li><em>@username@domain</em> <FormattedMessage id='search_popout.tips.user' defaultMessage='user' /></li>
+          <li><em>URL</em> <FormattedMessage id='search_popout.tips.user' defaultMessage='user' /></li>
+          <li><em>URL</em> <FormattedMessage id='search_popout.tips.status' defaultMessage='status' /></li>
+        </ul>
+
+        {extraInformation}
       </div>
     );
   }
@@ -115,6 +102,10 @@ class Search extends React.PureComponent {
     this.setState({ expanded: false });
   }
 
+  findTarget = () => {
+    return this.searchForm;
+  }
+
   render () {
     const { intl, value, submitted } = this.props;
     const { expanded } = this.state;
@@ -123,28 +114,31 @@ class Search extends React.PureComponent {
 
     return (
       <div className='search'>
-        <label>
-          <span style={{ display: 'none' }}>{intl.formatMessage(messages.placeholder)}</span>
-          <input
-            ref={this.setRef}
-            className='search__input'
-            type='text'
-            placeholder={intl.formatMessage(signedIn ? messages.placeholderSignedIn : messages.placeholder)}
-            value={value}
-            onChange={this.handleChange}
-            onKeyUp={this.handleKeyUp}
-            onFocus={this.handleFocus}
-            onBlur={this.handleBlur}
-          />
-        </label>
+        <input
+          ref={this.setRef}
+          className='search__input'
+          type='text'
+          placeholder={intl.formatMessage(signedIn ? messages.placeholderSignedIn : messages.placeholder)}
+          aria-label={intl.formatMessage(signedIn ? messages.placeholderSignedIn : messages.placeholder)}
+          value={value}
+          onChange={this.handleChange}
+          onKeyUp={this.handleKeyUp}
+          onFocus={this.handleFocus}
+          onBlur={this.handleBlur}
+        />
 
         <div role='button' tabIndex='0' className='search__icon' onClick={this.handleClear}>
           <Icon id='search' className={hasValue ? '' : 'active'} />
           <Icon id='times-circle' className={hasValue ? 'active' : ''} aria-label={intl.formatMessage(messages.placeholder)} />
         </div>
-
-        <Overlay show={expanded && !hasValue} placement='bottom' target={this}>
-          <SearchPopout />
+        <Overlay show={expanded && !hasValue} placement='bottom' target={this.findTarget} popperConfig={{ strategy: 'fixed' }}>
+          {({ props, placement }) => (
+            <div {...props} style={{ ...props.style, width: 285, zIndex: 2 }}>
+              <div className={`dropdown-animation ${placement}`}>
+                <SearchPopout />
+              </div>
+            </div>
+          )}
         </Overlay>
       </div>
     );
diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
index 1be7633cc..14cf9230b 100644
--- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js
+++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js
@@ -24,7 +24,6 @@ const mapStateToProps = state => ({
   isEditing: state.getIn(['compose', 'id']) !== null,
   isChangingUpload: state.getIn(['compose', 'is_changing_upload']),
   isUploading: state.getIn(['compose', 'is_uploading']),
-  showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
   anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
   isInReply: state.getIn(['compose', 'in_reply_to']) !== null,
 });
diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js
index f744fc611..aead7776a 100644
--- a/app/javascript/mastodon/features/compose/index.js
+++ b/app/javascript/mastodon/features/compose/index.js
@@ -18,6 +18,7 @@ import Icon from 'mastodon/components/icon';
 import { logOut } from 'mastodon/utils/log_out';
 import Column from 'mastodon/components/column';
 import { Helmet } from 'react-helmet';
+import { isMobile } from '../../is_mobile';
 
 const messages = defineMessages({
   start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
@@ -115,7 +116,7 @@ class Compose extends React.PureComponent {
             <div className='drawer__inner' onFocus={this.onFocus}>
               <NavigationContainer onClose={this.onBlur} />
 
-              <ComposeFormContainer />
+              <ComposeFormContainer autoFocus={!isMobile(window.innerWidth)} />
 
               <div className='drawer__inner__mastodon'>
                 <img alt='' draggable='false' src={mascot || elephantUIPlane} />
diff --git a/app/javascript/mastodon/features/compose/util/counter.js b/app/javascript/mastodon/features/compose/util/counter.js
index 7aa9e87b1..5a68bad99 100644
--- a/app/javascript/mastodon/features/compose/util/counter.js
+++ b/app/javascript/mastodon/features/compose/util/counter.js
@@ -6,4 +6,4 @@ export function countableText(inputText) {
   return inputText
     .replace(urlRegex, urlPlaceholder)
     .replace(/(^|[^\/\w])@(([a-z0-9_]+)@[a-z0-9\.\-]+[a-z0-9]+)/ig, '$1@$3');
-};
+}
diff --git a/app/javascript/mastodon/features/explore/index.js b/app/javascript/mastodon/features/explore/index.js
index 286170c9f..1ae249f45 100644
--- a/app/javascript/mastodon/features/explore/index.js
+++ b/app/javascript/mastodon/features/explore/index.js
@@ -24,16 +24,6 @@ const mapStateToProps = state => ({
   isSearching: state.getIn(['search', 'submitted']) || !showTrends,
 });
 
-// Fix strange bug on Safari where <span> (rendered by FormattedMessage) disappears
-// after clicking around Explore top bar (issue #20885).
-// Removing width=100% from <a> also fixes it, as well as replacing <span> with <div>
-// We're choosing to wrap span with div to keep the changes local only to this tool bar.
-const WrapFormattedMessage = ({ children, ...props }) => <div><FormattedMessage {...props}>{children}</FormattedMessage></div>;
-WrapFormattedMessage.propTypes = {
-  children: PropTypes.any,
-};
-
-
 export default @connect(mapStateToProps)
 @injectIntl
 class Explore extends React.PureComponent {
@@ -78,12 +68,22 @@ class Explore extends React.PureComponent {
           {isSearching ? (
             <SearchResults />
           ) : (
-            <React.Fragment>
+            <>
               <div className='account__section-headline'>
-                <NavLink exact to='/explore'><WrapFormattedMessage id='explore.trending_statuses' defaultMessage='Posts' /></NavLink>
-                <NavLink exact to='/explore/tags'><WrapFormattedMessage id='explore.trending_tags' defaultMessage='Hashtags' /></NavLink>
-                <NavLink exact to='/explore/links'><WrapFormattedMessage id='explore.trending_links' defaultMessage='News' /></NavLink>
-                {signedIn && <NavLink exact to='/explore/suggestions'><WrapFormattedMessage id='explore.suggested_follows' defaultMessage='For you' /></NavLink>}
+                <NavLink exact to='/explore'>
+                  <FormattedMessage tagName='div' id='explore.trending_statuses' defaultMessage='Posts' />
+                </NavLink>
+                <NavLink exact to='/explore/tags'>
+                  <FormattedMessage tagName='div' id='explore.trending_tags' defaultMessage='Hashtags' />
+                </NavLink>
+                <NavLink exact to='/explore/links'>
+                  <FormattedMessage tagName='div' id='explore.trending_links' defaultMessage='News' />
+                </NavLink>
+                {signedIn && (
+                  <NavLink exact to='/explore/suggestions'>
+                    <FormattedMessage tagName='div' id='explore.suggested_follows' defaultMessage='For you' />
+                  </NavLink>
+                )}
               </div>
 
               <Switch>
@@ -97,7 +97,7 @@ class Explore extends React.PureComponent {
                 <title>{intl.formatMessage(messages.title)}</title>
                 <meta name='robots' content={isSearching ? 'noindex' : 'all'} />
               </Helmet>
-            </React.Fragment>
+            </>
           )}
         </div>
       </Column>
diff --git a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
index ede8907e5..ac7863ed3 100644
--- a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.js
@@ -38,7 +38,7 @@ class ColumnSettings extends React.PureComponent {
     } else {
       return tags;
     }
-  };
+  }
 
   onSelect = mode => value => {
     const oldValue = this.tags(mode);
@@ -98,7 +98,7 @@ class ColumnSettings extends React.PureComponent {
     default:
       return '';
     }
-  };
+  }
 
   render () {
     const { settings, onChange } = this.props;
diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.js b/app/javascript/mastodon/features/hashtag_timeline/index.js
index b635c3529..733f54ff3 100644
--- a/app/javascript/mastodon/features/hashtag_timeline/index.js
+++ b/app/javascript/mastodon/features/hashtag_timeline/index.js
@@ -194,7 +194,7 @@ class HashtagTimeline extends React.PureComponent {
       const following = tag.get('following');
 
       followButton = (
-        <button className={classNames('column-header__button')} onClick={this.handleFollow} disabled={!signedIn} title={intl.formatMessage(following ? messages.unfollowHashtag : messages.followHashtag)} aria-label={intl.formatMessage(following ? messages.unfollowHashtag : messages.followHashtag)}>
+        <button className={classNames('column-header__button')} onClick={this.handleFollow} disabled={!signedIn} active={following} title={intl.formatMessage(following ? messages.unfollowHashtag : messages.followHashtag)} aria-label={intl.formatMessage(following ? messages.unfollowHashtag : messages.followHashtag)}>
           <Icon id={following ? 'user-times' : 'user-plus'} fixedWidth className='column-header__icon' />
         </button>
       );
diff --git a/app/javascript/mastodon/features/list_timeline/index.js b/app/javascript/mastodon/features/list_timeline/index.js
index f1829d34d..c2e72e2e9 100644
--- a/app/javascript/mastodon/features/list_timeline/index.js
+++ b/app/javascript/mastodon/features/list_timeline/index.js
@@ -126,7 +126,7 @@ class ListTimeline extends React.PureComponent {
       onConfirm: () => {
         dispatch(deleteList(id));
 
-        if (!!columnId) {
+        if (columnId) {
           dispatch(removeColumn(columnId));
         } else {
           this.context.router.history.push('/lists');
diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js
index c1242754c..46ee9f6c1 100644
--- a/app/javascript/mastodon/features/status/components/action_bar.js
+++ b/app/javascript/mastodon/features/status/components/action_bar.js
@@ -7,7 +7,7 @@ import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
 import { defineMessages, injectIntl } from 'react-intl';
 import { me } from '../../../initial_state';
 import classNames from 'classnames';
-import { PERMISSION_MANAGE_USERS } from 'mastodon/permissions';
+import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
 
 const messages = defineMessages({
   delete: { id: 'status.delete', defaultMessage: 'Delete' },
@@ -34,6 +34,7 @@ const messages = defineMessages({
   embed: { id: 'status.embed', defaultMessage: 'Embed' },
   admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
   admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
+  admin_domain: { id: 'status.admin_domain', defaultMessage: 'Open moderation interface for {domain}' },
   copy: { id: 'status.copy', defaultMessage: 'Copy link to status' },
   blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
   unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
@@ -243,10 +244,16 @@ class ActionBar extends React.PureComponent {
         }
       }
 
-      if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
+      if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS || (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION)) {
         menu.push(null);
-        menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
-        menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
+        if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
+          menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
+          menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
+        }
+        if (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION) {
+          const domain = account.get('acct').split('@')[1];
+          menu.push({ text: intl.formatMessage(messages.admin_domain, { domain: domain }), href: `/admin/instances/${domain}` });
+        }
       }
     }
 
diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js
index f4824f045..e7def800e 100644
--- a/app/javascript/mastodon/features/ui/components/columns_area.js
+++ b/app/javascript/mastodon/features/ui/components/columns_area.js
@@ -97,7 +97,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
       if (this.mediaQuery.removeEventListener) {
         this.mediaQuery.removeEventListener('change', this.handleLayoutChange);
       } else {
-        this.mediaQuery.removeListener(this.handleLayouteChange);
+        this.mediaQuery.removeListener(this.handleLayoutChange);
       }
     }
   }
diff --git a/app/javascript/mastodon/features/ui/components/disabled_account_banner.js b/app/javascript/mastodon/features/ui/components/disabled_account_banner.js
index cc8cc3285..038cc3553 100644
--- a/app/javascript/mastodon/features/ui/components/disabled_account_banner.js
+++ b/app/javascript/mastodon/features/ui/components/disabled_account_banner.js
@@ -89,4 +89,4 @@ class DisabledAccountBanner extends React.PureComponent {
     );
   }
 
-};
+}
diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.js b/app/javascript/mastodon/features/ui/components/focal_point_modal.js
index ba8aa8f03..479f4abd2 100644
--- a/app/javascript/mastodon/features/ui/components/focal_point_modal.js
+++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.js
@@ -291,11 +291,11 @@ class FocalPointModal extends ImmutablePureComponent {
     let descriptionLabel = null;
 
     if (media.get('type') === 'audio') {
-      descriptionLabel = <FormattedMessage id='upload_form.audio_description' defaultMessage='Describe for people with hearing loss' />;
+      descriptionLabel = <FormattedMessage id='upload_form.audio_description' defaultMessage='Describe for people who are hard of hearing' />;
     } else if (media.get('type') === 'video') {
-      descriptionLabel = <FormattedMessage id='upload_form.video_description' defaultMessage='Describe for people with hearing loss or visual impairment' />;
+      descriptionLabel = <FormattedMessage id='upload_form.video_description' defaultMessage='Describe for people who are deaf, hard of hearing, blind or have low vision' />;
     } else {
-      descriptionLabel = <FormattedMessage id='upload_form.description' defaultMessage='Describe for the visually impaired' />;
+      descriptionLabel = <FormattedMessage id='upload_form.description' defaultMessage='Describe for people who are blind or have low vision' />;
     }
 
     let ocrMessage = '';
diff --git a/app/javascript/mastodon/features/ui/components/link_footer.js b/app/javascript/mastodon/features/ui/components/link_footer.js
index c29aac418..3664a05bf 100644
--- a/app/javascript/mastodon/features/ui/components/link_footer.js
+++ b/app/javascript/mastodon/features/ui/components/link_footer.js
@@ -52,6 +52,8 @@ class LinkFooter extends React.PureComponent {
     const canInvite = signedIn && ((permissions & PERMISSION_INVITE_USERS) === PERMISSION_INVITE_USERS);
     const canProfileDirectory = profileDirectory;
 
+    const DividingCircle = <span aria-hidden>{' · '}</span>;
+
     return (
       <div className='link-footer'>
         <p>
@@ -60,17 +62,17 @@ class LinkFooter extends React.PureComponent {
           <Link key='about' to='/about'><FormattedMessage id='footer.about' defaultMessage='About' /></Link>
           {canInvite && (
             <>
-              {' · '}
+              {DividingCircle}
               <a key='invites' href='/invites' target='_blank'><FormattedMessage id='footer.invite' defaultMessage='Invite people' /></a>
             </>
           )}
           {canProfileDirectory && (
             <>
-              {' · '}
+              {DividingCircle}
               <Link key='directory' to='/directory'><FormattedMessage id='footer.directory' defaultMessage='Profiles directory' /></Link>
             </>
           )}
-          {' · '}
+          {DividingCircle}
           <Link key='privacy-policy' to='/privacy-policy'><FormattedMessage id='footer.privacy_policy' defaultMessage='Privacy policy' /></Link>
         </p>
 
@@ -78,17 +80,17 @@ class LinkFooter extends React.PureComponent {
           <strong>Mastodon</strong>:
           {' '}
           <a href='https://joinmastodon.org' target='_blank'><FormattedMessage id='footer.about' defaultMessage='About' /></a>
-          {' · '}
+          {DividingCircle}
           <a href='https://joinmastodon.org/apps' target='_blank'><FormattedMessage id='footer.get_app' defaultMessage='Get the app' /></a>
-          {' · '}
+          {DividingCircle}
           <Link to='/keyboard-shortcuts'><FormattedMessage id='footer.keyboard_shortcuts' defaultMessage='Keyboard shortcuts' /></Link>
-          {' · '}
+          {DividingCircle}
           <a href={source_url} rel='noopener noreferrer' target='_blank'><FormattedMessage id='footer.source_code' defaultMessage='View source code' /></a>
-          {' · '}
+          {DividingCircle}
           v{version}
         </p>
       </div>
     );
   }
 
-};
+}
diff --git a/app/javascript/mastodon/features/ui/components/video_modal.js b/app/javascript/mastodon/features/ui/components/video_modal.js
index d3bd034cb..a1533eba0 100644
--- a/app/javascript/mastodon/features/ui/components/video_modal.js
+++ b/app/javascript/mastodon/features/ui/components/video_modal.js
@@ -40,6 +40,7 @@ export default class VideoModal extends ImmutablePureComponent {
             autoPlay={options.autoPlay}
             volume={options.defaultVolume}
             onCloseVideo={onClose}
+            autoFocus
             detailed
             alt={media.get('description')}
           />
diff --git a/app/javascript/mastodon/features/ui/util/react_router_helpers.js b/app/javascript/mastodon/features/ui/util/react_router_helpers.js
index 2ee06c3ff..205dd6f10 100644
--- a/app/javascript/mastodon/features/ui/util/react_router_helpers.js
+++ b/app/javascript/mastodon/features/ui/util/react_router_helpers.js
@@ -46,7 +46,7 @@ export class WrappedRoute extends React.Component {
     return {
       hasError: true,
     };
-  };
+  }
 
   state = {
     hasError: false,
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index 4f90e955f..1c35ca9d1 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -122,6 +122,7 @@ class Video extends React.PureComponent {
     volume: PropTypes.number,
     muted: PropTypes.bool,
     componentIndex: PropTypes.number,
+    autoFocus: PropTypes.bool,
   };
 
   static defaultProps = {
@@ -523,7 +524,7 @@ class Video extends React.PureComponent {
   }
 
   render () {
-    const { preview, src, inline, onOpenVideo, onCloseVideo, intl, alt, detailed, sensitive, editable, blurhash } = this.props;
+    const { preview, src, inline, onOpenVideo, onCloseVideo, intl, alt, detailed, sensitive, editable, blurhash, autoFocus } = this.props;
     const { containerWidth, currentTime, duration, volume, buffer, dragging, paused, fullscreen, hovered, muted, revealed } = this.state;
     const progress = Math.min((currentTime / duration) * 100, 100);
     const playerStyle = {};
@@ -617,7 +618,7 @@ class Video extends React.PureComponent {
 
           <div className='video-player__buttons-bar'>
             <div className='video-player__buttons left'>
-              <button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay} autoFocus={detailed}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
+              <button type='button' title={intl.formatMessage(paused ? messages.play : messages.pause)} aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} className='player-button' onClick={this.togglePlay} autoFocus={autoFocus}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
               <button type='button' title={intl.formatMessage(muted ? messages.unmute : messages.mute)} aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} className='player-button' onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
 
               <div className={classNames('video-player__volume', { active: this.state.hovered })} onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
diff --git a/app/javascript/mastodon/load_polyfills.js b/app/javascript/mastodon/load_polyfills.js
index cc5bcd18f..f5a897f75 100644
--- a/app/javascript/mastodon/load_polyfills.js
+++ b/app/javascript/mastodon/load_polyfills.js
@@ -23,15 +23,14 @@ function loadPolyfills() {
   );
 
   // Latest version of Firefox and Safari do not have IntersectionObserver.
-  // Edge does not have requestIdleCallback and object-fit CSS property.
+  // Edge does not have requestIdleCallback.
   // This avoids shipping them all the polyfills.
   const needsExtraPolyfills = !(
     window.AbortController &&
     window.IntersectionObserver &&
     window.IntersectionObserverEntry &&
     'isIntersecting' in IntersectionObserverEntry.prototype &&
-    window.requestIdleCallback &&
-    'object-fit' in (new Image()).style
+    window.requestIdleCallback
   );
 
   return Promise.all([
diff --git a/app/javascript/mastodon/locales/af.json b/app/javascript/mastodon/locales/af.json
index 60a814373..abd664fc8 100644
--- a/app/javascript/mastodon/locales/af.json
+++ b/app/javascript/mastodon/locales/af.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Plasings en antwoorde",
   "account.report": "Rapporteer @{name}",
   "account.requested": "Wag op goedkeuring. Klik om volgversoek te kanselleer",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Deel @{name} se profiel",
   "account.show_reblogs": "Wys aangestuurde plasings van @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Plaas} other {{counter} Plasings}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Soek tale...",
   "compose_form.direct_message_warning_learn_more": "Leer meer",
   "compose_form.encryption_warning": "Plasings op Mastodon is nie van punt tot punt versleutel nie. Moet geen sensitiewe inligting op Mastodon deel nie.",
-  "compose_form.hashtag_warning": "Hierdie plasing is ongelys en sal dus onder geen hutsetiket verskyn nie. Slegs openbare plasings is vindbaar wanneer daar na hutsetikette gesoek word.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Jou rekening is nie {locked} nie. Enigiemand kan jou volg en sien wat jy vir jou volgers plaas.",
   "compose_form.lock_disclaimer.lock": "gesluit",
   "compose_form.placeholder": "Wat wil jy deel?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Soekresultate",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open hierdie plasing as moderator",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/an.json b/app/javascript/mastodon/locales/an.json
index 83722156b..0a86e32ef 100644
--- a/app/javascript/mastodon/locales/an.json
+++ b/app/javascript/mastodon/locales/an.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Publicacions y respuestas",
   "account.report": "Denunciar a @{name}",
   "account.requested": "Esperando l'aprebación",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Compartir lo perfil de @{name}",
   "account.show_reblogs": "Amostrar retutz de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Publicación} other {{counter} Publicaciones}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Buscar idiomas...",
   "compose_form.direct_message_warning_learn_more": "Aprender mas",
   "compose_form.encryption_warning": "Las publicacions en Mastodon no son zifradas de cabo a cabo. No comparta garra información sensible en Mastodon.",
-  "compose_form.hashtag_warning": "Esta publicación no s'amostrará baixo garra hashtag perque no ye listada. Nomás las publicacions publicas se pueden buscar per hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "La tuya cuenta no ye {locked}. Totz pueden seguir-te pa veyer las tuyas publicacions nomás pa seguidores.",
   "compose_form.lock_disclaimer.lock": "blocau",
   "compose_form.placeholder": "En qué yes pensando?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copiar lo seguimiento de pila en o portafuellas",
   "errors.unexpected_crash.report_issue": "Informar d'un problema/error",
   "explore.search_results": "Resultaus de busqueda",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explorar",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Esta categoría de filtro no s'aplica a lo contexto en o qual ha accediu a esta publlicación. Si quiers que la publicación sía filtrada tamién en este contexto, habrás d'editar lo filtro.",
   "filter_modal.added.context_mismatch_title": "Lo contexto no coincide!",
   "filter_modal.added.expired_explanation": "Esta categoría de filtro ha caducau, amenesterá cambiar la calendata de caducidat pa que s'aplique.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Iniciar sesión",
   "sign_in_banner.text": "Inicia sesión en este servidor pa seguir perfils u etiquetas, alzar, compartir y responder a mensaches. Tamién puetz interactuar dende unatra cuenta en un servidor diferent.",
   "status.admin_account": "Ubrir interficie de moderación pa @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Ubrir este estau en a interficie de moderación",
   "status.block": "Blocar a @{name}",
   "status.bookmark": "Anyadir marcador",
@@ -553,7 +559,7 @@
   "status.favourite": "Favorito",
   "status.filter": "Filtrar esta publicación",
   "status.filtered": "Filtrau",
-  "status.hide": "Amagar publicación",
+  "status.hide": "Hide post",
   "status.history.created": "{name} creyó {date}",
   "status.history.edited": "{name} editó {date}",
   "status.load_more": "Cargar mas",
diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json
index 6c95d47d6..87804ab07 100644
--- a/app/javascript/mastodon/locales/ar.json
+++ b/app/javascript/mastodon/locales/ar.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "المنشورات والرُدود",
   "account.report": "الإبلاغ عن @{name}",
   "account.requested": "في انتظار القبول. اضغط لإلغاء طلب المُتابعة",
+  "account.requested_follow": "لقد طلب {name} متابعتك",
   "account.share": "شارِك الملف التعريفي لـ @{name}",
   "account.show_reblogs": "عرض مشاركات @{name}",
   "account.statuses_counter": "{count, plural, zero {لَا منشورات} one {منشور واحد} two {منشوران إثنان} few {{counter} منشورات} many {{counter} منشورًا} other {{counter} منشور}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "البحث عن لغة…",
   "compose_form.direct_message_warning_learn_more": "تَعَلَّم المَزيد",
   "compose_form.encryption_warning": "إنّ المنشورات على ماستدون ليست مشفرة من النهاية إلى النهاية. لا تشارك أي معلومات حساسة عبر ماستدون.",
-  "compose_form.hashtag_warning": "لن يُدرَج هذا المنشور تحت أي وسم بما أنَّه غير مُدرَج. فقط المنشورات العامة يُمكن البحث عنها بواسطة الوسم.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "حسابُك غير {locked}. يُمكن لأي شخص مُتابعتك لرؤية (منشورات المتابعين فقط).",
   "compose_form.lock_disclaimer.lock": "مُقفَل",
   "compose_form.placeholder": "فِيمَ تُفكِّر؟",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "انسخ تتبع الارتباطات إلى الحافظة",
   "errors.unexpected_crash.report_issue": "الإبلاغ عن خلل",
   "explore.search_results": "نتائج البحث",
+  "explore.suggested_follows": "لك",
   "explore.title": "استكشف",
+  "explore.trending_links": "الأخبار",
+  "explore.trending_statuses": "المنشورات",
+  "explore.trending_tags": "هاشتاجات",
   "filter_modal.added.context_mismatch_explanation": "فئة عامل التصفية هذه لا تنطبق على السياق الذي وصلت فيه إلى هذه المشاركة. إذا كنت ترغب في تصفية المنشور في هذا السياق أيضا، فسيتعين عليك تعديل عامل التصفية.",
   "filter_modal.added.context_mismatch_title": "عدم تطابق السياق!",
   "filter_modal.added.expired_explanation": "انتهت صلاحية فئة عامل التصفية هذه، سوف تحتاج إلى تغيير تاريخ انتهاء الصلاحية لتطبيقها.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "تسجيل الدخول",
   "sign_in_banner.text": "قم بالولوج بحسابك لمتابعة الصفحات الشخصية أو الوسوم، أو لإضافة الرسائل إلى المفضلة ومشاركتها والرد عليها أو التفاعل بواسطة حسابك المتواجد على خادم مختلف.",
   "status.admin_account": "افتح الواجهة الإدارية لـ @{name}",
+  "status.admin_domain": "فتح واجهة الإشراف لـ {domain}",
   "status.admin_status": "افتح هذا المنشور على واجهة الإشراف",
   "status.block": "احجب @{name}",
   "status.bookmark": "أضفه إلى الفواصل المرجعية",
@@ -553,7 +559,7 @@
   "status.favourite": "أضف إلى المفضلة",
   "status.filter": "تصفية هذه الرسالة",
   "status.filtered": "مُصفّى",
-  "status.hide": "اخف التبويق",
+  "status.hide": "إخفاء المنشور",
   "status.history.created": "أنشأه {name} {date}",
   "status.history.edited": "عدله {name} {date}",
   "status.load_more": "حمّل المزيد",
diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json
index e287b9a46..484a263cf 100644
--- a/app/javascript/mastodon/locales/ast.json
+++ b/app/javascript/mastodon/locales/ast.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Artículos ya rempuestes",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval. Click to cancel follow request",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Amosar los artículos compartíos de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} artículu} other {{counter} artículos}}",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Resultaos de la busca",
+  "explore.suggested_follows": "Pa ti",
   "explore.title": "Esploración",
+  "explore.trending_links": "Noticies",
+  "explore.trending_statuses": "Artículos",
+  "explore.trending_tags": "Etiquetes",
   "filter_modal.added.context_mismatch_explanation": "Esta categoría de peñera nun s'aplica al contestu nel qu'accediesti a esti artículu. Si tamién quies que se peñere l'artículu nesti contestu, tienes d'editar la peñera.",
   "filter_modal.added.context_mismatch_title": "¡El contestu nun coincide!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -257,7 +262,7 @@
   "follow_recommendations.lead": "Los artículos de los perfiles que sigas van apaecer n'orde cronolóxicu nel to feed d'aniciu. ¡Nun tengas mieu d'enquivocate, pues dexar de siguilos con facilidá en cualesquier momentu!",
   "follow_request.authorize": "Autorizar",
   "follow_request.reject": "Refugar",
-  "follow_requests.unlocked_explanation": "Magar que la cuenta nun tea bloquiada, ye posible que'l personal del dominiu {domain} quiera revisar manualmente les solicitúes de siguimientu d'estes cuentes.",
+  "follow_requests.unlocked_explanation": "Magar que la to cuenta nun seya privada, el personal del dominiu «{domain}» pensó qu'a lo meyor quies revisar manualmente les solicitúes de siguimientu d'estes cuentes.",
   "footer.about": "Tocante a",
   "footer.directory": "Direutoriu de perfiles",
   "footer.get_app": "Consiguir l'aplicación",
@@ -387,7 +392,7 @@
   "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
   "notification.admin.report": "{name} informó de: {target}",
   "notification.admin.sign_up": "{name} rexistróse",
-  "notification.favourite": "{name} favourited your status",
+  "notification.favourite": "{name} marcó'l to artículu como favoritu",
   "notification.follow": "{name} siguióte",
   "notification.follow_request": "{name} solicitó siguite",
   "notification.mention": "{name} mentóte",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Anicia la sesión pa siguir a perfiles o etiquetes, marcar como favoritu, compartir o responder a artículos, o interactuar cola to cuenta nun sirvidor diferente.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Meter en Marcadores",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Anubrir l'artículu",
   "status.history.created": "{name} creó {date}",
   "status.history.edited": "{name} editó {date}",
   "status.load_more": "Cargar más",
@@ -617,13 +623,13 @@
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
   "upload_error.poll": "La xuba de ficheros nun ta permitida coles encuestes.",
-  "upload_form.audio_description": "Descripción pa persones con perda auditiva",
-  "upload_form.description": "Descripción pa persones con discapacidá visual",
+  "upload_form.audio_description": "Describe for people who are hard of hearing",
+  "upload_form.description": "Describe for people who are blind or have low vision",
   "upload_form.description_missing": "Nun s'amestó la descripción",
   "upload_form.edit": "Editar",
   "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Desaniciar",
-  "upload_form.video_description": "Descripción pa persones con perda auditiva o discapacidá visual",
+  "upload_form.video_description": "Describe for people who are deaf, hard of hearing, blind or have low vision",
   "upload_modal.analyzing_picture": "Analizando la semeya…",
   "upload_modal.apply": "Aplicar",
   "upload_modal.applying": "Aplicando…",
diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json
index 0e84db718..ff99ec6e4 100644
--- a/app/javascript/mastodon/locales/be.json
+++ b/app/javascript/mastodon/locales/be.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Допісы і адказы",
   "account.report": "Паскардзіцца на @{name}",
   "account.requested": "Чакаецца ўхваленне. Націсніце, каб скасаваць запыт на падпіску",
+  "account.requested_follow": "{name} адправіў запыт на падпіску",
   "account.share": "Абагуліць профіль @{name}",
   "account.show_reblogs": "Паказаць падштурхоўванні ад @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} допіс} few {{counter} допісы} many {{counter} допісаў} other {{counter} допісу}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Шукаць мовы...",
   "compose_form.direct_message_warning_learn_more": "Даведацца больш",
   "compose_form.encryption_warning": "Допісы ў Mastodon не абаронены скразным шыфраваннем. Не дзяліцеся ніякай канфідэнцыяльнай інфармацыяй в Mastodon.",
-  "compose_form.hashtag_warning": "Гэты допіс не будзе паказаны пад аніякім хэштэгам, так як ён мае тып \"Не паказваць у стужках\". Толькі публічныя допісы могуць быць знойдзены па хэштэгу.",
+  "compose_form.hashtag_warning": "Гэты допіс не будзе паказаны пад аніякім хэштэгам, бо ён не публічны. Толькі публічныя допісы можна знайсці па хэштэгу.",
   "compose_form.lock_disclaimer": "Ваш уліковы запіс не {locked}. Усе могуць падпісацца на вас, каб бачыць допісы толькі для падпісчыкаў.",
   "compose_form.lock_disclaimer.lock": "закрыты",
   "compose_form.placeholder": "Што здарылася?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Дадаць дыягнастычны стэк у буфер абмену",
   "errors.unexpected_crash.report_issue": "Паведаміць аб праблеме",
   "explore.search_results": "Вынікі пошуку",
+  "explore.suggested_follows": "Для вас",
   "explore.title": "Агляд",
+  "explore.trending_links": "Навіны",
+  "explore.trending_statuses": "Допісы",
+  "explore.trending_tags": "Хэштэгі",
   "filter_modal.added.context_mismatch_explanation": "Гэтая катэгорыя фільтра не прымяняецца да кантэксту, у якім вы адкрылі гэты пост. Калі вы хочаце, каб паведамленне таксама было адфільтравана ў гэтым кантэксце, вам трэба будзе адрэдагаваць фільтр",
   "filter_modal.added.context_mismatch_title": "Неадпаведны кантэкст!",
   "filter_modal.added.expired_explanation": "Тэрмін дзеяння гэтай катэгорыі фільтраў скончыўся, вам трэба будзе змяніць дату заканчэння тэрміну дзеяння, каб яна прымянялася",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Увайсці",
   "sign_in_banner.text": "Увайдзіце, каб падпісацца на людзей і тэгі, каб адказваць на допісы, дзяліцца імі і падабаць іх, альбо кантактаваць з вашага ўліковага запісу на іншым серверы.",
   "status.admin_account": "Адкрыць інтэрфейс мадэратара для @{name}",
+  "status.admin_domain": "Адкрыць інтэрфейс мадэратара для {domain}",
   "status.admin_status": "Адкрыць гэты допіс у інтэрфейсе мадэрацыі",
   "status.block": "Заблакаваць @{name}",
   "status.bookmark": "Дадаць закладку",
diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json
index f04f6054d..284d162b1 100644
--- a/app/javascript/mastodon/locales/bg.json
+++ b/app/javascript/mastodon/locales/bg.json
@@ -12,7 +12,7 @@
   "about.powered_by": "Децентрализирана социална мрежа, захранвана от {mastodon}",
   "about.rules": "Правила на сървъра",
   "account.account_note_header": "Бележка",
-  "account.add_or_remove_from_list": "Добави или премахни от списъците",
+  "account.add_or_remove_from_list": "Добавяне или премахване от списъци",
   "account.badges.bot": "Бот",
   "account.badges.group": "Група",
   "account.block": "Блокиране на @{name}",
@@ -36,11 +36,11 @@
   "account.following": "Последвани",
   "account.following_counter": "{count, plural, one {{counter} последван} other {{counter} последвани}}",
   "account.follows.empty": "Потребителят още никого не следва.",
-  "account.follows_you": "Ваш последовател",
+  "account.follows_you": "Следва ви",
   "account.go_to_profile": "Към профила",
-  "account.hide_reblogs": "Скриване на споделяния от @{name}",
+  "account.hide_reblogs": "Скриване на подсилвания от @{name}",
   "account.joined_short": "Дата на присъединяване",
-  "account.languages": "Смяна на показваните езици",
+  "account.languages": "Промяна на езиците, за които сте абонирани",
   "account.link_verified_on": "Собствеността върху тази връзка е проверена на {date}",
   "account.locked_info": "Състоянието за поверителността на акаунта е зададено заключено. Собственикът преглежда ръчно от кого може да се следва.",
   "account.media": "Мултимедия",
@@ -49,21 +49,22 @@
   "account.mute": "Заглушаване на @{name}",
   "account.mute_notifications": "Заглушаване на известия от @{name}",
   "account.muted": "Заглушено",
-  "account.open_original_page": "Отваряне на оригиналната страница",
+  "account.open_original_page": "Отваряне на първообразната страница",
   "account.posts": "Публикации",
-  "account.posts_with_replies": "С отговори",
+  "account.posts_with_replies": "Публ. и отговори",
   "account.report": "Докладване на @{name}",
   "account.requested": "Чака се одобрение. Щракнете за отмяна на заявката за последване",
-  "account.share": "Изпращане на профила на @{name}",
-  "account.show_reblogs": "Показване на споделяния от @{name}",
+  "account.requested_follow": "{name} поиска да ви последва",
+  "account.share": "Споделяне на профила на @{name}",
+  "account.show_reblogs": "Показване на подсилвания от @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} публикация} other {{counter} публикации}}",
   "account.unblock": "Отблокиране на @{name}",
   "account.unblock_domain": "Отблокиране на домейн {domain}",
-  "account.unblock_short": "Отблокирване",
+  "account.unblock_short": "Отблокиране",
   "account.unendorse": "Не включвайте в профила",
-  "account.unfollow": "Не следвай",
+  "account.unfollow": "Стоп на следването",
   "account.unmute": "Без заглушаване на @{name}",
-  "account.unmute_notifications": "Без заглушаване на известия от @{name}",
+  "account.unmute_notifications": "Изпращане на известия от @{name}",
   "account.unmute_short": "Без заглушаване",
   "account_note.placeholder": "Щракнете, за да добавите бележка",
   "admin.dashboard.daily_retention": "Ниво на задържани на потребители след регистрация, в дни",
@@ -92,7 +93,7 @@
   "bundle_modal_error.close": "Затваряне",
   "bundle_modal_error.message": "Нещо се обърка, зареждайки компонента.",
   "bundle_modal_error.retry": "Нов опит",
-  "closed_registrations.other_server_instructions": "Поради това че Mastodon е децентрализиран, можеш да създадеш акаунт на друг сървър, от който можеш да комуникираш с този.",
+  "closed_registrations.other_server_instructions": "Oткак e децентрализиранa Mastodon, може да създадете акаунт на друг сървър и още може да взаимодействате с този.",
   "closed_registrations_modal.description": "Създаването на акаунт в {domain} сега не е възможно, но обърнете внимание, че нямате нужда от акаунт конкретно на {domain}, за да ползвате Mastodon.",
   "closed_registrations_modal.find_another_server": "Намиране на друг сървър",
   "closed_registrations_modal.preamble": "Mastodon е децентрализиран, така че няма значение къде създавате акаунта си, ще може да последвате и взаимодействате с всеки на този сървър. Може дори да стартирате свой собствен сървър!",
@@ -127,14 +128,14 @@
   "compose.language.search": "Търсене на езици...",
   "compose_form.direct_message_warning_learn_more": "Още информация",
   "compose_form.encryption_warning": "Публикациите в Mastodon не са криптирани от край до край. Не споделяйте никаква чувствителна информация там.",
-  "compose_form.hashtag_warning": "Тази публикация няма да бъде изброена под нито един хаштаг, тъй като е скрита. Само публични публикации могат да се търсят по хаштаг.",
-  "compose_form.lock_disclaimer": "Вашият акаунт не е {locked}. Всеки може да ви последва, за да прегледа вашите публикации само за последователи.",
+  "compose_form.hashtag_warning": "Тази публикация няма да се вписва под никакъв хаштаг, тъй като не е обществена. Само публични публикации могат да се търсят по хаштаг.",
+  "compose_form.lock_disclaimer": "Вашият акаунт не е в положение {locked}. Всеки може да ви последва, за да разглежда публикациите ви само за последователи.",
   "compose_form.lock_disclaimer.lock": "заключено",
   "compose_form.placeholder": "Какво мислите?",
   "compose_form.poll.add_option": "Добавяне на избор",
   "compose_form.poll.duration": "Времетраене на анкетата",
   "compose_form.poll.option_placeholder": "Избор {number}",
-  "compose_form.poll.remove_option": "Премахване на избора",
+  "compose_form.poll.remove_option": "Премахване на този избор",
   "compose_form.poll.switch_to_multiple": "Промяна на анкетата, за да се позволят множество възможни избора",
   "compose_form.poll.switch_to_single": "Промяна на анкетата, за да се позволи един възможен избор",
   "compose_form.publish": "Публикуване",
@@ -142,11 +143,11 @@
   "compose_form.publish_loud": "{publish}!",
   "compose_form.save_changes": "Запазване на промените",
   "compose_form.sensitive.hide": "{count, plural, one {Маркиране на мултимедията като деликатна} other {Маркиране на мултимедиите като деликатни}}",
-  "compose_form.sensitive.marked": "{count, plural, one {Мултимедията е маркирана като деликатна} other {Мултимедиите са маркирани като деликатни}}",
+  "compose_form.sensitive.marked": "{count, plural, one {мултимедия е означена като деликатна} other {мултимедии са означени като деликатни}}",
   "compose_form.sensitive.unmarked": "{count, plural, one {Мултимедията не е маркирана като деликатна} other {Мултимедиите не са маркирани като деликатни}}",
   "compose_form.spoiler.marked": "Премахване на предупреждението за съдържание",
   "compose_form.spoiler.unmarked": "Добавяне на предупреждение за съдържание",
-  "compose_form.spoiler_placeholder": "Напишете предупреждение",
+  "compose_form.spoiler_placeholder": "Тук напишете предупреждението си",
   "confirmation_modal.cancel": "Отказ",
   "confirmations.block.block_and_report": "Блокиране и докладване",
   "confirmations.block.confirm": "Блокиране",
@@ -167,7 +168,7 @@
   "confirmations.mute.explanation": "Това ще скрие публикациите от тях и публикации, които ги споменават, но все още ще им позволява да виждат публикациите ви и да ви следват.",
   "confirmations.mute.message": "Наистина ли искате да заглушите {name}?",
   "confirmations.redraft.confirm": "Изтриване и преработване",
-  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
+  "confirmations.redraft.message": "Сигурни ли сте, че искате да изтриете тази публикация и да я върнете в чернова? Ще загубите подсилванията и означаванията като любима, и отговорите към оригинала ще останат висящи.",
   "confirmations.reply.confirm": "Отговор",
   "confirmations.reply.message": "Отговарянето сега ще замени съобщението, което в момента съставяте. Сигурни ли сте, че искате да продължите?",
   "confirmations.unfollow.confirm": "Без следване",
@@ -178,13 +179,13 @@
   "conversation.with": "С {names}",
   "copypaste.copied": "Копирано",
   "copypaste.copy": "Копиране",
-  "directory.federated": "От познатата федивселена",
+  "directory.federated": "От позната федивселена",
   "directory.local": "Само от {domain}",
   "directory.new_arrivals": "Новодошли",
   "directory.recently_active": "Наскоро дейни",
   "disabled_account_banner.account_settings": "Настройки на акаунта",
   "disabled_account_banner.text": "Вашият акаунт {disabledAccount} сега е изключен.",
-  "dismissable_banner.community_timeline": "Ето най-скорошните публични публикации, създадени от акаунти в {domain}.",
+  "dismissable_banner.community_timeline": "Ето най-скорошните публични публикации от хора, чиито акаунти са разположени в {domain}.",
   "dismissable_banner.dismiss": "Отхвърляне",
   "dismissable_banner.explore_links": "Тези новини се разказват от хората в този и други сървъри на децентрализираната мрежа точно сега.",
   "dismissable_banner.explore_statuses": "Тези публикации от този и други сървъри в децентрализираната мрежа набират популярност сега на този сървър.",
@@ -194,7 +195,7 @@
   "embed.preview": "Ето как ще изглежда:",
   "emoji_button.activity": "Дейност",
   "emoji_button.clear": "Изчистване",
-  "emoji_button.custom": "Персонализирани",
+  "emoji_button.custom": "Персонализирано",
   "emoji_button.flags": "Знамена",
   "emoji_button.food": "Храна и напитки",
   "emoji_button.label": "Вмъкване на емоджи",
@@ -207,35 +208,39 @@
   "emoji_button.search_results": "Резултати от търсене",
   "emoji_button.symbols": "Символи",
   "emoji_button.travel": "Пътуване и места",
-  "empty_column.account_suspended": "Профилът е спрян",
+  "empty_column.account_suspended": "Спрян акаунт",
   "empty_column.account_timeline": "Тук няма публикации!",
-  "empty_column.account_unavailable": "Няма достъп до профила",
+  "empty_column.account_unavailable": "Профилът не е наличен",
   "empty_column.blocks": "Още не сте блокирали никакви потребители.",
   "empty_column.bookmarked_statuses": "Още не сте отметнали публикации. Отметвайки някоя, то тя ще се покаже тук.",
   "empty_column.community": "Локалният инфопоток е празен. Публикувайте нещо, за да започнете!",
   "empty_column.direct": "Все още нямате лични съобщения. Когато изпратите или получите някое, то ще се покаже тук.",
   "empty_column.domain_blocks": "Още няма блокирани домейни.",
-  "empty_column.explore_statuses": "Няма нищо популярно в момента. Проверете пак по-късно!",
+  "empty_column.explore_statuses": "Няма нищо налагащо се в момента. Проверете пак по-късно!",
   "empty_column.favourited_statuses": "Още нямате любими публикации. Поставяйки някоя в любими, то тя ще се покаже тук.",
   "empty_column.favourites": "Още никой не е поставил публикацията в любими. Когато някой го направи, този човек ще се покаже тук.",
-  "empty_column.follow_recommendations": "Изглежда, че няма генерирани предложения за вас. Можете да опитате да търсите за хора, които знаете или да разгледате популярните тагове.",
-  "empty_column.follow_requests": "Все още нямате заявки за последване. Когато получите такава, тя ще се покаже тук.",
+  "empty_column.follow_recommendations": "Изглежда, че няма предложения, които може да се породят за вас. Може да опитате да потърсите хора, които познавате или да разгледате налагащи се хаштагове.",
+  "empty_column.follow_requests": "Още нямате заявки за последване. Получавайки такава, то тя ще се покаже тук.",
   "empty_column.hashtag": "Още няма нищо в този хаштаг.",
-  "empty_column.home": "Вашият личен инфопоток е празен! Последвайте повече хора, за да го запълните. {suggestions}",
+  "empty_column.home": "Вашата начална часова ос е празна! Последвайте повече хора, за да я запълните. {suggestions}",
   "empty_column.home.suggestions": "Преглед на някои предложения",
-  "empty_column.list": "Още няма нищо в този списък. Когато членовете на списъка публикуват нови публикации, то те ще се появят тук.",
+  "empty_column.list": "Все още списъкът е празен. Членуващите на списъка, публикуващи нови публикации, ще се появят тук.",
   "empty_column.lists": "Все още нямате списъци. Когато създадете такъв, той ще се покаже тук.",
   "empty_column.mutes": "Още не сте заглушавали потребители.",
   "empty_column.notifications": "Все още нямате известия. Взаимодействайте с другите, за да започнете разговора.",
   "empty_column.public": "Тук няма нищо! Публикувайте нещо или последвайте потребители от други сървъри, за да го напълните",
   "error.unexpected_crash.explanation": "Поради грешка в нашия код или проблем със съвместимостта на браузъра, тази страница не може да се покаже правилно.",
-  "error.unexpected_crash.explanation_addons": "Тази страница не може да се покаже правилно. Тази грешка вероятно е причинена от добавка на браузъра или инструменти за автоматичен превод.",
+  "error.unexpected_crash.explanation_addons": "Страницата не можа да се покаже правилно. Тази грешка вероятно е причинена от добавка на браузъра или от средства за автоматичен превод.",
   "error.unexpected_crash.next_steps": "Опитайте да опресните страницата. Ако това не помогне, все още можете да използвате Mastodon чрез различен браузър или приложение.",
   "error.unexpected_crash.next_steps_addons": "Опитайте се да ги изключите и да опресните страницата. Ако това не помогне, то още може да използвате Mastodon чрез различен браузър или приложение.",
-  "errors.unexpected_crash.copy_stacktrace": "Копиране на stacktrace-а в клипборда",
+  "errors.unexpected_crash.copy_stacktrace": "Копиране на трасето на стека в буферната памет",
   "errors.unexpected_crash.report_issue": "Сигнал за проблем",
   "explore.search_results": "Резултати от търсенето",
+  "explore.suggested_follows": "За вас",
   "explore.title": "Разглеждане",
+  "explore.trending_links": "Новини",
+  "explore.trending_statuses": "Публикации",
+  "explore.trending_tags": "Хаштагове",
   "filter_modal.added.context_mismatch_explanation": "Тази категория филтър не е приложима към контекста, в който достъпвате тази публикация. Ако желаете да филтрирате публикациите в този контекст, трябва да изберете друг филтър.",
   "filter_modal.added.context_mismatch_title": "Несъвпадащ контекст!",
   "filter_modal.added.expired_explanation": "Валидността на тази категория филтър е изтекла. Сменете срока на валидност, за да я приложите.",
@@ -245,7 +250,7 @@
   "filter_modal.added.settings_link": "страница с настройки",
   "filter_modal.added.short_explanation": "Тази публикация е добавена към следната категория на филтъра: {title}.",
   "filter_modal.added.title": "Филтърът е добавен!",
-  "filter_modal.select_filter.context_mismatch": "не е приложимо за този контекст",
+  "filter_modal.select_filter.context_mismatch": "неприложимо за контекста",
   "filter_modal.select_filter.expired": "изтекло",
   "filter_modal.select_filter.prompt_new": "Нова категория: {name}",
   "filter_modal.select_filter.search": "Търсене или създаване",
@@ -260,7 +265,7 @@
   "follow_requests.unlocked_explanation": "Въпреки че акаунтът ви не е заключен, служителите на {domain} помислиха, че може да искате да преглеждате ръчно заявките за последване на тези профили.",
   "footer.about": "Относно",
   "footer.directory": "Директория на профилите",
-  "footer.get_app": "Изтегли приложението",
+  "footer.get_app": "Вземане на приложението",
   "footer.invite": "Поканване на хора",
   "footer.keyboard_shortcuts": "Клавишни комбинации",
   "footer.privacy_policy": "Политика за поверителност",
@@ -279,43 +284,43 @@
   "hashtag.follow": "Следване на хаштаг",
   "hashtag.unfollow": "Спиране на следване на хаштаг",
   "home.column_settings.basic": "Основно",
-  "home.column_settings.show_reblogs": "Показване на споделяния",
-  "home.column_settings.show_replies": "Показване на отговори",
-  "home.hide_announcements": "Скриване на оповестявания",
-  "home.show_announcements": "Показване на оповестявания",
-  "interaction_modal.description.favourite": "Ако имате профил в Mastodon, можете да маркирате публикация като любима, за да уведомите автора, че я оценявате, и да я запазите за по-късно.",
-  "interaction_modal.description.follow": "Ако имате профил в Mastodon, можете да последвате {name}, за да виждате постовете от този профил в своя основен инфопоток.",
-  "interaction_modal.description.reblog": "Ако имате профил в Mastodon, можете да споделите тази публикация със своите последователи.",
-  "interaction_modal.description.reply": "Ако имате профил в Mastodon, можете да добавите отговор към тази публикация.",
+  "home.column_settings.show_reblogs": "Показване на подсилванията",
+  "home.column_settings.show_replies": "Показване на отговорите",
+  "home.hide_announcements": "Скриване на оповестяванията",
+  "home.show_announcements": "Показване на оповестяванията",
+  "interaction_modal.description.favourite": "С акаунт в Mastodon може да направите тази публикация като любима, за да известите автора, че я цените, и да я запазите за по-късно.",
+  "interaction_modal.description.follow": "С акаунт в Mastodon може да последвате {name}, за да получавате публикациите от този акаунт в началния си инфоканал.",
+  "interaction_modal.description.reblog": "С акаунт в Mastodon може да подсилите тази публикация, за да я споделите с последователите си.",
+  "interaction_modal.description.reply": "С акаунт в Mastodon може да добавите отговор към тази публикация.",
   "interaction_modal.on_another_server": "На различен сървър",
   "interaction_modal.on_this_server": "На този сървър",
   "interaction_modal.other_server_instructions": "Копипейстнете този URL адрес в полето за търсене на любимото си приложение Mastodon или мрежови интерфейс на своя Mastodon сървър.",
   "interaction_modal.preamble": "Откак Mastodon е децентрализиран, може да употребявате съществуващ акаунт, разположен на друг сървър на Mastodon или съвместима платформа, ако нямате акаунт на този сървър.",
   "interaction_modal.title.favourite": "Любими публикации на {name}",
   "interaction_modal.title.follow": "Последване на {name}",
-  "interaction_modal.title.reblog": "Споделете публикацията от {name}",
+  "interaction_modal.title.reblog": "Подсилване на публикацията на {name}",
   "interaction_modal.title.reply": "Отговаряне на публикацията на {name}",
   "intervals.full.days": "{number, plural, one {# ден} other {# дни}}",
   "intervals.full.hours": "{number, plural, one {# час} other {# часа}}",
   "intervals.full.minutes": "{number, plural, one {# минута} other {# минути}}",
   "keyboard_shortcuts.back": "Навигиране назад",
   "keyboard_shortcuts.blocked": "Отваряне на списъка с блокирани потребители",
-  "keyboard_shortcuts.boost": "за споделяне",
+  "keyboard_shortcuts.boost": "Подсилване на публикация",
   "keyboard_shortcuts.column": "Съсредоточение на колона",
-  "keyboard_shortcuts.compose": "Фокус на текстовото пространство за композиране",
+  "keyboard_shortcuts.compose": "Фокус на текстовата зона за съставяне",
   "keyboard_shortcuts.description": "Опис",
   "keyboard_shortcuts.direct": "за отваряне на колоната с лични съобщения",
   "keyboard_shortcuts.down": "Преместване надолу в списъка",
   "keyboard_shortcuts.enter": "Отваряне на публикация",
-  "keyboard_shortcuts.favourite": "Любима публикация",
+  "keyboard_shortcuts.favourite": "Към любими публикации",
   "keyboard_shortcuts.favourites": "Отваряне на списъка с любими",
   "keyboard_shortcuts.federated": "Отваряне на федерирания инфопоток",
   "keyboard_shortcuts.heading": "Клавишни съчетания",
-  "keyboard_shortcuts.home": "Отваряне на личния инфопоток",
+  "keyboard_shortcuts.home": "Отваряне на началната часова ос",
   "keyboard_shortcuts.hotkey": "Бърз клавиш",
   "keyboard_shortcuts.legend": "Показване на тази легенда",
-  "keyboard_shortcuts.local": "Отваряне на локалния инфопоток",
-  "keyboard_shortcuts.mention": "Споменаване на автор",
+  "keyboard_shortcuts.local": "Отваряне на местна часова ос",
+  "keyboard_shortcuts.mention": "Споменаване на автора",
   "keyboard_shortcuts.muted": "Отваряне на списъка със заглушени потребители",
   "keyboard_shortcuts.my_profile": "Отваряне на профила ви",
   "keyboard_shortcuts.notifications": "Отваряне на колоната с известия",
@@ -325,29 +330,29 @@
   "keyboard_shortcuts.reply": "Отговаряне на публикация",
   "keyboard_shortcuts.requests": "Отваряне на списъка със заявки за последване",
   "keyboard_shortcuts.search": "Фокус на лентата за търсене",
-  "keyboard_shortcuts.spoilers": "за показване/скриване на ПС полето",
+  "keyboard_shortcuts.spoilers": "Показване/скриване на полето за предупреждение на съдържание",
   "keyboard_shortcuts.start": "Отваряне на колоната \"първи стъпки\"",
-  "keyboard_shortcuts.toggle_hidden": "за показване/скриване на текст зад ПС",
+  "keyboard_shortcuts.toggle_hidden": "Показване/скриване на текст зад предупреждение на съдържание",
   "keyboard_shortcuts.toggle_sensitivity": "Показване/скриване на мултимедията",
   "keyboard_shortcuts.toot": "Начало на нова публикация",
-  "keyboard_shortcuts.unfocus": "Разфокусиране на текстовото поле за композиране/търсене",
+  "keyboard_shortcuts.unfocus": "Разфокусиране на текстовото поле за съставяне/търсене",
   "keyboard_shortcuts.up": "Преместване нагоре в списъка",
   "lightbox.close": "Затваряне",
   "lightbox.compress": "Свиване на полето за преглед на образи",
   "lightbox.expand": "Разгъване на полето за преглед на образи",
   "lightbox.next": "Напред",
   "lightbox.previous": "Назад",
-  "limited_account_hint.action": "Покажи профила въпреки това",
-  "limited_account_hint.title": "Този профил е бил скрит от модераторита на {domain}.",
+  "limited_account_hint.action": "Показване на профила въпреки това",
+  "limited_account_hint.title": "Този профил е бил скрит от модераторите на {domain}.",
   "lists.account.add": "Добавяне към списък",
-  "lists.account.remove": "Премахване от списък",
-  "lists.delete": "Изтриване на списък",
+  "lists.account.remove": "Премахване от списъка",
+  "lists.delete": "Изтриване на списъка",
   "lists.edit": "Промяна на списъка",
   "lists.edit.submit": "Промяна на заглавие",
   "lists.new.create": "Добавяне на списък",
   "lists.new.title_placeholder": "Име на нов списък",
   "lists.replies_policy.followed": "Някой последван потребител",
-  "lists.replies_policy.list": "Членове на списъка",
+  "lists.replies_policy.list": "Членуващите в списъка",
   "lists.replies_policy.none": "Никого",
   "lists.replies_policy.title": "Показване на отговори на:",
   "lists.search": "Търсене измежду последваните",
@@ -361,7 +366,7 @@
   "mute_modal.duration": "Времетраене",
   "mute_modal.hide_notifications": "Скривате ли известията от този потребител?",
   "mute_modal.indefinite": "Неопределено",
-  "navigation_bar.about": "За тази инстанция",
+  "navigation_bar.about": "Относно",
   "navigation_bar.blocks": "Блокирани потребители",
   "navigation_bar.bookmarks": "Отметки",
   "navigation_bar.community_timeline": "Локален инфопоток",
@@ -381,19 +386,19 @@
   "navigation_bar.personal": "Лично",
   "navigation_bar.pins": "Закачени публикации",
   "navigation_bar.preferences": "Предпочитания",
-  "navigation_bar.public_timeline": "Федериран инфопоток",
+  "navigation_bar.public_timeline": "Федеративна хронология",
   "navigation_bar.search": "Търсене",
   "navigation_bar.security": "Сигурност",
-  "not_signed_in_indicator.not_signed_in": "Трябва да влезете за достъп до този ресурс.",
+  "not_signed_in_indicator.not_signed_in": "Трябва да влезете, за да имате достъп до този ресурс.",
   "notification.admin.report": "{name} докладва {target}",
   "notification.admin.sign_up": "{name} се регистрира",
-  "notification.favourite": "{name} хареса ваша публикация",
+  "notification.favourite": "{name} сложи в любими ваша публикация",
   "notification.follow": "{name} ви последва",
   "notification.follow_request": "{name} поиска да ви последва",
   "notification.mention": "{name} ви спомена",
   "notification.own_poll": "Анкетата ви приключи",
   "notification.poll": "Анкета, в която гласувахте, приключи",
-  "notification.reblog": "{name} сподели вашата публикация",
+  "notification.reblog": "{name} подсили ваша публикация",
   "notification.status": "{name} току-що публикува",
   "notification.update": "{name} промени публикация",
   "notifications.clear": "Изчистване на известията",
@@ -410,15 +415,15 @@
   "notifications.column_settings.mention": "Споменавания:",
   "notifications.column_settings.poll": "Резултати от анкета:",
   "notifications.column_settings.push": "Изскачащи известия",
-  "notifications.column_settings.reblog": "Споделяния:",
+  "notifications.column_settings.reblog": "Подсилвания:",
   "notifications.column_settings.show": "Показване в колоната",
   "notifications.column_settings.sound": "Пускане на звук",
   "notifications.column_settings.status": "Нови публикации:",
   "notifications.column_settings.unread_notifications.category": "Непрочетени известия",
   "notifications.column_settings.unread_notifications.highlight": "Изтъкване на непрочетените известия",
-  "notifications.column_settings.update": "Редакции:",
+  "notifications.column_settings.update": "Промени:",
   "notifications.filter.all": "Всичко",
-  "notifications.filter.boosts": "Споделяния",
+  "notifications.filter.boosts": "Подсилвания",
   "notifications.filter.favourites": "Любими",
   "notifications.filter.follows": "Последвания",
   "notifications.filter.mentions": "Споменавания",
@@ -428,7 +433,7 @@
   "notifications.group": "{count} известия",
   "notifications.mark_as_read": "Отбелязване на всички известия като прочетени",
   "notifications.permission_denied": "Известията на работния плот не са налични поради предварително отказана заявка за разрешение в браузъра",
-  "notifications.permission_denied_alert": "Известията на работния плот не могат да бъдат активирани, тъй като разрешението на браузъра е отказвано преди",
+  "notifications.permission_denied_alert": "Известията на работния плот не могат да се включат, тъй като разрешението на браузъра е отказвано преди",
   "notifications.permission_required": "Известията на работния плот ги няма, щото няма дадено нужното позволение.",
   "notifications_permission_banner.enable": "Включване на известията на работния плот",
   "notifications_permission_banner.how_to_control": "За да получавате известия, когато Mastodon не е отворен, включете известията на работния плот. Може да управлявате точно кои видове взаимодействия пораждат известия на работния плот чрез бутона {icon} по-горе, след като бъдат включени.",
@@ -436,7 +441,7 @@
   "picture_in_picture.restore": "Връщане обратно",
   "poll.closed": "Затворено",
   "poll.refresh": "Опресняване",
-  "poll.total_people": "{count, plural, one {# човек} other {# човека}}",
+  "poll.total_people": "{count, plural, one {# човек} other {# души}}",
   "poll.total_votes": "{count, plural, one {# глас} other {# гласа}}",
   "poll.vote": "Гласуване",
   "poll.voted": "Гласувахте за този отговор",
@@ -451,21 +456,21 @@
   "privacy.public.long": "Видимо за всички",
   "privacy.public.short": "Публично",
   "privacy.unlisted.long": "Видимо за всички, но не чрез възможността за откриване",
-  "privacy.unlisted.short": "Скрито",
+  "privacy.unlisted.short": "Несписъчно",
   "privacy_policy.last_updated": "Последно осъвременяване на {date}",
   "privacy_policy.title": "Политика за поверителност",
   "refresh": "Опресняване",
   "regeneration_indicator.label": "Зареждане…",
-  "regeneration_indicator.sublabel": "Вашият основен инфопоток се подготвя!",
+  "regeneration_indicator.sublabel": "Подготовка на началния ви инфоканал!",
   "relative_time.days": "{number} д.",
   "relative_time.full.days": "преди {number, plural, one {# ден} other {# дни}}",
   "relative_time.full.hours": "преди {number, plural, one {# час} other {# часа}}",
   "relative_time.full.just_now": "току-що",
   "relative_time.full.minutes": "преди {number, plural, one {# минута} other {# минути}}",
   "relative_time.full.seconds": "преди {number, plural, one {# секунда} other {# секунди}}",
-  "relative_time.hours": "{number} ч.",
+  "relative_time.hours": "{number}ч.",
   "relative_time.just_now": "сега",
-  "relative_time.minutes": "{number} мин.",
+  "relative_time.minutes": "{number}м.",
   "relative_time.seconds": "{number}с.",
   "relative_time.today": "днес",
   "reply_indicator.cancel": "Отказ",
@@ -481,23 +486,23 @@
   "report.close": "Готово",
   "report.comment.title": "Има ли нещо друго, което смятате, че трябва да знаем?",
   "report.forward": "Препращане до {target}",
-  "report.forward_hint": "Акаунтът е от друг сървър. Ще изпратите ли анонимно копие на доклада и там?",
+  "report.forward_hint": "Акаунтът е от друг сървър. Ще изпратите ли безимено копие на доклада и там?",
   "report.mute": "Заглушаване",
   "report.mute_explanation": "Няма да виждате публикациите на това лице. То още може да ви следва и да вижда публикациите ви и няма да знае, че е заглушено.",
   "report.next": "Напред",
   "report.placeholder": "Допълнителни коментари",
   "report.reasons.dislike": "Не ми харесва",
-  "report.reasons.dislike_description": "Не е нещо, които искам да виждам",
+  "report.reasons.dislike_description": "Не е нещо, което искате да виждате",
   "report.reasons.other": "Нещо друго е",
   "report.reasons.other_description": "Проблемът не попада в нито една от другите категории",
   "report.reasons.spam": "Спам е",
-  "report.reasons.spam_description": "Зловредни връзки, фалшиви взаимодействия, или повтарящи се отговори",
+  "report.reasons.spam_description": "Зловредни връзки, фалшиви ангажименти, или повтарящи се отговори",
   "report.reasons.violation": "Нарушава правилата на сървъра",
   "report.reasons.violation_description": "Знаете, че нарушава особени правила",
   "report.rules.subtitle": "Изберете всичко, което да се прилага",
   "report.rules.title": "Кои правила са нарушени?",
   "report.statuses.subtitle": "Изберете всичко, което да се прилага",
-  "report.statuses.title": "Има ли някакви публикации, подкрепящи този доклад?",
+  "report.statuses.title": "Има ли някакви публикации, подкрепящи доклада?",
   "report.submit": "Подаване",
   "report.target": "Докладване на {target}",
   "report.thanks.take_action": "Ето възможностите ви за управление какво виждате в Mastodon:",
@@ -505,8 +510,8 @@
   "report.thanks.title": "Не искате ли да виждате това?",
   "report.thanks.title_actionable": "Благодарности за докладването, ще го прегледаме.",
   "report.unfollow": "Стоп на следването на @{name}",
-  "report.unfollow_explanation": "Последвали сте този акаунт. За да не виждате повече публикациите му в основния си инфопоток, то спрете да го следвате.",
-  "report_notification.attached_statuses": "прикачено {count, plural, one {{count} публикация} other {{count} публикации}}",
+  "report.unfollow_explanation": "Последвали сте този акаунт. За да не виждате повече публикациите му в началния си инфопоток, спрете да го следвате.",
+  "report_notification.attached_statuses": "{count, plural, one {прикаченa {count} публикация} other {прикачени {count} публикации}}",
   "report_notification.categories.other": "Друго",
   "report_notification.categories.spam": "Спам",
   "report_notification.categories.violation": "Нарушение на правилото",
@@ -514,7 +519,7 @@
   "search.placeholder": "Търсене",
   "search.search_or_paste": "Търсене или поставяне на URL адрес",
   "search_popout.search_format": "Формат за разширено търсене",
-  "search_popout.tips.full_text": "Търсене с обикновен текст връща публикации, които сте написали, харесали, споделили, или в които сте били споменати, както и съвпадащи потребителски имена, показвани имена и хаштагове.",
+  "search_popout.tips.full_text": "Търсене с обикновен текст връща публикации, които сте написали, поставили в любими, споделили, или в които сте били споменати, както и съвпадащи потребителски имена, показвани имена и хаштагове.",
   "search_popout.tips.hashtag": "хаштаг",
   "search_popout.tips.status": "публикация",
   "search_popout.tips.text": "Обикновеният текст връща съответстващи показвани имена, потребителски имена и хаштагове",
@@ -524,7 +529,7 @@
   "search_results.hashtags": "Хаштагове",
   "search_results.nothing_found": "Не може да се намери каквото и да било за тези термини при търсене",
   "search_results.statuses": "Публикации",
-  "search_results.statuses_fts_disabled": "Търсенето на публикации по тяхното съдържание не е активирано за този Mastodon сървър.",
+  "search_results.statuses_fts_disabled": "Търсенето на публикации по съдържанието им не е включено в този сървър на Mastodon.",
   "search_results.title": "Търсене за {q}",
   "search_results.total": "{count, number} {count, plural, one {резултат} other {резултата}}",
   "server_banner.about_active_users": "Ползващите сървъра през последните 30 дни (дейните месечно потребители)",
@@ -537,11 +542,12 @@
   "sign_in_banner.sign_in": "Вход",
   "sign_in_banner.text": "Влезте, за да последвате профили или хаштагове, любимо, споделяне и отговаряне на публикации или взаимодействие от акаунта ви на друг сървър.",
   "status.admin_account": "Отваряне на интерфейс за модериране за @{name}",
-  "status.admin_status": "Open this status in the moderation interface",
+  "status.admin_domain": "Отваряне на модериращия интерфейс за {domain}",
+  "status.admin_status": "Отваряне на публикацията в интерфейса за модериране",
   "status.block": "Блокиране на @{name}",
   "status.bookmark": "Отмятане",
-  "status.cancel_reblog_private": "Отсподеляне",
-  "status.cannot_reblog": "Тази публикация не може да бъде споделена",
+  "status.cancel_reblog_private": "Край на подсилването",
+  "status.cannot_reblog": "Публикация не може да се подсили",
   "status.copy": "Копиране на връзката към публикация",
   "status.delete": "Изтриване",
   "status.detailed_status": "Подробен изглед на разговора",
@@ -566,17 +572,17 @@
   "status.pin": "Закачане в профила",
   "status.pinned": "Закачена публикация",
   "status.read_more": "Още за четене",
-  "status.reblog": "Споделяне",
-  "status.reblog_private": "Споделяне с оригинална видимост",
-  "status.reblogged_by": "{name} сподели",
-  "status.reblogs.empty": "Все още никой не е споделил тази публикация. Когато някой го направи, ще се покаже тук.",
+  "status.reblog": "Подсилване",
+  "status.reblog_private": "Подсилване с оригиналната видимост",
+  "status.reblogged_by": "{name} подсили",
+  "status.reblogs.empty": "Още никого не е подсилвал публикацията. Подсилващият ще се покаже тук.",
   "status.redraft": "Изтриване и преработване",
   "status.remove_bookmark": "Премахване на отметката",
   "status.replied_to": "В отговор до {name}",
   "status.reply": "Отговор",
-  "status.replyAll": "Отговор на тема",
+  "status.replyAll": "Отговор на нишка",
   "status.report": "Докладване на @{name}",
-  "status.sensitive_warning": "Чувствително съдържание",
+  "status.sensitive_warning": "Деликатно съдържание",
   "status.share": "Споделяне",
   "status.show_filter_reason": "Покажи въпреки това",
   "status.show_less": "Показване на по-малко",
@@ -587,20 +593,20 @@
   "status.translate": "Превод",
   "status.translated_from_with": "Преведено от {lang}, използвайки {provider}",
   "status.uncached_media_warning": "Не е налично",
-  "status.unmute_conversation": "Раззаглушаване на разговор",
+  "status.unmute_conversation": "Без заглушаването на разговора",
   "status.unpin": "Разкачане от профила",
   "subscribed_languages.lead": "Публикации само на избрани езици ще се явяват в началото ви и в списъка с часови оси след промяната. Изберете \"нищо\", за да получавате публикации на всички езици.",
   "subscribed_languages.save": "Запазване на промените",
   "subscribed_languages.target": "Смяна на езика за {target}",
   "suggestions.dismiss": "Отхвърляне на предложение",
-  "suggestions.header": "Може да се интересувате от…",
-  "tabs_bar.federated_timeline": "Федерална",
+  "suggestions.header": "Може да имате интерес от…",
+  "tabs_bar.federated_timeline": "Федеративен",
   "tabs_bar.home": "Начало",
   "tabs_bar.local_timeline": "Местни",
   "tabs_bar.notifications": "Известия",
-  "time_remaining.days": "{number, plural, one {# ден} other {# дни}} остава",
-  "time_remaining.hours": "{number, plural, one {# час} other {# часа}} остава",
-  "time_remaining.minutes": "{number, plural, one {# минута} other {# минути}} остава",
+  "time_remaining.days": "{number, plural, one {остава # ден} other {остават # дни}}",
+  "time_remaining.hours": "{number, plural, one {остава # час} other {остават # часа}}",
+  "time_remaining.minutes": "{number, plural, one {остава # минута} other {остават # минути}}",
   "time_remaining.moments": "Оставащи моменти",
   "time_remaining.seconds": "{number, plural, one {# секунда} other {# секунди}} остава",
   "timeline_hint.remote_resource_not_displayed": "{resource} от други сървъри не се показват.",
@@ -615,22 +621,22 @@
   "units.short.thousand": "{count}хил",
   "upload_area.title": "Влачене и пускане за качване",
   "upload_button.label": "Добавете файл с образ, видео или звук",
-  "upload_error.limit": "Превишено ограничение за качване на файлове.",
+  "upload_error.limit": "Превишено ограничението за качване на файлове.",
   "upload_error.poll": "Качването на файлове не е позволено с анкети.",
-  "upload_form.audio_description": "Опишете за хора със загубен слух",
-  "upload_form.description": "Опишете за хора със зрително увреждане",
-  "upload_form.description_missing": "Няма добавено описание",
+  "upload_form.audio_description": "Опишете за хора, които са глухи или трудно чуват",
+  "upload_form.description": "Опишете за хора, които са слепи или имат слабо зрение",
+  "upload_form.description_missing": "Няма добавен опис",
   "upload_form.edit": "Редактиране",
   "upload_form.thumbnail": "Промяна на миниобраза",
   "upload_form.undo": "Изтриване",
-  "upload_form.video_description": "Опишете за хора със загубен слух или зрително увреждане",
-  "upload_modal.analyzing_picture": "Анализ на снимка…",
+  "upload_form.video_description": "Опишете за хора, които са глухи или трудно чуват, слепи или имат слабо зрение",
+  "upload_modal.analyzing_picture": "Снимков анализ…",
   "upload_modal.apply": "Прилагане",
   "upload_modal.applying": "Прилагане…",
   "upload_modal.choose_image": "Избор на образ",
   "upload_modal.description_placeholder": "Ах, чудна българска земьо, полюшвай цъфтящи жита",
   "upload_modal.detect_text": "Откриване на текст от картина",
-  "upload_modal.edit_media": "Редакция на мултимедия",
+  "upload_modal.edit_media": "Промяна на мултимедия",
   "upload_modal.hint": "Щракнете или плъзнете кръга на визуализацията, за да изберете фокусна точка, която винаги ще бъде видима на всички миниатюри.",
   "upload_modal.preparing_ocr": "Подготовка за оптично разпознаване на знаци…",
   "upload_modal.preview_label": "Нагледно ({ratio})",
diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json
index 6e33bf789..e4e240423 100644
--- a/app/javascript/mastodon/locales/bn.json
+++ b/app/javascript/mastodon/locales/bn.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "টুট এবং মতামত",
   "account.report": "@{name} কে রিপোর্ট করুন",
   "account.requested": "অনুমতির অপেক্ষা। অনুসরণ করার অনুরোধ বাতিল করতে এখানে ক্লিক করুন",
+  "account.requested_follow": "{name} আপনাকে অনুসরণ করার জন্য অনুরোধ করেছে",
   "account.share": "@{name} র প্রোফাইল অন্যদের দেখান",
   "account.show_reblogs": "@{name} র সমর্থনগুলো দেখান",
   "account.statuses_counter": "{count, plural,one {{counter} টুট} other {{counter} টুট}}",
@@ -70,7 +71,7 @@
   "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
   "admin.dashboard.retention.average": "Average",
   "admin.dashboard.retention.cohort": "Sign-up month",
-  "admin.dashboard.retention.cohort_size": "New users",
+  "admin.dashboard.retention.cohort_size": "নতুন ব্যবহারকারী",
   "alert.rate_limited.message": "{retry_time, time, medium} -এর পরে আবার প্রচেষ্টা করুন।",
   "alert.rate_limited.title": "হার সীমিত",
   "alert.unexpected.message": "সমস্যা অপ্রত্যাশিত.",
@@ -123,11 +124,11 @@
   "community.column_settings.local_only": "শুধুমাত্র স্থানীয়",
   "community.column_settings.media_only": "শুধুমাত্র ছবি বা ভিডিও",
   "community.column_settings.remote_only": "শুধুমাত্র দূরবর্তী",
-  "compose.language.change": "Change language",
+  "compose.language.change": "ভাষা পরিবর্তন করুন",
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "আরো জানুন",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "কোনো হ্যাশট্যাগের ভেতরে এই টুটটি থাকবেনা কারণ এটি তালিকাবহির্ভূত। শুধুমাত্র প্রকাশ্য ঠোটগুলো হ্যাশট্যাগের ভেতরে খুঁজে পাওয়া যাবে।",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "আপনার নিবন্ধনে তালা দেওয়া নেই, যে কেও আপনাকে অনুসরণ করতে পারবে এবং অনুশারকদের জন্য লেখা দেখতে পারবে।",
   "compose_form.lock_disclaimer.lock": "তালা দেওয়া",
   "compose_form.placeholder": "আপনি কি ভাবছেন ?",
@@ -137,7 +138,7 @@
   "compose_form.poll.remove_option": "এই বিকল্পটি মুছে ফেলুন",
   "compose_form.poll.switch_to_multiple": "একাধিক পছন্দ অনুমতি দেওয়ার জন্য পোল পরিবর্তন করুন",
   "compose_form.poll.switch_to_single": "একটি একক পছন্দের অনুমতি দেওয়ার জন্য পোল পরিবর্তন করুন",
-  "compose_form.publish": "Publish",
+  "compose_form.publish": "প্রকাশ করুন",
   "compose_form.publish_form": "Publish",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.save_changes": "Save changes",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "স্টেকট্রেস ক্লিপবোর্ডে কপি করুন",
   "errors.unexpected_crash.report_issue": "সমস্যার প্রতিবেদন করুন",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "সংবাদ",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -269,7 +274,7 @@
   "getting_started.heading": "শুরু করা",
   "hashtag.column_header.tag_mode.all": "এবং {additional}",
   "hashtag.column_header.tag_mode.any": "অথবা {additional}",
-  "hashtag.column_header.tag_mode.none": "বাদ দিয়ে {additional}",
+  "hashtag.column_header.tag_mode.none": "{additional} বাদ দিয়ে",
   "hashtag.column_settings.select.no_options_message": "কোনটা পাওয়া যায় নি",
   "hashtag.column_settings.select.placeholder": "হ্যাশট্যাগের ভেতরে ঢুকুন…",
   "hashtag.column_settings.tag_mode.all": "এগুলো সব",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "@{name} র জন্য পরিচালনার ইন্টারফেসে ঢুকুন",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "যায় লেখাটি পরিচালনার ইন্টারফেসে খুলুন",
   "status.block": "@{name} কে ব্লক করুন",
   "status.bookmark": "বুকমার্ক",
@@ -553,7 +559,7 @@
   "status.favourite": "পছন্দের করতে",
   "status.filter": "Filter this post",
   "status.filtered": "ছাঁকনিদিত",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "আরো দেখুন",
diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json
index e046824b6..51523ab22 100644
--- a/app/javascript/mastodon/locales/br.json
+++ b/app/javascript/mastodon/locales/br.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Toudoù ha respontoù",
   "account.report": "Disklêriañ @{name}",
   "account.requested": "O c'hortoz an asant. Klikit evit nullañ ar goulenn heuliañ",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Skignañ profil @{name}",
   "account.show_reblogs": "Diskouez skignadennoù @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toud} two {{counter} Doud} other {{counter} a Doudoù}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Klask yezhoù...",
   "compose_form.direct_message_warning_learn_more": "Gouzout hiroc'h",
   "compose_form.encryption_warning": "Toudoù war Mastodon na vezont ket sifret penn-da-benn. Na rannit ket titouroù kizidik dre Mastodon.",
-  "compose_form.hashtag_warning": "Ne vo ket listennet an toud-mañ dindan gerioù-klik ebet dre m'eo anlistennet. N'eus nemet an toudoù foran a c'hall bezañ klasket dre c'her-klik.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "N'eo ket {locked} ho kont. An holl a c'hal ho heuliañ evit gwelet ho toudoù prevez.",
   "compose_form.lock_disclaimer.lock": "prennet",
   "compose_form.placeholder": "Petra emaoc'h o soñjal e-barzh ?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Eilañ ar roudoù diveugañ er golver",
   "errors.unexpected_crash.report_issue": "Danevellañ ur fazi",
   "explore.search_results": "Disoc'hoù an enklask",
+  "explore.suggested_follows": "For you",
   "explore.title": "Furchal",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Kenarroud digenglotus !",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Kevreañ",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Digeriñ etrefas evezherezh evit @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Digeriñ an toud e-barzh an etrefas evezherezh",
   "status.block": "Berzañ @{name}",
   "status.bookmark": "Ouzhpennañ d'ar sinedoù",
@@ -553,7 +559,7 @@
   "status.favourite": "Muiañ-karet",
   "status.filter": "Silañ ar c'hannad-mañ",
   "status.filtered": "Silet",
-  "status.hide": "Kuzhat ar c'hannad",
+  "status.hide": "Hide post",
   "status.history.created": "Krouet gant {name} {date}",
   "status.history.edited": "Kemmet gant {name} {date}",
   "status.load_more": "Kargañ muioc'h",
diff --git a/app/javascript/mastodon/locales/bs.json b/app/javascript/mastodon/locales/bs.json
index 3e3a5243e..ef30c76da 100644
--- a/app/javascript/mastodon/locales/bs.json
+++ b/app/javascript/mastodon/locales/bs.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Posts and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval. Click to cancel follow request",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Posts}}",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json
index 6b1743d61..dbc1af4b1 100644
--- a/app/javascript/mastodon/locales/ca.json
+++ b/app/javascript/mastodon/locales/ca.json
@@ -21,18 +21,18 @@
   "account.browse_more_on_origin_server": "Navega més en el perfil original",
   "account.cancel_follow_request": "Retira la sol·licitud de seguiment",
   "account.direct": "Missatge directe a @{name}",
-  "account.disable_notifications": "No em notifiquis les publicacions de @{name}",
+  "account.disable_notifications": "Deixa de notificar-me els tuts de @{name}",
   "account.domain_blocked": "Domini blocat",
   "account.edit_profile": "Edita el perfil",
-  "account.enable_notifications": "Notifica'm les publicacions de @{name}",
+  "account.enable_notifications": "Notifica'm els tuts de @{name}",
   "account.endorse": "Recomana en el perfil",
   "account.featured_tags.last_status_at": "Darrera publicació el {date}",
-  "account.featured_tags.last_status_never": "No hi ha publicacions",
+  "account.featured_tags.last_status_never": "No hi ha tuts",
   "account.featured_tags.title": "etiquetes destacades de {name}",
   "account.follow": "Segueix",
   "account.followers": "Seguidors",
   "account.followers.empty": "A aquest usuari encara no el segueix ningú.",
-  "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidors}}",
+  "account.followers_counter": "{count, plural, one {{counter} seguidor} other {{counter} seguidors}}",
   "account.following": "Seguint",
   "account.following_counter": "{count, plural, other {Seguint-ne {counter}}}",
   "account.follows.empty": "Aquest usuari encara no segueix ningú.",
@@ -54,9 +54,10 @@
   "account.posts_with_replies": "Tuts i respostes",
   "account.report": "Informa sobre @{name}",
   "account.requested": "S'espera l'aprovació. Clica per a cancel·lar la petició de seguiment",
+  "account.requested_follow": "{name} ha demanat de seguir-te",
   "account.share": "Comparteix el perfil de @{name}",
   "account.show_reblogs": "Mostra els impulsos de @{name}",
-  "account.statuses_counter": "{count, plural, one {{counter} Publicació} other {{counter} Publicacions}}",
+  "account.statuses_counter": "{count, plural, one {{counter} Tut} other {{counter} Tuts}}",
   "account.unblock": "Desbloca @{name}",
   "account.unblock_domain": "Desbloca el domini {domain}",
   "account.unblock_short": "Desbloca",
@@ -104,7 +105,7 @@
   "column.direct": "Missatges directes",
   "column.directory": "Navega pels perfils",
   "column.domain_blocks": "Dominis blocats",
-  "column.favourites": "Preferits",
+  "column.favourites": "Favorits",
   "column.follow_requests": "Peticions de seguir-te",
   "column.home": "Inici",
   "column.lists": "Llistes",
@@ -126,9 +127,9 @@
   "compose.language.change": "Canvia d'idioma",
   "compose.language.search": "Cerca idiomes...",
   "compose_form.direct_message_warning_learn_more": "Més informació",
-  "compose_form.encryption_warning": "Les publicacions a Mastodon no estant xifrades punt a punt. No comparteixis informació sensible mitjançant Mastodon.",
-  "compose_form.hashtag_warning": "Aquesta publicació no es mostrarà en cap etiqueta, ja que no està llistada. Només les publicacions públiques es poden cercar per etiqueta.",
-  "compose_form.lock_disclaimer": "El teu compte no està {locked}. Tothom pot seguir-te i veure les publicacions de només per a seguidors.",
+  "compose_form.encryption_warning": "Els tuts a Mastodon no estant xifrats punt a punt. No comparteixis informació sensible mitjançant Mastodon.",
+  "compose_form.hashtag_warning": "Aquest tut no es mostrarà en cap etiqueta, ja que no és públic. Només els tuts públics es poden cercar per etiqueta.",
+  "compose_form.lock_disclaimer": "El teu compte no està {locked}. Tothom pot seguir-te i veure els tuts de només per a seguidors.",
   "compose_form.lock_disclaimer.lock": "blocat",
   "compose_form.placeholder": "Què et passa pel cap?",
   "compose_form.poll.add_option": "Afegeix una opció",
@@ -137,11 +138,11 @@
   "compose_form.poll.remove_option": "Elimina aquesta opció",
   "compose_form.poll.switch_to_multiple": "Canvia l’enquesta per a permetre diverses opcions",
   "compose_form.poll.switch_to_single": "Canvia l’enquesta per a permetre una única opció",
-  "compose_form.publish": "Publica",
+  "compose_form.publish": "Tut",
   "compose_form.publish_form": "Publica",
-  "compose_form.publish_loud": "{publish}!",
+  "compose_form.publish_loud": "Tut!",
   "compose_form.save_changes": "Desa els canvis",
-  "compose_form.sensitive.hide": "{count, plural, one {Marca el contingut com a sensible} other {Marca el contingut com a sensible}}",
+  "compose_form.sensitive.hide": "{count, plural, one {Marca mèdia com a sensible} other {Marca mèdia com a sensible}}",
   "compose_form.sensitive.marked": "{count, plural, one {Contingut marcat com a sensible} other {Contingut marcat com a sensible}}",
   "compose_form.sensitive.unmarked": "{count, plural, one {Contingut no marcat com a sensible} other {Contingut no marcat com a sensible}}",
   "compose_form.spoiler.marked": "Elimina l'avís de contingut",
@@ -164,7 +165,7 @@
   "confirmations.logout.confirm": "Tanca la sessió",
   "confirmations.logout.message": "Segur que vols tancar la sessió?",
   "confirmations.mute.confirm": "Silencia",
-  "confirmations.mute.explanation": "Això amagarà les seves publicacions i les que els mencionen, però encara els permetrà veure les teves i seguir-te.",
+  "confirmations.mute.explanation": "Això amagarà els tuts d'ells i els d'els que els mencionin, però encara els permetrà veure els teus tuts i seguir-te.",
   "confirmations.mute.message": "Segur que vols silenciar {name}?",
   "confirmations.redraft.confirm": "Elimina i reescriu-la",
   "confirmations.redraft.message": "Segur que vols eliminar aquesta publicació i tornar-la a escriure? Es perdran tots els impulsos i els favorits, i les respostes a la publicació original quedaran aïllades.",
@@ -181,16 +182,16 @@
   "directory.federated": "Del fedivers conegut",
   "directory.local": "Només de {domain}",
   "directory.new_arrivals": "Arribades noves",
-  "directory.recently_active": "Recentment actius",
+  "directory.recently_active": "Actius recentment",
   "disabled_account_banner.account_settings": "Paràmetres del compte",
-  "disabled_account_banner.text": "El teu compte {disabledAccount} està actualment desactivat.",
-  "dismissable_banner.community_timeline": "Aquestes són les publicacions més recents d'usuaris amb el compte a {domain}.",
+  "disabled_account_banner.text": "El teu compte {disabledAccount} està desactivat.",
+  "dismissable_banner.community_timeline": "Aquests són els tuts públics més recents d'usuaris amb els seus comptes a {domain}.",
   "dismissable_banner.dismiss": "Ometre",
   "dismissable_banner.explore_links": "Gent d'aquest i d'altres servidors de la xarxa descentralitzada estan comentant ara mateix aquestes notícies.",
-  "dismissable_banner.explore_statuses": "Aquestes publicacions d'aquest i altres servidors de la xarxa descentralitzada estan guanyant l'atenció ara mateix en aquest servidor.",
+  "dismissable_banner.explore_statuses": "Aquests tuts d'aquest i altres servidors de la xarxa descentralitzada estan guanyant l'atenció ara mateix en aquest servidor.",
   "dismissable_banner.explore_tags": "Aquestes etiquetes estan guanyant ara mateix l'atenció dels usuaris d'aquest i altres servidors de la xarxa descentralitzada.",
-  "dismissable_banner.public_timeline": "Aquestes són les publicacions públiques més recents de persones en aquest i altres servidors de la xarxa descentralitzada que aquest servidor coneix.",
-  "embed.instructions": "Incrusta aquesta publicació a la teva pàgina web copiant el codi següent.",
+  "dismissable_banner.public_timeline": "Aquestes són els tuts públics més recents de persones en aquest i altres servidors de la xarxa descentralitzada que aquest servidor coneix.",
+  "embed.instructions": "Incrusta aquest tut a la teva pàgina web copiant el codi següent.",
   "embed.preview": "Aquest aspecte tindrà:",
   "emoji_button.activity": "Activitat",
   "emoji_button.clear": "Neteja",
@@ -211,19 +212,19 @@
   "empty_column.account_timeline": "No hi ha tuts aquí!",
   "empty_column.account_unavailable": "Perfil no disponible",
   "empty_column.blocks": "Encara no has blocat cap usuari.",
-  "empty_column.bookmarked_statuses": "Encara no has marcat cap publicació com a preferida. Quan en marquis una, apareixerà aquí.",
+  "empty_column.bookmarked_statuses": "Encara no tens marcada cap publicació. Quan en marquis una apareixerà aquí.",
   "empty_column.community": "La línia de temps local és buida. Escriu alguna cosa públicament per posar-ho tot en marxa!",
-  "empty_column.direct": "Encara no teniu missatges directes. Quan n'envieu o en rebeu, sortiran aquí.",
+  "empty_column.direct": "Encara no tens missatges directes. Quan n'enviïs o en rebis un, sortirà aquí.",
   "empty_column.domain_blocks": "Encara no hi ha dominis blocats.",
   "empty_column.explore_statuses": "No hi ha res en tendència ara mateix. Revisa-ho més tard!",
-  "empty_column.favourited_statuses": "Encara no has afavorit cap publicació. Quan ho facis, apareixerà aquí.",
+  "empty_column.favourited_statuses": "Encara no has afavorit cap tut. Quan ho facis, apareixerà aquí.",
   "empty_column.favourites": "Encara no ha marcat ningú aquesta publicació com a preferida. Quan ho faci algú apareixerà aquí.",
-  "empty_column.follow_recommendations": "Sembla que no s'han pogut generar suggeriments per a tu. Pots provar d'usar la cerca per trobar persones que vulguis conèixer o explorar les etiquetes en tendència.",
+  "empty_column.follow_recommendations": "Sembla que no s'han pogut generar suggeriments per a tu. Pots provar d'usar la cerca per a trobar persones que vulguis conèixer o explorar les etiquetes en tendència.",
   "empty_column.follow_requests": "Encara no tens cap petició de seguiment. Quan en rebis una, apareixerà aquí.",
   "empty_column.hashtag": "Encara no hi ha res en aquesta etiqueta.",
   "empty_column.home": "La teva línia de temps és buida! Segueix més gent per a emplenar-la. {suggestions}",
   "empty_column.home.suggestions": "Mostra alguns suggeriments",
-  "empty_column.list": "Encara no hi ha res en aquesta llista. Quan els membres facin noves publicacions, apareixeran aquí.",
+  "empty_column.list": "Encara no hi ha res en aquesta llista. Quan els membres facin nous tuts, apareixeran aquí.",
   "empty_column.lists": "Encara no tens cap llista. Quan en facis una, apareixerà aquí.",
   "empty_column.mutes": "Encara no has silenciat cap usuari.",
   "empty_column.notifications": "Encara no tens notificacions. Quan altre gent interactuï amb tu, les veuràs aquí.",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copia stacktrace al porta-retalls",
   "errors.unexpected_crash.report_issue": "Informa d'un problema",
   "explore.search_results": "Resultats de la cerca",
+  "explore.suggested_follows": "Per a tu",
   "explore.title": "Explora",
+  "explore.trending_links": "Notícies",
+  "explore.trending_statuses": "Tuts",
+  "explore.trending_tags": "Etiquetes",
   "filter_modal.added.context_mismatch_explanation": "Aquesta categoria de filtre no s'aplica al context en què has accedit a aquesta publicació. Si també vols que la publicació es filtri en aquest context, hauràs d'editar el filtre.",
   "filter_modal.added.context_mismatch_title": "El context no coincideix!",
   "filter_modal.added.expired_explanation": "La categoria d'aquest filtre ha caducat, necessitaràs canviar la seva data de caducitat per a aplicar-la.",
@@ -251,10 +256,10 @@
   "filter_modal.select_filter.search": "Cerca o crea",
   "filter_modal.select_filter.subtitle": "Usa una categoria existent o crea'n una de nova",
   "filter_modal.select_filter.title": "Filtra aquesta publicació",
-  "filter_modal.title.status": "Filtra una publicació",
+  "filter_modal.title.status": "Filtra un tut",
   "follow_recommendations.done": "Fet",
   "follow_recommendations.heading": "Segueix a la gent de la que t'agradaria veure els seus tuts! Aquí hi ha algunes recomanacions.",
-  "follow_recommendations.lead": "Les publicacions dels usuaris que segueixes es mostraran en ordre cronològic en la teva línia de temps d'Inici. No tinguis por de cometre errors, pots deixar de seguir-los en qualsevol moment!",
+  "follow_recommendations.lead": "Els tuts dels usuaris que segueixes es mostraran en ordre cronològic en la teva línia de temps Inici. No tinguis por en cometre errors, pots fàcilment deixar de seguir-los en qualsevol moment!",
   "follow_request.authorize": "Autoritza",
   "follow_request.reject": "Rebutja",
   "follow_requests.unlocked_explanation": "Tot i que el teu compte no està blocat, el personal de {domain} ha pensat que és possible que vulguis revisar manualment les sol·licituds de seguiment d’aquests comptes.",
@@ -284,14 +289,14 @@
   "home.hide_announcements": "Amaga els anuncis",
   "home.show_announcements": "Mostra els anuncis",
   "interaction_modal.description.favourite": "Amb un compte a Mastodon pots afavorir aquesta publicació, que l'autor sàpiga que t'ha agradat i desar-la per a més endavant.",
-  "interaction_modal.description.follow": "Amb un compte a Mastodon, pots seguir a {name} per a rebre les seves publicacions en la teva línia de temps d'Inici.",
+  "interaction_modal.description.follow": "Amb un compte a Mastodon, pots seguir a {name} per a rebre els seus tuts en la teva línia de temps d'Inici.",
   "interaction_modal.description.reblog": "Amb un compte a Mastodon, pots impulsar aquesta publicació per a compartir-la amb els teus seguidors.",
-  "interaction_modal.description.reply": "Amb un compte a Mastodon, pots respondre aquesta publicació.",
-  "interaction_modal.on_another_server": "En un servidor diferent",
+  "interaction_modal.description.reply": "Amb un compte a Mastodon, pots respondre aquest tut.",
+  "interaction_modal.on_another_server": "A un altre servidor",
   "interaction_modal.on_this_server": "En aquest servidor",
-  "interaction_modal.other_server_instructions": "Copia i enganxa aquesta URL en el camp de cerca de la teva aplicació Mastodon preferida o en l'interfície web del teu servidor Mastodon.",
+  "interaction_modal.other_server_instructions": "Copia i enganxa aquest URL en el camp de cerca de la teva aplicació Mastodon preferida o a la interfície web del teu servidor Mastodon.",
   "interaction_modal.preamble": "Com que Mastodon és descentralitzat, pots fer servir el teu compte existent en un altre servidor Mastodon o plataforma compatible si no tens compte en aquest.",
-  "interaction_modal.title.favourite": "Marca la publicació de {name}",
+  "interaction_modal.title.favourite": "Marca el tut de {name}",
   "interaction_modal.title.follow": "Segueix {name}",
   "interaction_modal.title.reblog": "Impulsa la publicació de {name}",
   "interaction_modal.title.reply": "Respon a la publicació de {name}",
@@ -300,15 +305,15 @@
   "intervals.full.minutes": "{number, plural, one {# minut} other {# minuts}}",
   "keyboard_shortcuts.back": "Vés enrere",
   "keyboard_shortcuts.blocked": "Obre la llista d'usuaris blocats",
-  "keyboard_shortcuts.boost": "Impulsa la publicació",
+  "keyboard_shortcuts.boost": "Impulsa el tut",
   "keyboard_shortcuts.column": "Centra la columna",
   "keyboard_shortcuts.compose": "Centra l'àrea de composició de text",
   "keyboard_shortcuts.description": "Descripció",
-  "keyboard_shortcuts.direct": "per a obrir la columna de missatges directes",
+  "keyboard_shortcuts.direct": "Obre la columna de missatges directes",
   "keyboard_shortcuts.down": "Abaixa a la llista",
   "keyboard_shortcuts.enter": "Obre la publicació",
   "keyboard_shortcuts.favourite": "Afavoreix la publicació",
-  "keyboard_shortcuts.favourites": "Obre la llista de favorits",
+  "keyboard_shortcuts.favourites": "Obre la llista de preferits",
   "keyboard_shortcuts.federated": "Obre la línia de temps federada",
   "keyboard_shortcuts.heading": "Dreceres de teclat",
   "keyboard_shortcuts.home": "Obre la línia de temps de l'Inici",
@@ -319,10 +324,10 @@
   "keyboard_shortcuts.muted": "Obre la llista d'usuaris silenciats",
   "keyboard_shortcuts.my_profile": "Obre el teu perfil",
   "keyboard_shortcuts.notifications": "Obre la columna de notificacions",
-  "keyboard_shortcuts.open_media": "Obre el contingut",
-  "keyboard_shortcuts.pinned": "Obre la llista de publicacions fixades",
+  "keyboard_shortcuts.open_media": "Obre mèdia",
+  "keyboard_shortcuts.pinned": "Obre la llista de tuts fixats",
   "keyboard_shortcuts.profile": "Obre el perfil de l'autor",
-  "keyboard_shortcuts.reply": "Respon a la publicació",
+  "keyboard_shortcuts.reply": "Respon al tut",
   "keyboard_shortcuts.requests": "Obre la llista de sol·licituds de seguiment",
   "keyboard_shortcuts.search": "Centra la barra de cerca",
   "keyboard_shortcuts.spoilers": "Mostra/amaga el camp CW",
@@ -365,7 +370,7 @@
   "navigation_bar.blocks": "Usuaris blocats",
   "navigation_bar.bookmarks": "Marcadors",
   "navigation_bar.community_timeline": "Línia de temps local",
-  "navigation_bar.compose": "Redacta una nova publicació",
+  "navigation_bar.compose": "Redacta un tut",
   "navigation_bar.direct": "Missatges directes",
   "navigation_bar.discover": "Descobreix",
   "navigation_bar.domain_blocks": "Dominis blocats",
@@ -401,7 +406,7 @@
   "notifications.column_settings.admin.report": "Nous informes:",
   "notifications.column_settings.admin.sign_up": "Nous registres:",
   "notifications.column_settings.alert": "Notificacions d'escriptori",
-  "notifications.column_settings.favourite": "Preferits:",
+  "notifications.column_settings.favourite": "Favorits:",
   "notifications.column_settings.filter_bar.advanced": "Mostra totes les categories",
   "notifications.column_settings.filter_bar.category": "Barra ràpida de filtres",
   "notifications.column_settings.filter_bar.show_bar": "Mostra la barra de filtres",
@@ -413,7 +418,7 @@
   "notifications.column_settings.reblog": "Impulsos:",
   "notifications.column_settings.show": "Mostra a la columna",
   "notifications.column_settings.sound": "Reprodueix so",
-  "notifications.column_settings.status": "Noves publicacions:",
+  "notifications.column_settings.status": "Nous tuts:",
   "notifications.column_settings.unread_notifications.category": "Notificacions no llegides",
   "notifications.column_settings.unread_notifications.highlight": "Destaca les notificacions no llegides",
   "notifications.column_settings.update": "Edicions:",
@@ -470,20 +475,20 @@
   "relative_time.today": "avui",
   "reply_indicator.cancel": "Cancel·la",
   "report.block": "Bloca",
-  "report.block_explanation": "No veuràs les seves publicacions. Ell no podran veure les teves ni seguir-te. Podran saber que estan blocats.",
+  "report.block_explanation": "No veuràs els seus tuts. Ells no podran veure els teus tuts ni et podran seguir. Podran saber que estan blocats.",
   "report.categories.other": "Altres",
   "report.categories.spam": "Brossa",
   "report.categories.violation": "El contingut viola una o més regles del servidor",
   "report.category.subtitle": "Tria la millor coincidència",
   "report.category.title": "Explica'ns què passa amb això ({type})",
   "report.category.title_account": "perfil",
-  "report.category.title_status": "publicació",
+  "report.category.title_status": "tut",
   "report.close": "Fet",
   "report.comment.title": "Hi ha res més que creguis que hauríem de saber?",
   "report.forward": "Reenvia a {target}",
   "report.forward_hint": "El compte és d'un altre servidor. Vols enviar-hi també una còpia anònima de l'informe?",
   "report.mute": "Silencia",
-  "report.mute_explanation": "No veuràs les seves publicacions. Encara pot seguir-te i veure les teves publicacions, però no sabrà que ha estat silenciat.",
+  "report.mute_explanation": "No veuràs els seus tuts. Encara poden seguir-te i veure els teus tuts, però no sabran que han estat silenciats.",
   "report.next": "Següent",
   "report.placeholder": "Comentaris addicionals",
   "report.reasons.dislike": "No m'agrada",
@@ -497,7 +502,7 @@
   "report.rules.subtitle": "Selecciona totes les aplicables",
   "report.rules.title": "Quines regles s'han violat?",
   "report.statuses.subtitle": "Selecciona totes les aplicables",
-  "report.statuses.title": "Hi ha cap publicació que doni suport a aquest informe?",
+  "report.statuses.title": "Hi ha cap tut que doni suport a aquest informe?",
   "report.submit": "Envia",
   "report.target": "Es reporta {target}",
   "report.thanks.take_action": "Aquestes són les teves opcions per a controlar el que veus a Mastodon:",
@@ -505,8 +510,8 @@
   "report.thanks.title": "No ho vols veure?",
   "report.thanks.title_actionable": "Gràcies per informar, ho investigarem.",
   "report.unfollow": "Deixa de seguir @{name}",
-  "report.unfollow_explanation": "Segueixes aquest compte. Per no veure les seves publicacions a la teva línia de temps d'Inici deixa de seguir-lo.",
-  "report_notification.attached_statuses": "{count, plural, one {{count} publicació adjunta} other {{count} publicacions adjuntes}}",
+  "report.unfollow_explanation": "Estàs seguint aquest compte. Per no veure els seus tuts a la teva línia de temps d'Inici, deixa de seguir-lo.",
+  "report_notification.attached_statuses": "{count, plural, one {{count} tut} other {{count} tuts}} adjunts",
   "report_notification.categories.other": "Altres",
   "report_notification.categories.spam": "Brossa",
   "report_notification.categories.violation": "Violació de norma",
@@ -514,17 +519,17 @@
   "search.placeholder": "Cerca",
   "search.search_or_paste": "Cerca o escriu l'URL",
   "search_popout.search_format": "Format de cerca avançada",
-  "search_popout.tips.full_text": "Text simple recupera publicacions que has escrit, les marcades com a preferides, les impulsades o en les que has estat esmentat, així com usuaris, noms d'usuari i etiquetes.",
+  "search_popout.tips.full_text": "Text simple recupera tuts que has escrit, els marcats com a favorits, els impulsats o en els que has estat esmentat, així com usuaris, noms d'usuari i etiquetes.",
   "search_popout.tips.hashtag": "etiqueta",
-  "search_popout.tips.status": "publicació",
+  "search_popout.tips.status": "tut",
   "search_popout.tips.text": "El text simple recupera coincidències amb els usuaris, els noms d'usuari i les etiquetes",
   "search_popout.tips.user": "usuari",
   "search_results.accounts": "Gent",
   "search_results.all": "Tots",
   "search_results.hashtags": "Etiquetes",
   "search_results.nothing_found": "No s'ha pogut trobar res per a aquests termes de cerca",
-  "search_results.statuses": "Publicacions",
-  "search_results.statuses_fts_disabled": "La cerca de publicacions pel seu contingut no està habilitada en aquest servidor Mastodon.",
+  "search_results.statuses": "Tuts",
+  "search_results.statuses_fts_disabled": "La cerca de tuts pel seu contingut no està habilitada en aquest servidor Mastodon.",
   "search_results.title": "Cerca de {q}",
   "search_results.total": "{count, number} {count, plural, one {resultat} other {resultats}}",
   "server_banner.about_active_users": "Gent que ha fet servir aquest servidor en els darrers 30 dies (Usuaris Actius Mensuals)",
@@ -533,16 +538,17 @@
   "server_banner.introduction": "{domain} és part de la xarxa social descentralitzada, potenciat per {mastodon}.",
   "server_banner.learn_more": "Més informació",
   "server_banner.server_stats": "Estadístiques del servidor:",
-  "sign_in_banner.create_account": "Crea un compte",
+  "sign_in_banner.create_account": "Registra'm",
   "sign_in_banner.sign_in": "Inicia sessió",
-  "sign_in_banner.text": "Inicia la sessió per seguir perfils o etiquetes, afavorir, compartir i respondre a publicacions o interactuar des del teu compte en un servidor diferent.",
+  "sign_in_banner.text": "Inicia la sessió per a seguir perfils o etiquetes, afavorir, compartir i respondre tuts o interactuar des del teu compte en un servidor diferent.",
   "status.admin_account": "Obre la interfície de moderació per a @{name}",
-  "status.admin_status": "Obre aquesta publicació a la interfície de moderació",
+  "status.admin_domain": "Obre la interfície de moderació per a @{domain}",
+  "status.admin_status": "Obrir aquest tut a la interfície de moderació",
   "status.block": "Bloca @{name}",
   "status.bookmark": "Marca",
   "status.cancel_reblog_private": "Desfés l'impuls",
-  "status.cannot_reblog": "No es pot impulsar aquesta publicació",
-  "status.copy": "Copia l'enllaç a la publicació",
+  "status.cannot_reblog": "No es pot impulsar aquest tut",
+  "status.copy": "Copia l'enllaç al tut",
   "status.delete": "Elimina",
   "status.detailed_status": "Vista detallada de la conversa",
   "status.direct": "Missatge directe a @{name}",
@@ -550,10 +556,10 @@
   "status.edited": "Editat {date}",
   "status.edited_x_times": "Editat {count, plural, one {{count} vegada} other {{count} vegades}}",
   "status.embed": "Incrusta",
-  "status.favourite": "Preferit",
-  "status.filter": "Filtra aquesta publicació",
+  "status.favourite": "Favorit",
+  "status.filter": "Filtra aquest tut",
   "status.filtered": "Filtrada",
-  "status.hide": "Amaga la publicació",
+  "status.hide": "Amaga el tut",
   "status.history.created": "creat per {name} {date}",
   "status.history.edited": "editat per {name} {date}",
   "status.load_more": "Carrega'n més",
@@ -562,9 +568,9 @@
   "status.more": "Més",
   "status.mute": "Silencia @{name}",
   "status.mute_conversation": "Silencia la conversa",
-  "status.open": "Amplia la publicació",
+  "status.open": "Amplia el tut",
   "status.pin": "Fixa en el perfil",
-  "status.pinned": "Publicació fixada",
+  "status.pinned": "Tut fixat",
   "status.read_more": "Més informació",
   "status.reblog": "Impulsa",
   "status.reblog_private": "Impulsa amb la visibilitat original",
@@ -589,7 +595,7 @@
   "status.uncached_media_warning": "No està disponible",
   "status.unmute_conversation": "Deixa de silenciar la conversa",
   "status.unpin": "Desfixa del perfil",
-  "subscribed_languages.lead": "Només les publicacions en les llengües seleccionades apareixeran en les teves línies de temps \"Inici\" i \"Llistes\" després del canvi. No en seleccionis cap per a rebre publicacions en totes les llengües.",
+  "subscribed_languages.lead": "Només els tuts en les llengües seleccionades apareixeran en les teves línies de temps \"Inici\" i \"Llistes\" després del canvi. No en seleccionis cap per a rebre tuts en totes les llengües.",
   "subscribed_languages.save": "Desa els canvis",
   "subscribed_languages.target": "Canvia les llengües subscrites per a {target}",
   "suggestions.dismiss": "Ignora el suggeriment",
@@ -610,27 +616,27 @@
   "trends.counter_by_accounts": "{count, plural, one {{counter} persona} other {{counter} persones}} en {days, plural, one {el passat dia} other {els passats {days} dies}}",
   "trends.trending_now": "És tendència",
   "ui.beforeunload": "El teu esborrany es perdrà si surts de Mastodon.",
-  "units.short.billion": "{count} B",
-  "units.short.million": "{count} M",
-  "units.short.thousand": "{count} K",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
   "upload_area.title": "Arrossega i deixa anar per a carregar",
   "upload_button.label": "Afegeix imatges, un vídeo o un fitxer d'àudio",
   "upload_error.limit": "S'ha superat el límit de càrrega d'arxius.",
   "upload_error.poll": "No es permet carregar fitxers a les enquestes.",
-  "upload_form.audio_description": "Descripció per a persones amb discapacitat auditiva",
-  "upload_form.description": "Descripció per a persones amb discapacitat visual",
+  "upload_form.audio_description": "Descriu-ho per a persones amb problemes d'audició",
+  "upload_form.description": "Descriu-ho per a persones amb problemes de visió",
   "upload_form.description_missing": "No s'hi ha afegit cap descripció",
   "upload_form.edit": "Edita",
   "upload_form.thumbnail": "Canvia la miniatura",
   "upload_form.undo": "Elimina",
-  "upload_form.video_description": "Descripció per a persones amb discapacitat auditiva o amb discapacitat visual",
+  "upload_form.video_description": "Descriu-ho per a persones amb problemes de visió o audició",
   "upload_modal.analyzing_picture": "S'analitza la imatge…",
   "upload_modal.apply": "Aplica",
   "upload_modal.applying": "S'aplica…",
   "upload_modal.choose_image": "Tria la imatge",
-  "upload_modal.description_placeholder": "Jove xef, porti whisky amb quinze glaçons d’hidrogen, coi!",
+  "upload_modal.description_placeholder": "Setze jutges d'un jutjat mengen fetge d'un penjat",
   "upload_modal.detect_text": "Detecta el text de la imatge",
-  "upload_modal.edit_media": "Edita el contingut",
+  "upload_modal.edit_media": "Edita el Mèdia",
   "upload_modal.hint": "Fes clic o arrossega el cercle en la previsualització per a triar el punt focal que sempre serà visible en totes les miniatures.",
   "upload_modal.preparing_ocr": "Es prepara l'OCR…",
   "upload_modal.preview_label": "Previsualitza ({ratio})",
diff --git a/app/javascript/mastodon/locales/ckb.json b/app/javascript/mastodon/locales/ckb.json
index f2879ca6e..62c24583d 100644
--- a/app/javascript/mastodon/locales/ckb.json
+++ b/app/javascript/mastodon/locales/ckb.json
@@ -6,11 +6,11 @@
   "about.domain_blocks.preamble": "ماستۆدۆن بە گشتی ڕێگەت پێدەدات بە پیشاندانی ناوەڕۆکەکان و کارلێک کردن لەگەڵ بەکارهێنەران لە هەر ڕاژەیەکی تر بە گشتی. ئەمانە ئەو بەدەرکردنانەن کە کراون لەسەر ئەم ڕاژە تایبەتە.",
   "about.domain_blocks.silenced.explanation": "بە گشتی ناتوانی زانیاریە تایبەتەکان و ناوەڕۆکی ئەم ڕاژەیە ببینی، مەگەر بە ڕوونی بەدوایدا بگەڕێیت یان هەڵیبژێریت بۆ شوێنکەوتنی.",
   "about.domain_blocks.silenced.title": "سنووردار",
-  "about.domain_blocks.suspended.explanation": "No data from this server will be processed, stored or exchanged, making any interaction or communication with users from this server impossible.",
+  "about.domain_blocks.suspended.explanation": "هیچ داتایەک لەم سێرڤەرەوە پرۆسێس ناکرێت، هەڵناگیرێت یان ئاڵوگۆڕ ناکرێت، ئەمەش وا دەکات هیچ کارلێکێک یان پەیوەندییەک لەگەڵ بەکارهێنەران لەم سێرڤەرەوە مەحاڵ بێت.",
   "about.domain_blocks.suspended.title": "هەڵپەسێردراوە",
-  "about.not_available": "This information has not been made available on this server.",
-  "about.powered_by": "Decentralized social media powered by {mastodon}",
-  "about.rules": "Server rules",
+  "about.not_available": "ئەم زانیاریانە لەسەر ئەم سێرڤەرە بەردەست نەکراون.",
+  "about.powered_by": "سۆشیال میدیای لامەرکەزی کە لەلایەن {mastodon} ەوە بەهێز دەکرێت",
+  "about.rules": "یاساکانی سێرڤەر",
   "account.account_note_header": "تێبینی    ",
   "account.add_or_remove_from_list": "زیادکردن یان سڕینەوە لە پێرستەکان",
   "account.badges.bot": "بوت",
@@ -19,16 +19,16 @@
   "account.block_domain": "بلۆکی هەموو شتێک لە {domain}",
   "account.blocked": "بلۆککرا",
   "account.browse_more_on_origin_server": "گەڕانی فرەتر لە سەر پرۆفایلی سەرەکی",
-  "account.cancel_follow_request": "Withdraw follow request",
+  "account.cancel_follow_request": "داواکاری فۆڵۆو بکشێنەوە",
   "account.direct": "پەیامی تایبەت بە @{name}",
   "account.disable_notifications": "ئاگانامە مەنێرە بۆم کاتێک @{name} پۆست دەکرێت",
   "account.domain_blocked": "دۆمەین قەپاتکرا",
   "account.edit_profile": "دەستکاری پرۆفایل",
   "account.enable_notifications": "ئاگادارم بکەوە کاتێک @{name} بابەتەکان",
   "account.endorse": "ناساندن لە پرۆفایل",
-  "account.featured_tags.last_status_at": "Last post on {date}",
-  "account.featured_tags.last_status_never": "No posts",
-  "account.featured_tags.title": "{name}'s featured hashtags",
+  "account.featured_tags.last_status_at": "دوایین پۆست لە {date}",
+  "account.featured_tags.last_status_never": "هیچ پۆستێک نییە",
+  "account.featured_tags.title": "هاشتاگە تایبەتەکانی {name}",
   "account.follow": "شوێنکەوتن",
   "account.followers": "شوێنکەوتووان",
   "account.followers.empty": "کەسێک شوێن ئەم بەکارهێنەرە نەکەوتووە",
@@ -37,23 +37,24 @@
   "account.following_counter": "{count, plural, one {{counter} شوێنکەوتوو} other {{counter} شوێنکەوتوو}}",
   "account.follows.empty": "ئەم بەکارهێنەرە تا ئێستا شوێن کەس نەکەوتووە.",
   "account.follows_you": "شوێنکەوتووەکانت",
-  "account.go_to_profile": "Go to profile",
+  "account.go_to_profile": "بڕۆ بۆ پڕۆفایلی",
   "account.hide_reblogs": "داشاردنی بووستەکان لە @{name}",
-  "account.joined_short": "Joined",
-  "account.languages": "Change subscribed languages",
+  "account.joined_short": "بەشداری کردووە",
+  "account.languages": "گۆڕینی زمانە بەشداربووەکان",
   "account.link_verified_on": "خاوەنداریەتی ئەم لینکە لە {date} چێک کراوە",
   "account.locked_info": "تایبەتمەندی ئەم هەژمارەیە ڕیکخراوە بۆ قوفڵدراوە. خاوەنەکە بە دەستی پێداچوونەوە دەکات کە کێ دەتوانێت شوێنیان بکەوێت.",
   "account.media": "میدیا",
   "account.mention": "ئاماژە @{name}",
-  "account.moved_to": "{name} has indicated that their new account is now:",
+  "account.moved_to": "{name} ئاماژەی بەوە کردووە کە ئەکاونتە نوێیەکەیان ئێستا:",
   "account.mute": "بێدەنگکردن @{name}",
   "account.mute_notifications": "هۆشیارکەرەوەکان لاببە لە @{name}",
   "account.muted": "بێ دەنگ",
-  "account.open_original_page": "Open original page",
+  "account.open_original_page": "لاپەڕەی ئەسڵی بکەرەوە",
   "account.posts": "توتس",
   "account.posts_with_replies": "توتس و وەڵامەکان",
   "account.report": "گوزارشت @{name}",
   "account.requested": "چاوەڕێی ڕەزامەندین. کرتە بکە بۆ هەڵوەشاندنەوەی داواکاری شوێنکەوتن",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "پرۆفایلی @{name} هاوبەش بکە",
   "account.show_reblogs": "پیشاندانی بەرزکردنەوەکان لە @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
@@ -77,27 +78,27 @@
   "alert.unexpected.title": "تەححح!",
   "announcement.announcement": "بانگەواز",
   "attachments_list.unprocessed": "(unprocessed)",
-  "audio.hide": "Hide audio",
+  "audio.hide": "شاردنەوەی دەنگ",
   "autosuggest_hashtag.per_week": "{count} هەرهەفتە",
   "boost_modal.combo": "دەتوانیت دەست بنێی بە سەر {combo} بۆ بازدان لە جاری داهاتوو",
-  "bundle_column_error.copy_stacktrace": "Copy error report",
-  "bundle_column_error.error.body": "The requested page could not be rendered. It could be due to a bug in our code, or a browser compatibility issue.",
-  "bundle_column_error.error.title": "Oh, no!",
-  "bundle_column_error.network.body": "There was an error when trying to load this page. This could be due to a temporary problem with your internet connection or this server.",
-  "bundle_column_error.network.title": "Network error",
+  "bundle_column_error.copy_stacktrace": "ڕاپۆرتی هەڵەی کۆپی بکە",
+  "bundle_column_error.error.body": "لاپەڕەی داواکراو نەتوانرا ڕەندەر بکرێت. دەکرێت بەهۆی هەڵەیەکی کۆدەکەمانەوە بێت، یان کێشەی گونجانی وێبگەڕ.",
+  "bundle_column_error.error.title": "ئای نا!",
+  "bundle_column_error.network.body": "لە کاتی هەوڵدان بۆ بارکردنی ئەم لاپەڕەیە هەڵەیەک ڕوویدا. ئەمەش دەتوانێت بەهۆی کێشەیەکی کاتی هێڵی ئینتەرنێتەکەت یان ئەم سێرڤەرە بێت.",
+  "bundle_column_error.network.title": "هەڵەی تۆڕ",
   "bundle_column_error.retry": "دووبارە هەوڵبدە",
-  "bundle_column_error.return": "Go back home",
-  "bundle_column_error.routing.body": "The requested page could not be found. Are you sure the URL in the address bar is correct?",
-  "bundle_column_error.routing.title": "404",
+  "bundle_column_error.return": "بگەڕێرەوە ماڵەوە",
+  "bundle_column_error.routing.body": "پەیجی داواکراو ناتوانرێت بدۆزرێتەوە. ئایا دڵنیای کە URL ی ناو ناونیشانەکان ڕاستە?",
+  "bundle_column_error.routing.title": "٤٠٤",
   "bundle_modal_error.close": "داخستن",
   "bundle_modal_error.message": "هەڵەیەک ڕوویدا لەکاتی بارکردنی ئەم پێکهاتەیە.",
   "bundle_modal_error.retry": "دووبارە تاقی بکەوە",
-  "closed_registrations.other_server_instructions": "Since Mastodon is decentralized, you can create an account on another server and still interact with this one.",
-  "closed_registrations_modal.description": "Creating an account on {domain} is currently not possible, but please keep in mind that you do not need an account specifically on {domain} to use Mastodon.",
-  "closed_registrations_modal.find_another_server": "Find another server",
-  "closed_registrations_modal.preamble": "Mastodon is decentralized, so no matter where you create your account, you will be able to follow and interact with anyone on this server. You can even self-host it!",
-  "closed_registrations_modal.title": "Signing up on Mastodon",
-  "column.about": "About",
+  "closed_registrations.other_server_instructions": "بەو پێیەی ماستۆدۆن لامەرکەزییە، دەتوانیت ئەکاونتێک لەسەر سێرڤەرێکی تر دروست بکەیت و هێشتا کارلێک لەگەڵ ئەم سێرڤەرەدا بکەیت.",
+  "closed_registrations_modal.description": "دروستکردنی ئەکاونت لەسەر {domain} لە ئێستادا ناتوانرێت، بەڵام تکایە ئەوەت لەبەرچاو بێت کە پێویستت بە ئەکاونتێک نییە بە تایبەتی لەسەر {domain} بۆ بەکارهێنانی ماستۆدۆن.",
+  "closed_registrations_modal.find_another_server": "سێرڤەرێکی تر بدۆزەرەوە",
+  "closed_registrations_modal.preamble": "ماستۆدۆن لامەرکەزییە، بۆیە گرنگ نییە لە کوێ ئەکاونتەکەت دروست بکەیت، دەتوانیت فۆڵۆوی هەر کەسێک بکەیت و کارلێک لەگەڵیدا بکەیت لەسەر ئەم سێرڤەرە. تەنانەت دەتوانیت خۆت میوانداری بکەیت!",
+  "closed_registrations_modal.title": "ناو تۆمارکردن لە ماستۆدۆن",
+  "column.about": "دەربارە",
   "column.blocks": "بەکارهێنەرە بلۆککراوەکان",
   "column.bookmarks": "نیشانەکان",
   "column.community": "هێڵی کاتی ناوخۆیی",
@@ -123,11 +124,11 @@
   "community.column_settings.local_only": "تەنها خۆماڵی",
   "community.column_settings.media_only": "تەنها میدیا",
   "community.column_settings.remote_only": "تەنها بۆ دوور",
-  "compose.language.change": "Change language",
-  "compose.language.search": "Search languages...",
+  "compose.language.change": "گۆڕینی زمان",
+  "compose.language.search": "گەڕان بە زمانەکان...",
   "compose_form.direct_message_warning_learn_more": "زیاتر فێربه",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "ئەم توتە لە ژێر هیچ هاشتاگییەک دا ناکرێت وەک ئەوەی لە لیستەکەدا نەریزراوە. تەنها توتی گشتی دەتوانرێت بە هاشتاگی بگەڕێت.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "هەژمێرەکەی لە حاڵەتی {locked}. هەر کەسێک دەتوانێت شوێنت بکەوێت بۆ پیشاندانی بابەتەکانی تەنها دوایخۆی.",
   "compose_form.lock_disclaimer.lock": "قفڵ دراوە",
   "compose_form.placeholder": "چی لە مێشکتدایە?",
@@ -137,8 +138,8 @@
   "compose_form.poll.remove_option": "لابردنی ئەم هەڵبژاردەیە",
   "compose_form.poll.switch_to_multiple": "ڕاپرسی بگۆڕە بۆ ڕێگەدان بە چەند هەڵبژاردنێک",
   "compose_form.poll.switch_to_single": "گۆڕینی ڕاپرسی بۆ ڕێگەدان بە تاکە هەڵبژاردنێک",
-  "compose_form.publish": "Publish",
-  "compose_form.publish_form": "Publish",
+  "compose_form.publish": "بڵاوی بکەوە",
+  "compose_form.publish_form": "بڵاوی بکەوە",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.save_changes": "پاشکەوتی گۆڕانکاریەکان",
   "compose_form.sensitive.hide": "نیشانکردنی میدیا وەک هەستیار",
@@ -151,8 +152,8 @@
   "confirmations.block.block_and_report": "بلۆک & گوزارشت",
   "confirmations.block.confirm": "بلۆک",
   "confirmations.block.message": "ئایا دڵنیایت لەوەی دەتەوێت {name} بلۆک بکەیت?",
-  "confirmations.cancel_follow_request.confirm": "Withdraw request",
-  "confirmations.cancel_follow_request.message": "Are you sure you want to withdraw your request to follow {name}?",
+  "confirmations.cancel_follow_request.confirm": "داواکاری کشانەوە",
+  "confirmations.cancel_follow_request.message": "ئایا دڵنیای کە دەتەوێت داواکارییەکەت بۆ شوێنکەوتنی {ناو} بکشێنیتەوە؟",
   "confirmations.delete.confirm": "سڕینەوە",
   "confirmations.delete.message": "ئایا دڵنیایت لەوەی دەتەوێت ئەم توتە بسڕیتەوە?",
   "confirmations.delete_list.confirm": "سڕینەوە",
@@ -176,20 +177,20 @@
   "conversation.mark_as_read": "نیشانەکردن وەک خوێندراوە",
   "conversation.open": "نیشاندان گفتوگۆ",
   "conversation.with": "لەگەڵ{names}",
-  "copypaste.copied": "Copied",
-  "copypaste.copy": "Copy",
+  "copypaste.copied": "کۆپی کراوە",
+  "copypaste.copy": "ڕوونووس",
   "directory.federated": "لە ڕاژەکانی ناسراو",
   "directory.local": "تەنها لە {domain}",
   "directory.new_arrivals": "تازە گەیشتنەکان",
   "directory.recently_active": "بەم دواییانە چالاکە",
-  "disabled_account_banner.account_settings": "Account settings",
-  "disabled_account_banner.text": "Your account {disabledAccount} is currently disabled.",
-  "dismissable_banner.community_timeline": "These are the most recent public posts from people whose accounts are hosted by {domain}.",
-  "dismissable_banner.dismiss": "Dismiss",
-  "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
-  "dismissable_banner.explore_statuses": "These posts from this and other servers in the decentralized network are gaining traction on this server right now.",
-  "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
-  "dismissable_banner.public_timeline": "These are the most recent public posts from people on this and other servers of the decentralized network that this server knows about.",
+  "disabled_account_banner.account_settings": "ڕێکخستنەکانی هەژمارە",
+  "disabled_account_banner.text": "ئەکاونتەکەت {disabledAccount} لە ئێستادا لەکارخراوە.",
+  "dismissable_banner.community_timeline": "ئەمانە دوایین پۆستی گشتی ئەو کەسانەن کە ئەکاونتەکانیان لەلایەن {domain}ەوە هۆست کراوە.",
+  "dismissable_banner.dismiss": "بەلاوە نان",
+  "dismissable_banner.explore_links": "ئەم هەواڵانە لە ئێستادا لەلایەن کەسانێکەوە لەسەر ئەم سێرڤەرە و سێرڤەرەکانی تری تۆڕی لامەرکەزی باس دەکرێن.",
+  "dismissable_banner.explore_statuses": "ئەم پۆستانەی ئەم سێرڤەرە و سێرڤەرەکانی تری ناو تۆڕی لامەرکەزی لە ئێستادا خەریکە کێشکردن لەسەر ئەم سێرڤەرە بەدەست دەهێنن.",
+  "dismissable_banner.explore_tags": "ئەم هاشتاگانە لە ئێستادا لە نێو خەڵکی سەر ئەم سێرڤەرە و سێرڤەرەکانی تری تۆڕی لامەرکەزیدا جێگەی خۆیان دەگرن.",
+  "dismissable_banner.public_timeline": "ئەمانە دوایین پۆستە گشتیەکانن لە کەسانی سەر ئەم سێرڤەرە و سێرڤەرەکانی تری تۆڕی لامەرکەزی کە ئەم سێرڤەرە دەزانێت.",
   "embed.instructions": "ئەم توتە بنچین بکە لەسەر وێب سایتەکەت بە کۆپیکردنی کۆدەکەی خوارەوە.",
   "embed.preview": "ئەمە ئەو شتەیە کە لە شێوەی خۆی دەچێت:",
   "emoji_button.activity": "چالاکی",
@@ -235,12 +236,16 @@
   "errors.unexpected_crash.copy_stacktrace": "کۆپیکردنی ستێکتراسی بۆ کلیپ بۆرد",
   "errors.unexpected_crash.report_issue": "کێشەی گوزارشت",
   "explore.search_results": "ئەنجامەکانی گەڕان",
+  "explore.suggested_follows": "For you",
   "explore.title": "گەڕان",
-  "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
-  "filter_modal.added.context_mismatch_title": "Context mismatch!",
-  "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
-  "filter_modal.added.expired_title": "Expired filter!",
-  "filter_modal.added.review_and_configure": "To review and further configure this filter category, go to the {settings_link}.",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
+  "filter_modal.added.context_mismatch_explanation": "ئەم پۆلە فلتەرە ئەو چوارچێوەیە ناگرێتەوە کە تۆ تێیدا دەستت بەم پۆستە کردووە. ئەگەر بتەوێت پۆستەکە لەم چوارچێوەیەشدا فلتەر بکرێت، دەبێت دەستکاری فلتەرەکە بکەیت.",
+  "filter_modal.added.context_mismatch_title": "ناتەبایی دەقی نووسراو!",
+  "filter_modal.added.expired_explanation": "ئەم پۆلە فلتەرە بەسەرچووە، پێویستە بەرواری بەسەرچوونی بگۆڕیت بۆ ئەوەی جێبەجێی بکات.",
+  "filter_modal.added.expired_title": "فلتەری بەسەرچووە!",
+  "filter_modal.added.review_and_configure": "بۆ پێداچوونەوە و ڕێکخستنی زیاتری ئەم پۆلە فلتەرە، بچۆ بۆ {settings_link}.",
   "filter_modal.added.review_and_configure_title": "Filter settings",
   "filter_modal.added.settings_link": "settings page",
   "filter_modal.added.short_explanation": "This post has been added to the following filter category: {title}.",
@@ -528,15 +533,16 @@
   "search_results.title": "Search for {q}",
   "search_results.total": "{count, number} {count, plural, one {دەرئەنجام} other {دەرئەنجام}}",
   "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)",
-  "server_banner.active_users": "active users",
-  "server_banner.administered_by": "Administered by:",
-  "server_banner.introduction": "{domain} is part of the decentralized social network powered by {mastodon}.",
-  "server_banner.learn_more": "Learn more",
-  "server_banner.server_stats": "Server stats:",
-  "sign_in_banner.create_account": "Create account",
-  "sign_in_banner.sign_in": "Sign in",
-  "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
+  "server_banner.active_users": "بەکارهێنەرانی چالاک",
+  "server_banner.administered_by": "بەڕێوەبردن لەلایەن:",
+  "server_banner.introduction": "{domain} بەشێکە لەو تۆڕە کۆمەڵایەتییە لامەرکەزییەی کە لەلایەن {mastodon}ەوە بەهێز دەکرێت.",
+  "server_banner.learn_more": "زیاتر فێربه",
+  "server_banner.server_stats": "دۆخی ڕاژەکار:",
+  "sign_in_banner.create_account": "هەژمار دروستبکە",
+  "sign_in_banner.sign_in": "بچۆ ژوورەوە",
+  "sign_in_banner.text": "چوونەژوورەوە بۆ فۆڵۆوکردنی پڕۆفایلی یان هاشتاگەکان، دڵخوازکردن، هاوبەشکردن و وەڵامدانەوەی پۆستەکان، یان کارلێککردن لە ئەکاونتەکەتەوە لەسەر سێرڤەرێکی جیاواز.",
   "status.admin_account": "کردنەوەی میانڕەوی بەڕێوەبەر بۆ @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "ئەم توتە بکەوە لە ناو ڕووکاری بەڕیوەبەر",
   "status.block": "@{name} ئاستەنگ بکە",
   "status.bookmark": "نیشانه",
@@ -551,9 +557,9 @@
   "status.edited_x_times": "دەستکاریکراوە {count, plural, one {{count} کات} other {{count} کات}}",
   "status.embed": "نیشتەجێ بکە",
   "status.favourite": "دڵخواز",
-  "status.filter": "Filter this post",
+  "status.filter": "ئەم پۆستە فلتەر بکە",
   "status.filtered": "پاڵاوتن",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} دروستکراوە لە{date}",
   "status.history.edited": "{name} دروستکاریکراوە لە{date}",
   "status.load_more": "زیاتر بار بکە",
@@ -572,26 +578,26 @@
   "status.reblogs.empty": "کەس ئەم توتەی دووبارە نەتوتاندوە ،کاتێک کەسێک وا بکات، لێرە دەرئەکەون.",
   "status.redraft": "سڕینەوەی و دووبارە ڕەشنووس",
   "status.remove_bookmark": "لابردنی نیشانه",
-  "status.replied_to": "Replied to {name}",
+  "status.replied_to": "لە وەڵامدا بۆ {name}",
   "status.reply": "وەڵام",
   "status.replyAll": "بە نووسراوە وەڵام بدەوە",
   "status.report": "گوزارشت @{name}",
   "status.sensitive_warning": "ناوەڕۆکی هەستیار",
   "status.share": "هاوبەشی بکە",
-  "status.show_filter_reason": "Show anyway",
+  "status.show_filter_reason": "بە هەر حاڵ نیشان بدە",
   "status.show_less": "کەمتر نیشان بدە",
   "status.show_less_all": "هەمووی بچووک بکەوە",
   "status.show_more": "زیاتر نیشان بدە",
   "status.show_more_all": "زیاتر نیشان بدە بۆ هەمووی",
-  "status.show_original": "Show original",
-  "status.translate": "Translate",
-  "status.translated_from_with": "Translated from {lang} using {provider}",
+  "status.show_original": "پیشاندانی شێوه‌ی ڕاسته‌قینه‌",
+  "status.translate": "وەریبگێرە",
+  "status.translated_from_with": "لە {lang} وەرگێڕدراوە بە بەکارهێنانی {provider}",
   "status.uncached_media_warning": "بەردەست نیە",
   "status.unmute_conversation": "گفتوگۆی بێدەنگ",
   "status.unpin": "لە سەرەوە لایبە",
-  "subscribed_languages.lead": "Only posts in selected languages will appear on your home and list timelines after the change. Select none to receive posts in all languages.",
-  "subscribed_languages.save": "Save changes",
-  "subscribed_languages.target": "Change subscribed languages for {target}",
+  "subscribed_languages.lead": "تەنها پۆستەکان بە زمانە هەڵبژێردراوەکان لە ماڵەکەتدا دەردەکەون و هێڵەکانی کاتی لیستەکەت دوای گۆڕانکارییەکە. هیچیان هەڵبژێرە بۆ وەرگرتنی پۆست بە هەموو زمانەکان.",
+  "subscribed_languages.save": "پاشکەوتی گۆڕانکاریەکان",
+  "subscribed_languages.target": "گۆڕینی زمانە بەشداربووەکان بۆ {target}",
   "suggestions.dismiss": "ڕەتکردنەوەی پێشنیار",
   "suggestions.header": "لەوانەیە حەزت لەمەش بێت…",
   "tabs_bar.federated_timeline": "گشتی",
@@ -635,7 +641,7 @@
   "upload_modal.preparing_ocr": "نووسینەکە دەستنیشان دەکرێت…",
   "upload_modal.preview_label": "پێشبینین ({ratio})",
   "upload_progress.label": "بار دەکرێت...",
-  "upload_progress.processing": "Processing…",
+  "upload_progress.processing": "جێبەجێکردن...",
   "video.close": "داخستنی ڤیدیۆ",
   "video.download": "داگرتنی فایل",
   "video.exit_fullscreen": "دەرچوون لە پڕ شاشە",
diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json
index 743d577d7..1820e511c 100644
--- a/app/javascript/mastodon/locales/co.json
+++ b/app/javascript/mastodon/locales/co.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Statuti è risposte",
   "account.report": "Palisà @{name}",
   "account.requested": "In attesa d'apprubazione. Cliccate per annullà a dumanda",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Sparte u prufile di @{name}",
   "account.show_reblogs": "Vede spartere da @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Statutu} other {{counter} Statuti}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Amparà di più",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "Stu statutu ùn hè \"Micca listatu\" è ùn sarà micca listatu indè e circate da hashtag. Per esse vistu in quesse, u statutu deve esse \"Pubblicu\".",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "U vostru contu ùn hè micca {locked}. Tuttu u mondu pò seguitavi è vede i vostri statuti privati.",
   "compose_form.lock_disclaimer.lock": "privatu",
   "compose_form.placeholder": "À chè pensate?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Cupià stacktrace nant'à u fermacarta",
   "errors.unexpected_crash.report_issue": "Palisà prublemu",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Apre l'interfaccia di muderazione per @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Apre stu statutu in l'interfaccia di muderazione",
   "status.block": "Bluccà @{name}",
   "status.bookmark": "Segnalibru",
@@ -553,7 +559,7 @@
   "status.favourite": "Aghjunghje à i favuriti",
   "status.filter": "Filter this post",
   "status.filtered": "Filtratu",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Vede di più",
diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json
index f153d823b..0559cebf8 100644
--- a/app/javascript/mastodon/locales/cs.json
+++ b/app/javascript/mastodon/locales/cs.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Příspěvky a odpovědi",
   "account.report": "Nahlásit @{name}",
   "account.requested": "Čeká na schválení. Kliknutím žádost o sledování zrušíte",
+  "account.requested_follow": "{name} tě požádal o sledování",
   "account.share": "Sdílet profil @{name}",
   "account.show_reblogs": "Zobrazit boosty od @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Příspěvek} few {{counter} Příspěvky} many {{counter} Příspěvků} other {{counter} Příspěvků}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Prohledat jazyky...",
   "compose_form.direct_message_warning_learn_more": "Zjistit více",
   "compose_form.encryption_warning": "Příspěvky na Mastodonu nejsou end-to-end šifrovány. Nesdílejte přes Mastodon žádné citlivé informace.",
-  "compose_form.hashtag_warning": "Tento příspěvek nebude zobrazen pod žádným hashtagem, neboť je neveřejný. Pouze veřejné příspěvky mohou být vyhledány podle hashtagu.",
+  "compose_form.hashtag_warning": "Tento příspěvek nebude zobrazen pod žádným hashtagem, protože není veřejný. Podle hashtagu lze vyhledávat jen veřejné příspěvky.",
   "compose_form.lock_disclaimer": "Váš účet není {locked}. Kdokoliv vás může sledovat a vidět vaše příspěvky učené pouze pro sledující.",
   "compose_form.lock_disclaimer.lock": "zamčený",
   "compose_form.placeholder": "Co se vám honí hlavou?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Zkopírovat stacktrace do schránky",
   "errors.unexpected_crash.report_issue": "Nahlásit problém",
   "explore.search_results": "Výsledky hledání",
+  "explore.suggested_follows": "Pro vás",
   "explore.title": "Objevit",
+  "explore.trending_links": "Zprávy",
+  "explore.trending_statuses": "Příspěvky",
+  "explore.trending_tags": "Hashtagy",
   "filter_modal.added.context_mismatch_explanation": "Tato kategorie filtrů se nevztahuje na kontext, ve kterém jste tento příspěvek otevřeli. Pokud chcete, aby byl příspěvek filtrován i v tomto kontextu, budete muset filtr upravit.",
   "filter_modal.added.context_mismatch_title": "Kontext se neshoduje!",
   "filter_modal.added.expired_explanation": "Tato kategorie filtrů vypršela, budete muset změnit datum vypršení platnosti, aby mohla být použita.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Přihlásit se",
   "sign_in_banner.text": "Přihlaste se pro sledování profilů nebo hashtagů, oblíbení, sdílení a odpovědí na příspěvky nebo interakci z vašeho účtu na jiném serveru.",
   "status.admin_account": "Otevřít moderátorské rozhraní pro @{name}",
+  "status.admin_domain": "Otevřít moderátorské rozhraní pro {domain}",
   "status.admin_status": "Otevřít tento příspěvek v moderátorském rozhraní",
   "status.block": "Blokovat @{name}",
   "status.bookmark": "Přidat do záložek",
diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json
index 0f29be2c9..c854501fa 100644
--- a/app/javascript/mastodon/locales/cy.json
+++ b/app/javascript/mastodon/locales/cy.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Postiadau ac atebion",
   "account.report": "Adrodd @{name}",
   "account.requested": "Aros am gymeradwyaeth. Cliciwch er mwyn canslo cais dilyn",
+  "account.requested_follow": "Mae {name} wedi gwneud cais i'ch dilyn",
   "account.share": "Rhannwch broffil @{name}",
   "account.show_reblogs": "Dangos hybiau gan @{name}",
   "account.statuses_counter": "{count, plural, one {Postiad: {counter}} other {Postiad: {counter}}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Chwilio ieithoedd...",
   "compose_form.direct_message_warning_learn_more": "Dysgu mwy",
   "compose_form.encryption_warning": "Dyw postiadau ar Mastodon ddim wedi'u hamgryptio o ben i ben. Peidiwch â rhannu unrhyw wybodaeth sensitif dros Mastodon.",
-  "compose_form.hashtag_warning": "Ni fydd y post hwn wedi ei restru o dan unrhyw hashnod gan ei fod heb ei restru. Dim ond postiadau cyhoeddus gellid chwilio amdanynt drwy hashnod.",
+  "compose_form.hashtag_warning": "Ni fydd y postiad hwn wedi ei restru o dan unrhyw hashnod gan nad yw'n gyhoeddus. Dim ond postiadau cyhoeddus y mae modd eu chwilio drwy hashnod.",
   "compose_form.lock_disclaimer": "Nid yw eich cyfri wedi'i {locked}. Gall unrhyw un eich dilyn i weld eich postiadau dilynwyr-yn-unig.",
   "compose_form.lock_disclaimer.lock": "wedi ei gloi",
   "compose_form.placeholder": "Beth sydd ar eich meddwl?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copïo'r olrhain stac i'r clipfwrdd",
   "errors.unexpected_crash.report_issue": "Rhoi gwybod am broblem",
   "explore.search_results": "Canlyniadau chwilio",
+  "explore.suggested_follows": "I chi",
   "explore.title": "Archwilio",
+  "explore.trending_links": "Newyddion",
+  "explore.trending_statuses": "Postiadau",
+  "explore.trending_tags": "Hashnodau",
   "filter_modal.added.context_mismatch_explanation": "Nid yw'r categori hidlo hwn yn berthnasol i'r cyd-destun yr ydych wedi cyrchu'r postiad hwn ynddo. Os ydych chi am i'r postiad gael ei hidlo yn y cyd-destun hwn hefyd, bydd yn rhaid i chi olygu'r hidlydd.",
   "filter_modal.added.context_mismatch_title": "Diffyg cyfatebiaeth cyd-destun!",
   "filter_modal.added.expired_explanation": "Mae'r categori hidlydd hwn wedi dod i ben, bydd angen i chi newid y dyddiad dod i ben er mwyn iddo fod yn berthnasol.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Mewngofnodi",
   "sign_in_banner.text": "Mewngofnodwch i ddilyn proffiliau neu hashnodau, ffefrynnau, rhannu ac ymateb i bostiadau, neu ryngweithio o'ch cyfrif ar weinydd gwahanol.",
   "status.admin_account": "Agor rhyngwyneb cymedroli ar gyfer @{name}",
+  "status.admin_domain": "Agor rhyngwyneb cymedroli {domain}",
   "status.admin_status": "Agor y post hwn yn y rhyngwyneb goruwchwylio",
   "status.block": "Blocio @{name}",
   "status.bookmark": "Nod Tudalen",
@@ -553,7 +559,7 @@
   "status.favourite": "Ffefryn",
   "status.filter": "Hidlo'r postiad hwn",
   "status.filtered": "Wedi'i hidlo",
-  "status.hide": "Cuddio postiad",
+  "status.hide": "Cuddio'r postiad",
   "status.history.created": "Crëwyd gan {name} {date}",
   "status.history.edited": "Golygwyd gan {name} {date}",
   "status.load_more": "Llwythwch ragor",
diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json
index 684f308a6..743822366 100644
--- a/app/javascript/mastodon/locales/da.json
+++ b/app/javascript/mastodon/locales/da.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Indlæg og svar",
   "account.report": "Anmeld @{name}",
   "account.requested": "Afventer godkendelse. Tryk for at annullere følgeanmodning",
+  "account.requested_follow": "{name} har anmodet om at følge dig",
   "account.share": "Del @{name}s profil",
   "account.show_reblogs": "Vis fremhævelser fra @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Indlæg} other {{counter} Indlæg}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Søg efter sprog...",
   "compose_form.direct_message_warning_learn_more": "Få mere at vide",
   "compose_form.encryption_warning": "Indlæg på Mastodon er ikke ende-til-ende krypteret. Del derfor ikke sensitiv information via Mastodon.",
-  "compose_form.hashtag_warning": "Da indlægget ikke er offentligt, vises det ikke under noget hashtag, idet kun offentlige indlæg kan søges via hashtags.",
+  "compose_form.hashtag_warning": "Da indlægget ikke er offentligt, vises det ikke under noget hashtag, da kun offentlige indlæg er søgbare via hashtags.",
   "compose_form.lock_disclaimer": "Din konto er ikke {locked}. Enhver kan følge dig og se indlæg kun beregnet for følgere.",
   "compose_form.lock_disclaimer.lock": "låst",
   "compose_form.placeholder": "Hvad tænker du på?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopiér stacktrace til udklipsholderen",
   "errors.unexpected_crash.report_issue": "Anmeld problem",
   "explore.search_results": "Søgeresultater",
+  "explore.suggested_follows": "Til dig",
   "explore.title": "Udforsk",
+  "explore.trending_links": "Nyheder",
+  "explore.trending_statuses": "Indlæg",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Denne filterkategori omfatter ikke konteksten, hvorunder dette indlæg er tilgået. Redigér filteret, hvis indlægget også ønskes filtreret i denne kontekst.",
   "filter_modal.added.context_mismatch_title": "Kontekstmisforhold!",
   "filter_modal.added.expired_explanation": "Denne filterkategori er udløbet. Ændr dens udløbsdato, for at anvende den.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Log ind",
   "sign_in_banner.text": "Log ind for at følge profiler eller hashtags, markere som favorit, dele og svare på indlæg eller interagere fra din konto på en anden server.",
   "status.admin_account": "Åbn modereringsbrugerflade for @{name}",
+  "status.admin_domain": "Åbn modereringsbrugerflade for {domain}",
   "status.admin_status": "Åbn dette indlæg i modereringsbrugerfladen",
   "status.block": "Blokér @{name}",
   "status.bookmark": "Bogmærk",
diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json
index 8e3a6c65d..c43ff56f7 100644
--- a/app/javascript/mastodon/locales/de.json
+++ b/app/javascript/mastodon/locales/de.json
@@ -3,8 +3,8 @@
   "about.contact": "Kontakt:",
   "about.disclaimer": "Mastodon ist eine freie, quelloffene Software und eine Marke der Mastodon gGmbH.",
   "about.domain_blocks.no_reason_available": "Grund unbekannt",
-  "about.domain_blocks.preamble": "Mastodon erlaubt es dir grundsätzlich, alle Inhalte von allen Nutzer*innen auf allen Servern im Fediversum zu sehen und mit ihnen zu interagieren. Für diese Instanz gibt es aber ein paar Ausnahmen.",
-  "about.domain_blocks.silenced.explanation": "Alle Inhalte dieses Servers sind stumm geschaltet und werden zunächst nicht angezeigt. Du kannst die Profile und anderen Inhalte aber dennoch manuell aufrufen – oder Du folgst einer Person dieser Mastodon-Instanz.",
+  "about.domain_blocks.preamble": "Mastodon erlaubt es dir grundsätzlich, alle Inhalte von allen Nutzer*innen auf allen Servern im Fediversum zu sehen und mit ihnen zu interagieren. Für diesen Server gibt es aber ein paar Ausnahmen.",
+  "about.domain_blocks.silenced.explanation": "Alle Inhalte und Profile dieses Servers werden zunächst nicht angezeigt. Du kannst die Profile und Inhalte aber dennoch sehen, wenn du explizit nach diesen suchst oder diesen folgst.",
   "about.domain_blocks.silenced.title": "Stummgeschaltet",
   "about.domain_blocks.suspended.explanation": "Es werden keine Daten von diesem Server verarbeitet, gespeichert oder ausgetauscht, sodass eine Interaktion oder Kommunikation mit Nutzer*innen dieses Servers nicht möglich ist.",
   "about.domain_blocks.suspended.title": "Gesperrt",
@@ -49,15 +49,16 @@
   "account.mute": "@{name} stummschalten",
   "account.mute_notifications": "Benachrichtigungen von @{name} stummschalten",
   "account.muted": "Stummgeschaltet",
-  "account.open_original_page": "Auf ursprünglicher Instanz anzeigen",
+  "account.open_original_page": "Ursprüngliche Seite öffnen",
   "account.posts": "Beiträge",
   "account.posts_with_replies": "Beiträge und Antworten",
   "account.report": "@{name} melden",
   "account.requested": "Warte auf Genehmigung. Klicke hier, um die Anfrage zum Folgen abzubrechen",
+  "account.requested_follow": "{name} hat angefragt, dir folgen zu dürfen",
   "account.share": "Profil von @{name} teilen",
   "account.show_reblogs": "Geteilte Beiträge von @{name} wieder anzeigen",
   "account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
-  "account.unblock": "@{name} entsperren",
+  "account.unblock": "@{name} Sperre aufheben",
   "account.unblock_domain": "Sperre von {domain} aufheben",
   "account.unblock_short": "Sperre aufheben",
   "account.unendorse": "Im Profil nicht mehr empfehlen",
@@ -120,14 +121,14 @@
   "column_header.show_settings": "Einstellungen anzeigen",
   "column_header.unpin": "Lösen",
   "column_subheading.settings": "Einstellungen",
-  "community.column_settings.local_only": "Nur lokale Instanz",
+  "community.column_settings.local_only": "Nur lokal",
   "community.column_settings.media_only": "Nur Beiträge mit angehängten Medien",
-  "community.column_settings.remote_only": "Nur andere Mastodon-Instanzen anzeigen",
+  "community.column_settings.remote_only": "Nur andere Mastodon-Server anzeigen",
   "compose.language.change": "Sprache festlegen",
   "compose.language.search": "Sprachen suchen …",
   "compose_form.direct_message_warning_learn_more": "Mehr erfahren",
   "compose_form.encryption_warning": "Beiträge auf Mastodon sind nicht Ende-zu-Ende-verschlüsselt. Teile keine sensiblen Informationen über Mastodon.",
-  "compose_form.hashtag_warning": "Dieser Beitrag ist über Hashtags nicht zu finden, weil er nicht gelistet ist. Nur öffentliche Beiträge tauchen in den Hashtag-Timelines auf.",
+  "compose_form.hashtag_warning": "Dieser Beitrag wird unter keinem Hashtag sichtbar sein, weil er nicht öffentlich ist. Nur öffentliche Beiträge können nach Hashtags durchsucht werden.",
   "compose_form.lock_disclaimer": "Dein Profil ist nicht {locked}. Andere können dir folgen und deine Beiträge sehen, die nur für Follower bestimmt sind.",
   "compose_form.lock_disclaimer.lock": "geschützt",
   "compose_form.placeholder": "Was gibt's Neues?",
@@ -189,7 +190,7 @@
   "dismissable_banner.explore_links": "Diese Nachrichten werden gerade von Leuten auf diesem und anderen Servern des dezentralen Netzwerks besprochen.",
   "dismissable_banner.explore_statuses": "Diese Beiträge von diesem und anderen Servern im dezentralen Netzwerk gewinnen gerade an Reichweite auf diesem Server.",
   "dismissable_banner.explore_tags": "Diese Hashtags gewinnen gerade unter den Leuten auf diesem und anderen Servern des dezentralen Netzwerkes an Reichweite.",
-  "dismissable_banner.public_timeline": "Dies sind die neuesten öffentlichen Beiträge von Profilen auf dieser Mastodon-Instanz und auf anderen Servern des dezentralen Netzwerks, von denen dieser Server Kenntnis hat.",
+  "dismissable_banner.public_timeline": "Dies sind die neuesten öffentlichen Beiträge von Profilen auf diesem und anderen Servern des dezentralen Netzwerks, von denen dieser Server Kenntnis hat.",
   "embed.instructions": "Du kannst diesen Beitrag außerhalb des Fediverse (z. B. auf deiner Website) einbetten, indem du diesen iFrame-Code einfügst.",
   "embed.preview": "Vorschau:",
   "emoji_button.activity": "Aktivitäten",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Fehlerdiagnose in die Zwischenablage kopieren",
   "errors.unexpected_crash.report_issue": "Fehler melden",
   "explore.search_results": "Suchergebnisse",
+  "explore.suggested_follows": "Für dich",
   "explore.title": "Entdecken",
+  "explore.trending_links": "Neuigkeiten",
+  "explore.trending_statuses": "Beiträge",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Diese Filterkategorie gilt nicht für den Kontext, in welchem du auf diesen Beitrag zugegriffen hast. Wenn der Beitrag auch in diesem Kontext gefiltert werden soll, musst du den Filter bearbeiten.",
   "filter_modal.added.context_mismatch_title": "Kontext stimmt nicht überein!",
   "filter_modal.added.expired_explanation": "Diese Filterkategorie ist abgelaufen. Du musst das Ablaufdatum für diese Kategorie ändern.",
@@ -248,10 +253,10 @@
   "filter_modal.select_filter.context_mismatch": "gilt nicht für diesen Kontext",
   "filter_modal.select_filter.expired": "abgelaufen",
   "filter_modal.select_filter.prompt_new": "Neue Kategorie: {name}",
-  "filter_modal.select_filter.search": "Suchen oder Erstellen",
+  "filter_modal.select_filter.search": "Filter suchen oder erstellen",
   "filter_modal.select_filter.subtitle": "Einem vorhandenen Filter hinzufügen oder einen neuen erstellen",
   "filter_modal.select_filter.title": "Diesen Beitrag filtern",
-  "filter_modal.title.status": "Beitrag filtern",
+  "filter_modal.title.status": "Beitrag per Filter ausblenden",
   "follow_recommendations.done": "Fertig",
   "follow_recommendations.heading": "Folge Leuten, deren Beiträge du sehen möchtest! Hier sind einige Vorschläge.",
   "follow_recommendations.lead": "Beiträge von Personen, denen du folgst, werden in chronologischer Reihenfolge auf deiner Startseite angezeigt. Hab keine Angst, Fehler zu machen, du kannst den Leuten jederzeit wieder entfolgen!",
@@ -338,7 +343,7 @@
   "lightbox.next": "Vor",
   "lightbox.previous": "Zurück",
   "limited_account_hint.action": "Profil trotzdem anzeigen",
-  "limited_account_hint.title": "Dieses Profil wurde von den Moderator*innen der Mastodon-Instanz {domain} ausgeblendet.",
+  "limited_account_hint.title": "Dieses Profil wurde von den Moderator*innen von {domain} ausgeblendet.",
   "lists.account.add": "Zur Liste hinzufügen",
   "lists.account.remove": "Von der Liste entfernen",
   "lists.delete": "Liste löschen",
@@ -493,7 +498,7 @@
   "report.reasons.spam": "Das ist Spam",
   "report.reasons.spam_description": "Bösartige Links, gefälschtes Engagement oder wiederholte Antworten",
   "report.reasons.violation": "Es verstößt gegen Serverregeln",
-  "report.reasons.violation_description": "Du weißt, welche Regeln verletzt werden",
+  "report.reasons.violation_description": "Du bist dir bewusst, dass es gegen bestimmte Regeln verstößt",
   "report.rules.subtitle": "Wähle alle zutreffenden Inhalte aus",
   "report.rules.title": "Welche Regeln werden verletzt?",
   "report.statuses.subtitle": "Wähle alle zutreffenden Inhalte aus",
@@ -517,7 +522,7 @@
   "search_popout.tips.full_text": "Einfache Texteingabe gibt Beiträge, die du geschrieben, favorisiert und geteilt hast, zurück; außerdem auch Beiträge, in denen du erwähnt wurdest, aber auch passende Nutzernamen, Anzeigenamen oder Hashtags.",
   "search_popout.tips.hashtag": "Hashtag",
   "search_popout.tips.status": "Beitrag",
-  "search_popout.tips.text": "Einfache Texteingabe gibt Anzeigenamen, Benutzernamen und Hashtags zurück",
+  "search_popout.tips.text": "Einfache Texteingabe gibt Anzeigenamen, Profilnamen und Hashtags zurück",
   "search_popout.tips.user": "Profil",
   "search_results.accounts": "Profile",
   "search_results.all": "Alles",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Anmelden",
   "sign_in_banner.text": "Melde dich an, um Profilen oder Hashtags zu folgen, Beiträge zu favorisieren, zu teilen und auf sie zu antworten oder um von deinem Konto aus auf einem anderen Server zu interagieren.",
   "status.admin_account": "Moderationsoberfläche für @{name} öffnen",
+  "status.admin_domain": "Moderationsoberfläche für {domain} öffnen",
   "status.admin_status": "Diesen Beitrag in der Moderationsoberfläche öffnen",
   "status.block": "@{name} blockieren",
   "status.bookmark": "Beitrag als Lesezeichen setzen",
@@ -553,7 +559,7 @@
   "status.favourite": "Favorisieren",
   "status.filter": "Beitrag filtern",
   "status.filtered": "Gefiltert",
-  "status.hide": "Beitrag verbergen",
+  "status.hide": "Beitrag ausblenden",
   "status.history.created": "{name} erstellte {date}",
   "status.history.edited": "{name} bearbeitete {date}",
   "status.load_more": "Weitere laden",
@@ -617,13 +623,13 @@
   "upload_button.label": "Bilder, Videos oder Audios hinzufügen",
   "upload_error.limit": "Dateiupload-Limit überschritten.",
   "upload_error.poll": "Medien-Anhänge sind zusammen mit Umfragen nicht erlaubt.",
-  "upload_form.audio_description": "Beschreibung für Gehörlose und hörbehinderte Menschen",
-  "upload_form.description": "Bildbeschreibung für blinde und sehbehinderte Menschen",
+  "upload_form.audio_description": "Für Gehörlose und hörbehinderte Menschen beschreiben",
+  "upload_form.description": "Beschreibe für Menschen mit Sehbehinderung",
   "upload_form.description_missing": "Keine Beschreibung hinzugefügt",
   "upload_form.edit": "Beschreiben",
   "upload_form.thumbnail": "Vorschaubild ändern",
   "upload_form.undo": "Löschen",
-  "upload_form.video_description": "Beschreibe das Video für Menschen mit einer Hör- oder Sehbehinderung",
+  "upload_form.video_description": "Beschreibe für Menschen mit einer Hör- oder Sehbehinderung",
   "upload_modal.analyzing_picture": "Bild wird analysiert …",
   "upload_modal.apply": "Übernehmen",
   "upload_modal.applying": "Wird angewendet …",
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 265466695..6f3c5e1a0 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -652,15 +652,19 @@
         "id": "status.admin_account"
       },
       {
-        "defaultMessage": "Open this status in the moderation interface",
+        "defaultMessage": "Open this post in the moderation interface",
         "id": "status.admin_status"
       },
       {
-        "defaultMessage": "Copy link to status",
+        "defaultMessage": "Open moderation interface for {domain}",
+        "id": "status.admin_domain"
+      },
+      {
+        "defaultMessage": "Copy link to post",
         "id": "status.copy"
       },
       {
-        "defaultMessage": "Hide toot",
+        "defaultMessage": "Hide post",
         "id": "status.hide"
       },
       {
@@ -1044,6 +1048,23 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "{name} has requested to follow you",
+        "id": "account.requested_follow"
+      },
+      {
+        "defaultMessage": "Authorize",
+        "id": "follow_request.authorize"
+      },
+      {
+        "defaultMessage": "Reject",
+        "id": "follow_request.reject"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/account/components/follow_request_note.json"
+  },
+  {
+    "descriptors": [
+      {
         "defaultMessage": "Unfollow",
         "id": "account.unfollow"
       },
@@ -1180,6 +1201,10 @@
         "id": "status.admin_account"
       },
       {
+        "defaultMessage": "Open moderation interface for {domain}",
+        "id": "status.admin_domain"
+      },
+      {
         "defaultMessage": "Change subscribed languages",
         "id": "account.languages"
       },
@@ -2014,6 +2039,22 @@
       {
         "defaultMessage": "Search results",
         "id": "explore.search_results"
+      },
+      {
+        "defaultMessage": "Posts",
+        "id": "explore.trending_statuses"
+      },
+      {
+        "defaultMessage": "Hashtags",
+        "id": "explore.trending_tags"
+      },
+      {
+        "defaultMessage": "News",
+        "id": "explore.trending_links"
+      },
+      {
+        "defaultMessage": "For you",
+        "id": "explore.suggested_follows"
       }
     ],
     "path": "app/javascript/mastodon/features/explore/index.json"
@@ -3564,6 +3605,10 @@
         "id": "status.admin_status"
       },
       {
+        "defaultMessage": "Open moderation interface for {domain}",
+        "id": "status.admin_domain"
+      },
+      {
         "defaultMessage": "Copy link to status",
         "id": "status.copy"
       },
@@ -3918,15 +3963,15 @@
         "id": "confirmations.discard_edit_media.confirm"
       },
       {
-        "defaultMessage": "Describe for people with hearing loss",
+        "defaultMessage": "Describe for people who are hard of hearing",
         "id": "upload_form.audio_description"
       },
       {
-        "defaultMessage": "Describe for people with hearing loss or visual impairment",
+        "defaultMessage": "Describe for people who are deaf, hard of hearing, blind or have low vision",
         "id": "upload_form.video_description"
       },
       {
-        "defaultMessage": "Describe for the visually impaired",
+        "defaultMessage": "Describe for people who are blind or have low vision",
         "id": "upload_form.description"
       },
       {
diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json
index 8026e6cdb..ad88129e9 100644
--- a/app/javascript/mastodon/locales/el.json
+++ b/app/javascript/mastodon/locales/el.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Τουτ και απαντήσεις",
   "account.report": "Κατάγγειλε @{name}",
   "account.requested": "Εκκρεμεί έγκριση. Κάνε κλικ για να ακυρώσεις το αίτημα παρακολούθησης",
+  "account.requested_follow": "Ο/Η {name} αιτήθηκε να σε ακολουθήσει",
   "account.share": "Μοίρασμα του προφίλ @{name}",
   "account.show_reblogs": "Εμφάνιση προωθήσεων από @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Τουτ} other {{counter} Τουτ}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Αναζήτηση γλωσσών...",
   "compose_form.direct_message_warning_learn_more": "Μάθετε περισσότερα",
   "compose_form.encryption_warning": "Οι δημοσιεύσεις στο Mastodon δεν είναι κρυπτογραφημένες από άκρο σε άκρο. Μην μοιράζεστε ευαίσθητες πληροφορίες μέσω του Mastodon.",
-  "compose_form.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από κανένα hashtag καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
   "compose_form.lock_disclaimer.lock": "κλειδωμένο",
   "compose_form.placeholder": "Τι σκέφτεσαι;",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Αντιγραφή μηνυμάτων κώδικα στο πρόχειρο",
   "errors.unexpected_crash.report_issue": "Αναφορά προβλήματος",
   "explore.search_results": "Κανένα αποτέλεσμα.",
+  "explore.suggested_follows": "Για σένα",
   "explore.title": "Εξερεύνηση",
+  "explore.trending_links": "Νέα",
+  "explore.trending_statuses": "Αναρτήσεις",
+  "explore.trending_tags": "Ετικέτες",
   "filter_modal.added.context_mismatch_explanation": "Αυτή η κατηγορία φίλτρων δεν ισχύει για το πλαίσιο εντός του οποίου προσπελάσατε αυτή την ανάρτηση. Αν θέλετε να φιλτραριστεί η δημοσίευση και εντός αυτού του πλαισίου, θα πρέπει να τροποποιήσετε το φίλτρο.",
   "filter_modal.added.context_mismatch_title": "Συνοδευτικά",
   "filter_modal.added.expired_explanation": "Αυτή η κατηγορία φίλτρων έχει λήξει, πρέπει να αλλάξετε την ημερομηνία λήξης για να ισχύσει.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Σύνδεση",
   "sign_in_banner.text": "Συνδεθείτε για να ακολουθήσετε προφίλ ή ταμπέλες, αγαπημένα, να μοιραστείτε και να απαντήσετε σε δημοσιεύσεις ή να αλληλεπιδράσετε από το λογαριασμό σας σε διαφορετικό διακομιστή.",
   "status.admin_account": "Άνοιγμα λειτουργίας διαμεσολάβησης για τον/την @{name}",
+  "status.admin_domain": "Άνοιγμα λειτουργίας διαμεσολάβησης για {domain}",
   "status.admin_status": "Άνοιγμα αυτής της δημοσίευσης στη λειτουργία διαμεσολάβησης",
   "status.block": "Αποκλεισμός @{name}",
   "status.bookmark": "Σελιδοδείκτης",
@@ -553,7 +559,7 @@
   "status.favourite": "Σημείωσε ως αγαπημένο",
   "status.filter": "Φίλτρο...",
   "status.filtered": "Φιλτραρισμένα",
-  "status.hide": "Απόκρυψη toot",
+  "status.hide": "Απόκρυψη ανάρτησης",
   "status.history.created": "Δημιουργήθηκε από",
   "status.history.edited": "Τελευταία επεξεργασία από:",
   "status.load_more": "Φόρτωσε περισσότερα",
@@ -618,7 +624,7 @@
   "upload_error.limit": "Υπέρβαση ορίου μεγέθους ανεβασμένων αρχείων.",
   "upload_error.poll": "Στις δημοσκοπήσεις δεν επιτρέπεται η μεταφόρτωση αρχείου.",
   "upload_form.audio_description": "Περιγραφή για άτομα με προβλήματα ακοής",
-  "upload_form.description": "Περιέγραψε για όσους & όσες έχουν προβλήματα όρασης",
+  "upload_form.description": "Περιγραφή για όσους & όσες έχουν προβλήματα όρασης",
   "upload_form.description_missing": "Δεν προστέθηκε περιγραφή",
   "upload_form.edit": "Ενημέρωση",
   "upload_form.thumbnail": "Αλλαγή μικρογραφίας",
diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json
index 666ac0e4c..242569c4d 100644
--- a/app/javascript/mastodon/locales/en-GB.json
+++ b/app/javascript/mastodon/locales/en-GB.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Posts and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval. Click to cancel follow request",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Posts}}",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -255,7 +260,7 @@
   "follow_recommendations.done": "Done",
   "follow_recommendations.heading": "Follow people you'd like to see posts from! Here are some suggestions.",
   "follow_recommendations.lead": "Posts from people you follow will show up in chronological order on your home feed. Don't be afraid to make mistakes, you can unfollow people just as easily any time!",
-  "follow_request.authorize": "Authorize",
+  "follow_request.authorize": "Authorise",
   "follow_request.reject": "Reject",
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
   "footer.about": "About",
@@ -290,7 +295,7 @@
   "interaction_modal.on_another_server": "On a different server",
   "interaction_modal.on_this_server": "On this server",
   "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favourite Mastodon app or the web interface of your Mastodon server.",
-  "interaction_modal.preamble": "Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.",
+  "interaction_modal.preamble": "Since Mastodon is decentralised, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.",
   "interaction_modal.title.favourite": "Favourite {name}'s post",
   "interaction_modal.title.follow": "Follow {name}",
   "interaction_modal.title.reblog": "Boost {name}'s post",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index ce5fee3cb..8175c2bdf 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Posts and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval. Click to cancel follow request",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Posts}}",
@@ -131,7 +132,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Learn more",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any sensitive information over Mastodon.",
-  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is not public. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
   "compose_form.placeholder": "What's on your mind?",
@@ -239,7 +240,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -542,6 +547,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this post in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -558,7 +564,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
@@ -622,13 +628,13 @@
   "upload_button.label": "Add images, a video or an audio file",
   "upload_error.limit": "File upload limit exceeded.",
   "upload_error.poll": "File upload not allowed with polls.",
-  "upload_form.audio_description": "Describe for people with hearing loss",
-  "upload_form.description": "Describe for the visually impaired",
+  "upload_form.audio_description": "Describe for people who are deaf or hard of hearing",
+  "upload_form.description": "Describe for people who are blind or have low vision",
   "upload_form.description_missing": "No description added",
   "upload_form.edit": "Describe",
   "upload_form.thumbnail": "Change thumbnail",
   "upload_form.undo": "Delete",
-  "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
+  "upload_form.video_description": "Describe for people who are deaf, hard of hearing, blind or have low vision",
   "upload_modal.analyzing_picture": "Analyzing picture…",
   "upload_modal.apply": "Apply",
   "upload_modal.applying": "Applying…",
diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json
index 0c8857a69..de2f7e670 100644
--- a/app/javascript/mastodon/locales/eo.json
+++ b/app/javascript/mastodon/locales/eo.json
@@ -27,7 +27,7 @@
   "account.enable_notifications": "Sciigi min, kiam @{name} mesaĝas",
   "account.endorse": "Rekomendi ĉe via profilo",
   "account.featured_tags.last_status_at": "Lasta afîŝo je {date}",
-  "account.featured_tags.last_status_never": "Neniuj afiŝoj",
+  "account.featured_tags.last_status_never": "Neniu afiŝo",
   "account.featured_tags.title": "Rekomendataj kradvortoj de {name}",
   "account.follow": "Sekvi",
   "account.followers": "Sekvantoj",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Mesaĝoj kaj respondoj",
   "account.report": "Raporti @{name}",
   "account.requested": "Atendo de aprobo. Klaku por nuligi la peton por sekvado",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Diskonigi la profilon de @{name}",
   "account.show_reblogs": "Montri diskonigojn de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Afiŝo} other {{counter} Afiŝoj}}",
@@ -80,7 +81,7 @@
   "audio.hide": "Kaŝi aŭdion",
   "autosuggest_hashtag.per_week": "po {count} por semajno",
   "boost_modal.combo": "Vi povas premi {combo} por preterpasi sekvafoje",
-  "bundle_column_error.copy_stacktrace": "Kopii la raporto de error",
+  "bundle_column_error.copy_stacktrace": "Kopii la eraran raporton",
   "bundle_column_error.error.body": "La petita paĝo ne povas redonitis. Eble estas eraro.",
   "bundle_column_error.error.title": "Ho, ve!",
   "bundle_column_error.network.body": "Okazis eraro dum ŝarĝado de ĉi tiu paĝo. Tion povas kaŭzi portempa problemo pri via retkonektado aŭ pri ĉi tiu servilo.",
@@ -91,7 +92,7 @@
   "bundle_column_error.routing.title": "404",
   "bundle_modal_error.close": "Fermi",
   "bundle_modal_error.message": "Io misfunkciis en la ŝargado de ĉi tiu elemento.",
-  "bundle_modal_error.retry": "Provu refoje",
+  "bundle_modal_error.retry": "Bonvolu reprovi",
   "closed_registrations.other_server_instructions": "Ĉar Mastodon estas malcentraliza, vi povas krei konton ĉe alia servilo kaj ankoraŭ komuniki kun ĉi tiu.",
   "closed_registrations_modal.description": "Krei konton ĉe {domain} aktuale ne eblas, tamen bonvole rimarku, ke vi ne bezonas konton specife ĉe {domain} por uzi Mastodon.",
   "closed_registrations_modal.find_another_server": "Trovi alian servilon",
@@ -110,7 +111,7 @@
   "column.lists": "Listoj",
   "column.mutes": "Silentigitaj uzantoj",
   "column.notifications": "Sciigoj",
-  "column.pins": "Alpinglitaj mesaĝoj",
+  "column.pins": "Alpinglitaj afiŝoj",
   "column.public": "Fratara templinio",
   "column_back_button.label": "Reveni",
   "column_header.hide_settings": "Kaŝi la agordojn",
@@ -126,9 +127,9 @@
   "compose.language.change": "Ŝanĝi lingvon",
   "compose.language.search": "Serĉi lingvojn...",
   "compose_form.direct_message_warning_learn_more": "Lerni pli",
-  "compose_form.encryption_warning": "La mesaĵoj en Mastodon ne estas tutvoje ĉifritaj. Ne kundividu tiklajn informojn ĉe Mastodon.",
-  "compose_form.hashtag_warning": "Ĉi tiu mesaĝo ne estos listigita per ajna kradvorto. Nur publikaj mesaĝoj estas serĉeblaj per kradvortoj.",
-  "compose_form.lock_disclaimer": "Via konto ne estas {locked}. Iu ajn povas sekvi vin por vidi viajn mesaĝojn nur al la sekvantoj.",
+  "compose_form.encryption_warning": "La afiŝoj en Mastodon ne estas tutvoje ĉifritaj. Ne kunhavigu tiklajn informojn ĉe Mastodon.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
+  "compose_form.lock_disclaimer": "Via konto ne estas {locked}. Iu ajn povas sekvi vin por vidi viajn afiŝojn nur al la sekvantoj.",
   "compose_form.lock_disclaimer.lock": "ŝlosita",
   "compose_form.placeholder": "Kion vi pensas?",
   "compose_form.poll.add_option": "Aldoni elekteblon",
@@ -154,7 +155,7 @@
   "confirmations.cancel_follow_request.confirm": "Eksigi peton",
   "confirmations.cancel_follow_request.message": "Ĉu vi certas ke vi volas eksigi vian peton por sekvi {name}?",
   "confirmations.delete.confirm": "Forigi",
-  "confirmations.delete.message": "Ĉu vi certas, ke vi volas forigi ĉi tiun mesaĝon?",
+  "confirmations.delete.message": "Ĉu vi certas, ke vi volas forigi ĉi tiun afiŝon?",
   "confirmations.delete_list.confirm": "Forigi",
   "confirmations.delete_list.message": "Ĉu vi certas, ke vi volas porĉiame forigi ĉi tiun liston?",
   "confirmations.discard_edit_media.confirm": "Forĵeti",
@@ -167,7 +168,7 @@
   "confirmations.mute.explanation": "Tio kaŝos la mesaĝojn de la uzanto kaj la mesaĝojn kiuj mencias rin, sed ri ankoraŭ rajtos vidi viajn mesaĝojn kaj sekvi vin.",
   "confirmations.mute.message": "Ĉu vi certas, ke vi volas silentigi {name}?",
   "confirmations.redraft.confirm": "Forigi kaj reskribi",
-  "confirmations.redraft.message": "Ĉu vi certas ke vi volas forigi tiun mesaĝon kaj reskribi ĝin? Ĉiuj diskonigoj kaj stelumoj estos perditaj, kaj respondoj al la originala mesaĝo estos senparentaj.",
+  "confirmations.redraft.message": "Ĉu vi certas ke vi volas forigi tiun afiŝon kaj reskribi ĝin? Ĉiuj diskonigoj kaj stelumoj estos perditaj, kaj respondoj al la originala mesaĝo estos senparentaj.",
   "confirmations.reply.confirm": "Respondi",
   "confirmations.reply.message": "Respondi nun anstataŭigos la mesaĝon, kiun vi nun skribas. Ĉu vi certas, ke vi volas daŭrigi?",
   "confirmations.unfollow.confirm": "Ne plu sekvi",
@@ -186,7 +187,7 @@
   "disabled_account_banner.text": "Via konto {disabledAccount} estas nune malvalidigita.",
   "dismissable_banner.community_timeline": "Jen la plej novaj publikaj afiŝoj de uzantoj, kies kontojn gastigas {domain}.",
   "dismissable_banner.dismiss": "Eksigi",
-  "dismissable_banner.explore_links": "Tiuj novaĵoj estas aktuale priparolataj de uzantoj el ĉi tiu servilo, kaj el aliaj, sur la malcentralizita reto.",
+  "dismissable_banner.explore_links": "Tiuj novaĵoj estas aktuale priparolataj de uzantoj en tiu ĉi kaj aliaj serviloj, sur la malcentrigita reto.",
   "dismissable_banner.explore_statuses": "Ĉi tiuj mesaĝoj de ĉi tiu kaj aliaj serviloj en la malcentra reto pli populariĝas en ĉi tiu servilo nun.",
   "dismissable_banner.explore_tags": "Ĉi tiuj kradvostoj populariĝas en ĉi tiu kaj aliaj serviloj en la malcentraliza reto nun.",
   "dismissable_banner.public_timeline": "Ĉi tiuj estas plej lastaj publika mesaĝoj de personoj ĉe ĉi tiu kaj aliaj serviloj de la malcentra reto kiun ĉi tiu servilo scias.",
@@ -216,7 +217,7 @@
   "empty_column.direct": "Vi ankoraŭ ne havas rektan mesaĝon. Kiam vi sendos aŭ ricevos iun, ĝi aperos ĉi tie.",
   "empty_column.domain_blocks": "Ankoraŭ neniu domajno estas blokita.",
   "empty_column.explore_statuses": "Nenio tendencas nun. Rekontrolu poste!",
-  "empty_column.favourited_statuses": "Vi ankoraŭ ne stelumis mesaĝon. Kiam vi stelumos iun, ĝi aperos ĉi tie.",
+  "empty_column.favourited_statuses": "Vi ankoraŭ ne stelumis afiŝon. Kiam vi stelumos iun, ĝi aperos ĉi tie.",
   "empty_column.favourites": "Ankoraŭ neniu stelumis tiun mesaĝon. Kiam iu faros tion, tiu aperos ĉi tie.",
   "empty_column.follow_recommendations": "Ŝajnas, ke neniuj sugestoj povis esti generitaj por vi. Vi povas provi uzi serĉon por serĉi homojn, kiujn vi eble konas, aŭ esplori tendencajn kradvortojn.",
   "empty_column.follow_requests": "Vi ne ankoraŭ havas iun peton de sekvado. Kiam vi ricevos unu, ĝi aperos ĉi tie.",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopii stakspuron en tondujo",
   "errors.unexpected_crash.report_issue": "Raporti problemon",
   "explore.search_results": "Serĉaj rezultoj",
+  "explore.suggested_follows": "For you",
   "explore.title": "Esplori",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Afiŝoj",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Ĉi tiu filtrilkategorio ne kongruas la kuntekston de ĉi tiu mesaĝo. Vi devas redakti la filtrilon.",
   "filter_modal.added.context_mismatch_title": "Ne kongruas la kunteksto!",
   "filter_modal.added.expired_explanation": "Ĉi tiu filtrilkategorio eksvalidiĝis, vu bezonos ŝanĝi la eksvaliddaton por ĝi.",
@@ -387,7 +392,7 @@
   "not_signed_in_indicator.not_signed_in": "Necesas saluti por aliri tiun rimedon.",
   "notification.admin.report": "{name} raportis {target}",
   "notification.admin.sign_up": "{name} kreis konton",
-  "notification.favourite": "{name} stelumis vian mesaĝon",
+  "notification.favourite": "{name} stelumis vian afiŝon",
   "notification.follow": "{name} eksekvis vin",
   "notification.follow_request": "{name} petis sekvi vin",
   "notification.mention": "{name} menciis vin",
@@ -505,7 +510,7 @@
   "report.thanks.title": "Ĉu vi ne volas vidi ĉi tion?",
   "report.thanks.title_actionable": "Dankon pro raporti, ni esploros ĉi tion.",
   "report.unfollow": "Malsekvi @{name}",
-  "report.unfollow_explanation": "Vi sekvas ĉi tiun konton. Por ne plu vidi ĝiajn abonfluojn en via hejma templinio, ĉesu sekvi ĝin.",
+  "report.unfollow_explanation": "Vi sekvas ĉi tiun konton. Por ne plu vidi ĝiajn afiŝojn en via hejma templinio, ĉesu sekvi ĝin.",
   "report_notification.attached_statuses": "{count, plural, one {{count} afiŝo almetita} other {{count} afiŝoj almetitaj}}",
   "report_notification.categories.other": "Alia",
   "report_notification.categories.spam": "Trudmesaĝo",
@@ -516,7 +521,7 @@
   "search_popout.search_format": "Detala serĉo",
   "search_popout.tips.full_text": "Simplaj tekstoj montras la mesaĝojn, kiujn vi skribis, stelumis, diskonigis, aŭ en kiuj vi estis menciita, sed ankaŭ kongruajn uzantnomojn, montratajn nomojn, kaj kradvortojn.",
   "search_popout.tips.hashtag": "kradvorto",
-  "search_popout.tips.status": "mesaĝoj",
+  "search_popout.tips.status": "afiŝoj",
   "search_popout.tips.text": "Simpla teksto montras la kongruajn afiŝitajn nomojn, uzantnomojn kaj kradvortojn",
   "search_popout.tips.user": "uzanto",
   "search_results.accounts": "Homoj",
@@ -524,7 +529,7 @@
   "search_results.hashtags": "Kradvortoj",
   "search_results.nothing_found": "Povis trovi nenion por ĉi tiuj serĉaj terminoj",
   "search_results.statuses": "Mesaĝoj",
-  "search_results.statuses_fts_disabled": "Serĉi mesaĝojn laŭ enhavo ne estas ebligita en ĉi tiu Mastodon-servilo.",
+  "search_results.statuses_fts_disabled": "Serĉi afiŝojn laŭ enhavo ne estas ebligita en ĉi tiu Mastodon-servilo.",
   "search_results.title": "Serĉ-rezultoj por {q}",
   "search_results.total": "{count, number} {count, plural, one {rezulto} other {rezultoj}}",
   "server_banner.about_active_users": "Personoj uzantaj ĉi tiun servilon dum la lastaj 30 tagoj (Aktivaj Uzantoj Monate)",
@@ -535,8 +540,9 @@
   "server_banner.server_stats": "Statistikoj de la servilo:",
   "sign_in_banner.create_account": "Krei konton",
   "sign_in_banner.sign_in": "Saluti",
-  "sign_in_banner.text": "Ensalutu por sekvi profilojn aŭ kradvortojn, stelumi, kunhavigi kaj respondi afiŝojn aŭ interagi per via konto de alia servilo.",
+  "sign_in_banner.text": "Ensalutu por sekvi profilojn aŭ kradvortojn, stelumi, diskonigi afiŝojn kaj respondi al ili, aŭ interagi per via konto de alia servilo.",
   "status.admin_account": "Malfermi fasadon de moderigado por @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Malfermi ĉi tiun mesaĝon en la kontrola interfaco",
   "status.block": "Bloki @{name}",
   "status.bookmark": "Aldoni al la legosignoj",
@@ -618,7 +624,7 @@
   "upload_error.limit": "Limo de dosiera alŝutado transpasita.",
   "upload_error.poll": "Alŝuto de dosiero ne permesita kun balotenketo.",
   "upload_form.audio_description": "Priskribi por homoj kiuj malfacile aŭdi",
-  "upload_form.description": "Priskribi por misvidantaj homoj",
+  "upload_form.description": "Priskribi por personoj, kiuj estas blindaj aŭ havas vidmalsufiĉon",
   "upload_form.description_missing": "Neniu priskribo aldonita",
   "upload_form.edit": "Redakti",
   "upload_form.thumbnail": "Ŝanĝi etigita bildo",
diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json
index 4540ab5d0..cd6e91e67 100644
--- a/app/javascript/mastodon/locales/es-AR.json
+++ b/app/javascript/mastodon/locales/es-AR.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Mnsjs y resp. públicas",
   "account.report": "Denunciar a @{name}",
   "account.requested": "Esperando aprobación. Hacé clic para cancelar la solicitud de seguimiento",
+  "account.requested_follow": "{name} solicitó seguirte",
   "account.share": "Compartir el perfil de @{name}",
   "account.show_reblogs": "Mostrar adhesiones de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Mensaje} other {{counter} Mensajes}}",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copiar stacktrace al portapapeles",
   "errors.unexpected_crash.report_issue": "Informar problema",
   "explore.search_results": "Resultados de búsqueda",
+  "explore.suggested_follows": "Para vos",
   "explore.title": "Explorá",
+  "explore.trending_links": "Novedades",
+  "explore.trending_statuses": "Mensajes",
+  "explore.trending_tags": "Etiquetas",
   "filter_modal.added.context_mismatch_explanation": "Esta categoría de filtro no se aplica al contexto en el que accediste a este mensaje. Si querés que el mensaje sea filtrado también en este contexto, vas a tener que editar el filtro.",
   "filter_modal.added.context_mismatch_title": "¡El contexto no coincide!",
   "filter_modal.added.expired_explanation": "Esta categoría de filtro caducó; vas a necesitar cambiar la fecha de caducidad para que se aplique.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Iniciar sesión",
   "sign_in_banner.text": "Iniciá sesión para seguir cuentas o etiquetas, marcar mensajes como favoritos, compartirlos y responderlos o interactuar desde tu cuenta en un servidor diferente.",
   "status.admin_account": "Abrir interface de moderación para @{name}",
+  "status.admin_domain": "Abrir interface de moderación para {domain}",
   "status.admin_status": "Abrir este mensaje en la interface de moderación",
   "status.block": "Bloquear a @{name}",
   "status.bookmark": "Marcar",
diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json
index c5ec5d098..00c815554 100644
--- a/app/javascript/mastodon/locales/es-MX.json
+++ b/app/javascript/mastodon/locales/es-MX.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Publicaciones y respuestas",
   "account.report": "Denunciar a @{name}",
   "account.requested": "Esperando aprobación. Haga clic para cancelar la solicitud de seguimiento",
+  "account.requested_follow": "{name} ha solicitado seguirte",
   "account.share": "Compartir el perfil de @{name}",
   "account.show_reblogs": "Mostrar retoots de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Buscar idiomas...",
   "compose_form.direct_message_warning_learn_more": "Aprender mas",
   "compose_form.encryption_warning": "Las publicaciones en Mastodon no están cifradas de extremo a extremo. No comparta ninguna información sensible en Mastodon.",
-  "compose_form.hashtag_warning": "Esta publicación no se mostrará bajo ningún hashtag porque no está listada. Sólo las publicaciones públicas se pueden buscar por hashtag.",
+  "compose_form.hashtag_warning": "Este toot no será listado bajo ningún hashtag dado que no es público. Solo toots públicos pueden ser buscados por hashtag.",
   "compose_form.lock_disclaimer": "Tu cuenta no está bloqueada. Todos pueden seguirte para ver tus toots solo para seguidores.",
   "compose_form.lock_disclaimer.lock": "bloqueado",
   "compose_form.placeholder": "¿En qué estás pensando?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copiar el seguimiento de pila en el portapapeles",
   "errors.unexpected_crash.report_issue": "Informar problema",
   "explore.search_results": "Resultados de búsqueda",
+  "explore.suggested_follows": "Para ti",
   "explore.title": "Descubrir",
+  "explore.trending_links": "Noticias",
+  "explore.trending_statuses": "Publicaciones",
+  "explore.trending_tags": "Etiquetas",
   "filter_modal.added.context_mismatch_explanation": "Esta categoría de filtro no se aplica al contexto en el que has accedido a esta publlicación. Si quieres que la publicación sea filtrada también en este contexto, tendrás que editar el filtro.",
   "filter_modal.added.context_mismatch_title": "¡El contexto no coincide!",
   "filter_modal.added.expired_explanation": "Esta categoría de filtro ha caducado, necesitaras cambiar la fecha de caducidad para que se aplique.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Iniciar sesión",
   "sign_in_banner.text": "Inicia sesión para seguir perfiles o etiquetas, marcar favorito, compartir y responder a publicaciones, o interactua desde tu cuenta en un servidor diferente.",
   "status.admin_account": "Abrir interfaz de moderación para @{name}",
+  "status.admin_domain": "Abrir interfaz de moderación para {domain}",
   "status.admin_status": "Abrir este estado en la interfaz de moderación",
   "status.block": "Bloquear a @{name}",
   "status.bookmark": "Añadir marcador",
diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json
index 53dd4c387..0c1b3c690 100644
--- a/app/javascript/mastodon/locales/es.json
+++ b/app/javascript/mastodon/locales/es.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Publicaciones y respuestas",
   "account.report": "Reportar a @{name}",
   "account.requested": "Esperando aprobación. Clica para cancelar la solicitud de seguimiento",
+  "account.requested_follow": "{name} ha solicitado seguirte",
   "account.share": "Compartir el perfil de @{name}",
   "account.show_reblogs": "Mostrar impulsos de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Publicación} other {{counter} Publicaciones}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Buscar idiomas...",
   "compose_form.direct_message_warning_learn_more": "Aprender más",
   "compose_form.encryption_warning": "Las publicaciones en Mastodon no están cifradas de extremo a extremo. No comparta ninguna información sensible en Mastodon.",
-  "compose_form.hashtag_warning": "Esta publicación no se mostrará bajo ningún hashtag porque no está listada. Sólo las publicaciones públicas se pueden buscar por hashtag.",
+  "compose_form.hashtag_warning": "Esta publicación no se mostrará bajo ningún hashtag no está pública. Solo las publicaciones públicas se pueden buscar por hashtag.",
   "compose_form.lock_disclaimer": "Tu cuenta no está {locked}. Todos pueden seguirte para ver tus publicaciones solo para seguidores.",
   "compose_form.lock_disclaimer.lock": "bloqueado",
   "compose_form.placeholder": "¿En qué estás pensando?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copiar el seguimiento de pila en el portapapeles",
   "errors.unexpected_crash.report_issue": "Informar de un problema/error",
   "explore.search_results": "Resultados de búsqueda",
+  "explore.suggested_follows": "Para ti",
   "explore.title": "Explorar",
+  "explore.trending_links": "Noticias",
+  "explore.trending_statuses": "Publicaciones",
+  "explore.trending_tags": "Etiquetas",
   "filter_modal.added.context_mismatch_explanation": "Esta categoría de filtro no se aplica al contexto en el que ha accedido a esta publlicación. Si quieres que la publicación sea filtrada también en este contexto, tendrás que editar el filtro.",
   "filter_modal.added.context_mismatch_title": "¡El contexto no coincide!",
   "filter_modal.added.expired_explanation": "Esta categoría de filtro ha caducado, necesitará cambiar la fecha de caducidad para que se aplique.",
@@ -272,7 +277,7 @@
   "hashtag.column_header.tag_mode.none": "sin {additional}",
   "hashtag.column_settings.select.no_options_message": "No se encontraron sugerencias",
   "hashtag.column_settings.select.placeholder": "Introduzca hashtags…",
-  "hashtag.column_settings.tag_mode.all": "Cualquiera de estos",
+  "hashtag.column_settings.tag_mode.all": "Todos estos",
   "hashtag.column_settings.tag_mode.any": "Cualquiera de estos",
   "hashtag.column_settings.tag_mode.none": "Ninguno de estos",
   "hashtag.column_settings.tag_toggle": "Incluir etiquetas adicionales en esta columna",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Iniciar sesión",
   "sign_in_banner.text": "Inicia sesión en este servidor para seguir perfiles o etiquetas, guardar, compartir y responder a mensajes. También puedes interactuar desde otra cuenta en un servidor diferente.",
   "status.admin_account": "Abrir interfaz de moderación para @{name}",
+  "status.admin_domain": "Abrir interfaz de moderación para {domain}",
   "status.admin_status": "Abrir este estado en la interfaz de moderación",
   "status.block": "Bloquear a @{name}",
   "status.bookmark": "Añadir marcador",
diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json
index 19064ec04..5b36f41e4 100644
--- a/app/javascript/mastodon/locales/et.json
+++ b/app/javascript/mastodon/locales/et.json
@@ -3,11 +3,11 @@
   "about.contact": "Kontakt:",
   "about.disclaimer": "Mastodon on tasuta ja vaba tarkvara ning Mastodon gGmbH kaubamärk.",
   "about.domain_blocks.no_reason_available": "Mittesaadavuse põhjus",
-  "about.domain_blocks.preamble": "Mastodon tavaliselt lubab Teil vaadata sisu ning suhelda kasutajatega üks kõik millisest teisest serverist fediversumis. Need on erandid, mis on paika pandud sellel kindlal serveril.",
+  "about.domain_blocks.preamble": "Mastodon lubab tavaliselt vaadata sisu ning suhelda kasutajatega ükskõik millisest teisest fediversumi serverist. Need on erandid, mis on paika pandud sellel kindlal serveril.",
   "about.domain_blocks.silenced.explanation": "Sa ei näe üldiselt profiile ja sisu sellelt serverilt, kui sa just tahtlikult seda ei otsi või jälgimise moel nõusolekut ei anna.",
   "about.domain_blocks.silenced.title": "Piiratud",
-  "about.domain_blocks.suspended.explanation": "Mitte mingeid andmeid sellelt serveritl ei töödelda, salvestata ega vahetata, tehes igasuguse interaktsiooni või kirjavahetuse kasutajatega sellelt serverilt võimatuks.",
-  "about.domain_blocks.suspended.title": "Kustutatud",
+  "about.domain_blocks.suspended.explanation": "Mitte mingeid andmeid sellelt serverilt ei töödelda, salvestata ega vahetata, tehes igasuguse interaktsiooni või kirjavahetuse selle serveri kasutajatega võimatuks.",
+  "about.domain_blocks.suspended.title": "Peatatud",
   "about.not_available": "See info ei ole sellel serveril saadavaks tehtud.",
   "about.powered_by": "Hajutatud sotsiaalmeedia, mille taga on {mastodon}",
   "about.rules": "Serveri reeglid",
@@ -19,12 +19,12 @@
   "account.block_domain": "Peida kõik domeenist {domain}",
   "account.blocked": "Blokeeritud",
   "account.browse_more_on_origin_server": "Vaata rohkem algsel profiilil",
-  "account.cancel_follow_request": "Võta tagasi jälgimistaotlus",
-  "account.direct": "Saada otsesõnum @{name}'ile",
-  "account.disable_notifications": "Ära teavita, kui @{name} postitab",
+  "account.cancel_follow_request": "Võta jälgimistaotlus tagasi",
+  "account.direct": "Otsesõnum kasutajale @{name}",
+  "account.disable_notifications": "Peata teavitused @{name} postitustest",
   "account.domain_blocked": "Domeen peidetud",
   "account.edit_profile": "Muuda profiili",
-  "account.enable_notifications": "Teavita mind, kui @{name} postitab",
+  "account.enable_notifications": "Teavita mind @{name} postitustest",
   "account.endorse": "Too profiilil esile",
   "account.featured_tags.last_status_at": "Viimane postitus {date}",
   "account.featured_tags.last_status_never": "Postitusi pole",
@@ -36,13 +36,13 @@
   "account.following": "Jälgib",
   "account.following_counter": "{count, plural, one {{counter} jälgitav} other {{counter} jälgitavat}}",
   "account.follows.empty": "See kasutaja ei jälgi veel kedagi.",
-  "account.follows_you": "Jälgib",
+  "account.follows_you": "Jälgib sind",
   "account.go_to_profile": "Mine profiilile",
   "account.hide_reblogs": "Peida @{name} jagamised",
   "account.joined_short": "Liitus",
   "account.languages": "Muuda tellitud keeli",
   "account.link_verified_on": "Selle lingi autorsust kontrolliti {date}",
-  "account.locked_info": "Selle konto privaatsussätteks on lukustatud. Omanik vaatab manuaalselt üle, kes teda jägida saab.",
+  "account.locked_info": "Selle konto privaatsussätteks on lukustatud. Omanik vaatab käsitsi üle, kes teda jälgida saab.",
   "account.media": "Meedia",
   "account.mention": "Maini @{name}",
   "account.moved_to": "{name} on teada andnud, et ta uus konto on nüüd:",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Postitused ja vastused",
   "account.report": "Raporteeri @{name}",
   "account.requested": "Ootab kinnitust. Klõpsa jälgimise soovi tühistamiseks",
+  "account.requested_follow": "{name} on taodelnud sinu jälgimist",
   "account.share": "Jaga @{name} profiili",
   "account.show_reblogs": "Näita @{name} jagamisi",
   "account.statuses_counter": "{count, plural, one {{counter} postitus} other {{counter} postitust}}",
@@ -64,7 +65,7 @@
   "account.unfollow": "Jälgid",
   "account.unmute": "Ära vaigista @{name}",
   "account.unmute_notifications": "Ära vaigista teateid kasutajalt @{name}",
-  "account.unmute_short": "Lõpeta vaigistus",
+  "account.unmute_short": "Lõpeta vaigistamine",
   "account_note.placeholder": "Klõpsa märkme lisamiseks",
   "admin.dashboard.daily_retention": "Kasutajate päevane allesjäämine peale registreerumist",
   "admin.dashboard.monthly_retention": "Kasutajate kuine allesjäämine peale registreerumist",
@@ -72,7 +73,7 @@
   "admin.dashboard.retention.cohort": "Registreerumiskuu",
   "admin.dashboard.retention.cohort_size": "Uued kasutajad",
   "alert.rate_limited.message": "Palun proovi uuesti pärast {retry_time, time, medium}.",
-  "alert.rate_limited.title": "Piiratud",
+  "alert.rate_limited.title": "Kiiruspiirang",
   "alert.unexpected.message": "Tekkis ootamatu viga.",
   "alert.unexpected.title": "Oih!",
   "announcement.announcement": "Teadaanne",
@@ -81,21 +82,21 @@
   "autosuggest_hashtag.per_week": "{count} nädalas",
   "boost_modal.combo": "Vajutades {combo}, saab selle edaspidi vahele jätta",
   "bundle_column_error.copy_stacktrace": "Kopeeri veateade",
-  "bundle_column_error.error.body": "Soovitud lehte ei suudetud esitleda. See võib olla mingi koodivea tagajärg või probleem brauseri ühilduvusega.",
+  "bundle_column_error.error.body": "Soovitud lehte ei õnnestunud esitada. See võib olla meie koodiviga või probleem brauseri ühilduvusega.",
   "bundle_column_error.error.title": "Oh, ei!",
-  "bundle_column_error.network.body": "Selle lehe laadimisel tekkis tõrge. See võib olla ajutine probleem internetiühendusega või selle serveriga.",
+  "bundle_column_error.network.body": "Lehe laadimisel tekkis tõrge. See võib olla ajutine probleem internetiühendusega või selle serveriga.",
   "bundle_column_error.network.title": "Võrguühenduse viga",
   "bundle_column_error.retry": "Proovi uuesti",
   "bundle_column_error.return": "Tagasi koju",
-  "bundle_column_error.routing.body": "Päritud lehte ei leitud. Kas URL aadressiribal on õige?",
+  "bundle_column_error.routing.body": "Päritud lehte ei leitud. Kas URL on aadressiribal õige?",
   "bundle_column_error.routing.title": "404",
   "bundle_modal_error.close": "Sulge",
   "bundle_modal_error.message": "Selle komponendi laadimisel läks midagi viltu.",
   "bundle_modal_error.retry": "Proovi uuesti",
   "closed_registrations.other_server_instructions": "Kuna Mastodon on detsentraliseeritud, võib konto teha teise serverisse ja sellegipoolest siinse kontoga suhelda.",
-  "closed_registrations_modal.description": "Praegu ei ole võimalik teha {domain} peale kontot, aga pidage meeles, et teil ei pea olema just {domain} konto, et Mastodoni kasutada.",
+  "closed_registrations_modal.description": "Praegu ei ole võimalik teha {domain} peale kontot, aga pea meeles, et sul ei pea olema just {domain} konto, et Mastodoni kasutada.",
   "closed_registrations_modal.find_another_server": "Leia teine server",
-  "closed_registrations_modal.preamble": "Mastodon on detsentraliseeritud, mis tähendab seda, et ükskõik kuhu konto luua, võib jälgida ja suhelda igaühega sellel serveril. Võib isegi oma serveri püsti panna!",
+  "closed_registrations_modal.preamble": "Mastodon on detsentraliseeritud, mis tähendab, et konto võib luua ükskõik kuhu, kuid ikkagi saab jälgida ja suhelda igaühega sellel serveril. Võib isegi oma serveri püsti panna!",
   "closed_registrations_modal.title": "Mastodoni registreerumine",
   "column.about": "Teave",
   "column.blocks": "Blokeeritud kasutajad",
@@ -107,7 +108,7 @@
   "column.favourites": "Lemmikud",
   "column.follow_requests": "Jälgimistaotlused",
   "column.home": "Kodu",
-  "column.lists": "Nimistud",
+  "column.lists": "Nimekirjad",
   "column.mutes": "Vaigistatud kasutajad",
   "column.notifications": "Teated",
   "column.pins": "Kinnitatud postitused",
@@ -126,52 +127,52 @@
   "compose.language.change": "Muuda keelt",
   "compose.language.search": "Otsi keeli...",
   "compose_form.direct_message_warning_learn_more": "Vaata täpsemalt",
-  "compose_form.encryption_warning": "Postitused Mastodonis ei ole otsast-otsani krüpteeritud. Ärge jagage mingeid delikaatseid andmeid Mastodoni kaudu.",
-  "compose_form.hashtag_warning": "Seda postitust ei kuvata ühegi sildi all, sest see ei ole leitav avastustoimingute kaudu. Ainult avalikud postitused on sildi järgi otsitavad.",
-  "compose_form.lock_disclaimer": "Teie konto ei ole {locked}. Igaüks saab teid jälgida ja näha teie ainult-jälgijatele postitusi.",
+  "compose_form.encryption_warning": "Postitused Mastodonis ei ole otsast-otsani krüpteeritud. Ära jaga mingeid delikaatseid andmeid Mastodoni kaudu.",
+  "compose_form.hashtag_warning": "See postitus ei ilmu ühegi märksõna all, kuna pole avalik. Vaid avalikud postitused on märksõnade kaudu leitavad.",
+  "compose_form.lock_disclaimer": "Su konto ei ole {locked}. Igaüks saab sind jälgida, et näha su ainult-jälgijatele postitusi.",
   "compose_form.lock_disclaimer.lock": "lukus",
   "compose_form.placeholder": "Millest mõtled?",
   "compose_form.poll.add_option": "Lisa valik",
   "compose_form.poll.duration": "Küsitluse kestus",
   "compose_form.poll.option_placeholder": "Valik {number}",
   "compose_form.poll.remove_option": "Eemalda see valik",
-  "compose_form.poll.switch_to_multiple": "Muuda küsitlust lubamaks mitut valikut",
-  "compose_form.poll.switch_to_single": "Muuda küsitlust lubamaks ainult ühte valikut",
+  "compose_form.poll.switch_to_multiple": "Muuda küsitlust mitmikvaliku lubamiseks",
+  "compose_form.poll.switch_to_single": "Muuda küsitlust ainult ühe valiku lubamiseks",
   "compose_form.publish": "Postita",
   "compose_form.publish_form": "Postita",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.save_changes": "Salvesta muudatused",
-  "compose_form.sensitive.hide": "Märgista meedia tundlikuks",
-  "compose_form.sensitive.marked": "Meedia on sensitiivseks märgitud",
-  "compose_form.sensitive.unmarked": "Meedia ei ole sensitiivseks märgitud",
-  "compose_form.spoiler.marked": "Tekst on hoiatuse taha peidetud",
+  "compose_form.sensitive.hide": "{count, plural, one {Märgi meedia tundlikuks} other {Märgi meediad tundlikuks}}",
+  "compose_form.sensitive.marked": "{count, plural, one {Meedia on märgitud tundlikuks} other {Meediad on märgitud tundlikuks}}",
+  "compose_form.sensitive.unmarked": "{count, plural, one {Meedia ei ole tundlikuks märgitud} other {Meediad ei ole märgitud tundlikuks}}",
+  "compose_form.spoiler.marked": "Tekst on peidetud hoiatuse taha",
   "compose_form.spoiler.unmarked": "Märgi sisu tundlikuks",
-  "compose_form.spoiler_placeholder": "Kirjutage oma hoiatus siia",
+  "compose_form.spoiler_placeholder": "Kirjuta hoiatus siia",
   "confirmation_modal.cancel": "Katkesta",
   "confirmations.block.block_and_report": "Blokeeri ja teata",
   "confirmations.block.confirm": "Blokeeri",
-  "confirmations.block.message": "Kindel, et blokeerida {name}?",
+  "confirmations.block.message": "Oled kindel, et soovid blokeerida {name}?",
   "confirmations.cancel_follow_request.confirm": "Tühista taotlus",
-  "confirmations.cancel_follow_request.message": "Olete kindel, et tahate võtta tagasi taotluse jälgida kasutajat {name}?",
+  "confirmations.cancel_follow_request.message": "Oled kindel, et soovid kasutaja {name} jälgimistaotluse tagasi võtta?",
   "confirmations.delete.confirm": "Kustuta",
-  "confirmations.delete.message": "Olete kindel, et soovite selle staatuse kustutada?",
+  "confirmations.delete.message": "Oled kindel, et soovid postituse kustutada?",
   "confirmations.delete_list.confirm": "Kustuta",
-  "confirmations.delete_list.message": "Olete kindel, et soovite selle nimekirja pöördumatult kustutada?",
+  "confirmations.delete_list.message": "Oled kindel, et soovid selle loetelu pöördumatult kustutada?",
   "confirmations.discard_edit_media.confirm": "Hülga",
-  "confirmations.discard_edit_media.message": "Teil on salvestamata muudatused meediakirjelduses või eelvaates, kas hülgame need?",
+  "confirmations.discard_edit_media.message": "Sul on salvestamata muudatusi meediakirjelduses või eelvaates, kas hülgad need?",
   "confirmations.domain_block.confirm": "Peida terve domeen",
-  "confirmations.domain_block.message": "Olete ikka päris kindel, et soovite blokeerida terve {domain}? Enamikul juhtudel piisab mõnest sihitud blokist või vaigistusest, mis on eelistatav. Te ei näe selle domeeni sisu üheski avalikus ajajoones või teadetes. Teie jälgijad sellest domeenist eemaldatakse.",
+  "confirmations.domain_block.message": "Oled ikka päris-päris kindel, et soovid blokeerida terve {domain}? Enamikel juhtudel piisab mõnest sihitud blokist või vaigistusest, mis on eelistatavam. Sa ei näe selle domeeni sisu ühelgi avalikul ajajoonel või enda teadetes. Su jälgijad sellest domeenist eemaldatakse.",
   "confirmations.logout.confirm": "Välju",
-  "confirmations.logout.message": "Kas olete kindel, et soovite välja logida?",
+  "confirmations.logout.message": "Kas oled kindel, et soovid välja logida?",
   "confirmations.mute.confirm": "Vaigista",
-  "confirmations.mute.explanation": "See peidab postitusi temalt ning postitusi, kus mainitakse neid, kuid see lubab neil ikka näha teie postitusi ning teid jälgida.",
-  "confirmations.mute.message": "Olete kindel, et soovite {name} vaigistada?",
+  "confirmations.mute.explanation": "See peidab tema postitused ning postitused, milles teda mainitakse, kuid lubab tal ikkagi sinu postitusi näha ning sind jälgida.",
+  "confirmations.mute.message": "Oled kindel, et soovid {name} vaigistada?",
   "confirmations.redraft.confirm": "Kustuta & taasalusta",
   "confirmations.redraft.message": "Kas kustutada postitus ja võtta uue aluseks? Meeldimised ja jagamised lähevad kaotsi ning vastused jäävad ilma algse postituseta.",
   "confirmations.reply.confirm": "Vasta",
-  "confirmations.reply.message": "Praegu vastamine kirjutab üle sõnumi, mida hetkel koostate. Olete kindel, et soovite jätkata?",
+  "confirmations.reply.message": "Praegu vastamine kirjutab hetkel koostatava sõnumi üle. Oled kindel, et soovid jätkata?",
   "confirmations.unfollow.confirm": "Ära jälgi",
-  "confirmations.unfollow.message": "Olete kindel, et ei soovi rohkem jälgida kasutajat {name}?",
+  "confirmations.unfollow.message": "Oled kindel, et ei soovi rohkem jälgida kasutajat {name}?",
   "conversation.delete": "Kustuta vestlus",
   "conversation.mark_as_read": "Märgi loetuks",
   "conversation.open": "Vaata vestlust",
@@ -183,14 +184,14 @@
   "directory.new_arrivals": "Uustulijad",
   "directory.recently_active": "Hiljuti aktiivne",
   "disabled_account_banner.account_settings": "Kontosätted",
-  "disabled_account_banner.text": "Teie konto {disabledAccount} ei ole praegu kasutusvõimeline.",
+  "disabled_account_banner.text": "Su konto {disabledAccount} on hetkel keelatud.",
   "dismissable_banner.community_timeline": "Need on kõige viimased avalikud postitused inimestelt, kelle kontosid majutab {domain}.",
   "dismissable_banner.dismiss": "Sulge",
   "dismissable_banner.explore_links": "Need on uudised, millest inimesed siin ja teistes serverites üle detsentraliseeritud võrgu praegu räägivad.",
   "dismissable_banner.explore_statuses": "Need postitused siit ja teistes serveritest detsentraliseeritud võrgus koguvad tähelepanu just praegu selles serveris.",
   "dismissable_banner.explore_tags": "Need sildid siit ja teistes serveritest detsentraliseeritud võrgus koguvad tähelepanu just praegu selles serveris.",
   "dismissable_banner.public_timeline": "Need on kõige uuemad avalikud postitused inimestelt selles ja teistes serverites üle detsentraliseeritud võrgu, millest see server on teadlik.",
-  "embed.instructions": "Manusta see staatus oma veebilehele, kopeerides alloleva koodi.",
+  "embed.instructions": "Lisa see postitus oma veebilehele, kopeerides alloleva koodi.",
   "embed.preview": "Nii näeb see välja:",
   "emoji_button.activity": "Tegevus",
   "emoji_button.clear": "Tühjenda",
@@ -211,38 +212,42 @@
   "empty_column.account_timeline": "Siin postitusi ei ole!",
   "empty_column.account_unavailable": "Profiil pole saadaval",
   "empty_column.blocks": "Blokeeritud kasutajaid pole.",
-  "empty_column.bookmarked_statuses": "Teil pole veel järjehoidjatesse lisatud postitusi. Kui lisate mõne, näete neid siin.",
-  "empty_column.community": "Kohalik ajajoon on tühi. Kirjutage midagi avalikult, et pall veerema ajada!",
-  "empty_column.direct": "Teil ei ole veel otsesõnumeid. Kui saadate või võtate mõne vastu, ilmuvad nad siia.",
+  "empty_column.bookmarked_statuses": "Järjehoidjatesse pole veel lisatud postitusi. Kui lisad mõne, näed neid siin.",
+  "empty_column.community": "Kohalik ajajoon on tühi. Kirjuta midagi avalikult, et pall veerema ajada!",
+  "empty_column.direct": "Ei ole veel otsesõnumeid. Kui saadad või võtad mõne vastu, ilmuvad nad siia.",
   "empty_column.domain_blocks": "Siin ei ole veel peidetud domeene.",
   "empty_column.explore_statuses": "Praegu pole ühtegi trendi. Tule hiljem tagasi!",
-  "empty_column.favourited_statuses": "Teil pole veel lemmikpostitusi. Kui märgite mõne, näete neid siin.",
+  "empty_column.favourited_statuses": "Pole veel lemmikpostitusi. Kui märgid mõne, näed neid siin.",
   "empty_column.favourites": "Keegi pole veel seda postitust lemmikuks märkinud. Kui seegi seda teeb, näed seda siin.",
-  "empty_column.follow_recommendations": "Tundub, et teie jaoks ei ole võimalik soovitusi tekitada. Proovige kasutada otsingut, et leida inimesi, keda te teate või sirvida trendivaid silte.",
-  "empty_column.follow_requests": "Teil pole hetkel ühtegi jälgimistaotlust. Kui saate mõne, näete neid siin.",
+  "empty_column.follow_recommendations": "Tundub, et sinu jaoks ei ole võimalik soovitusi luua. Proovi kasutada otsingut, et leida tuttavaid inimesi, või sirvi populaarseid silte.",
+  "empty_column.follow_requests": "Pole hetkel ühtegi jälgimistaotlust. Kui saad mõne, näed neid siin.",
   "empty_column.hashtag": "Seda sildi all ei ole ühtegi postitust.",
-  "empty_column.home": "Teie kodu ajajoon on tühi! Külastage {public} või kasutage otsingut alustamaks ja kohtamaks teisi kasutajaid.",
+  "empty_column.home": "Su koduajajoon on tühi. Jälgi rohkemaid inimesi, et seda täita {suggestions}",
   "empty_column.home.suggestions": "Vaata mõndasid soovitusi",
-  "empty_column.list": "Siin nimistus pole veel midagi. Kui nimistu liikmed teevad uusi postitusi, näed neid siin.",
-  "empty_column.lists": "Teil pole veel ühtegi nimekirja. Kui loote mõne, näete neid siin.",
-  "empty_column.mutes": "Te pole veel ühtegi kasutajat vaigistanud.",
-  "empty_column.notifications": "Teil ei ole veel teateid. Suhelge teistega alustamaks vestlust.",
-  "empty_column.public": "Siin pole midagi! Kirjuta midagi avalikut või jälgi ise kasutajaid täitmaks seda ruumi",
-  "error.unexpected_crash.explanation": "Meie poolse probleemi või veebilehitseja ühilduvus probleemi tõttu ei suutnud me teile seda lehekülge korrektselt näidata.",
-  "error.unexpected_crash.explanation_addons": "Seda lehte ei suudetud õigesti kuvada. See viga arvatavasti põhjustas mingi brauseri lisand või automaattõlke tööriist.",
-  "error.unexpected_crash.next_steps": "Proovige lehekülge uuesti avada. Kui see ei aita, võite proovida kasutada Mastodoni mõne muu veebilehitseja või äppi kaudu.",
-  "error.unexpected_crash.next_steps_addons": "Proovige need välja lülitada ja leht uuesti laadida. Kui sellest pole abi, võib olla võimalik Mastodoni kasutada mingi teise brauseri või rakendusega.",
+  "empty_column.list": "Siin loetelus pole veel midagi. Kui loetelu liikmed teevad uusi postitusi, näed neid siin.",
+  "empty_column.lists": "Pole veel ühtegi nimekirja. Kui lood mõne, näed neid siin.",
+  "empty_column.mutes": "Sa pole veel ühtegi kasutajat vaigistanud.",
+  "empty_column.notifications": "Ei ole veel teateid. Kui keegi suhtleb sinuga, näed seda siin.",
+  "empty_column.public": "Siin pole midagi! Kirjuta midagi avalikku või jälgi ise kasutajaid täitmaks seda ruumi",
+  "error.unexpected_crash.explanation": "Meie poolse probleemi või veebilehitseja ühilduvusprobleemi tõttu ei suutnud me seda lehekülge korrektselt näidata.",
+  "error.unexpected_crash.explanation_addons": "Seda lehte ei suudetud õigesti kuvada. Selle vea põhjustas arvatavasti mõni lehitseja lisand või automaattõlke tööriist.",
+  "error.unexpected_crash.next_steps": "Proovi lehekülge uuesti avada. Kui see ei aita, võib proovida kasutada Mastodoni mõne muu veebilehitseja või äpi kaudu.",
+  "error.unexpected_crash.next_steps_addons": "Proovi need välja lülitada ja leht uuesti laadida. Kui sellest pole abi, võib siiski võimalik olla Mastodoni kasutada mõne teise lehitseja või rakendusega.",
   "errors.unexpected_crash.copy_stacktrace": "Kopeeri stacktrace lõikelauale",
   "errors.unexpected_crash.report_issue": "Teavita veast",
   "explore.search_results": "Otsitulemused",
+  "explore.suggested_follows": "Kasutajad",
   "explore.title": "Avasta",
-  "filter_modal.added.context_mismatch_explanation": "See filtrikategooria ei rakendu selles kontekstis, kuidas te postitusele jõudsite. Kui tahate postitust ka selles kontekstis filtreerida, võite muuta filtrit.",
+  "explore.trending_links": "Uudised",
+  "explore.trending_statuses": "Postitused",
+  "explore.trending_tags": "Sildid",
+  "filter_modal.added.context_mismatch_explanation": "See filtrikategooria ei rakendu kontekstis, kuidas postituseni jõudsid. Kui tahad postitust ka selles kontekstis filtreerida, pead muutma filtrit.",
   "filter_modal.added.context_mismatch_title": "Konteksti mittesobivus!",
-  "filter_modal.added.expired_explanation": "Selle filtri kategooria on aegunud, peate muutma aegumiskuupäeva, kui tahate, et filter kehtiks.",
+  "filter_modal.added.expired_explanation": "Selle filtri kategooria on aegunud. pead muutma aegumiskuupäeva, kui tahad, et filter kehtiks.",
   "filter_modal.added.expired_title": "Aegunud filter!",
-  "filter_modal.added.review_and_configure": "Et vaadata üle ja täpsemalt seadistada seda filtrikategooriat, minge lehele {settings_link}.",
+  "filter_modal.added.review_and_configure": "Et vaadata üle ja täpsemalt seadistada seda filtrikategooriat, mine lehele {settings_link}.",
   "filter_modal.added.review_and_configure_title": "Filtrite sätted",
-  "filter_modal.added.settings_link": "sättete leht",
+  "filter_modal.added.settings_link": "sätete leht",
   "filter_modal.added.short_explanation": "See postitus on lisatud järgmisesse filtrikategooriasse: {title}.",
   "filter_modal.added.title": "Filter lisatud!",
   "filter_modal.select_filter.context_mismatch": "ei avaldu selles kontekstis",
@@ -253,16 +258,16 @@
   "filter_modal.select_filter.title": "Filtreeri seda postitust",
   "filter_modal.title.status": "Postituse filtreerimine",
   "follow_recommendations.done": "Valmis",
-  "follow_recommendations.heading": "Jälgi inimesi, kelle postituse tahaksite näha! Mõned soovitused on siin.",
-  "follow_recommendations.lead": "Postitused inimestelt, keda te jälgite ilmuvad ajalises järjekorras teie kodu ajajoonel. Ärge kartke eksida, alati saate inimeste jälgimist ka lõpetada!",
+  "follow_recommendations.heading": "Jälgi inimesi, kelle postitusi tahaksid näha! Mõned soovitused on siin.",
+  "follow_recommendations.lead": "Postitused inimestelt, keda jälgid, ilmuvad ajalises järjestuses kodu ajajoonel. Ära karda eksida, alati saab inimeste jälgimist ka lõpetada!",
   "follow_request.authorize": "Autoriseeri",
   "follow_request.reject": "Hülga",
-  "follow_requests.unlocked_explanation": "Kuigi teie konto pole lukustatud, soovitab {domain} personal siiski manuaalselt üle vaadata jälgimistaotlused nendelt kontodelt.",
+  "follow_requests.unlocked_explanation": "Kuigi su konto pole lukustatud, soovitab {domain} personal siiski nende kontode jälgimistaotlused käsitsi üle vaadata.",
   "footer.about": "Teave",
   "footer.directory": "Profiilikataloog",
   "footer.get_app": "Tõmba äpp",
-  "footer.invite": "Liituma kutsumine",
-  "footer.keyboard_shortcuts": "Klaviatuuri otseteed",
+  "footer.invite": "Kutsu liituma",
+  "footer.keyboard_shortcuts": "Kiirklahvid",
   "footer.privacy_policy": "Isikuandmete kaitse",
   "footer.source_code": "Lähtekood",
   "generic.saved": "Salvestatud",
@@ -283,55 +288,55 @@
   "home.column_settings.show_replies": "Näita vastuseid",
   "home.hide_announcements": "Peida teadaanded",
   "home.show_announcements": "Kuva teadaandeid",
-  "interaction_modal.description.favourite": "Mastodoni kontoga saate seda postitust lemmikuks märkida, et autor teaks, et te seda hindate ja hiljemaks alles jätta.",
-  "interaction_modal.description.follow": "Mastodoni kontoga saate jälgida kasutajat {name}, et tema postitusi oma kodu ajajoonel näha.",
-  "interaction_modal.description.reblog": "Mastodoni kontoga saate jagada seda postitust oma jälgijatele.",
-  "interaction_modal.description.reply": "Mastodoni kontoga saate sellele postitusele vastata.",
+  "interaction_modal.description.favourite": "Mastodoni kontoga saad selle postituse lemmikuks märkida, et autor teaks, et sa hindad seda, ja hiljemaks alles jätta.",
+  "interaction_modal.description.follow": "Mastodoni kontoga saad jälgida kasutajat {name}, et tema postitusi oma kodu ajajoonel näha.",
+  "interaction_modal.description.reblog": "Mastodoni kontoga saad seda postitust levitada, jagades seda oma jälgijatele.",
+  "interaction_modal.description.reply": "Mastodoni kontoga saad sellele postitusele vastata.",
   "interaction_modal.on_another_server": "Teises serveris",
   "interaction_modal.on_this_server": "Selles serveris",
-  "interaction_modal.other_server_instructions": "Kopeeri ja aseta see URL oma lemmikusse Mastodoni äppi või oma Mastodoni serveri veebiliidesesse.",
-  "interaction_modal.preamble": "Kuna Mastodon on detsentraliseeritud, võite kasutada olemasolevat kontot, mis on teises Mastodoni servers või ühilduval platvormil, kui teil siin kontot ei ole.",
+  "interaction_modal.other_server_instructions": "Kopeeri ja kleebi see URL oma Mastodoni lemmikäppi või Mastodoni serveri veebiliidesesse.",
+  "interaction_modal.preamble": "Kuna Mastodon on detsentraliseeritud, saab kasutada teises Mastodoni serveris olevat kontot või ka ühilduval platvormil, kui siin serveril kontot ei ole.",
   "interaction_modal.title.favourite": "Lisa konto {name} postitus lemmikuks",
   "interaction_modal.title.follow": "Jälgi kontot {name}",
   "interaction_modal.title.reblog": "Jaga {name} postitust",
   "interaction_modal.title.reply": "Vasta kasutaja {name} postitusele",
-  "intervals.full.days": "{number, plural, one {# päev} other {# päevad}}",
+  "intervals.full.days": "{number, plural, one {# päev} other {# päeva}}",
   "intervals.full.hours": "{number, plural, one {# tund} other {# tundi}}",
   "intervals.full.minutes": "{number, plural, one {# minut} other {# minutit}}",
-  "keyboard_shortcuts.back": "tagasiminekuks",
+  "keyboard_shortcuts.back": "Liigu tagasi",
   "keyboard_shortcuts.blocked": "avamaks blokeeritud kasutajate nimistut",
   "keyboard_shortcuts.boost": "Jaga",
-  "keyboard_shortcuts.column": "fokuseerimaks staatust ühele tulpadest",
-  "keyboard_shortcuts.compose": "fokuseerimaks tekstikoostamise alale",
+  "keyboard_shortcuts.column": "Fookus veerule",
+  "keyboard_shortcuts.compose": "Fookus teksti koostamise alale",
   "keyboard_shortcuts.description": "Kirjeldus",
-  "keyboard_shortcuts.direct": "avamaks otsesõnumite tulpa",
-  "keyboard_shortcuts.down": "liikumaks nimstus alla",
+  "keyboard_shortcuts.direct": "ava otsesõnumite veerg",
+  "keyboard_shortcuts.down": "Liigu loetelus alla",
   "keyboard_shortcuts.enter": "Ava postitus",
-  "keyboard_shortcuts.favourite": "lemmikuks märkimiseks",
-  "keyboard_shortcuts.favourites": "avamaks lemmikute nimistut",
-  "keyboard_shortcuts.federated": "avamaks föderatsiooni ajajoont",
-  "keyboard_shortcuts.heading": "Klaviatuuri kiirkäsud",
-  "keyboard_shortcuts.home": "avamaks kodu ajajoont",
+  "keyboard_shortcuts.favourite": "Märgi lemmikuks",
+  "keyboard_shortcuts.favourites": "Ava lemmikute loetelu",
+  "keyboard_shortcuts.federated": "Ava föderatsiooni ajajoon",
+  "keyboard_shortcuts.heading": "Kiirklahvid",
+  "keyboard_shortcuts.home": "Ava kodu ajajoon",
   "keyboard_shortcuts.hotkey": "Kiirklahv",
-  "keyboard_shortcuts.legend": "selle legendi kuvamiseks",
-  "keyboard_shortcuts.local": "avamaks kohalikku ajajoont",
-  "keyboard_shortcuts.mention": "autori mainimiseks",
-  "keyboard_shortcuts.muted": "avamaks vaigistatud kasutajate nimistut",
-  "keyboard_shortcuts.my_profile": "avamaks profiili",
-  "keyboard_shortcuts.notifications": "avamaks teadete tulpa",
-  "keyboard_shortcuts.open_media": "et avada meedia",
-  "keyboard_shortcuts.pinned": "Ava kinnitatud postituste nimekiri",
-  "keyboard_shortcuts.profile": "avamaks autori profiili",
-  "keyboard_shortcuts.reply": "vastamiseks",
-  "keyboard_shortcuts.requests": "avamaks jälgimistaotluste nimistut",
-  "keyboard_shortcuts.search": "otsingu fokuseerimiseks",
-  "keyboard_shortcuts.spoilers": "to show/hide CW field",
-  "keyboard_shortcuts.start": "avamaks \"Alusta\" tulpa",
-  "keyboard_shortcuts.toggle_hidden": "näitamaks/peitmaks teksti CW taga",
-  "keyboard_shortcuts.toggle_sensitivity": "et peita/näidata meediat",
+  "keyboard_shortcuts.legend": "Kuva see legend",
+  "keyboard_shortcuts.local": "Ava kohalik ajajoon",
+  "keyboard_shortcuts.mention": "Maini autorit",
+  "keyboard_shortcuts.muted": "Ava vaigistatud kasutajate loetelu",
+  "keyboard_shortcuts.my_profile": "Ava oma profiil",
+  "keyboard_shortcuts.notifications": "Ava teadete veerg",
+  "keyboard_shortcuts.open_media": "Ava meedia",
+  "keyboard_shortcuts.pinned": "Ava kinnitatud postituste loetelu",
+  "keyboard_shortcuts.profile": "Ava autori profiil",
+  "keyboard_shortcuts.reply": "Vasta postitusele",
+  "keyboard_shortcuts.requests": "Ava jälgimistaotluste loetelu",
+  "keyboard_shortcuts.search": "Fookus otsingule",
+  "keyboard_shortcuts.spoilers": "Näita/peida CW väli",
+  "keyboard_shortcuts.start": "Ava veerg \"Alusta\"",
+  "keyboard_shortcuts.toggle_hidden": "Näida/peida teksti CW taga",
+  "keyboard_shortcuts.toggle_sensitivity": "Näita/peida meediat",
   "keyboard_shortcuts.toot": "Alusta uut postitust",
-  "keyboard_shortcuts.unfocus": "tekstiala/otsingu koostamise mittefokuseerimiseks",
-  "keyboard_shortcuts.up": "liikumaks nimistus üles",
+  "keyboard_shortcuts.unfocus": "Fookus tekstialalt/otsingult ära",
+  "keyboard_shortcuts.up": "Liigu loetelus üles",
   "lightbox.close": "Sulge",
   "lightbox.compress": "Suru kokku pildi vaatamise kast",
   "lightbox.expand": "Laienda pildi vaatamise kast",
@@ -339,25 +344,25 @@
   "lightbox.previous": "Eelmine",
   "limited_account_hint.action": "Näita profilli sellegipoolest",
   "limited_account_hint.title": "See profiil on peidetud {domain} moderaatorite poolt.",
-  "lists.account.add": "Lisa nimistusse",
-  "lists.account.remove": "Eemalda nimistust",
-  "lists.delete": "Kustuta nimistu",
-  "lists.edit": "Muuda nimistut",
+  "lists.account.add": "Lisa nimekirja",
+  "lists.account.remove": "Eemalda nimekirjast",
+  "lists.delete": "Kustuta nimekiri",
+  "lists.edit": "Muuda nimekirja",
   "lists.edit.submit": "Pealkirja muutmine",
-  "lists.new.create": "Lisa nimistu",
-  "lists.new.title_placeholder": "Uue nimistu pealkiri",
+  "lists.new.create": "Lisa nimekiri",
+  "lists.new.title_placeholder": "Uue nimekirja pealkiri",
   "lists.replies_policy.followed": "Igalt jälgitud kasutajalt",
   "lists.replies_policy.list": "Listi liikmetelt",
-  "lists.replies_policy.none": "Mitte kellegilt",
+  "lists.replies_policy.none": "Mitte kelleltki",
   "lists.replies_policy.title": "Näita vastuseid nendele:",
-  "lists.search": "Otsige teie poolt jälgitavate inimese hulgast",
-  "lists.subheading": "Teie nimistud",
+  "lists.search": "Otsi enda jälgitavate inimeste hulgast",
+  "lists.subheading": "Sinu nimekirjad",
   "load_pending": "{count, plural, one {# uus kirje} other {# uut kirjet}}",
   "loading_indicator.label": "Laeb..",
   "media_gallery.toggle_visible": "{number, plural, one {Varja pilt} other {Varja pildid}}",
   "missing_indicator.label": "Ei leitud",
   "missing_indicator.sublabel": "Seda ressurssi ei leitud",
-  "moved_to_account_banner.text": "Teie kontot {disabledAccount} ei ole praegu võimalik kasutada, sest te kolisite kontole {movedToAccount}.",
+  "moved_to_account_banner.text": "Kontot {disabledAccount} ei ole praegu võimalik kasutada, sest kolisid kontole {movedToAccount}.",
   "mute_modal.duration": "Kestus",
   "mute_modal.hide_notifications": "Kas peita teated sellelt kasutajalt?",
   "mute_modal.indefinite": "Lõpmatu",
@@ -375,7 +380,7 @@
   "navigation_bar.filters": "Vaigistatud sõnad",
   "navigation_bar.follow_requests": "Jälgimistaotlused",
   "navigation_bar.follows_and_followers": "Jälgitavad ja jälgijad",
-  "navigation_bar.lists": "Nimistud",
+  "navigation_bar.lists": "Nimekirjad",
   "navigation_bar.logout": "Logi välja",
   "navigation_bar.mutes": "Vaigistatud kasutajad",
   "navigation_bar.personal": "Isiklik",
@@ -384,20 +389,20 @@
   "navigation_bar.public_timeline": "Föderatiivne ajajoon",
   "navigation_bar.search": "Otsing",
   "navigation_bar.security": "Turvalisus",
-  "not_signed_in_indicator.not_signed_in": "Peate logima sisse, et saada ligipääsu sellele ressursile.",
+  "not_signed_in_indicator.not_signed_in": "Pead sisse logima, et saada ligipääsu sellele ressursile.",
   "notification.admin.report": "{name} saatis teavituse {target} kohta",
   "notification.admin.sign_up": "{name} registreerus",
-  "notification.favourite": "{name} märkis teie staatuse lemmikuks",
-  "notification.follow": "{name} jälgib nüüd teid",
+  "notification.favourite": "{name} märkis su postituse lemmikuks",
+  "notification.follow": "{name} alustas su jälgimist",
   "notification.follow_request": "{name} soovib teid jälgida",
   "notification.mention": "{name} mainis teid",
-  "notification.own_poll": "Teie küsitlus on lõppenud",
-  "notification.poll": "Küsitlus, milles osalesite, on lõppenud",
-  "notification.reblog": "{name} jagas postitust",
+  "notification.own_poll": "Su küsitlus on lõppenud",
+  "notification.poll": "Küsitlus, milles osalesid, on lõppenud",
+  "notification.reblog": "{name} jagas edasi postitust",
   "notification.status": "{name} just postitas",
   "notification.update": "{name} muutis postitust",
   "notifications.clear": "Puhasta teated",
-  "notifications.clear_confirmation": "Olete kindel, et soovite püsivalt kõik oma teated eemaldada?",
+  "notifications.clear_confirmation": "Oled kindel, et soovid püsivalt kõik oma teated eemaldada?",
   "notifications.column_settings.admin.report": "Uued teavitused:",
   "notifications.column_settings.admin.sign_up": "Uued kasutajad:",
   "notifications.column_settings.alert": "Töölauateated",
@@ -423,23 +428,23 @@
   "notifications.filter.follows": "Jälgib",
   "notifications.filter.mentions": "Mainimised",
   "notifications.filter.polls": "Küsitluse tulemused",
-  "notifications.filter.statuses": "Uuendused inimestelt, keda te jälgite",
+  "notifications.filter.statuses": "Uuendused inimestelt, keda jälgid",
   "notifications.grant_permission": "Anna luba.",
   "notifications.group": "{count} teated",
   "notifications.mark_as_read": "Märgi kõik teated loetuks",
-  "notifications.permission_denied": "Töölaua märguanded pole seadaval, kuna eelnevalt keelduti brauserile teavituste luba anda",
+  "notifications.permission_denied": "Töölauamärguanded pole saadaval, kuna eelnevalt keelduti lehitsejale teavituste luba andmast",
   "notifications.permission_denied_alert": "Töölaua märguandeid ei saa lubada, kuna brauseri luba on varem keeldutud",
   "notifications.permission_required": "Töölaua märguanded ei ole saadaval, kuna vajalik luba pole antud.",
   "notifications_permission_banner.enable": "Luba töölaua märguanded",
-  "notifications_permission_banner.how_to_control": "Et saada teateid, kui Mastodon pole avatud, lubage töölaua märguanded. Saate määrata täpselt, mis tüüpi läbikäimised tekitavad töölauale märguandeid kasutates {icon} nuppu üleval, kui need on sisse lülitatud.",
-  "notifications_permission_banner.title": "Ärge jääge millestki ilma",
+  "notifications_permission_banner.how_to_control": "Et saada teateid, ajal mil Mastodon pole avatud, luba töölauamärguanded. Saad täpselt määrata, mis tüüpi tegevused tekitavad märguandeid, kasutates peale teadaannete sisse lülitamist üleval olevat nuppu {icon}.",
+  "notifications_permission_banner.title": "Ära jää millestki ilma",
   "picture_in_picture.restore": "Pane tagasi",
   "poll.closed": "Suletud",
   "poll.refresh": "Värskenda",
   "poll.total_people": "{count, plural,one {# inimene} other {# inimest}}",
   "poll.total_votes": "{count, plural, one {# hääl} other {# häält}}",
   "poll.vote": "Hääleta",
-  "poll.voted": "Teie hääletasite selle poolt",
+  "poll.voted": "Hääletasid selle poolt",
   "poll.votes": "{votes, plural, one {# hääl} other {# häält}}",
   "poll_button.add_poll": "Lisa küsitlus",
   "poll_button.remove_poll": "Eemalda küsitlus",
@@ -456,7 +461,7 @@
   "privacy_policy.title": "Isikuandmete kaitse",
   "refresh": "Värskenda",
   "regeneration_indicator.label": "Laeb…",
-  "regeneration_indicator.sublabel": "Teie kodu voog on ettevalmistamisel!",
+  "regeneration_indicator.sublabel": "Su koduvoog on ettevalmistamisel!",
   "relative_time.days": "{number}p",
   "relative_time.full.days": "{number, plural, one {# päev} other {# päeva}} tagasi",
   "relative_time.full.hours": "{number, plural, one {# tund} other {# tundi}} tagasi",
@@ -470,53 +475,53 @@
   "relative_time.today": "täna",
   "reply_indicator.cancel": "Tühista",
   "report.block": "Blokeeri",
-  "report.block_explanation": "Te ei näe tema postitusi. Tema ei saa näha teie postitusi ega teid jälgida. Talle on näha, et ta on blokeeritud.",
+  "report.block_explanation": "Sa ei näe tema postitusi. Tema ei saa näha sinu postitusi ega sind jälgida. Talle on näha, et ta on blokeeritud.",
   "report.categories.other": "Muud",
   "report.categories.spam": "Rämpspost",
   "report.categories.violation": "Sisu, mis rikub ühte või enamat serveri reeglit",
-  "report.category.subtitle": "Valige parim vaste",
-  "report.category.title": "Öelge, mis on sellel {type} valesti",
-  "report.category.title_account": "profiilil",
-  "report.category.title_status": "postitusel",
+  "report.category.subtitle": "Vali parim vaste",
+  "report.category.title": "Selgita, mis on selle {type} valesti",
+  "report.category.title_account": "kontoga",
+  "report.category.title_status": "postitusega",
   "report.close": "Valmis",
-  "report.comment.title": "Kas on midagi veel, mis te arvate, et me peaks teadma?",
+  "report.comment.title": "Kas arvad, et on veel midagi, mida me peaks teadma?",
   "report.forward": "Edasta kasutajale {target}",
   "report.forward_hint": "See kasutaja on teisest serverist. Kas saadan anonümiseeritud koopia sellest teatest sinna ka?",
   "report.mute": "Vaigista",
-  "report.mute_explanation": "Te ei näe tema postitusi. Ta võib ikka teil jälgida ja näha teie postitusi ja ta ei saa teada, et ta on vaigistatud.",
+  "report.mute_explanation": "Sa ei näe tema postitusi. Ta võib ikka sind jälgida ja su postitusi näha. Ta ei saa teada, et ta on vaigistatud.",
   "report.next": "Järgmine",
   "report.placeholder": "Lisaks kommentaarid",
   "report.reasons.dislike": "Mulle ei meeldi see",
-  "report.reasons.dislike_description": "Midagi sellist, mida te ei taha näha",
+  "report.reasons.dislike_description": "See on midagi sellist, mida sa näha ei taha",
   "report.reasons.other": "Midagi muud",
   "report.reasons.other_description": "Probleem ei sobi teistesse kategooriatesse",
   "report.reasons.spam": "See on rämpspost",
   "report.reasons.spam_description": "Pahatahtlikud lingid, võltssuhtlus või korduvad vastused",
   "report.reasons.violation": "Rikub serveri reegleid",
-  "report.reasons.violation_description": "Teate, et see rikub teatud reegleid",
-  "report.rules.subtitle": "Valige kõik, mis sobivad",
+  "report.reasons.violation_description": "Tead, et see rikub teatud reegleid",
+  "report.rules.subtitle": "Vali kõik, mis sobivad",
   "report.rules.title": "Milliseid reegleid rikutakse?",
-  "report.statuses.subtitle": "Valige kõik, mis sobivad",
+  "report.statuses.subtitle": "Vali kõik, mis sobivad",
   "report.statuses.title": "Kas on olemas postitusi, mis on sellele teavitusele tõenduseks?",
   "report.submit": "Esita",
   "report.target": "Teatamine {target} kohta",
-  "report.thanks.take_action": "Need on võimalused, mis teil on, et juhtida, mida Mastodonis näete:",
-  "report.thanks.take_action_actionable": "Kuniks me seda üle vaatame, võite teha need tegevused @{name} vastu:",
+  "report.thanks.take_action": "Need on su võimalused määrata, mida Mastodonis näed:",
+  "report.thanks.take_action_actionable": "Kuniks me seda üle vaatame, võid @{name} vastu teha need tegevused:",
   "report.thanks.title": "Ei taha seda näha?",
   "report.thanks.title_actionable": "Täname teavitamise eest, uurime seda.",
   "report.unfollow": "Lõpeta @{name} jälgimine",
-  "report.unfollow_explanation": "Te jälgite seda kontot. Et mitte näha tema postitusi oma kodu ajajoonel, lõpetage tema jälgimine.",
+  "report.unfollow_explanation": "Jälgid seda kontot. Et mitte näha tema postitusi oma kodu ajajoonel, lõpeta ta jälgimine.",
   "report_notification.attached_statuses": "{count, plural, one {{count} postitus} other {{count} postitust}} listatud",
   "report_notification.categories.other": "Muu",
   "report_notification.categories.spam": "Rämpspost",
   "report_notification.categories.violation": "Reeglite rikkumine",
   "report_notification.open": "Ava teavitus",
   "search.placeholder": "Otsi",
-  "search.search_or_paste": "Otsi või aseta URL",
+  "search.search_or_paste": "Otsi või kleebi URL",
   "search_popout.search_format": "Täiustatud otsiformaat",
-  "search_popout.tips.full_text": "Lihttekst annab vastuseks postitused, mida olete kirjutanud, lisanud lemmikuks, jaganud või kus mainitud, ning lisaks kattuvad kasutajanimed, kuvanimed ja sildid.",
+  "search_popout.tips.full_text": "Lihttekst annab vastuseks postitused, mille oled kirjutanud, lisanud lemmikuks, jaganud või kus on sind mainitud, ning lisaks kokkusobivad kasutajanimed, profiili kuvanimed ja sildid.",
   "search_popout.tips.hashtag": "silt",
-  "search_popout.tips.status": "staatus",
+  "search_popout.tips.status": "postitus",
   "search_popout.tips.text": "Lihtne tekst toob esile kattuvad kuvanimed, kasutajanimed ning sildid",
   "search_popout.tips.user": "kasutaja",
   "search_results.accounts": "Inimesed",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Logi sisse",
   "sign_in_banner.text": "Logi sisse, et jälgida profiile või silte, märkida lemmikuks, jagada ja vastata postitustele või kasutada suhtlemiseks kontot teises serveris.",
   "status.admin_account": "Ava @{name} moderaatorivaates",
+  "status.admin_domain": "Ava {domain} modeereerimisliides",
   "status.admin_status": "Ava postitus moderaatorivaates",
   "status.block": "Blokeeri @{name}",
   "status.bookmark": "Järjehoidja",
@@ -562,7 +568,7 @@
   "status.more": "Veel",
   "status.mute": "Vaigista @{name}",
   "status.mute_conversation": "Vaigista vestlus",
-  "status.open": "Laienda see postitus",
+  "status.open": "Laienda postitus",
   "status.pin": "Kinnita profiilile",
   "status.pinned": "Kinnitatud postitus",
   "status.read_more": "Loe veel",
@@ -579,19 +585,19 @@
   "status.sensitive_warning": "Tundlik sisu",
   "status.share": "Jaga",
   "status.show_filter_reason": "Näita ikka",
-  "status.show_less": "Näita vähem",
-  "status.show_less_all": "Näita vähem kõigile",
-  "status.show_more": "Näita veel",
-  "status.show_more_all": "Näita enam kõigile",
+  "status.show_less": "Peida sisu",
+  "status.show_less_all": "Peida kogu tundlik sisu",
+  "status.show_more": "Näita sisu",
+  "status.show_more_all": "Näita kogu tundlikku sisu",
   "status.show_original": "Näita algset",
   "status.translate": "Tõlgi",
   "status.translated_from_with": "Tõlgitud {lang} keelest kasutades teenust {provider}",
   "status.uncached_media_warning": "Pole saadaval",
   "status.unmute_conversation": "Ära vaigista vestlust",
   "status.unpin": "Eemalda profiilile kinnitus",
-  "subscribed_languages.lead": "Pärast muudatust näidatakse kodu ja nimistute ajajoontel postitusi valitud keeltes. Jäta tühjaks, kui tahad näha postitusi keelest sõltumata.",
+  "subscribed_languages.lead": "Pärast muudatust näed koduvaates ja loetelude ajajoontel postitusi valitud keeltes. Ära vali midagi, kui tahad näha postitusi kõikides keeltes.",
   "subscribed_languages.save": "Salvesta muudatused",
-  "subscribed_languages.target": "Muutke tellitud keeli {target} jaoks",
+  "subscribed_languages.target": "Muuda tellitud keeli {target} jaoks",
   "suggestions.dismiss": "Eira soovitust",
   "suggestions.header": "Teid võib huvitada…",
   "tabs_bar.federated_timeline": "Föderatiivne",
@@ -609,7 +615,7 @@
   "timeline_hint.resources.statuses": "Eelnevaid postitusi",
   "trends.counter_by_accounts": "{count, plural, one {{counter} inimene} other {{counter} inimest}} viimase {days, plural, one {päeva} other {{days} päeva}} jooksul",
   "trends.trending_now": "Hetkel populaarne",
-  "ui.beforeunload": "Teie mustand läheb kaotsi, kui lahkute Mastodonist.",
+  "ui.beforeunload": "Mustand läheb kaotsi, kui lahkud Mastodonist.",
   "units.short.billion": "{count} mld",
   "units.short.million": "{count} mln",
   "units.short.thousand": "{count} tuh",
diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json
index fd17288b3..9f771a811 100644
--- a/app/javascript/mastodon/locales/eu.json
+++ b/app/javascript/mastodon/locales/eu.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Bidalketak eta erantzunak",
   "account.report": "Salatu @{name}",
   "account.requested": "Onarpenaren zain. Klikatu jarraitzeko eskaera ezeztatzeko",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "@{name}(e)ren profila elkarbanatu",
   "account.show_reblogs": "Erakutsi @{name}(r)en bultzadak",
   "account.statuses_counter": "{count, plural, one {Bidalketa {counter}} other {{counter} bidalketa}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Bilatu hizkuntzak...",
   "compose_form.direct_message_warning_learn_more": "Ikasi gehiago",
   "compose_form.encryption_warning": "Mastodoneko bidalketak ez daude muturretik muturrera enkriptatuta. Ez partekatu informazio sentikorrik Mastodonen.",
-  "compose_form.hashtag_warning": "Bidalketa hau ez da traoletan agertuko zerrendatu gabekoa baita. Traoletan bidalketa publikoak besterik ez dira agertzen.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Zure kontua ez dago {locked}. Edonork jarraitu zaitzake zure jarraitzaileentzako soilik diren bidalketak ikusteko.",
   "compose_form.lock_disclaimer.lock": "giltzapetuta",
   "compose_form.placeholder": "Zer duzu buruan?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopiatu irteera arbelera",
   "errors.unexpected_crash.report_issue": "Eman arazoaren berri",
   "explore.search_results": "Bilaketaren emaitzak",
+  "explore.suggested_follows": "Zuretzako",
   "explore.title": "Arakatu",
+  "explore.trending_links": "Berriak",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Iragazki-kategoria hau ez zaio aplikatzen bidalketa honetara sartzeko erabili duzun testuinguruari. Bidalketa testuinguru horretan ere iragaztea nahi baduzu, iragazkia editatu beharko duzu.",
   "filter_modal.added.context_mismatch_title": "Testuingurua ez dator bat!",
   "filter_modal.added.expired_explanation": "Iragazki kategoria hau iraungi da, eragina izan dezan bere iraungitze-data aldatu beharko duzu.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Hasi saioa",
   "sign_in_banner.text": "Hasi saioa beste zerbitzari bateko zure kontuarekin profilak edo traolak jarraitu, bidalketei erantzun, gogoko egin edo partekatzeko.",
   "status.admin_account": "Ireki @{name} erabiltzailearen moderazio interfazea",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Ireki bidalketa hau moderazio interfazean",
   "status.block": "Blokeatu @{name}",
   "status.bookmark": "Laster-marka",
@@ -553,7 +559,7 @@
   "status.favourite": "Gogokoa",
   "status.filter": "Iragazi bidalketa hau",
   "status.filtered": "Iragazita",
-  "status.hide": "Ezkutatu bidalketa hau",
+  "status.hide": "Hide post",
   "status.history.created": "{name} erabiltzaileak sortua {date}",
   "status.history.edited": "{name} erabiltzaileak editatua {date}",
   "status.load_more": "Kargatu gehiago",
diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json
index 13382d67a..a58d9824a 100644
--- a/app/javascript/mastodon/locales/fa.json
+++ b/app/javascript/mastodon/locales/fa.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "فرسته‌ها و پاسخ‌ها",
   "account.report": "گزارش ‎@{name}",
   "account.requested": "منتظر پذیرش است. برای لغو درخواست پی‌گیری کلیک کنید",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "هم‌رسانی نمایهٔ ‎@{name}",
   "account.show_reblogs": "نمایش تقویت‌های ‎@{name}",
   "account.statuses_counter": "{count, plural, one {{counter} فرسته} other {{counter} فرسته}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "جست‌وجوی زبان‌ها…",
   "compose_form.direct_message_warning_learn_more": "بیشتر بدانید",
   "compose_form.encryption_warning": "فرسته‌های ماستودون رمزگذاری سرتاسری نشده‌اند. هیچ اطّلاعات حساسی را روی ماستودون هم‌رسانی نکنید.",
-  "compose_form.hashtag_warning": "از آن‌جا که این فرسته فهرست نشده است، در نتایج جست‌وجوی هشتگ‌ها پیدا نخواهد شد. تنها فرسته‌های عمومی را می‌توان با جست‌وجوی هشتگ یافت.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "حسابتان {locked} نیست. هر کسی می‌تواند پی‌گیرتان شده و فرسته‌های ویژهٔ پی‌گیرانتان را ببیند.",
   "compose_form.lock_disclaimer.lock": "قفل‌شده",
   "compose_form.placeholder": "تازه چه خبر؟",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "رونوشت از جزئیات اشکال",
   "errors.unexpected_crash.report_issue": "گزارش مشکل",
   "explore.search_results": "نتایج جست‌وجو",
+  "explore.suggested_follows": "برای شما",
   "explore.title": "کاوش",
+  "explore.trending_links": "اخبار",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "هشتگ‌ها",
   "filter_modal.added.context_mismatch_explanation": "این دستهٔ پالایه به بافتاری که در آن به این فرسته دسترسی دارید اعمال نمی‌شود. اگر می‌خواهید فرسته در این بافتار هم پالوده شود، باید پالایه را ویرایش کنید.",
   "filter_modal.added.context_mismatch_title": "بافتار نامطابق!",
   "filter_modal.added.expired_explanation": "این دستهٔ پالایه منقضی شده است. برای اعمالش باید تاریخ انقضا را عوض کنید.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "ورود",
   "sign_in_banner.text": "برای پی‌گیری نمایه‌ها یا برچسب‌ها، هم‌رسانی و پاسخ به فرسته‌ها یا تعامل از حسابتان روی کارسازی دیگر، وارد شوید.",
   "status.admin_account": "گشودن واسط مدیریت برای ‎@{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "گشودن این فرسته در واسط مدیریت",
   "status.block": "مسدود کردن ‎@{name}",
   "status.bookmark": "نشانک",
@@ -553,7 +559,7 @@
   "status.favourite": "پسندیدن",
   "status.filter": "پالایش این فرسته",
   "status.filtered": "پالوده",
-  "status.hide": "نهفتن بوق",
+  "status.hide": "Hide post",
   "status.history.created": "توسط {name} در {date} ایجاد شد",
   "status.history.edited": "توسط {name} در {date} ویرایش شد",
   "status.load_more": "بار کردن بیش‌تر",
diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json
index 91a2bbbfd..5f3f7a416 100644
--- a/app/javascript/mastodon/locales/fi.json
+++ b/app/javascript/mastodon/locales/fi.json
@@ -3,11 +3,11 @@
   "about.contact": "Yhteystiedot:",
   "about.disclaimer": "Mastodon on vapaa avoimen lähdekoodin ohjelmisto ja Mastodon gGmbH:n tavaramerkki.",
   "about.domain_blocks.no_reason_available": "Syytä ei ole ilmoitettu",
-  "about.domain_blocks.preamble": "Mastodonin avulla voit yleensä tarkastella sisältöä ja olla vuorovaikutuksessa käyttäjien kanssa millä tahansa muulla palvelimella fediversessä. Nämä ovat poikkeuksia, jotka on tehty tälle palvelimelle.",
-  "about.domain_blocks.silenced.explanation": "Et yleensä näe profiileja ja sisältöä tältä palvelimelta, ellet nimenomaisesti etsi tai valitse sitä seuraamalla.",
+  "about.domain_blocks.preamble": "Yleisesti Mastodonin avulla voidaan tarkastella minkä tahansa muun fediverse-palvelinten sisältöä ja vuorovaikuttaa eri palvelinten käyttäjien kanssa. Nämä ovat tälle palvelimelle määritetyt poikkeukset.",
+  "about.domain_blocks.silenced.explanation": "Et yleensä näe tämän palvelimen profiileja ja sisältöä, jollet erityisesti etsi juuri sitä tai liity siihen seuraamalla.",
   "about.domain_blocks.silenced.title": "Rajoitettu",
-  "about.domain_blocks.suspended.explanation": "Tämän palvelimen tietoja ei käsitellä, tallenneta tai vaihdeta, mikä tekee käyttäjän kanssa vuorovaikutuksen tai yhteydenpidon mahdottomaksi tällä palvelimella.",
-  "about.domain_blocks.suspended.title": "Keskeytetty",
+  "about.domain_blocks.suspended.explanation": "Mitään tämän palvelimen tietoja ei käsitellä, tallenneta tai vaihdeta, mikä tekee vuorovaikutuksesta ja viestinnästä sen käyttäjien kanssa mahdotonta.",
+  "about.domain_blocks.suspended.title": "Jäädytetty",
   "about.not_available": "Näitä tietoja ei ole julkaistu tällä palvelimella.",
   "about.powered_by": "Hajautettu sosiaalinen media, tarjoaa {mastodon}",
   "about.rules": "Palvelimen säännöt",
@@ -16,7 +16,7 @@
   "account.badges.bot": "Botti",
   "account.badges.group": "Ryhmä",
   "account.block": "Estä @{name}",
-  "account.block_domain": "Estä verkkotunnus {domain}",
+  "account.block_domain": "Estä palvelu {domain}",
   "account.blocked": "Estetty",
   "account.browse_more_on_origin_server": "Selaile lisää alkuperäisellä palvelimella",
   "account.cancel_follow_request": "Peruuta seurantapyyntö",
@@ -28,8 +28,8 @@
   "account.endorse": "Suosittele profiilissasi",
   "account.featured_tags.last_status_at": "Viimeisin viesti {date}",
   "account.featured_tags.last_status_never": "Ei viestejä",
-  "account.featured_tags.title": "{name} esillä olevat hashtagit",
-  "account.follow": "Seuraa",
+  "account.featured_tags.title": "Käyttäjän {name} esillä olevat aihetunnisteet",
+  "account.follow": "Seuratut",
   "account.followers": "Seuraajat",
   "account.followers.empty": "Kukaan ei seuraa tätä käyttäjää vielä.",
   "account.followers_counter": "{count, plural, one {{counter} seuraaja} other {{counter} seuraajaa}}",
@@ -54,11 +54,12 @@
   "account.posts_with_replies": "Viestit ja vastaukset",
   "account.report": "Ilmoita käyttäjästä @{name}",
   "account.requested": "Odottaa hyväksyntää. Peruuta seuraamispyyntö klikkaamalla",
+  "account.requested_follow": "{name} on pyytänyt lupaa seurata sinua",
   "account.share": "Jaa käyttäjän @{name} profiili",
   "account.show_reblogs": "Näytä buustaukset käyttäjältä @{name}",
-  "account.statuses_counter": "{count, plural, one {{counter} viesti} other {{counter} viestiä}}",
+  "account.statuses_counter": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}",
   "account.unblock": "Salli @{name}",
-  "account.unblock_domain": "Salli {domain}",
+  "account.unblock_domain": "Salli palvelu {domain}",
   "account.unblock_short": "Poista esto",
   "account.unendorse": "Poista suosittelu profiilistasi",
   "account.unfollow": "Lopeta seuraaminen",
@@ -93,7 +94,7 @@
   "bundle_modal_error.message": "Jotain meni pieleen komponenttia ladattaessa.",
   "bundle_modal_error.retry": "Yritä uudelleen",
   "closed_registrations.other_server_instructions": "Koska Mastodon on hajautettu, voit luoda tilin toiselle palvelimelle ja silti olla vuorovaikutuksessa tämän kanssa.",
-  "closed_registrations_modal.description": "Tilin luominen palvelimeen {domain} ei ole tällä hetkellä mahdollista, mutta huomioi, että et tarvitse tiliä erityisesti palvelimeen {domain} käyttääksesi Mastodonia.",
+  "closed_registrations_modal.description": "Tilin luonti palveluun {domain} ei tällä hetkellä ole mahdollista, mutta huomioi, ettei Mastodonin käyttö edellytä juuri kyseisen palvelun tiliä.",
   "closed_registrations_modal.find_another_server": "Etsi toinen palvelin",
   "closed_registrations_modal.preamble": "Mastodon on hajautettu, joten riippumatta siitä, missä luot tilisi, voit seurata ja olla vuorovaikutuksessa kenen tahansa kanssa tällä palvelimella. Voit jopa isännöidä palvelinta!",
   "closed_registrations_modal.title": "Rekisteröityminen Mastodoniin",
@@ -127,7 +128,7 @@
   "compose.language.search": "Hae kieliä...",
   "compose_form.direct_message_warning_learn_more": "Lisätietoja",
   "compose_form.encryption_warning": "Mastodonin viestit eivät ole päästä päähän salattuja. Älä jaa arkaluonteisia tietoja Mastodonissa.",
-  "compose_form.hashtag_warning": "Tätä julkaisua listata minkään hastagin alle, koska se on listaamaton. Ainoastaan julkisia julkaisuja etsiä hastageilla.",
+  "compose_form.hashtag_warning": "Tätä julkaisua ei voi liittää aihetunnisteisiin, koska se ei ole julkinen. Vain näkyvyydeltään julkisiksi määritettyjä julkaisuja voidaan hakea aihetunnisteiden avulla.",
   "compose_form.lock_disclaimer": "Tilisi ei ole {locked}. Kuka tahansa voi seurata tiliäsi ja nähdä vain seuraajille rajaamasi julkaisut.",
   "compose_form.lock_disclaimer.lock": "lukittu",
   "compose_form.placeholder": "Mitä sinulla on mielessäsi?",
@@ -159,8 +160,8 @@
   "confirmations.delete_list.message": "Haluatko varmasti poistaa tämän listan kokonaan?",
   "confirmations.discard_edit_media.confirm": "Hylkää",
   "confirmations.discard_edit_media.message": "Onko sinulla tallentamattomia muutoksia kuvaukseen tai esikatseluun, hylätäänkö ne silti?",
-  "confirmations.domain_block.confirm": "Piilota koko verkko-osoite",
-  "confirmations.domain_block.message": "Oletko todella varma, että haluat estää koko {domain}? Useimmissa tapauksissa muutama kohdennettu lohko tai mykistys on riittävä ja parempi. Et näe kyseisen verkkotunnuksen sisältöä missään julkisessa aikajanassa tai ilmoituksissa. Seuraajasi tältä verkkotunnukselta poistetaan.",
+  "confirmations.domain_block.confirm": "Estä koko palvelu",
+  "confirmations.domain_block.message": "Haluatko aivan varmasti estää palvelun {domain} täysin? Useimmiten muutama kohdistettu esto tai mykistys on riittävä ja suositeltava toimenpide. Et näe kyseisen sisältöä kyseiseltä verkkoalueelta missään julkisissa aikajanoissa tai ilmoituksissa. Tälle verkkoalueelle kuuluvat seuraajasi poistetaan.",
   "confirmations.logout.confirm": "Kirjaudu ulos",
   "confirmations.logout.message": "Oletko varma, että haluat kirjautua ulos?",
   "confirmations.mute.confirm": "Mykistä",
@@ -179,16 +180,16 @@
   "copypaste.copied": "Kopioitu",
   "copypaste.copy": "Kopioi",
   "directory.federated": "Koko tunnettu fediverse",
-  "directory.local": "Vain palvelimelta {domain}",
+  "directory.local": "Vain palvelusta {domain}",
   "directory.new_arrivals": "Äskettäin saapuneet",
   "directory.recently_active": "Hiljattain aktiiviset",
   "disabled_account_banner.account_settings": "Tilin asetukset",
   "disabled_account_banner.text": "Tilisi {disabledAccount} on tällä hetkellä poissa käytöstä.",
-  "dismissable_banner.community_timeline": "Nämä ovat uusimmat julkiset viestit ihmisiltä, joiden tilejä isännöi {domain}.",
+  "dismissable_banner.community_timeline": "Nämä ovat uusimmat julkiset julkaisut käyttäjiltä, joiden tilejä isännöi {domain}.",
   "dismissable_banner.dismiss": "Hylkää",
   "dismissable_banner.explore_links": "Näistä uutisista puhuvat ihmiset juuri nyt tällä ja muilla hajautetun verkon palvelimilla.",
   "dismissable_banner.explore_statuses": "Nämä viestit juuri nyt tältä ja muilta hajautetun verkon palvelimilta ovat saamassa vetoa tältä palvelimelta.",
-  "dismissable_banner.explore_tags": "Nämä hashtagit juuri nyt ovat saamassa vetovoimaa tällä ja muilla hajautetun verkon palvelimilla olevien ihmisten keskuudessa.",
+  "dismissable_banner.explore_tags": "Nämä aihetunnisteet saavat juuri nyt vetovoimaa tällä ja muilla hajautetun verkon palvelimilla olevien ihmisten keskuudessa.",
   "dismissable_banner.public_timeline": "Nämä ovat viimeisimpiä julkisia viestejä ihmisiltä, jotka ovat tällä ja muilla hajautetun verkon palvelimilla, joista tämä palvelin tietää.",
   "embed.instructions": "Upota julkaisu verkkosivullesi kopioimalla alla oleva koodi.",
   "embed.preview": "Se tulee näyttämään tältä:",
@@ -214,12 +215,12 @@
   "empty_column.bookmarked_statuses": "Et ole vielä lisännyt viestejä kirjanmerkkeihisi. Kun lisäät yhden, se näkyy tässä.",
   "empty_column.community": "Paikallinen aikajana on tyhjä. Kirjoita jotain julkista, niin homma lähtee käyntiin!",
   "empty_column.direct": "Sinulla ei ole vielä yksityisviestejä. Kun lähetät tai vastaanotat sellaisen, se näkyy tässä.",
-  "empty_column.domain_blocks": "Verkkotunnuksia ei ole vielä estetty.",
+  "empty_column.domain_blocks": "Palveluita ei ole vielä estetty.",
   "empty_column.explore_statuses": "Mikään ei ole nyt trendi. Tarkista myöhemmin!",
   "empty_column.favourited_statuses": "Et ole vielä lisännyt viestejä kirjanmerkkeihisi. Kun lisäät yhden, se näkyy tässä.",
   "empty_column.favourites": "Kukaan ei ole vielä lisännyt tätä viestiä suosikkeihinsa. Kun joku tekee niin, näkyy kyseinen henkilö tässä.",
-  "empty_column.follow_recommendations": "Näyttää siltä, että sinulle ei voi luoda ehdotuksia. Voit yrittää etsiä ihmisiä, jotka saatat tuntea tai tutkia trendaavia aihesanoja.",
-  "empty_column.follow_requests": "Sinulla ei ole vielä seurauspyyntöjä. Kun saat sellaisen, näkyy se tässä.",
+  "empty_column.follow_recommendations": "Näyttää siltä, että sinulle ei voi luoda ehdotuksia. Voit yrittää etsiä ihmisiä, jotka saatat tuntea tai tutkia trendaavia aihetunnisteita.",
+  "empty_column.follow_requests": "Et ole vielä vastaanottanut seurauspyyntöjä. Saamasi pyynnöt näytetään täällä.",
   "empty_column.hashtag": "Tällä hashtagilla ei ole vielä mitään.",
   "empty_column.home": "Kotisi aikajana on tyhjä! Seuraa lisää ihmisiä täyttääksesi sen. {suggestions}",
   "empty_column.home.suggestions": "Katso joitakin ehdotuksia",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopioi pinon jäljitys leikepöydälle",
   "errors.unexpected_crash.report_issue": "Ilmoita ongelmasta",
   "explore.search_results": "Hakutulokset",
+  "explore.suggested_follows": "Sinulle",
   "explore.title": "Selaa",
+  "explore.trending_links": "Uutiset",
+  "explore.trending_statuses": "Julkaisut",
+  "explore.trending_tags": "Aihetunnisteet",
   "filter_modal.added.context_mismatch_explanation": "Tämä suodatinluokka ei koske asiayhteyttä, jossa olet käyttänyt tätä viestiä. Jos haluat, että viesti suodatetaan myös tässä yhteydessä, sinun on muokattava suodatinta.",
   "filter_modal.added.context_mismatch_title": "Asiayhteys ei täsmää!",
   "filter_modal.added.expired_explanation": "Tämä suodatinluokka on vanhentunut ja sinun on muutettava viimeistä voimassaolon päivää, jotta sitä voidaan käyttää.",
@@ -276,8 +281,8 @@
   "hashtag.column_settings.tag_mode.any": "Mikä tahansa näistä",
   "hashtag.column_settings.tag_mode.none": "Ei mitään näistä",
   "hashtag.column_settings.tag_toggle": "Sisällytä lisätunnisteet tähän sarakkeeseen",
-  "hashtag.follow": "Seuraa hashtagia",
-  "hashtag.unfollow": "Lopeta seuraaminen hashtagilla",
+  "hashtag.follow": "Seuraa aihetunnistetta",
+  "hashtag.unfollow": "Lopeta aihetunnisteen seuraaminen",
   "home.column_settings.basic": "Perusasetukset",
   "home.column_settings.show_reblogs": "Näytä buustaukset",
   "home.column_settings.show_replies": "Näytä vastaukset",
@@ -338,7 +343,7 @@
   "lightbox.next": "Seuraava",
   "lightbox.previous": "Edellinen",
   "limited_account_hint.action": "Näytä profiili joka tapauksessa",
-  "limited_account_hint.title": "Palvelun {domain} moderaattorit ovat piilottaneet tämän profiilin.",
+  "limited_account_hint.title": "Palvelun {domain} ylläpito on piilottanut tämän profiilin.",
   "lists.account.add": "Lisää listaan",
   "lists.account.remove": "Poista listasta",
   "lists.delete": "Poista lista",
@@ -368,7 +373,7 @@
   "navigation_bar.compose": "Luo uusi viesti",
   "navigation_bar.direct": "Yksityisviestit",
   "navigation_bar.discover": "Löydä uutta",
-  "navigation_bar.domain_blocks": "Estetyt verkkotunnukset",
+  "navigation_bar.domain_blocks": "Estetyt palvelut",
   "navigation_bar.edit_profile": "Muokkaa profiilia",
   "navigation_bar.explore": "Selaa",
   "navigation_bar.favourites": "Suosikit",
@@ -413,7 +418,7 @@
   "notifications.column_settings.reblog": "Buustit:",
   "notifications.column_settings.show": "Näytä sarakkeessa",
   "notifications.column_settings.sound": "Äänimerkki",
-  "notifications.column_settings.status": "Uudet viestit:",
+  "notifications.column_settings.status": "Uudet julkaisut:",
   "notifications.column_settings.unread_notifications.category": "Lukemattomat ilmoitukset",
   "notifications.column_settings.unread_notifications.highlight": "Korosta lukemattomat ilmoitukset",
   "notifications.column_settings.update": "Muokkaukset:",
@@ -514,29 +519,30 @@
   "search.placeholder": "Hae",
   "search.search_or_paste": "Etsi tai kirjoita URL-osoite",
   "search_popout.search_format": "Tarkennettu haku",
-  "search_popout.tips.full_text": "Tekstihaku listaa tilapäivitykset, jotka olet kirjoittanut, lisännyt suosikkeihisi, boostannut tai joissa sinut mainitaan, sekä tekstin sisältävät käyttäjänimet, nimimerkit ja hastagit.",
+  "search_popout.tips.full_text": "Tekstihaku listaa tilapäivitykset, jotka olet kirjoittanut, lisännyt suosikkeihisi, boostannut tai joissa sinut mainitaan, sekä tekstin sisältävät käyttäjänimet, nimimerkit ja aihetunnisteet.",
   "search_popout.tips.hashtag": "aihetunnisteet",
   "search_popout.tips.status": "julkaisu",
-  "search_popout.tips.text": "Tekstihaku listaa hakua vastaavat nimimerkit, käyttäjänimet ja hastagit",
+  "search_popout.tips.text": "Tekstihaku listaa hakua vastaavat nimimerkit, käyttäjänimet ja aihetunnisteet",
   "search_popout.tips.user": "käyttäjä",
   "search_results.accounts": "Ihmiset",
   "search_results.all": "Kaikki",
   "search_results.hashtags": "Aihetunnisteet",
   "search_results.nothing_found": "Näille hakusanoille ei löytynyt mitään",
-  "search_results.statuses": "Viestit",
+  "search_results.statuses": "Julkaisut",
   "search_results.statuses_fts_disabled": "Viestien haku sisällön perusteella ei ole käytössä tällä Mastodon-palvelimella.",
   "search_results.title": "Etsi {q}",
   "search_results.total": "{count, number} {count, plural, one {tulos} other {tulosta}}",
   "server_banner.about_active_users": "Palvelinta käyttäneet ihmiset viimeisen 30 päivän aikana (kuukauden aktiiviset käyttäjät)",
-  "server_banner.active_users": "aktiiviset käyttäjät",
+  "server_banner.active_users": "aktiivista käyttäjää",
   "server_banner.administered_by": "Ylläpitäjä:",
-  "server_banner.introduction": "{domain} on osa hajautettua sosiaalista verkostoa, jonka tarjoaa {mastodon}.",
+  "server_banner.introduction": "{domain} kuuluu hajautettuun sosiaaliseen verkostoon, jonka voimanlähde on {mastodon}.",
   "server_banner.learn_more": "Lue lisää",
   "server_banner.server_stats": "Palvelimen tilastot:",
   "sign_in_banner.create_account": "Luo tili",
   "sign_in_banner.sign_in": "Kirjaudu sisään",
-  "sign_in_banner.text": "Kirjaudu sisään seurataksesi profiileja tai hashtageja, lisätäksesi suosikkeihin, jakaaksesi viestejä ja vastataksesi niihin tai ollaksesi vuorovaikutuksessa tililläsi toisella palvelimella.",
+  "sign_in_banner.text": "Kirjaudu sisään seurataksesi profiileja tai aihetunnisteita, lisätäksesi suosikkeihin, jakaaksesi julkaisuja ja vastataksesi niihin tai ollaksesi vuorovaikutuksessa tililläsi toisella palvelimella.",
   "status.admin_account": "Avaa moderaattorinäkymä tilistä @{name}",
+  "status.admin_domain": "Avaa palvelimen {domain} moderointitoiminnot",
   "status.admin_status": "Avaa julkaisu moderointinäkymässä",
   "status.block": "Estä @{name}",
   "status.bookmark": "Tallenna kirjanmerkki",
@@ -553,7 +559,7 @@
   "status.favourite": "Lisää suosikkeihin",
   "status.filter": "Suodata tämä viesti",
   "status.filtered": "Suodatettu",
-  "status.hide": "Piilota toot",
+  "status.hide": "Piilota viesti",
   "status.history.created": "{name} luotu {date}",
   "status.history.edited": "{name} muokkasi {date}",
   "status.load_more": "Lataa lisää",
@@ -604,8 +610,8 @@
   "time_remaining.moments": "Hetki jäljellä",
   "time_remaining.seconds": "{number, plural, one {# sekunti} other {# sekuntia}} jäljellä",
   "timeline_hint.remote_resource_not_displayed": "{resource} muilta palvelimilta ei näytetä.",
-  "timeline_hint.resources.followers": "Seuraajat",
-  "timeline_hint.resources.follows": "seurattua",
+  "timeline_hint.resources.followers": "Seuraajia",
+  "timeline_hint.resources.follows": "Seurattuja",
   "timeline_hint.resources.statuses": "Vanhemmat julkaisut",
   "trends.counter_by_accounts": "{count, plural, one {{counter} henkilö} other {{counter} henkilöä}} viimeisten {days, plural, one {päivän} other {{days} päivän}}",
   "trends.trending_now": "Suosittua nyt",
@@ -617,13 +623,13 @@
   "upload_button.label": "Lisää mediaa",
   "upload_error.limit": "Tiedostolatauksien raja ylitetty.",
   "upload_error.poll": "Tiedon lataaminen ei ole sallittua kyselyissä.",
-  "upload_form.audio_description": "Kuvaile kuulovammaisille",
-  "upload_form.description": "Anna kuvaus näkörajoitteisia varten",
+  "upload_form.audio_description": "Kuvaile sisältöä kuuroille ja kuulorajoitteisille",
+  "upload_form.description": "Kuvaile sisältöä sokeille ja näkörajoitteisille",
   "upload_form.description_missing": "Kuvausta ei ole lisätty",
   "upload_form.edit": "Kuvaile",
   "upload_form.thumbnail": "Vaihda pikkukuva",
   "upload_form.undo": "Peru",
-  "upload_form.video_description": "Kuvaile kuulo- tai näkövammaisille",
+  "upload_form.video_description": "Kuvaile sisältöä kuuroille, kuulorajoitteisille, sokeille tai näkörajoitteisille",
   "upload_modal.analyzing_picture": "Analysoidaan kuvaa…",
   "upload_modal.apply": "Käytä",
   "upload_modal.applying": "Asetetaan…",
diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json
index f716b6373..1841df058 100644
--- a/app/javascript/mastodon/locales/fo.json
+++ b/app/javascript/mastodon/locales/fo.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Uppsløg og svar",
   "account.report": "Melda @{name}",
   "account.requested": "Bíðar eftir góðkenning. Trýst fyri at angra umbønina",
+  "account.requested_follow": "{name} hevur biðið um at fylgja tær",
   "account.share": "Deil vanga @{name}'s",
   "account.show_reblogs": "Vís lyft frá @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} postur} other {{counter} postar}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Leita eftir málum...",
   "compose_form.direct_message_warning_learn_more": "Fleiri upplýsingar",
   "compose_form.encryption_warning": "Postar á Mastodon eru ikki bronglaðir úr enda í annan. Lat vera við at deila viðkvæmar upplýsingar á Mastodon.",
-  "compose_form.hashtag_warning": "Hesin posturin verður ikki listaður undir nøkrum frámerki, tí hann er ólistaður. Tað ber einans til at leita eftir almennum postum eftir frámerki.",
+  "compose_form.hashtag_warning": "Hesin posturin verður ikki listaður undir nøkrum frámerki, tí hann er ikki almennur. Tað ber einans til at leita eftir almennum postum eftir frámerki.",
   "compose_form.lock_disclaimer": "Kontoin hjá tær er ikki {locked}. Øll kunnu fylgja tær og lesa tað, tú bert letur fyljgarar lesa.",
   "compose_form.lock_disclaimer.lock": "læst",
   "compose_form.placeholder": "Hvat hevur tú í huga?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Avrita stakkaslóðina til setiborðið",
   "errors.unexpected_crash.report_issue": "Fráboða trupulleika",
   "explore.search_results": "Leitiúrslit",
+  "explore.suggested_follows": "Til tín",
   "explore.title": "Rannsaka",
+  "explore.trending_links": "Tíðindi",
+  "explore.trending_statuses": "Postar",
+  "explore.trending_tags": "Frámerki",
   "filter_modal.added.context_mismatch_explanation": "Hesin filturbólkurin viðvíkur ikki kontekstinum, sum tú hevur fingið atgongd til hendan postin. Ynskir tú at posturin verður filtreraður í hesum kontekstinum eisini, so er neyðugt at tú rættar filtrið.",
   "filter_modal.added.context_mismatch_title": "Ósamsvar við kontekst!",
   "filter_modal.added.expired_explanation": "Hesin filturbólkurin er útgingin, og tú mást broyta dagfestingina fyri at hann skal virka.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Rita inn",
   "sign_in_banner.text": "Innrita fyri at fylgja vangum og frámerkjum, seta yndismerki á, deila og svara postum, ella at brúka kontuna til at samvirka á einum øðrum ambætara.",
   "status.admin_account": "Lat kjakleiðaramarkamót upp fyri @{name}",
+  "status.admin_domain": "Lat umsjónarmarkamót upp fyri {domain}",
   "status.admin_status": "Lat hendan postin upp í kjakleiðaramarkamótinum",
   "status.block": "Blokera @{name}",
   "status.bookmark": "Goym",
@@ -617,13 +623,13 @@
   "upload_button.label": "Legg myndir, sjónfílu ella ljóðfílu afturat",
   "upload_error.limit": "Farið er um markið fyri fíluuppsending.",
   "upload_error.poll": "Ikki loyvt at leggja fílur upp í spurnarkanningum.",
-  "upload_form.audio_description": "Lýsing, av innihaldi, fyri deyv",
-  "upload_form.description": "Lýsing, av innihaldi, fyri blind og sjónveik",
+  "upload_form.audio_description": "Lýs fyri teimum, sum eru deyv ella hava ringa hoyrn",
+  "upload_form.description": "Lýs fyri teimum, sum eru blind ella eru sjónveik",
   "upload_form.description_missing": "Lýsing vantar",
   "upload_form.edit": "Rætta",
   "upload_form.thumbnail": "Broyt smámynd",
   "upload_form.undo": "Strika",
-  "upload_form.video_description": "Lýsing fyri deyv, blind og sjónveik",
+  "upload_form.video_description": "Lýs fyri teimum, sum eru deyv, hava ringa hoyrn, eru blind ella eru sjónveik",
   "upload_modal.analyzing_picture": "Greini mynd…",
   "upload_modal.apply": "Ger virkið",
   "upload_modal.applying": "Geri virkið…",
diff --git a/app/javascript/mastodon/locales/fr-QC.json b/app/javascript/mastodon/locales/fr-QC.json
index d0d84fa4a..89c3e7644 100644
--- a/app/javascript/mastodon/locales/fr-QC.json
+++ b/app/javascript/mastodon/locales/fr-QC.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Publications et réponses",
   "account.report": "Signaler @{name}",
   "account.requested": "En attente d’approbation. Cliquez pour annuler la demande",
+  "account.requested_follow": "{name} a demandé à vous suivre",
   "account.share": "Partager le profil de @{name}",
   "account.show_reblogs": "Afficher les boosts de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Publication} other {{counter} Publications}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Rechercher des langues…",
   "compose_form.direct_message_warning_learn_more": "En savoir plus",
   "compose_form.encryption_warning": "Les publications sur Mastodon ne sont pas chiffrées de bout en bout. Veuillez ne partager aucune information sensible sur Mastodon.",
-  "compose_form.hashtag_warning": "Cette publication ne sera pas listée dans les recherches par hashtag car sa visibilité est réglée sur « non listée ». Seuls les publications avec visibilité « publique » peuvent être recherchées par hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Votre compte n’est pas {locked}. Tout le monde peut vous suivre et voir vos publications privés.",
   "compose_form.lock_disclaimer.lock": "verrouillé",
   "compose_form.placeholder": "À quoi pensez-vous?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copier la trace d'appels dans le presse-papier",
   "errors.unexpected_crash.report_issue": "Signaler un problème",
   "explore.search_results": "Résultats",
+  "explore.suggested_follows": "Pour vous",
   "explore.title": "Explorer",
+  "explore.trending_links": "Nouvelles",
+  "explore.trending_statuses": "Messages",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Cette catégorie de filtre ne s'applique pas au contexte dans lequel vous avez accédé à cette publication. Si vous voulez que la publication soit filtrée dans ce contexte également, vous devrez modifier le filtre.",
   "filter_modal.added.context_mismatch_title": "Incompatibilité du contexte!",
   "filter_modal.added.expired_explanation": "Cette catégorie de filtre a expiré, vous devrez modifier la date d'expiration pour qu'elle soit appliquée.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Se connecter",
   "sign_in_banner.text": "Connectez-vous pour suivre les profils ou les hashtags, ajouter aux favoris, partager et répondre aux publications, ou interagir depuis votre compte sur un autre serveur.",
   "status.admin_account": "Ouvrir l’interface de modération pour @{name}",
+  "status.admin_domain": "Ouvrir l’interface de modération pour {domain}",
   "status.admin_status": "Ouvrir ce message dans l’interface de modération",
   "status.block": "Bloquer @{name}",
   "status.bookmark": "Ajouter aux signets",
@@ -553,7 +559,7 @@
   "status.favourite": "Ajouter aux favoris",
   "status.filter": "Filtrer cette publication",
   "status.filtered": "Filtrée",
-  "status.hide": "Cacher la publication",
+  "status.hide": "Masquer la publication",
   "status.history.created": "créé par {name} {date}",
   "status.history.edited": "modifié par {name} {date}",
   "status.load_more": "Charger plus",
diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json
index bc4231bf8..d9c77089a 100644
--- a/app/javascript/mastodon/locales/fr.json
+++ b/app/javascript/mastodon/locales/fr.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Messages et réponses",
   "account.report": "Signaler @{name}",
   "account.requested": "En attente d’approbation. Cliquez pour annuler la demande",
+  "account.requested_follow": "{name} a demandé à vous suivre",
   "account.share": "Partager le profil de @{name}",
   "account.show_reblogs": "Afficher les partages de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Message} other {{counter} Messages}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Rechercher des langues …",
   "compose_form.direct_message_warning_learn_more": "En savoir plus",
   "compose_form.encryption_warning": "Les messages sur Mastodon ne sont pas chiffrés de bout en bout. Ne partagez aucune information sensible sur Mastodon.",
-  "compose_form.hashtag_warning": "Ce pouet ne sera pas listé dans les recherches par hashtag car sa visibilité est réglée sur « non listé ». Seuls les pouets avec une visibilité « publique » peuvent être recherchés par hashtag.",
+  "compose_form.hashtag_warning": "Ce message n'apparaîtra pas dans les listes de hashtags, car il n'est pas public. Seuls les messages publics peuvent appaître dans les recherches par hashtags.",
   "compose_form.lock_disclaimer": "Votre compte n’est pas {locked}. Tout le monde peut vous suivre et voir vos messages privés.",
   "compose_form.lock_disclaimer.lock": "verrouillé",
   "compose_form.placeholder": "Qu’avez-vous en tête ?",
@@ -186,7 +187,7 @@
   "disabled_account_banner.text": "Votre compte {disabledAccount} est actuellement désactivé.",
   "dismissable_banner.community_timeline": "Voici les messages publics les plus récents des personnes dont les comptes sont hébergés par {domain}.",
   "dismissable_banner.dismiss": "Rejeter",
-  "dismissable_banner.explore_links": "Ces nouvelles sont actuellement en cours de discussion par des personnes sur d'autres serveurs du réseau décentralisé ainsi que sur celui-ci.",
+  "dismissable_banner.explore_links": "On parle actuellement de ces nouvelles sur ce serveur, ainsi que sur d'autres serveurs du réseau décentralisé.",
   "dismissable_banner.explore_statuses": "Ces publications depuis les serveurs du réseau décentralisé, dont celui-ci, sont actuellement en train de gagner de l'ampleur sur ce serveur.",
   "dismissable_banner.explore_tags": "Ces hashtags sont actuellement en train de gagner de l'ampleur parmi les personnes sur les serveurs du réseau décentralisé dont celui-ci.",
   "dismissable_banner.public_timeline": "Voici les publications publiques les plus récentes des personnes de ce serveur et des autres du réseau décentralisé que ce serveur connait.",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copier la trace d'appels dans le presse-papier",
   "errors.unexpected_crash.report_issue": "Signaler le problème",
   "explore.search_results": "Résultats de la recherche",
+  "explore.suggested_follows": "Pour vous",
   "explore.title": "Explorer",
+  "explore.trending_links": "Nouvelles",
+  "explore.trending_statuses": "Messages",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Cette catégorie de filtre ne s'applique pas au contexte dans lequel vous avez accédé à ce message. Si vous voulez que le message soit filtré dans ce contexte également, vous devrez modifier le filtre.",
   "filter_modal.added.context_mismatch_title": "Incompatibilité du contexte !",
   "filter_modal.added.expired_explanation": "Cette catégorie de filtre a expiré, vous devrez modifier la date d'expiration pour qu'elle soit appliquée.",
@@ -386,7 +391,7 @@
   "navigation_bar.security": "Sécurité",
   "not_signed_in_indicator.not_signed_in": "Vous devez vous connecter pour accéder à cette ressource.",
   "notification.admin.report": "{name} a signalé {target}",
-  "notification.admin.sign_up": "{name} s'est inscrit·e",
+  "notification.admin.sign_up": "{name} s'est inscrit",
   "notification.favourite": "{name} a aimé votre publication",
   "notification.follow": "{name} vous suit",
   "notification.follow_request": "{name} a demandé à vous suivre",
@@ -518,7 +523,7 @@
   "search_popout.tips.hashtag": "hashtag",
   "search_popout.tips.status": "message",
   "search_popout.tips.text": "Un texte simple renvoie les noms affichés, les identifiants et les hashtags correspondants",
-  "search_popout.tips.user": "utilisateur·ice",
+  "search_popout.tips.user": "utilisateur",
   "search_results.accounts": "Comptes",
   "search_results.all": "Tous les résultats",
   "search_results.hashtags": "Hashtags",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Se connecter",
   "sign_in_banner.text": "Connectez-vous pour suivre les profils ou les hashtags, ajouter aux favoris, partager et répondre aux messages, ou interagir depuis votre compte sur un autre serveur.",
   "status.admin_account": "Ouvrir l’interface de modération pour @{name}",
+  "status.admin_domain": "Ouvrir l’interface de modération pour {domain}",
   "status.admin_status": "Ouvrir ce message dans l’interface de modération",
   "status.block": "Bloquer @{name}",
   "status.bookmark": "Ajouter aux marque-pages",
@@ -553,7 +559,7 @@
   "status.favourite": "Ajouter aux favoris",
   "status.filter": "Filtrer ce message",
   "status.filtered": "Filtré",
-  "status.hide": "Cacher le pouet",
+  "status.hide": "Masquer la publication",
   "status.history.created": "créé par {name} {date}",
   "status.history.edited": "édité par {name} {date}",
   "status.load_more": "Charger plus",
@@ -618,7 +624,7 @@
   "upload_error.limit": "Taille maximale d'envoi de fichier dépassée.",
   "upload_error.poll": "L’envoi de fichiers n’est pas autorisé avec les sondages.",
   "upload_form.audio_description": "Décrire pour les personnes ayant des difficultés d’audition",
-  "upload_form.description": "Décrire pour les malvoyant·e·s",
+  "upload_form.description": "Décrire pour les malvoyants",
   "upload_form.description_missing": "Description manquante",
   "upload_form.edit": "Décrire",
   "upload_form.thumbnail": "Changer la vignette",
diff --git a/app/javascript/mastodon/locales/fy.json b/app/javascript/mastodon/locales/fy.json
index 86cfe64ad..9cbf32e5c 100644
--- a/app/javascript/mastodon/locales/fy.json
+++ b/app/javascript/mastodon/locales/fy.json
@@ -3,8 +3,8 @@
   "about.contact": "Kontakt:",
   "about.disclaimer": "Mastodon is frije, iepenboarnesoftware en in hannelsmerk fan Mastodon gGmbH.",
   "about.domain_blocks.no_reason_available": "Reden net beskikber",
-  "about.domain_blocks.preamble": "Yn it algemien kinsto mei Mastodon berjochten ûntfange fan, en ynteraksje hawwe mei brûkers fan elke server yn de fediverse. Dit binne de útsûnderingen dy’t op dizze spesifike server jilde.",
-  "about.domain_blocks.silenced.explanation": "Yn it algemien sjochsto gjin berjochten en accounts fan dizze server, útsein do berjochten eksplisyt opsikest of derfoar kiest om in account fan dizze server te folgjen.",
+  "about.domain_blocks.preamble": "Yn it algemien kinne jo mei Mastodon berjochten ûntfange fan, en ynteraksje hawwe mei brûkers fan elke server yn de fediverse. Dit binne de útsûnderingen dy’t op dizze spesifike server jilde.",
+  "about.domain_blocks.silenced.explanation": "Yn it algemien sjogge jo gjin berjochten en accounts fan dizze server, útsein as jo berjochten eksplisyt opsikje of derfoar kieze om in account fan dizze server te folgjen.",
   "about.domain_blocks.silenced.title": "Beheind",
   "about.domain_blocks.suspended.explanation": "Der wurde gjin gegevens fan dizze server ferwurke, bewarre of útwiksele, wat ynteraksje of kommunikaasje mei brûkers fan dizze server ûnmooglik makket.",
   "about.domain_blocks.suspended.title": "Utsteld",
@@ -12,7 +12,7 @@
   "about.powered_by": "Desintralisearre sosjale media, mooglik makke troch {mastodon}",
   "about.rules": "Serverrigels",
   "account.account_note_header": "Opmerking",
-  "account.add_or_remove_from_list": "Tafoegje of fuortsmite fan listen út",
+  "account.add_or_remove_from_list": "Tafoegje oan of fuortsmite út listen",
   "account.badges.bot": "Bot",
   "account.badges.group": "Groep",
   "account.block": "@{name} blokkearje",
@@ -36,7 +36,7 @@
   "account.following": "Folgjend",
   "account.following_counter": "{count, plural, one {{counter} folgjend} other {{counter} folgjend}}",
   "account.follows.empty": "Dizze brûker folget noch net ien.",
-  "account.follows_you": "Folget dy",
+  "account.follows_you": "Folget jo",
   "account.go_to_profile": "Gean nei profyl",
   "account.hide_reblogs": "Boosts fan @{name} ferstopje",
   "account.joined_short": "Registrearre op",
@@ -45,15 +45,16 @@
   "account.locked_info": "De privacysteat fan dizze account is op beskoattele set. De eigener bepaalt hânmjittich wa’t dyjinge folgje kin.",
   "account.media": "Media",
   "account.mention": "@{name} fermelde",
-  "account.moved_to": "{name} is ferhuze net:",
+  "account.moved_to": "{name} is ferhuze nei:",
   "account.mute": "@{name} negearje",
   "account.mute_notifications": "Meldingen fan @{name} negearje",
   "account.muted": "Negearre",
-  "account.open_original_page": "Iepenje orizjinele side",
+  "account.open_original_page": "Orizjinele side iepenje",
   "account.posts": "Berjochten",
   "account.posts_with_replies": "Berjochten en reaksjes",
   "account.report": "@{name} rapportearje",
   "account.requested": "Wacht op goedkarring. Klik om it folchfersyk te annulearjen",
+  "account.requested_follow": "{name} hat dy in folchfersyk stjoerd",
   "account.share": "Profyl fan @{name} diele",
   "account.show_reblogs": "Boosts fan @{name} toane",
   "account.statuses_counter": "{count, plural, one {{counter} berjocht} other {{counter} berjochten}}",
@@ -63,39 +64,39 @@
   "account.unendorse": "Net op profyl werjaan",
   "account.unfollow": "Net mear folgje",
   "account.unmute": "@{name} net langer negearje",
-  "account.unmute_notifications": "Notifikaasjes fan @{name} ynskeakelje",
+  "account.unmute_notifications": "Meldingen fan @{name} ynskeakelje",
   "account.unmute_short": "Net mear negearje",
   "account_note.placeholder": "Klik om notysje ta te foegjen",
-  "admin.dashboard.daily_retention": "Meidogger retinsjegraad per dei nei oanmelding",
-  "admin.dashboard.monthly_retention": "Meidogger retinsjegraad per moanne nei oanmelding",
+  "admin.dashboard.daily_retention": "Brûkerretinsjegraad per dei nei oanmelding",
+  "admin.dashboard.monthly_retention": "Brûkerretinsjegraad per moanne nei oanmelding",
   "admin.dashboard.retention.average": "Gemiddelde",
-  "admin.dashboard.retention.cohort": "Moanne fan registraasje",
+  "admin.dashboard.retention.cohort": "Registraasjemoanne",
   "admin.dashboard.retention.cohort_size": "Nije brûkers",
-  "alert.rate_limited.message": "Besykje asjebleaft opnij nei {retry_time, time, medium}.",
+  "alert.rate_limited.message": "Opnij probearje nei {retry_time, time, medium}.",
   "alert.rate_limited.title": "Dataferkear beheind",
-  "alert.unexpected.message": "Der barde in ûnferwachte flater.",
+  "alert.unexpected.message": "Der is in ûnferwachte flater bard.",
   "alert.unexpected.title": "Oepsy!",
-  "announcement.announcement": "Meidieling",
+  "announcement.announcement": "Oankundiging",
   "attachments_list.unprocessed": "(net ferwurke)",
   "audio.hide": "Audio ferstopje",
   "autosuggest_hashtag.per_week": "{count} yn ’e wike",
-  "boost_modal.combo": "Jo kinne op {combo} drukke om dit in oare kear oer te slaan",
-  "bundle_column_error.copy_stacktrace": "Kopiearje flaterrapport",
+  "boost_modal.combo": "Jo kinne op {combo} drukke om dit de folgjende kear oer te slaan",
+  "bundle_column_error.copy_stacktrace": "Flaterrapport kopiearje",
   "bundle_column_error.error.body": "De opfrege side koe net werjûn wurde. It kin wêze troch in flater yn ús koade, of in probleem mei browserkompatibiliteit.",
   "bundle_column_error.error.title": "Oh nee!",
-  "bundle_column_error.network.body": "Der wie in flater by it laden fan dizze side. Dit kin komme troch in tydlik probleem mei jo ynternetferbining of dizze server.",
+  "bundle_column_error.network.body": "Der is in flater bard by it laden fan dizze side. Dit kin komme troch in tydlik probleem mei jo ynternetferbining of dizze server.",
   "bundle_column_error.network.title": "Netwurkflater",
   "bundle_column_error.retry": "Opnij probearje",
   "bundle_column_error.return": "Tebek nei startside",
-  "bundle_column_error.routing.body": "De opfrege side kin net fûn wurde. Binne jo wis dat de URL yn 'e adresbalke goed is?",
+  "bundle_column_error.routing.body": "De opfrege side kin net fûn wurde. Binne jo wis dat de URL yn de adresbalke goed is?",
   "bundle_column_error.routing.title": "404",
   "bundle_modal_error.close": "Slute",
-  "bundle_modal_error.message": "Der gie der mis by it laden fan dizze komponint.",
+  "bundle_modal_error.message": "Der gie wat mis by it laden fan dizze komponint.",
   "bundle_modal_error.retry": "Opnij probearje",
-  "closed_registrations.other_server_instructions": "Sûnt Mastodon desintralisearre is, kinne jo in akkount meitsje op in oare server en noch hieltyd ynteraksje hawwe mei dizze.",
-  "closed_registrations_modal.description": "It oanmeitsjen fan in akkount op {domain} is op it stuit net mooglik, mar hâld asjebleaft yn gedachten dat jo gjin akkount spesifyk op {domain} nedich hawwe om Mastodon te brûken.",
+  "closed_registrations.other_server_instructions": "Omdat Mastodon desintralisearre is, kinne jo in account meitsje op in oare server en noch hieltyd ynteraksje hawwe mei dizze.",
+  "closed_registrations_modal.description": "It oanmeitsjen fan in account op {domain} is op dit stuit net mooglik, mar hâld asjebleaft yn gedachten dat jo gjin account spesifyk op {domain} nedich hawwe om Mastodon te brûken.",
   "closed_registrations_modal.find_another_server": "Sykje in oare server",
-  "closed_registrations_modal.preamble": "Mastodon is desintralisearre, dus nettsjinsteande wêr't jo jo akkount oanmeitsje, jo kinne elkenien op dizze server folgje en ynteraksje mei hawwe. Jo kinne it sels sels hoste!",
+  "closed_registrations_modal.preamble": "Mastodon is desintralisearre, dus nettsjinsteande wêr't jo jo account oanmeitsje, jo kinne elkenien op dizze server folgje en der ynteraksje mei hawwe. Jo kinne it sels sels hoste!",
   "closed_registrations_modal.title": "Oanmelde op Mastodon",
   "column.about": "Oer",
   "column.blocks": "Blokkearre brûkers",
@@ -103,7 +104,7 @@
   "column.community": "Lokale tiidline",
   "column.direct": "Direkte berjochten",
   "column.directory": "Profilen trochsykje",
-  "column.domain_blocks": "Blokkeare domeinen",
+  "column.domain_blocks": "Blokkearre domeinen",
   "column.favourites": "Favoriten",
   "column.follow_requests": "Folchfersiken",
   "column.home": "Startside",
@@ -112,13 +113,13 @@
   "column.notifications": "Meldingen",
   "column.pins": "Fêstsette berjochten",
   "column.public": "Globale tiidline",
-  "column_back_button.label": "Werom",
+  "column_back_button.label": "Tebek",
   "column_header.hide_settings": "Ynstellingen ferstopje",
   "column_header.moveLeft_settings": "Kolom nei links ferpleatse",
   "column_header.moveRight_settings": "Kolom nei rjochts ferpleatse",
   "column_header.pin": "Fêstsette",
   "column_header.show_settings": "Ynstellingen toane",
-  "column_header.unpin": "Los helje",
+  "column_header.unpin": "Losmeitsje",
   "column_subheading.settings": "Ynstellingen",
   "community.column_settings.local_only": "Allinnich lokaal",
   "community.column_settings.media_only": "Allinnich media",
@@ -127,49 +128,49 @@
   "compose.language.search": "Talen sykje…",
   "compose_form.direct_message_warning_learn_more": "Mear ynfo",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
-  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
+  "compose_form.hashtag_warning": "Dit berjocht falt net ûnder in hashtag te besjen, omdat dizze net op iepenbier is. Allinnich iepenbiere berjochten kinne fia hashtags fûn wurde.",
+  "compose_form.lock_disclaimer": "Jo account is net {locked}. Elkenien kin jo folgje en kin de berjochten sjen dy’t jo allinnich oan jo folgers rjochte hawwe.",
   "compose_form.lock_disclaimer.lock": "beskoattele",
-  "compose_form.placeholder": "Wat wolsto kwyt?",
+  "compose_form.placeholder": "Wat wolle jo kwyt?",
   "compose_form.poll.add_option": "Kar tafoegje",
-  "compose_form.poll.duration": "Doer fan de poll",
-  "compose_form.poll.option_placeholder": "Keuze {number}",
+  "compose_form.poll.duration": "Doer fan de enkête",
+  "compose_form.poll.option_placeholder": "Kar {number}",
   "compose_form.poll.remove_option": "Dizze kar fuortsmite",
-  "compose_form.poll.switch_to_multiple": "Poll wizigje om meardere karren ta te stean",
-  "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
+  "compose_form.poll.switch_to_multiple": "Enkête wizigje om meardere karren ta te stean",
+  "compose_form.poll.switch_to_single": "Enkête wizigje om in inkelde kar ta te stean",
   "compose_form.publish": "Publisearje",
-  "compose_form.publish_form": "Publish",
+  "compose_form.publish_form": "Publisearje",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.save_changes": "Wizigingen bewarje",
   "compose_form.sensitive.hide": "{count, plural, one {Media as gefoelich markearje} other {Media as gefoelich markearje}}",
-  "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}",
-  "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}",
+  "compose_form.sensitive.marked": "{count, plural, one {Media as gefoelich markearre} other {Media as gefoelich markearre}}",
+  "compose_form.sensitive.unmarked": "{count, plural, one {Media is net as gefoelich markearre} other {Media is net as gefoelich markearre}}",
   "compose_form.spoiler.marked": "Ynhâldswarskôging fuortsmite",
   "compose_form.spoiler.unmarked": "Ynhâldswarskôging tafoegje",
-  "compose_form.spoiler_placeholder": "Write your warning here",
+  "compose_form.spoiler_placeholder": "Warskôgingstekst",
   "confirmation_modal.cancel": "Annulearje",
   "confirmations.block.block_and_report": "Blokkearje en rapportearje",
   "confirmations.block.confirm": "Blokkearje",
   "confirmations.block.message": "Bisto wis datsto {name} blokkearje wolst?",
-  "confirmations.cancel_follow_request.confirm": "Withdraw request",
-  "confirmations.cancel_follow_request.message": "Are you sure you want to withdraw your request to follow {name}?",
+  "confirmations.cancel_follow_request.confirm": "Fersyk annulearje",
+  "confirmations.cancel_follow_request.message": "Binne jo wis dat jo jo fersyk om {name} te folgjen annulearje wolle?",
   "confirmations.delete.confirm": "Fuortsmite",
-  "confirmations.delete.message": "Bisto wis datsto dit berjocht fuortsmite wolst?",
+  "confirmations.delete.message": "Binne jo wis dat jo dit berjocht fuortsmite wolle?",
   "confirmations.delete_list.confirm": "Fuortsmite",
   "confirmations.delete_list.message": "Bisto wis datsto dizze list foar permanint fuortsmite wolst?",
   "confirmations.discard_edit_media.confirm": "Fuortsmite",
-  "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?",
+  "confirmations.discard_edit_media.message": "Jo hawwe net-bewarre wizigingen yn de mediabeskriuwing of foarfertoaning, wolle jo dizze dochs fuortsmite?",
   "confirmations.domain_block.confirm": "Hide entire domain",
-  "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
+  "confirmations.domain_block.message": "Binne jo echt wis dat jo alles fan {domain} negearje wolle? Yn de measte gefallen is it blokkearjen of negearjen fan in pear spesifike persoanen genôch en better. Jo sille gjin berjochten fan dizze server op iepenbiere tiidlinen sjen of yn jo meldingen. Jo folgers fan dizze server wurde fuortsmiten.",
   "confirmations.logout.confirm": "Ofmelde",
   "confirmations.logout.message": "Bisto wis datsto ôfmelde wolst?",
   "confirmations.mute.confirm": "Negearje",
-  "confirmations.mute.explanation": "Dit sil berjochten fan harren en berjochten wêr’t se yn fermeld wurden ûnsichtber meitsje, mar se sille dyn berjochten noch hieltyd sjen kinne en dy folgje kinne.",
-  "confirmations.mute.message": "Bisto wis datsto {name} negearje wolst?",
+  "confirmations.mute.explanation": "Dit sil berjochten fan harren en berjochten dêr’t se yn fermeld wurde ûnsichtber meitsje, mar se sille berjochten noch hieltyd sjen kinne en jo folgje kinne.",
+  "confirmations.mute.message": "Binne jo wis dat jo {name} negearje wolle?",
   "confirmations.redraft.confirm": "Fuortsmite en opnij opstelle",
-  "confirmations.redraft.message": "Wolsto dit berjocht wurklik fuortsmite en opnij opstelle? Favoriten en boosts geane dan ferlern en reaksjes op it oarspronklike berjocht rekkesto kwyt.",
+  "confirmations.redraft.message": "Wolle jo dit berjocht wurklik fuortsmite en opnij opstelle? Favoriten en boosts geane dan ferlern en reaksjes op it oarspronklike berjocht reitsje jo kwyt.",
   "confirmations.reply.confirm": "Reagearje",
-  "confirmations.reply.message": "Troch no te reagearjen sil it berjocht watsto no oan it skriuwen binne oerskreaun wurde. Wolsto trochgean?",
+  "confirmations.reply.message": "Troch no te reagearjen sil it berjocht dat jo no oan it skriuwen binne oerskreaun wurde. Wolle jo trochgean?",
   "confirmations.unfollow.confirm": "Net mear folgje",
   "confirmations.unfollow.message": "Bisto wis datsto {name} net mear folgje wolst?",
   "conversation.delete": "Petear fuortsmite",
@@ -182,16 +183,16 @@
   "directory.local": "Allinnich fan {domain}",
   "directory.new_arrivals": "Nije accounts",
   "directory.recently_active": "Resint aktyf",
-  "disabled_account_banner.account_settings": "Account settings",
-  "disabled_account_banner.text": "Your account {disabledAccount} is currently disabled.",
-  "dismissable_banner.community_timeline": "These are the most recent public posts from people whose accounts are hosted by {domain}.",
+  "disabled_account_banner.account_settings": "Accountynstellingen",
+  "disabled_account_banner.text": "Jo account {disabledAccount} is op dit stuit útskeakele.",
+  "dismissable_banner.community_timeline": "Dit binne de meast resinte iepenbiere berjochten fan accounts op {domain}.",
   "dismissable_banner.dismiss": "Slute",
-  "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
-  "dismissable_banner.explore_statuses": "These posts from this and other servers in the decentralized network are gaining traction on this server right now.",
-  "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
-  "dismissable_banner.public_timeline": "These are the most recent public posts from people on this and other servers of the decentralized network that this server knows about.",
+  "dismissable_banner.explore_links": "Dizze nijsberjochten winne oan populariteit op dizze en oare servers binnen it desintrale netwurk.",
+  "dismissable_banner.explore_statuses": "Dizze berjochten winne oan populariteit op dizze en oare servers binnen it desintrale netwurk.",
+  "dismissable_banner.explore_tags": "Dizze hashtags winne oan populariteit op dizze en oare servers binnen it desintrale netwurk.",
+  "dismissable_banner.public_timeline": "Dit binne de meast resinte iepenbiere berjochten fan accounts op dizze en oare servers binnen it desintrale netwurk. Jo kinne ûnder ‘Ynstellingen > Foarkarren > Oars’ kieze hokker talen jo sjen wolle.",
   "embed.instructions": "Embed this status on your website by copying the code below.",
-  "embed.preview": "Here is what it will look like:",
+  "embed.preview": "Sa komt it der út te sjen:",
   "emoji_button.activity": "Aktiviteiten",
   "emoji_button.clear": "Wiskje",
   "emoji_button.custom": "Oanpast",
@@ -199,7 +200,7 @@
   "emoji_button.food": "Iten en drinken",
   "emoji_button.label": "Emoji tafoegje",
   "emoji_button.nature": "Natuer",
-  "emoji_button.not_found": "No matching emojis found",
+  "emoji_button.not_found": "Gjin oerienkommende emoji fûn",
   "emoji_button.objects": "Objekten",
   "emoji_button.people": "Minsken",
   "emoji_button.recent": "Faaks brûkt",
@@ -211,41 +212,45 @@
   "empty_column.account_timeline": "Hjir binne gjin berjochten!",
   "empty_column.account_unavailable": "Profyl net beskikber",
   "empty_column.blocks": "Do hast noch gjin brûkers blokkearre.",
-  "empty_column.bookmarked_statuses": "You don't have any bookmarked posts yet. When you bookmark one, it will show up here.",
-  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
-  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.bookmarked_statuses": "Jo hawwe noch gjin berjochten oan jo blêdwizers tafoege. Wannear’t jo der ien oan jo blêdwizers tafoegje, falt dizze hjir te sjen.",
+  "empty_column.community": "De lokale tiidline is noch leech. Pleats in iepenbier berjocht om de spits ôf te biten!",
+  "empty_column.direct": "Jo hawwe noch gjin direkte berjochten. Wannear’t jo der ien ferstjoere of ûntfang, komt dizze hjir te stean.",
   "empty_column.domain_blocks": "Der binne noch gjin blokkearre domeinen.",
-  "empty_column.explore_statuses": "Nothing is trending right now. Check back later!",
-  "empty_column.favourited_statuses": "You don't have any favourite posts yet. When you favourite one, it will show up here.",
-  "empty_column.favourites": "No one has favourited this post yet. When someone does, they will show up here.",
-  "empty_column.follow_recommendations": "Looks like no suggestions could be generated for you. You can try using search to look for people you might know or explore trending hashtags.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
-  "empty_column.hashtag": "There is nothing in this hashtag yet.",
-  "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
+  "empty_column.explore_statuses": "Op dit stuit binne der gjin trends. Kom letter werom!",
+  "empty_column.favourited_statuses": "Jo hawwe noch gjin favorite berjochten. Wannear’t jo ien as favoryt markearje, falt dizze hjir te sjen.",
+  "empty_column.favourites": "Net ien hat dit berjocht noch as favoryt markearre. Wannear’t ien dit docht, falt dat hjir te sjen.",
+  "empty_column.follow_recommendations": "It liket der op dat der gjin oanrekommandaasjes foar jo oanmakke wurde kinne. Jo kinne probearje te sykjen nei minsken dy’t jo miskien kinne, sykje op hashtags, de lokale en globale tiidlinen besjen of de brûkersgids trochblêdzje.",
+  "empty_column.follow_requests": "Jo hawwe noch gjin folchfersiken ûntfongen. Wannear’t jo der ien ûntfange, falt dat hjir te sjen.",
+  "empty_column.hashtag": "Der is noch neat te finen ûnder dizze hashtag.",
+  "empty_column.home": "Dizze tiidline is leech! Folgje mear minsken om it te foljen. {suggestions}",
   "empty_column.home.suggestions": "Suggestjes besjen",
   "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
-  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
-  "empty_column.mutes": "Do hast noch gjin brûkers negearre.",
+  "empty_column.lists": "Jo hawwe noch gjin inkelde list. Wannear’t jo der ien oanmakke hawwe, falt dat hjir te sjen.",
+  "empty_column.mutes": "Jo hawwe noch gjin brûkers negearre.",
   "empty_column.notifications": "Do hast noch gjin meldingen. Ynteraksjes mei oare minsken sjochsto hjir.",
   "empty_column.public": "Der is hjir neat! Skriuw eat publyklik, of folgje sels brûkers fan oare servers om it hjir te foljen",
   "error.unexpected_crash.explanation": "Troch in bug in ús koade of in probleem mei de komptabiliteit fan jo browser, koe dizze side net toand wurde.",
   "error.unexpected_crash.explanation_addons": "Dizze side kin net goed toand wurde. Dit probleem komt faaks troch in browserútwreiding of ark foar automatysk oersetten.",
-  "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
-  "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
-  "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
+  "error.unexpected_crash.next_steps": "Probearje dizze side te fernijen. Wannear’t dit net helpt is it noch hieltyd mooglik om Mastodon yn in oare browser of mobile app te brûken.",
+  "error.unexpected_crash.next_steps_addons": "Probearje dizze út te skeakeljen en de side te fernijen. Wannear’t dit net helpt is it noch hieltyd mooglik om Mastodon yn in oare browser of mobile app te brûken.",
+  "errors.unexpected_crash.copy_stacktrace": "Stacktrace nei klamboerd kopiearje",
   "errors.unexpected_crash.report_issue": "Technysk probleem melde",
   "explore.search_results": "Sykresultaten",
+  "explore.suggested_follows": "Foar jo",
   "explore.title": "Ferkenne",
-  "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
-  "filter_modal.added.context_mismatch_title": "Context mismatch!",
-  "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
-  "filter_modal.added.expired_title": "Expired filter!",
-  "filter_modal.added.review_and_configure": "To review and further configure this filter category, go to the {settings_link}.",
+  "explore.trending_links": "Nijs",
+  "explore.trending_statuses": "Berjochten",
+  "explore.trending_tags": "Hashtags",
+  "filter_modal.added.context_mismatch_explanation": "Dizze filterkategory is net fan tapassing op de kontekst wêryn jo dit berjocht benadere hawwe. As jo wolle dat it berjocht ek yn dizze kontekst filtere wurdt, moatte jo it filter bewurkje.",
+  "filter_modal.added.context_mismatch_title": "Kontekst komt net oerien!",
+  "filter_modal.added.expired_explanation": "Dizze filterkategory is ferrûn. Jo moatte de ferrindatum wizigje om de kategory tapasse te kinnen.",
+  "filter_modal.added.expired_title": "Filter ferrûn!",
+  "filter_modal.added.review_and_configure": "Gean nei {settings_link} om dizze filterkategory opnij te besjen en fierder te konfigurearjen.",
   "filter_modal.added.review_and_configure_title": "Filterynstellingen",
   "filter_modal.added.settings_link": "ynstellingenside",
-  "filter_modal.added.short_explanation": "This post has been added to the following filter category: {title}.",
+  "filter_modal.added.short_explanation": "Dit berjocht is tafoege oan de folgjende filterkategory: {title}.",
   "filter_modal.added.title": "Filter tafoege!",
-  "filter_modal.select_filter.context_mismatch": "does not apply to this context",
+  "filter_modal.select_filter.context_mismatch": "is net fan tapassing op dizze kontekst",
   "filter_modal.select_filter.expired": "ferrûn",
   "filter_modal.select_filter.prompt_new": "Nije kategory: {name}",
   "filter_modal.select_filter.search": "Sykje of tafoegje",
@@ -253,11 +258,11 @@
   "filter_modal.select_filter.title": "Dit berjocht filterje",
   "filter_modal.title.status": "In berjocht filterje",
   "follow_recommendations.done": "Klear",
-  "follow_recommendations.heading": "Folgje minsken dêr’tsto graach berjochten fan sjen wolst! Hjir binne wat suggestjes.",
-  "follow_recommendations.lead": "Posts from people you follow will show up in chronological order on your home feed. Don't be afraid to make mistakes, you can unfollow people just as easily any time!",
+  "follow_recommendations.heading": "Folgje minsken dêr’t jo graach berjochten fan sjen wolle! Hjir binne wat suggestjes.",
+  "follow_recommendations.lead": "Berjochten fan minsken dy’t jo folgje sille yn gronologyske folchoarder op jo starttiidline ferskine. Wês net bang om hjiryn flaters te meitsjen, want jo kinne minsken op elk momint krekt sa ienfâldich ûntfolgje!",
   "follow_request.authorize": "Goedkarre",
   "follow_request.reject": "Wegerje",
-  "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "follow_requests.unlocked_explanation": "Ek al is jo account net besletten, de meiwurkers fan {domain} tinke dat jo miskien de folgjende folchfersiken hânmjittich kontrolearje.",
   "footer.about": "Oer",
   "footer.directory": "Profylmap",
   "footer.get_app": "App downloade",
@@ -270,41 +275,41 @@
   "hashtag.column_header.tag_mode.all": "en {additional}",
   "hashtag.column_header.tag_mode.any": "of {additional}",
   "hashtag.column_header.tag_mode.none": "sûnder {additional}",
-  "hashtag.column_settings.select.no_options_message": "No suggestions found",
-  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.select.no_options_message": "Gjin suggestjes fûn",
+  "hashtag.column_settings.select.placeholder": "Folje hashtags yn…",
+  "hashtag.column_settings.tag_mode.all": "Allegearre",
+  "hashtag.column_settings.tag_mode.any": "Ien fan dizze",
+  "hashtag.column_settings.tag_mode.none": "Gjin fan dizze",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
-  "hashtag.follow": "Follow hashtag",
-  "hashtag.unfollow": "Unfollow hashtag",
+  "hashtag.follow": "Hashtag folgje",
+  "hashtag.unfollow": "Hashtag ûntfolgje",
   "home.column_settings.basic": "Algemien",
   "home.column_settings.show_reblogs": "Boosts toane",
   "home.column_settings.show_replies": "Reaksjes toane",
   "home.hide_announcements": "Meidielingen ferstopje",
   "home.show_announcements": "Meidielingen toane",
-  "interaction_modal.description.favourite": "With an account on Mastodon, you can favourite this post to let the author know you appreciate it and save it for later.",
-  "interaction_modal.description.follow": "With an account on Mastodon, you can follow {name} to receive their posts in your home feed.",
-  "interaction_modal.description.reblog": "With an account on Mastodon, you can boost this post to share it with your own followers.",
-  "interaction_modal.description.reply": "With an account on Mastodon, you can respond to this post.",
-  "interaction_modal.on_another_server": "On a different server",
+  "interaction_modal.description.favourite": "Jo kinne mei in Mastodon-account dit berjocht as favoryt markearje, om dy brûker witte te litten dat jo it berjocht wurdearje en om it te bewarjen.",
+  "interaction_modal.description.follow": "Jo kinne mei in Mastodon-account {name} folgje, om sa harren berjochten op jo starttiidline te ûntfangen.",
+  "interaction_modal.description.reblog": "Jo kinne mei in Mastodon-account dit berjocht booste, om it sa mei jo folgers te dielen.",
+  "interaction_modal.description.reply": "Jo kinne mei in Mastodon-account op dit berjocht reagearje.",
+  "interaction_modal.on_another_server": "Op een oare server",
   "interaction_modal.on_this_server": "Op dizze server",
-  "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favourite Mastodon app or the web interface of your Mastodon server.",
-  "interaction_modal.preamble": "Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.",
-  "interaction_modal.title.favourite": "Favourite {name}'s post",
+  "interaction_modal.other_server_instructions": "Kopiearje en plak ienfâldich dizze URL yn it sykfjild fan de troch jo brûkte Mastodon-app of op de website fan de Mastodon-server wêrop jo oanmeld binne.",
+  "interaction_modal.preamble": "Mastodon is desintralisearre. Dêrom hawwe jo gjin account op dizze Mastodon-server nedich, wannear’t jo al in account op in oare Mastodon-server of kompatibel platfoarm hawwe.",
+  "interaction_modal.title.favourite": "Berjocht fan {name} as favoryt markearje",
   "interaction_modal.title.follow": "{name} folgje",
-  "interaction_modal.title.reblog": "Boost {name}'s post",
-  "interaction_modal.title.reply": "Reply to {name}'s post",
-  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
-  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
-  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "interaction_modal.title.reblog": "Berjocht fan {name} booste",
+  "interaction_modal.title.reply": "Op it berjocht fan {name} reagearje",
+  "intervals.full.days": "{number, plural, one {# dei} other {# dagen}} lyn",
+  "intervals.full.hours": "{number, plural, one {# oere} other {# oeren}} lyn",
+  "intervals.full.minutes": "{number, plural, one {# minút} other {# minuten}} lyn",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.blocked": "to open blocked users list",
   "keyboard_shortcuts.boost": "Berjocht booste",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
   "keyboard_shortcuts.compose": "to focus the compose textarea",
   "keyboard_shortcuts.description": "Omskriuwing",
-  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.direct": "Direkte berjochten toane",
   "keyboard_shortcuts.down": "to move down in the list",
   "keyboard_shortcuts.enter": "Berjocht iepenje",
   "keyboard_shortcuts.favourite": "As favoryt markearje",
@@ -333,38 +338,38 @@
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "Nei boppe yn list ferpleatse",
   "lightbox.close": "Slute",
-  "lightbox.compress": "Compress image view box",
-  "lightbox.expand": "Expand image view box",
+  "lightbox.compress": "Ofbylding passend werjaan",
+  "lightbox.expand": "Ofbylding grut werjaan",
   "lightbox.next": "Folgjende",
   "lightbox.previous": "Foarige",
   "limited_account_hint.action": "Profyl dochs besjen",
-  "limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
+  "limited_account_hint.title": "Dit profyl is troch de behearders fan {domain} ferstoppe.",
   "lists.account.add": "Oan list tafoegje",
   "lists.account.remove": "Ut list fuortsmite",
   "lists.delete": "List fuortsmite",
-  "lists.edit": "Edit list",
+  "lists.edit": "List bewurkje",
   "lists.edit.submit": "Titel wizigje",
-  "lists.new.create": "Add list",
+  "lists.new.create": "List tafoegje",
   "lists.new.title_placeholder": "Nije listtitel",
   "lists.replies_policy.followed": "Elke folge brûker",
   "lists.replies_policy.list": "Leden fan de list",
   "lists.replies_policy.none": "Net ien",
   "lists.replies_policy.title": "Reaksjes toane oan:",
-  "lists.search": "Search among people you follow",
-  "lists.subheading": "Dyn listen",
-  "load_pending": "{count, plural, one {# new item} other {# new items}}",
-  "loading_indicator.label": "Loading...",
-  "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}",
+  "lists.search": "Sykje nei minsken dy’t jo folgje",
+  "lists.subheading": "Jo listen",
+  "load_pending": "{count, plural, one {# nij item} other {# nije items}}",
+  "loading_indicator.label": "Lade…",
+  "media_gallery.toggle_visible": "{number, plural, one {ôfbylding ferstopje} other {ôfbyldingen ferstopje}}",
   "missing_indicator.label": "Net fûn",
-  "missing_indicator.sublabel": "This resource could not be found",
-  "moved_to_account_banner.text": "Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.",
-  "mute_modal.duration": "Duration",
+  "missing_indicator.sublabel": "Dizze boarne kin net fûn wurde",
+  "moved_to_account_banner.text": "Omdat jo nei {movedToAccount} ferhuze binne is jo account {disabledAccount} op dit stuit útskeakele.",
+  "mute_modal.duration": "Doer",
   "mute_modal.hide_notifications": "Meldingen fan dizze brûker ferstopje?",
-  "mute_modal.indefinite": "Indefinite",
-  "navigation_bar.about": "About",
+  "mute_modal.indefinite": "Foar ûnbepaalde tiid",
+  "navigation_bar.about": "Oer",
   "navigation_bar.blocks": "Blokkearre brûkers",
   "navigation_bar.bookmarks": "Blêdwizers",
-  "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.community_timeline": "Lokale tiidline",
   "navigation_bar.compose": "Nij berjocht skriuwe",
   "navigation_bar.direct": "Direkte berjochten",
   "navigation_bar.discover": "Untdekke",
@@ -387,13 +392,13 @@
   "not_signed_in_indicator.not_signed_in": "Do moatst oanmelde om tagong ta dizze ynformaasje te krijen.",
   "notification.admin.report": "{name} hat {target} rapportearre",
   "notification.admin.sign_up": "{name} hat harren registrearre",
-  "notification.favourite": "{name} hat dyn berjocht as favoryt markearre",
+  "notification.favourite": "{name} hat jo berjocht as favoryt markearre",
   "notification.follow": "{name} folget dy",
   "notification.follow_request": "{name} hat dy in folchfersyk stjoerd",
   "notification.mention": "{name} hat dy fermeld",
   "notification.own_poll": "Dyn poll is beëinige",
-  "notification.poll": "In poll wêr’tsto yn stimd hast is beëinige",
-  "notification.reblog": "{name} hat dyn berjocht boost",
+  "notification.poll": "In enkête dêr’t jo yn stimd hawwe is beëinige",
+  "notification.reblog": "{name} hat jo berjocht boost",
   "notification.status": "{name} hat in berjocht pleatst",
   "notification.update": "{name} hat in berjocht bewurke",
   "notifications.clear": "Meldingen wiskje",
@@ -408,7 +413,7 @@
   "notifications.column_settings.follow": "Nije folgers:",
   "notifications.column_settings.follow_request": "Nij folchfersyk:",
   "notifications.column_settings.mention": "Fermeldingen:",
-  "notifications.column_settings.poll": "Pollresultaten:",
+  "notifications.column_settings.poll": "Enkêteresultaten:",
   "notifications.column_settings.push": "Pushmeldingen",
   "notifications.column_settings.reblog": "Boosts:",
   "notifications.column_settings.show": "Yn kolom toane",
@@ -423,26 +428,26 @@
   "notifications.filter.follows": "Folget",
   "notifications.filter.mentions": "Fermeldingen",
   "notifications.filter.polls": "Pollresultaten",
-  "notifications.filter.statuses": "Updates from people you follow",
-  "notifications.grant_permission": "Grant permission.",
-  "notifications.group": "{count} notifications",
-  "notifications.mark_as_read": "Mark every notification as read",
-  "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request",
-  "notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before",
-  "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.",
-  "notifications_permission_banner.enable": "Enable desktop notifications",
-  "notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.",
-  "notifications_permission_banner.title": "Never miss a thing",
-  "picture_in_picture.restore": "Put it back",
+  "notifications.filter.statuses": "Fernijingen fan minsken dy’t jo folgje",
+  "notifications.grant_permission": "Tastimming jaan.",
+  "notifications.group": "{count} meldingen",
+  "notifications.mark_as_read": "Alle meldingen as lêzen markearje",
+  "notifications.permission_denied": "Desktopmeldingen binne net beskikber, omdat in eardere browsertastimming wegere waard",
+  "notifications.permission_denied_alert": "Desktopmeldingen kinne net ynskeakele wurde, omdat in eardere browsertastimming wegere waard",
+  "notifications.permission_required": "Desktopmeldingen binne net beskikber, omdat de nedige tastimming net ferliend is.",
+  "notifications_permission_banner.enable": "Desktopmeldingen ynskeakelje",
+  "notifications_permission_banner.how_to_control": "Om meldingen te ûntfangen wannear’t Mastodon net iepen stiet. Jo kinne krekt bepale hokker soarte fan ynteraksjes wol of gjin desktopmeldingen jouwe fia de boppesteande {icon} knop.",
+  "notifications_permission_banner.title": "Mis neat",
+  "picture_in_picture.restore": "Tebeksette",
   "poll.closed": "Sluten",
   "poll.refresh": "Ferfarskje",
   "poll.total_people": "{count, plural, one {# persoan} other {# persoanen}}",
   "poll.total_votes": "{count, plural, one {# stim} other {# stimmen}}",
   "poll.vote": "Stimme",
-  "poll.voted": "Do hast hjir op stimd",
+  "poll.voted": "Jo hawwe hjir op stimd",
   "poll.votes": "{votes, plural, one {# stim} other {# stimmen}}",
   "poll_button.add_poll": "Poll tafoegje",
-  "poll_button.remove_poll": "Poll fuortsmite",
+  "poll_button.remove_poll": "Enkête fuortsmite",
   "privacy.change": "Sichtberheid fan berjocht oanpasse",
   "privacy.direct.long": "Allinnich sichtber foar fermelde brûkers",
   "privacy.direct.short": "Allinnich fermelde minsken",
@@ -450,13 +455,13 @@
   "privacy.private.short": "Allinnich folgers",
   "privacy.public.long": "Sichtber foar elkenien",
   "privacy.public.short": "Iepenbier",
-  "privacy.unlisted.long": "Visible for all, but opted-out of discovery features",
-  "privacy.unlisted.short": "Unlisted",
-  "privacy_policy.last_updated": "Last updated {date}",
-  "privacy_policy.title": "Privacy Policy",
-  "refresh": "Fernije",
+  "privacy.unlisted.long": "Foar elkenien sichtber, mar net ûnder trends, hashtags en op iepenbiere tiidlinen",
+  "privacy.unlisted.short": "Minder iepenbier",
+  "privacy_policy.last_updated": "Lêst bywurke op {date}",
+  "privacy_policy.title": "Privacybelied",
+  "refresh": "Ferfarskje",
   "regeneration_indicator.label": "Lade…",
-  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
+  "regeneration_indicator.sublabel": "Jo starttiidline wurdt oanmakke!",
   "relative_time.days": "{number}d",
   "relative_time.full.days": "{number, plural, one {# dei} other {# dagen}} lyn",
   "relative_time.full.hours": "{number, plural, one {# oere} other {# oeren}} lyn",
@@ -470,7 +475,7 @@
   "relative_time.today": "hjoed",
   "reply_indicator.cancel": "Annulearje",
   "report.block": "Blokkearje",
-  "report.block_explanation": "Do silst harren berjochten net sjen kinne. Se sille dyn berjochten net sjen kinne en do net folgje kinne. Se sille wol sjen kinne dat se blokkearre binne.",
+  "report.block_explanation": "Jo sille harren berjochten net sjen kinne. Se sille jo berjochten net sjen kinne en jo net folgje kinne. Se sille wol sjen kinne dat se blokkearre binne.",
   "report.categories.other": "Oars",
   "report.categories.spam": "Spam",
   "report.categories.violation": "De ynhâld oertrêdet ien of mear serverrigels",
@@ -481,71 +486,72 @@
   "report.close": "Klear",
   "report.comment.title": "Tinksto dat wy noch mear witte moatte?",
   "report.forward": "Nei {target} trochstjoere",
-  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.forward_hint": "De account stiet op in oare server. Wolle jo dêr ek in anonimisearre kopy fan dizze rapportaazje nei ta stjoere?",
   "report.mute": "Negearje",
-  "report.mute_explanation": "You will not see their posts. They can still follow you and see your posts and will not know that they are muted.",
+  "report.mute_explanation": "Jo kinne harren berjochten net sjen. Jo kinne noch wol folge wurde en jo berjochten binne noch sichtber, mar dyjinge kin net sjen dat dy negearre wurdt.",
   "report.next": "Folgjende",
   "report.placeholder": "Type or paste additional comments",
   "report.reasons.dislike": "Ik fyn der neat oan",
   "report.reasons.dislike_description": "It is net eat watsto sjen wolst",
   "report.reasons.other": "It is wat oars",
   "report.reasons.other_description": "It probleem stiet der net tusken",
-  "report.reasons.spam": "It's spam",
-  "report.reasons.spam_description": "Malicious links, fake engagement, or repetitive replies",
-  "report.reasons.violation": "It violates server rules",
-  "report.reasons.violation_description": "You are aware that it breaks specific rules",
-  "report.rules.subtitle": "Select all that apply",
-  "report.rules.title": "Which rules are being violated?",
-  "report.statuses.subtitle": "Select all that apply",
-  "report.statuses.title": "Are there any posts that back up this report?",
+  "report.reasons.spam": "It is spam",
+  "report.reasons.spam_description": "Skeadlike keppelingen, reklame, mislieding of werheljende antwurden",
+  "report.reasons.violation": "It skeint de serverregels",
+  "report.reasons.violation_description": "Jo witte dat it spesifike regels skeint",
+  "report.rules.subtitle": "Selektearje wat fan tapassing is",
+  "report.rules.title": "Hokker regels wurde skeind?",
+  "report.statuses.subtitle": "Selektearje wat fan tapassing is",
+  "report.statuses.title": "Binne der berjochten dy’t dizze rapportaazje stypje?",
   "report.submit": "Submit report",
   "report.target": "Report {target}",
-  "report.thanks.take_action": "Here are your options for controlling what you see on Mastodon:",
-  "report.thanks.take_action_actionable": "While we review this, you can take action against @{name}:",
-  "report.thanks.title": "Don't want to see this?",
-  "report.thanks.title_actionable": "Thanks for reporting, we'll look into this.",
-  "report.unfollow": "Unfollow @{name}",
-  "report.unfollow_explanation": "You are following this account. To not see their posts in your home feed anymore, unfollow them.",
-  "report_notification.attached_statuses": "{count, plural, one {{count} post} other {{count} posts}} attached",
-  "report_notification.categories.other": "Other",
+  "report.thanks.take_action": "Hjir binne jo opsjes wêrmei’t jo bepale kinne wat jo yn Mastodon sjen wolle:",
+  "report.thanks.take_action_actionable": "Wylst wy jo rapportaazje beoardiele, kinne jo dizze maatregels tsjin @{name} nimme:",
+  "report.thanks.title": "Wolle jo dit net sjen?",
+  "report.thanks.title_actionable": "Tank foar it rapportearjen. Wy sille der nei sjen.",
+  "report.unfollow": "{name} ûntfolgje",
+  "report.unfollow_explanation": "Jo folgje dizze account. Om harren berjochten net mear op jo starttiidline te sjen, kinne jo dyjinge ûntfolgje.",
+  "report_notification.attached_statuses": "{count, plural, one {{count} berjocht} other {{count} berjochten}} tafoege",
+  "report_notification.categories.other": "Oars",
   "report_notification.categories.spam": "Spam",
-  "report_notification.categories.violation": "Rule violation",
-  "report_notification.open": "Open report",
-  "search.placeholder": "Search",
-  "search.search_or_paste": "Search or paste URL",
-  "search_popout.search_format": "Advanced search format",
+  "report_notification.categories.violation": "Skeinde regels",
+  "report_notification.open": "Rapport iepenje",
+  "search.placeholder": "Sykje",
+  "search.search_or_paste": "Sykje of fier URL yn",
+  "search_popout.search_format": "Avansearre sykje",
   "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
   "search_popout.tips.hashtag": "hashtag",
   "search_popout.tips.status": "status",
-  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
-  "search_popout.tips.user": "user",
-  "search_results.accounts": "People",
-  "search_results.all": "All",
+  "search_popout.tips.text": "Brûk gewoane tekst om te sykjen op werjeftenammen, brûkersnammen en hashtags",
+  "search_popout.tips.user": "brûker",
+  "search_results.accounts": "Minsken",
+  "search_results.all": "Alles",
   "search_results.hashtags": "Hashtags",
-  "search_results.nothing_found": "Could not find anything for these search terms",
+  "search_results.nothing_found": "Dizze syktermen leverje gjin resultaat op",
   "search_results.statuses": "Berjochten",
-  "search_results.statuses_fts_disabled": "Searching posts by their content is not enabled on this Mastodon server.",
+  "search_results.statuses_fts_disabled": "It sykjen yn berjochten is op dizze Mastodon-server net ynskeakele.",
   "search_results.title": "Nei {q} sykje",
-  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
-  "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)",
+  "search_results.total": "{count, number} {count, plural, one {resultaat} other {resultaten}}",
+  "server_banner.about_active_users": "Oantal brûkers yn de ôfrûne 30 dagen (MAU)",
   "server_banner.active_users": "warbere brûkers",
   "server_banner.administered_by": "Beheard troch:",
-  "server_banner.introduction": "{domain} is part of the decentralized social network powered by {mastodon}.",
+  "server_banner.introduction": "{domain} is ûnderdiel fan it desintralisearre sosjale netwurk {mastodon}.",
   "server_banner.learn_more": "Mear ynfo",
   "server_banner.server_stats": "Serverstatistiken:",
   "sign_in_banner.create_account": "Account registrearje",
   "sign_in_banner.sign_in": "Oanmelde",
-  "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
-  "status.admin_account": "Open moderation interface for @{name}",
+  "sign_in_banner.text": "Wannear’t jo in account op dizze server hawwe, kinne jo oanmelde om minsken of hashtags te folgjen, op berjochten te reagearjen of om dizze te dielen. Wannear’t jo in account op in oare server hawwe, kinne jo dêr oanmelde en dêr ynteraksje mei minsken op dizze server hawwe.",
+  "status.admin_account": "Moderaasje-omjouwing fan @{name} iepenje",
+  "status.admin_domain": "Moderaasje-omjouwing fan {domain} iepenje",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "@{name} blokkearje",
   "status.bookmark": "Blêdwizer tafoegje",
   "status.cancel_reblog_private": "Net langer booste",
-  "status.cannot_reblog": "This post cannot be boosted",
+  "status.cannot_reblog": "Dit berjocht kin net boost wurde",
   "status.copy": "Copy link to status",
   "status.delete": "Fuortsmite",
   "status.detailed_status": "Detaillearre petearoersjoch",
-  "status.direct": "Direct message @{name}",
+  "status.direct": "@{name} in direkt berjocht stjoere",
   "status.edit": "Bewurkje",
   "status.edited": "Bewurke op {date}",
   "status.edited_x_times": "{count, plural, one {{count} kear} other {{count} kearen}} bewurke",
@@ -567,9 +573,9 @@
   "status.pinned": "Fêstset berjocht",
   "status.read_more": "Mear ynfo",
   "status.reblog": "Booste",
-  "status.reblog_private": "Boost with original visibility",
+  "status.reblog_private": "Boost nei oarspronklike ûntfangers",
   "status.reblogged_by": "{name} hat boost",
-  "status.reblogs.empty": "No one has boosted this post yet. When someone does, they will show up here.",
+  "status.reblogs.empty": "Net ien hat dit berjocht noch boost. Wannear’t ien dit docht, falt dat hjir te sjen.",
   "status.redraft": "Fuortsmite en opnij opstelle",
   "status.remove_bookmark": "Blêdwizer fuortsmite",
   "status.replied_to": "Antwurde op {name}",
@@ -589,12 +595,12 @@
   "status.uncached_media_warning": "Net beskikber",
   "status.unmute_conversation": "Petear net mear negearje",
   "status.unpin": "Fan profylside losmeitsje",
-  "subscribed_languages.lead": "Only posts in selected languages will appear on your home and list timelines after the change. Select none to receive posts in all languages.",
-  "subscribed_languages.save": "Save changes",
-  "subscribed_languages.target": "Change subscribed languages for {target}",
-  "suggestions.dismiss": "Dismiss suggestion",
-  "suggestions.header": "You might be interested in…",
-  "tabs_bar.federated_timeline": "Federated",
+  "subscribed_languages.lead": "Nei de wiziging wurde allinnich berjochten fan selektearre talen op jo starttiidline en yn listen werjaan.",
+  "subscribed_languages.save": "Wizigingen bewarje",
+  "subscribed_languages.target": "Toande talen foar {target} wizigje",
+  "suggestions.dismiss": "Oanrekommandaasje ferwerpe",
+  "suggestions.header": "Jo binne wierskynlik ek ynteressearre yn…",
+  "tabs_bar.federated_timeline": "Globaal",
   "tabs_bar.home": "Startside",
   "tabs_bar.local_timeline": "Lokaal",
   "tabs_bar.notifications": "Meldingen",
@@ -609,37 +615,37 @@
   "timeline_hint.resources.statuses": "Aldere berjochten",
   "trends.counter_by_accounts": "{count, plural, one {{counter} persoan} other {{counter} persoanen}} {days, plural, one {de ôfrûne dei} other {de ôfrûne {days} dagen}}",
   "trends.trending_now": "Aktuele trends",
-  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
-  "units.short.billion": "{count}B",
-  "units.short.million": "{count}M",
-  "units.short.thousand": "{count}K",
-  "upload_area.title": "Drag & drop to upload",
-  "upload_button.label": "Add images, a video or an audio file",
-  "upload_error.limit": "File upload limit exceeded.",
-  "upload_error.poll": "File upload not allowed with polls.",
+  "ui.beforeunload": "Jo konsept giet ferlern wannear’t jo Mastodon ferlitte.",
+  "units.short.billion": "{count} mrd.",
+  "units.short.million": "{count} mln.",
+  "units.short.thousand": "{count}k",
+  "upload_area.title": "Hjir nei ta slepe om op te laden",
+  "upload_button.label": "Ofbyldingen, in fideo- of in lûdsbestân tafoegje",
+  "upload_error.limit": "Oer de oplaadlimyt fan bestân.",
+  "upload_error.poll": "It opladen fan bestannen is yn enkêten net tastien.",
   "upload_form.audio_description": "Describe for people with hearing loss",
   "upload_form.description": "Describe for the visually impaired",
-  "upload_form.description_missing": "No description added",
-  "upload_form.edit": "Edit",
-  "upload_form.thumbnail": "Change thumbnail",
-  "upload_form.undo": "Delete",
+  "upload_form.description_missing": "Gjin omskriuwing tafoege",
+  "upload_form.edit": "Bewurkje",
+  "upload_form.thumbnail": "Miniatuerôfbylding wizigje",
+  "upload_form.undo": "Fuortsmite",
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
-  "upload_modal.analyzing_picture": "Analyzing picture…",
-  "upload_modal.apply": "Apply",
-  "upload_modal.applying": "Applying…",
-  "upload_modal.choose_image": "Choose image",
-  "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
-  "upload_modal.detect_text": "Detect text from picture",
-  "upload_modal.edit_media": "Edit media",
-  "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
-  "upload_modal.preparing_ocr": "Preparing OCR…",
-  "upload_modal.preview_label": "Preview ({ratio})",
+  "upload_modal.analyzing_picture": "Ofbylding analysearje…",
+  "upload_modal.apply": "Tapasse",
+  "upload_modal.applying": "Oan it tapassen…",
+  "upload_modal.choose_image": "Kies in ôfbylding",
+  "upload_modal.description_placeholder": "Heit syn wize foks ljept tûk oar de loaie hûn",
+  "upload_modal.detect_text": "Tekst yn in ôfbylding detektearje",
+  "upload_modal.edit_media": "Media bewurkje",
+  "upload_modal.hint": "Klik of sleep de sirkel yn de foarfertoaning nei in sintraal fokuspunt dat op elke thumbnail sichtber bliuwe moat.",
+  "upload_modal.preparing_ocr": "OCR tariede…",
+  "upload_modal.preview_label": "Foarfertoaning ({ratio})",
   "upload_progress.label": "Uploading…",
-  "upload_progress.processing": "Processing…",
-  "video.close": "Close video",
-  "video.download": "Download file",
-  "video.exit_fullscreen": "Exit full screen",
-  "video.expand": "Expand video",
+  "upload_progress.processing": "Dwaande…",
+  "video.close": "Fideo slute",
+  "video.download": "Bestân downloade",
+  "video.exit_fullscreen": "Folslein skerm slute",
+  "video.expand": "Fideo grutter meitsje",
   "video.fullscreen": "Folslein skerm",
   "video.hide": "Fideo ferstopje",
   "video.mute": "Lûd dôvje",
diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json
index eac6d9dbc..b5e2fbd8c 100644
--- a/app/javascript/mastodon/locales/ga.json
+++ b/app/javascript/mastodon/locales/ga.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Postálacha agus freagraí",
   "account.report": "Tuairiscigh @{name}",
   "account.requested": "Ag fanacht le ceadú. Cliceáil chun an iarratas leanúnaí a chealú",
+  "account.requested_follow": "D'iarr {name} ort do chuntas a leanúint",
   "account.share": "Roinn próifíl @{name}",
   "account.show_reblogs": "Taispeáin moltaí ó @{name}",
   "account.statuses_counter": "{count, plural, one {Postáil amháin} other {{counter} Postáil}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Cuardaigh teangacha...",
   "compose_form.direct_message_warning_learn_more": "Tuilleadh eolais",
   "compose_form.encryption_warning": "Ní criptiú taobh-go-taobh déanta ar theachtaireachtaí ar Mhastodon. Ná roinn eolas íogair ar Mhastodon.",
-  "compose_form.hashtag_warning": "Ní áireofar an teachtaireacht seo faoi haischlib ar bith mar go bhfuil sí neamhliostaithe. Ní féidir ach teachtaireachtaí poiblí a chuardach de réir haischlib.",
+  "compose_form.hashtag_warning": "Ní áireofar an teachtaireacht seo faoi haischlib ar bith mar níl sí ar fáil don phobal. Ní féidir ach teachtaireachtaí poiblí a chuardach de réir haischlib.",
   "compose_form.lock_disclaimer": "Níl an cuntas seo {locked}. Féadfaidh duine ar bith tú a leanúint agus na postálacha atá dírithe agat ar do lucht leanúna amháin a fheiceáil.",
   "compose_form.lock_disclaimer.lock": "faoi ghlas",
   "compose_form.placeholder": "Cad atá ag tarlú?",
@@ -211,7 +212,7 @@
   "empty_column.account_timeline": "Níl postálacha ar bith anseo!",
   "empty_column.account_unavailable": "Níl an phróifíl ar fáil",
   "empty_column.blocks": "Níl aon úsáideoir bactha agat fós.",
-  "empty_column.bookmarked_statuses": "You don't have any bookmarked posts yet. When you bookmark one, it will show up here.",
+  "empty_column.bookmarked_statuses": "Níl aon phostáil leabharmharcaithe agat fós. Nuair a dhéanann tú leabharmharc, beidh sé le feiceáil anseo.",
   "empty_column.community": "Tá an amlíne áitiúil folamh. Foilsigh rud éigin go poiblí le tús a chur le cúrsaí!",
   "empty_column.direct": "Níl aon teachtaireacht dírithe agat fós. Nuair a sheolann tú nó nuair a fhaigheann tú ceann, feicfear anseo í.",
   "empty_column.domain_blocks": "Níl aon fearainn bhactha ann go fóill.",
@@ -219,23 +220,27 @@
   "empty_column.favourited_statuses": "Níor roghnaigh tú postáil ar bith fós. Nuair a roghnaigh tú ceann, beidh sí le feiceáil anseo.",
   "empty_column.favourites": "Níor thogh éinne an phostáil seo fós. Nuair a thoghfaidh duine éigin í, taispeánfar anseo é sin.",
   "empty_column.follow_recommendations": "Is cosúil nár fhéadfaí moltaí a ghineadh. D'fhéadfá cuardach a úsáid le teacht ar dhaoine a bhfuil aithne agat orthu, nó iniúchadh ar haischlibeanna atá ag treochtáil a dhéanamh.",
-  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
+  "empty_column.follow_requests": "Níl aon phostáil leabharmharcaithe agat fós. Nuair a dhéanann tú leabharmharc, feicfear anseo é.",
   "empty_column.hashtag": "Níl rud ar bith faoin haischlib seo go fóill.",
   "empty_column.home": "Tá d'amlíne baile folamh! B'fhiú duit cúpla duine eile a leanúint lena líonadh! {suggestions}",
   "empty_column.home.suggestions": "Féach ar roinnt moltaí",
   "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
-  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
+  "empty_column.lists": "Níl aon liostaí fós agat. Nuair a chruthaíonn tú ceann, feicfear anseo é.",
   "empty_column.mutes": "Níl aon úsáideoir balbhaithe agat fós.",
-  "empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.",
-  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
-  "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
-  "error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.",
+  "empty_column.notifications": "Níl aon fógraí agat fós. Nuair a dhéanann daoine eile idirghníomhú leat, feicfear anseo é.",
+  "empty_column.public": "Faic anseo! Scríobh rud éigin go poiblí, nó lean úsáideoirí ar fhreastalaithe eile chun é a líonadh",
+  "error.unexpected_crash.explanation": "De bharr fabht inár gcód, nó fadhb le chomhoiriúnacht brabhsálaí, níorbh fhéadfadh an leathanach seo a léiriú i gceart.",
+  "error.unexpected_crash.explanation_addons": "Ní taispeántar an leathanach seo mar is ceart. Is dócha go gcruthaíonn breiseán brabhsálaí nó uirlisí uathaistriúcháin an fhadhb seo.",
   "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
   "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Tuairiscigh deacracht",
   "explore.search_results": "Torthaí cuardaigh",
+  "explore.suggested_follows": "Duitse",
   "explore.title": "Féach thart",
+  "explore.trending_links": "Nuacht",
+  "explore.trending_statuses": "Postálacha",
+  "explore.trending_tags": "Haischlibeanna",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -533,10 +538,11 @@
   "server_banner.introduction": "{domain} is part of the decentralized social network powered by {mastodon}.",
   "server_banner.learn_more": "Tuilleadh eolais",
   "server_banner.server_stats": "Server stats:",
-  "sign_in_banner.create_account": "Create account",
+  "sign_in_banner.create_account": "Cruthaigh cuntas",
   "sign_in_banner.sign_in": "Sinigh isteach",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Bac @{name}",
   "status.bookmark": "Leabharmharcanna",
@@ -551,7 +557,7 @@
   "status.edited_x_times": "Curtha in eagar {count, plural, one {{count} uair amháin} two {{count} uair} few {{count} uair} many {{count} uair} other {{count} uair}}",
   "status.embed": "Leabaigh",
   "status.favourite": "Rogha",
-  "status.filter": "Filter this post",
+  "status.filter": "Déan scagadh ar an bpostáil seo",
   "status.filtered": "Filtered",
   "status.hide": "Cuir postáil i bhfolach",
   "status.history.created": "{name} created {date}",
@@ -564,7 +570,7 @@
   "status.mute_conversation": "Balbhaigh comhrá",
   "status.open": "Expand this status",
   "status.pin": "Pionnáil ar do phróifíl",
-  "status.pinned": "Pinned post",
+  "status.pinned": "Postáil pionnáilte",
   "status.read_more": "Léan a thuilleadh",
   "status.reblog": "Mol",
   "status.reblog_private": "Mol le léargas bunúsach",
@@ -626,7 +632,7 @@
   "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
   "upload_modal.analyzing_picture": "Ag anailísiú íomhá…",
   "upload_modal.apply": "Cuir i bhFeidhm",
-  "upload_modal.applying": "Applying…",
+  "upload_modal.applying": "Á gcur i bhfeidhm…",
   "upload_modal.choose_image": "Roghnaigh íomhá",
   "upload_modal.description_placeholder": "Chuaigh bé mhórsách le dlúthspád fíorfhinn trí hata mo dhea-phorcáin bhig",
   "upload_modal.detect_text": "Detect text from picture",
diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json
index 8aa06ffe7..995bb585d 100644
--- a/app/javascript/mastodon/locales/gd.json
+++ b/app/javascript/mastodon/locales/gd.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Postaichean ’s freagairtean",
   "account.report": "Dèan gearan mu @{name}",
   "account.requested": "A’ feitheamh air aontachadh. Briog airson sgur dhen iarrtas leantainn",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Co-roinn a’ phròifil aig @{name}",
   "account.show_reblogs": "Seall na brosnachaidhean o @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} phost} two {{counter} phost} few {{counter} postaichean} other {{counter} post}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Lorg cànan…",
   "compose_form.direct_message_warning_learn_more": "Barrachd fiosrachaidh",
   "compose_form.encryption_warning": "Chan eil crioptachadh ceann gu ceann air postaichean Mhastodon. Na co-roinn fiosrachadh dìomhair idir le Mastodon.",
-  "compose_form.hashtag_warning": "Cha nochd am post seo fon taga hais on a tha e falaichte o liostaichean. Cha ghabh ach postaichean poblach a lorg a-rèir an tagaichean hais.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Chan eil an cunntas agad {locked}. ’S urrainn do dhuine sam bith ’gad leantainn is na postaichean agad a tha ag amas air an luchd-leantainn agad a-mhàin a shealltainn.",
   "compose_form.lock_disclaimer.lock": "glaiste",
   "compose_form.placeholder": "Dè tha air d’ aire?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Cuir lethbhreac dhen stacktrace air an stòr-bhòrd",
   "errors.unexpected_crash.report_issue": "Dèan aithris air an duilgheadas",
   "explore.search_results": "Toraidhean an luirg",
+  "explore.suggested_follows": "For you",
   "explore.title": "Rùraich",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Chan eil an roinn-seòrsa criathraidh iom seo chaidh dhan cho-theacs san do dh’inntrig thu am post seo. Ma tha thu airson am post a chriathradh sa cho-theacs seo cuideachd, feumaidh tu a’ chriathrag a dheasachadh.",
   "filter_modal.added.context_mismatch_title": "Co-theacsa neo-iomchaidh!",
   "filter_modal.added.expired_explanation": "Dh’fhalbh an ùine air an roinn-seòrsa criathraidh seo agus feumaidh tu an ceann-là crìochnachaidh atharrachadh mus cuir thu an sàs i.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Clàraich a-steach",
   "sign_in_banner.text": "Clàraich a-steach a leantainn phròifilean no thagaichean hais, a’ cur postaichean ris na h-annsachdan ’s ’gan co-roinneadh is freagairt dhaibh no gabh gnìomh le cunntas o fhrithealaiche eile.",
   "status.admin_account": "Fosgail eadar-aghaidh na maorsainneachd dha @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Fosgail am post seo ann an eadar-aghaidh na maorsainneachd",
   "status.block": "Bac @{name}",
   "status.bookmark": "Cuir ris na comharran-lìn",
@@ -553,7 +559,7 @@
   "status.favourite": "Cuir ris na h-annsachdan",
   "status.filter": "Criathraich am post seo",
   "status.filtered": "Criathraichte",
-  "status.hide": "Falaich am post",
+  "status.hide": "Hide post",
   "status.history.created": "Chruthaich {name} {date} e",
   "status.history.edited": "Dheasaich {name} {date} e",
   "status.load_more": "Luchdaich barrachd dheth",
diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json
index 2e1f4684f..d430a5a8d 100644
--- a/app/javascript/mastodon/locales/gl.json
+++ b/app/javascript/mastodon/locales/gl.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Publicacións e respostas",
   "account.report": "Informar sobre @{name}",
   "account.requested": "Agardando aprobación. Preme para desbotar a solicitude",
+  "account.requested_follow": "{name} solicitou seguirte",
   "account.share": "Compartir o perfil de @{name}",
   "account.show_reblogs": "Amosar compartidos de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Publicación} other {{counter} Publicacións}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Buscar idiomas...",
   "compose_form.direct_message_warning_learn_more": "Saber máis",
   "compose_form.encryption_warning": "As publicacións en Mastodon non están cifradas de extremo-a-extremo. Non compartas información sensible en Mastodon.",
-  "compose_form.hashtag_warning": "Esta publicación non aparecerá baixo ningún cancelo (hashtag) porque non está listada. Só se poden procurar publicacións públicas por cancelos.",
+  "compose_form.hashtag_warning": "Esta publicación non aparecerá incluída na lista dos cancelos xa que non é pública. Só se poden buscar cancelos nas publicacións públicas.",
   "compose_form.lock_disclaimer": "A túa conta non está {locked}. Todas poden seguirte para ollar os teus toots só para seguidoras.",
   "compose_form.lock_disclaimer.lock": "bloqueada",
   "compose_form.placeholder": "Que contas?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copiar trazas (stacktrace) ó portapapeis",
   "errors.unexpected_crash.report_issue": "Informar sobre un problema",
   "explore.search_results": "Resultados da busca",
+  "explore.suggested_follows": "Para ti",
   "explore.title": "Descubrir",
+  "explore.trending_links": "Novas",
+  "explore.trending_statuses": "Publicacións",
+  "explore.trending_tags": "Cancelos",
   "filter_modal.added.context_mismatch_explanation": "Esta categoría de filtro non se aplica ao contexto no que accedeches a esta publicación. Se queres que a publicación se filtre nese contexto tamén, terás que editar o filtro.",
   "filter_modal.added.context_mismatch_title": "Non concorda o contexto!",
   "filter_modal.added.expired_explanation": "Esta categoría de filtro caducou, terás que cambiar a data de caducidade para que se aplique.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Acceder",
   "sign_in_banner.text": "Inicia sesión para seguir perfís ou etiquetas, marcar como favorita, responder a publicacións ou interactuar con outro servidor desde a túa conta.",
   "status.admin_account": "Abrir interface de moderación para @{name}",
+  "status.admin_domain": "Abrir interface de moderación para {domain}",
   "status.admin_status": "Abrir esta publicación na interface de moderación",
   "status.block": "Bloquear a @{name}",
   "status.bookmark": "Marcar",
diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json
index 3307e3ed7..eb558a863 100644
--- a/app/javascript/mastodon/locales/he.json
+++ b/app/javascript/mastodon/locales/he.json
@@ -35,14 +35,14 @@
   "account.followers_counter": "{count, plural,one {עוקב אחד} other {{counter} עוקבים}}",
   "account.following": "נעקבים",
   "account.following_counter": "{count, plural,one {עוקב אחרי {counter}}other {עוקב אחרי {counter}}}",
-  "account.follows.empty": "משתמש זה לא עוקב אחר אף אחד עדיין.",
+  "account.follows.empty": "משתמש זה עדיין לא עוקב אחרי אף אחד.",
   "account.follows_you": "במעקב אחריך",
   "account.go_to_profile": "מעבר לפרופיל",
   "account.hide_reblogs": "להסתיר הידהודים מאת @{name}",
   "account.joined_short": "תאריך הצטרפות",
   "account.languages": "שנה שפת הרשמה",
   "account.link_verified_on": "בעלות על הקישור הזה נבדקה לאחרונה ב{date}",
-  "account.locked_info": "מצב הפרטיות של החשבון הנוכחי הוגדר כנעול. בעל החשבון קובע באופן פרטני מי יכול לעקוב אחריו.",
+  "account.locked_info": "החשבון הזה הוגדר כנעול. צריך לקבל אישור כדי לעקוב אחריו.",
   "account.media": "מדיה",
   "account.mention": "אזכור של @{name}",
   "account.moved_to": "{name} ציינו שהחשבון החדש שלהם הוא:",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "הודעות ותגובות",
   "account.report": "דווח על @{name}",
   "account.requested": "בהמתנה לאישור. לחצי כדי לבטל בקשת מעקב",
+  "account.requested_follow": "{name} ביקשו לעקוב אחריך",
   "account.share": "שתף את הפרופיל של @{name}",
   "account.show_reblogs": "הצג הדהודים מאת @{name}",
   "account.statuses_counter": "{count, plural, one {הודעה} two {הודעותיים} many {{count} הודעות} other {{count} הודעות}}",
@@ -119,7 +120,7 @@
   "column_header.pin": "הצמדה",
   "column_header.show_settings": "הצגת העדפות",
   "column_header.unpin": "שחרור הצמדה",
-  "column_subheading.settings": "אפשרויות",
+  "column_subheading.settings": "הגדרות",
   "community.column_settings.local_only": "מקומי בלבד",
   "community.column_settings.media_only": "מדיה בלבד",
   "community.column_settings.remote_only": "מרוחק בלבד",
@@ -127,7 +128,7 @@
   "compose.language.search": "חיפוש שפות...",
   "compose_form.direct_message_warning_learn_more": "מידע נוסף",
   "compose_form.encryption_warning": "הודעות במסטודון לא מוצפנות מקצה לקצה. אל תשתפו מידע רגיש במסטודון.",
-  "compose_form.hashtag_warning": "הודעה זו לא תרשם תחת תגיות הקבצה (האשטאגים) היות והנראות שלה היא 'לא רשום'. רק הודעות ציבוריות יכולות להימצא באמצעות תגיות הקבצה.",
+  "compose_form.hashtag_warning": "הודעה זו לא תרשם תחת תגיות הקבצה היות והנראות שלה איננה 'ציבורית'. רק הודעות ציבוריות ימצאו בחיפוש תגיות הקבצה.",
   "compose_form.lock_disclaimer": "חשבונך אינו {locked}. כל אחד יוכל לעקוב אחריך כדי לקרוא את הודעותיך המיועדות לעוקבים בלבד.",
   "compose_form.lock_disclaimer.lock": "נעול",
   "compose_form.placeholder": "על מה את/ה חושב/ת ?",
@@ -161,7 +162,7 @@
   "confirmations.discard_edit_media.message": "יש לך שינויים לא שמורים לתיאור המדיה. להשליך אותם בכל זאת?",
   "confirmations.domain_block.confirm": "חסמו לגמרי את שם המתחם (דומיין)",
   "confirmations.domain_block.message": "בטוחה שברצונך באמת לחסום את קהילת {domain}? ברב המקרים השתקה וחסימה של מספר משתמשים עשוייה להספיק. לא תראי תוכל מכלל שם המתחם בפידים הציבוריים או בהתראות שלך. העוקבים שלך מהקהילה הזאת יוסרו",
-  "confirmations.logout.confirm": "להתנתק",
+  "confirmations.logout.confirm": "התנתקות",
   "confirmations.logout.message": "האם אתם בטוחים שאתם רוצים להתנתק?",
   "confirmations.mute.confirm": "להשתיק",
   "confirmations.mute.explanation": "זה יסתיר הודעות שלהם והודעות שמאזכרות אותם, אבל עדיין יתיר להם לראות הודעות שלך ולעקוב אחריך.",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "להעתיק את הקוד ללוח הכתיבה",
   "errors.unexpected_crash.report_issue": "דווח על בעיה",
   "explore.search_results": "תוצאות חיפוש",
+  "explore.suggested_follows": "עבורך",
   "explore.title": "סיור",
+  "explore.trending_links": "חדשות",
+  "explore.trending_statuses": "הודעות",
+  "explore.trending_tags": "תגיות",
   "filter_modal.added.context_mismatch_explanation": "קטגוריית הסנן הזאת לא חלה על ההקשר שממנו הגעת אל ההודעה הזו. אם תרצה/י שההודעה תסונן גם בהקשר זה, תצטרך/י לערוך את הסנן.",
   "filter_modal.added.context_mismatch_title": "אין התאמה להקשר!",
   "filter_modal.added.expired_explanation": "פג תוקפה של קטגוריית הסינון הזו, יש צורך לשנות את תאריך התפוגה כדי שהסינון יוחל.",
@@ -273,7 +278,7 @@
   "hashtag.column_settings.select.no_options_message": "לא נמצאו הצעות",
   "hashtag.column_settings.select.placeholder": "הזן תגי הקבצה…",
   "hashtag.column_settings.tag_mode.all": "כל אלה",
-  "hashtag.column_settings.tag_mode.any": "כל אלה",
+  "hashtag.column_settings.tag_mode.any": "לפחות אחד מאלה",
   "hashtag.column_settings.tag_mode.none": "אף אחד מאלה",
   "hashtag.column_settings.tag_toggle": "כלול תגיות נוספות בטור זה",
   "hashtag.follow": "מעקב אחר תגית",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "התחברות",
   "sign_in_banner.text": "יש להתחבר כדי לעקוב אחרי משתמשים או תגיות, לחבב, לשתף ולענות לחצרוצים, או לנהל תקשורת מהחשבון שלך על שרת אחר.",
   "status.admin_account": "פתח/י ממשק ניהול עבור @{name}",
+  "status.admin_domain": "פתיחת ממשק ניהול עבור {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "חסימת @{name}",
   "status.bookmark": "סימניה",
@@ -553,7 +559,7 @@
   "status.favourite": "חיבוב",
   "status.filter": "סנן הודעה זו",
   "status.filtered": "סונן",
-  "status.hide": "הסתר חצרוץ",
+  "status.hide": "הסתר הודעה",
   "status.history.created": "{name} יצר/ה {date}",
   "status.history.edited": "{name} ערך/ה {date}",
   "status.load_more": "עוד",
@@ -572,7 +578,7 @@
   "status.reblogs.empty": "עוד לא הידהדו את ההודעה הזו. כאשר זה יקרה, ההדהודים יופיעו כאן.",
   "status.redraft": "מחיקה ועריכה מחדש",
   "status.remove_bookmark": "הסרת סימניה",
-  "status.replied_to": "הגב לחשבון {name}",
+  "status.replied_to": "בתגובה לחשבון {name}",
   "status.reply": "תגובה",
   "status.replyAll": "תגובה לשרשור",
   "status.report": "דיווח על @{name}",
diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json
index c8e23e399..70edbbe5e 100644
--- a/app/javascript/mastodon/locales/hi.json
+++ b/app/javascript/mastodon/locales/hi.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "टूट्स एवं जवाब",
   "account.report": "रिपोर्ट @{name}",
   "account.requested": "मंजूरी का इंतजार। फॉलो रिक्वेस्ट को रद्द करने के लिए क्लिक करें",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "@{name} की प्रोफाइल शेयर करे",
   "account.show_reblogs": "@{name} के बूस्ट दिखाए",
   "account.statuses_counter": "{count, plural, one {{counter} भोंपू} other {{counter} भोंपू}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "भाषाएँ खोजें...",
   "compose_form.direct_message_warning_learn_more": "और जानें",
   "compose_form.encryption_warning": "मास्टोडॉन पर पोस्ट एन्ड-टू-एन्ड एन्क्रिप्टेड नहीं है। कोई भी व्यक्तिगत जानकारी मास्टोडॉन पर मत भेजें।",
-  "compose_form.hashtag_warning": "यह टूट् किसी भी हैशटैग के तहत सूचीबद्ध नहीं होगा क्योंकि यह अनलिस्टेड है। हैशटैग द्वारा केवल सार्वजनिक टूट्स खोजे जा सकते हैं।",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "आपका खाता {locked} नहीं है। आपको केवल फॉलोवर्स को दिखाई दिए जाने वाले पोस्ट देखने के लिए कोई भी फॉलो कर सकता है।",
   "compose_form.lock_disclaimer.lock": "लॉक्ड",
   "compose_form.placeholder": "What is on your mind?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "स्टैकट्रेस को क्लिपबोर्ड पर कॉपी करें",
   "errors.unexpected_crash.report_issue": "समस्या सूचित करें",
   "explore.search_results": "सर्च रिजल्ट्स",
+  "explore.suggested_follows": "For you",
   "explore.title": "एक्स्प्लोर",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "यह फ़िल्टर श्रेणी उस संदर्भ पर लागू नहीं होती जिसमें आपने इस पोस्ट को एक्सेस किया है। यदि आप चाहते हैं कि इस संदर्भ में भी पोस्ट को फ़िल्टर किया जाए, तो आपको फ़िल्टर को एडिट करना होगा।",
   "filter_modal.added.context_mismatch_title": "कंटेंट मिसमैच!",
   "filter_modal.added.expired_explanation": "यह फ़िल्टर श्रेणी समाप्त हो गई है, इसे लागू करने के लिए आपको समाप्ति तिथि बदलनी होगी।",
@@ -295,8 +300,8 @@
   "interaction_modal.title.follow": "फॉलो {name}",
   "interaction_modal.title.reblog": "बूस्ट {name} की पोस्ट",
   "interaction_modal.title.reply": "{name} की पोस्ट पे रिप्लाई करें",
-  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
-  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.days": "{number, plural,one {# दिन} other {# दिन}}",
+  "intervals.full.hours": "{number, plural,one {# घंटा} other {# घंटे}}",
   "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
   "keyboard_shortcuts.back": "वापस जाने के लिए",
   "keyboard_shortcuts.blocked": "अवरुद्ध उपयोगकर्ताओं की सूची खोलने के लिए",
@@ -349,7 +354,7 @@
   "lists.replies_policy.followed": "अन्य फोल्लोवेद यूजर",
   "lists.replies_policy.list": "सूची के सदस्य",
   "lists.replies_policy.none": "कोई नहीं",
-  "lists.replies_policy.title": "Show replies to:",
+  "lists.replies_policy.title": "इसके जवाब दिखाएं:",
   "lists.search": "Search among people you follow",
   "lists.subheading": "आपकी सूचियाँ",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
@@ -358,21 +363,21 @@
   "missing_indicator.label": "नहीं मिला",
   "missing_indicator.sublabel": "यह संसाधन नहीं मिल सका।",
   "moved_to_account_banner.text": "Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.",
-  "mute_modal.duration": "Duration",
+  "mute_modal.duration": "अवधि",
   "mute_modal.hide_notifications": "Hide notifications from this user?",
   "mute_modal.indefinite": "Indefinite",
-  "navigation_bar.about": "About",
+  "navigation_bar.about": "विवरण",
   "navigation_bar.blocks": "ब्लॉक्ड यूज़र्स",
   "navigation_bar.bookmarks": "पुस्तकचिह्न:",
   "navigation_bar.community_timeline": "लोकल टाइम्लाइन",
   "navigation_bar.compose": "नया टूट् लिखें",
-  "navigation_bar.direct": "Direct messages",
+  "navigation_bar.direct": "प्रत्यक्ष संदेश",
   "navigation_bar.discover": "खोजें",
   "navigation_bar.domain_blocks": "Hidden domains",
   "navigation_bar.edit_profile": "प्रोफ़ाइल संपादित करें",
-  "navigation_bar.explore": "Explore",
-  "navigation_bar.favourites": "Favourites",
-  "navigation_bar.filters": "Muted words",
+  "navigation_bar.explore": "अन्वेषण करें",
+  "navigation_bar.favourites": "पसंदीदा",
+  "navigation_bar.filters": "वारित शब्द",
   "navigation_bar.follow_requests": "अनुसरण करने के अनुरोध",
   "navigation_bar.follows_and_followers": "Follows and followers",
   "navigation_bar.lists": "सूचियाँ",
@@ -398,7 +403,7 @@
   "notification.update": "{name} edited a post",
   "notifications.clear": "Clear notifications",
   "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
-  "notifications.column_settings.admin.report": "New reports:",
+  "notifications.column_settings.admin.report": "नई रिपोर्ट:",
   "notifications.column_settings.admin.sign_up": "New sign-ups:",
   "notifications.column_settings.alert": "Desktop notifications",
   "notifications.column_settings.favourite": "Favourites:",
@@ -416,7 +421,7 @@
   "notifications.column_settings.status": "New toots:",
   "notifications.column_settings.unread_notifications.category": "Unread notifications",
   "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications",
-  "notifications.column_settings.update": "Edits:",
+  "notifications.column_settings.update": "संपादन:",
   "notifications.filter.all": "सभी",
   "notifications.filter.boosts": "बूस्ट",
   "notifications.filter.favourites": "पसंदीदा",
@@ -448,7 +453,7 @@
   "privacy.direct.short": "Direct",
   "privacy.private.long": "Post to followers only",
   "privacy.private.short": "Followers-only",
-  "privacy.public.long": "Visible for all",
+  "privacy.public.long": "सब को दिखाई देगा",
   "privacy.public.short": "सार्वजनिक",
   "privacy.unlisted.long": "Visible for all, but opted-out of discovery features",
   "privacy.unlisted.short": "अनलिस्टेड",
@@ -471,15 +476,15 @@
   "reply_indicator.cancel": "रद्द करें",
   "report.block": "Block",
   "report.block_explanation": "आपको उनकी पोस्टें नहीं दिखेंगे। वे आपकी पोस्टें को देख नहीं पाएंगे और आपको फ़ॉलो नहीं कर पाएंगे। उन्हे पता लगेगा कि वे blocked हैं।",
-  "report.categories.other": "Other",
-  "report.categories.spam": "Spam",
+  "report.categories.other": "अन्य",
+  "report.categories.spam": "अवांछित",
   "report.categories.violation": "Content violates one or more server rules",
   "report.category.subtitle": "Choose the best match",
   "report.category.title": "Tell us what's going on with this {type}",
-  "report.category.title_account": "profile",
+  "report.category.title_account": "रूपरेखा",
   "report.category.title_status": "post",
-  "report.close": "Done",
-  "report.comment.title": "Is there anything else you think we should know?",
+  "report.close": "स्वीकार करें",
+  "report.comment.title": "क्या और कुछ है जिसके बारे में आपको लगता है कि हमें सूचित होना चाहिए?",
   "report.forward": "Forward to {target}",
   "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
   "report.mute": "Mute",
@@ -515,7 +520,7 @@
   "search.search_or_paste": "Search or paste URL",
   "search_popout.search_format": "Advanced search format",
   "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
-  "search_popout.tips.hashtag": "hashtag",
+  "search_popout.tips.hashtag": "हैशटैग",
   "search_popout.tips.status": "status",
   "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
   "search_popout.tips.user": "user",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json
index 8216e6303..5d38728b1 100644
--- a/app/javascript/mastodon/locales/hr.json
+++ b/app/javascript/mastodon/locales/hr.json
@@ -1,6 +1,6 @@
 {
   "about.blocks": "Moderated servers",
-  "about.contact": "Contact:",
+  "about.contact": "Kontakt:",
   "about.disclaimer": "Mastodon is free, open-source software, and a trademark of Mastodon gGmbH.",
   "about.domain_blocks.no_reason_available": "Reason not available",
   "about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.",
@@ -50,16 +50,17 @@
   "account.mute_notifications": "Utišaj obavijesti od @{name}",
   "account.muted": "Utišano",
   "account.open_original_page": "Open original page",
-  "account.posts": "Tootovi",
-  "account.posts_with_replies": "Tootovi i odgovori",
+  "account.posts": "Objave",
+  "account.posts_with_replies": "Objave i odgovori",
   "account.report": "Prijavi @{name}",
-  "account.requested": "Čekanje na potvrdu. Kliknite za otkazivanje zahtjeva za praćenje",
+  "account.requested": "Čekanje na potvrdu. Kliknite za poništavanje zahtjeva za praćenje",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Podijeli profil @{name}",
   "account.show_reblogs": "Prikaži boostove od @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} toot} other {{counter} toota}}",
   "account.unblock": "Deblokiraj @{name}",
   "account.unblock_domain": "Deblokiraj domenu {domain}",
-  "account.unblock_short": "Unblock",
+  "account.unblock_short": "Deblokiraj",
   "account.unendorse": "Ne ističi na profilu",
   "account.unfollow": "Prestani pratiti",
   "account.unmute": "Poništi utišavanje @{name}",
@@ -82,9 +83,9 @@
   "boost_modal.combo": "Možete pritisnuti {combo} kako biste preskočili ovo sljedeći put",
   "bundle_column_error.copy_stacktrace": "Copy error report",
   "bundle_column_error.error.body": "The requested page could not be rendered. It could be due to a bug in our code, or a browser compatibility issue.",
-  "bundle_column_error.error.title": "Oh, no!",
+  "bundle_column_error.error.title": "Oh, ne!",
   "bundle_column_error.network.body": "There was an error when trying to load this page. This could be due to a temporary problem with your internet connection or this server.",
-  "bundle_column_error.network.title": "Network error",
+  "bundle_column_error.network.title": "Greška mreže",
   "bundle_column_error.retry": "Pokušajte ponovno",
   "bundle_column_error.return": "Go back home",
   "bundle_column_error.routing.body": "The requested page could not be found. Are you sure the URL in the address bar is correct?",
@@ -123,11 +124,11 @@
   "community.column_settings.local_only": "Samo lokalno",
   "community.column_settings.media_only": "Samo medijski sadržaj",
   "community.column_settings.remote_only": "Samo udaljeno",
-  "compose.language.change": "Change language",
-  "compose.language.search": "Search languages...",
+  "compose.language.change": "Promijeni jezik",
+  "compose.language.search": "Pretraži jezike...",
   "compose_form.direct_message_warning_learn_more": "Saznajte više",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "Ovaj toot neće biti prikazan ni pod jednim hashtagom jer je postavljen kao neprikazan. Samo javni tootovi mogu biti pretraživani pomoći hashtagova.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Vaš račun nije {locked}. Svatko Vas može pratiti kako bi vidjeli objave namijenjene Vašim pratiteljima.",
   "compose_form.lock_disclaimer.lock": "zaključan",
   "compose_form.placeholder": "Što ti je na umu?",
@@ -137,10 +138,10 @@
   "compose_form.poll.remove_option": "Ukloni ovu opciju",
   "compose_form.poll.switch_to_multiple": "Omogući višestruki odabir opcija ankete",
   "compose_form.poll.switch_to_single": "Omogući odabir samo jedne opcije ankete",
-  "compose_form.publish": "Publish",
-  "compose_form.publish_form": "Publish",
+  "compose_form.publish": "Objavi",
+  "compose_form.publish_form": "Objavi",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.save_changes": "Save changes",
+  "compose_form.save_changes": "Spremi promjene",
   "compose_form.sensitive.hide": "Označi medijski sadržaj kao osjetljiv",
   "compose_form.sensitive.marked": "Medijski sadržaj označen je kao osjetljiv",
   "compose_form.sensitive.unmarked": "Medijski sadržaj nije označen kao osjetljiv",
@@ -151,7 +152,7 @@
   "confirmations.block.block_and_report": "Blokiraj i prijavi",
   "confirmations.block.confirm": "Blokiraj",
   "confirmations.block.message": "Sigurno želite blokirati {name}?",
-  "confirmations.cancel_follow_request.confirm": "Withdraw request",
+  "confirmations.cancel_follow_request.confirm": "Povuci zahtjev",
   "confirmations.cancel_follow_request.message": "Are you sure you want to withdraw your request to follow {name}?",
   "confirmations.delete.confirm": "Obriši",
   "confirmations.delete.message": "Stvarno želite obrisati ovaj toot?",
@@ -234,24 +235,28 @@
   "error.unexpected_crash.next_steps_addons": "Pokušaj ih onemogućiti i osvježiti stranicu. Ako to ne pomogne, i dalje ćeš biti u mogućnosti koristiti Mastodon preko nekog drugog preglednika ili izvornog app-a.",
   "errors.unexpected_crash.copy_stacktrace": "Kopiraj stacktrace u međuspremnik",
   "errors.unexpected_crash.report_issue": "Prijavi problem",
-  "explore.search_results": "Search results",
+  "explore.search_results": "Rezultati pretrage",
+  "explore.suggested_follows": "Za vas",
   "explore.title": "Explore",
+  "explore.trending_links": "Novosti",
+  "explore.trending_statuses": "Objave",
+  "explore.trending_tags": "Hashtagovi",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
   "filter_modal.added.expired_title": "Expired filter!",
   "filter_modal.added.review_and_configure": "To review and further configure this filter category, go to the {settings_link}.",
-  "filter_modal.added.review_and_configure_title": "Filter settings",
+  "filter_modal.added.review_and_configure_title": "Postavke filtara",
   "filter_modal.added.settings_link": "settings page",
   "filter_modal.added.short_explanation": "This post has been added to the following filter category: {title}.",
-  "filter_modal.added.title": "Filter added!",
+  "filter_modal.added.title": "Filtar dodan!",
   "filter_modal.select_filter.context_mismatch": "does not apply to this context",
   "filter_modal.select_filter.expired": "expired",
-  "filter_modal.select_filter.prompt_new": "New category: {name}",
-  "filter_modal.select_filter.search": "Search or create",
-  "filter_modal.select_filter.subtitle": "Use an existing category or create a new one",
-  "filter_modal.select_filter.title": "Filter this post",
-  "filter_modal.title.status": "Filter a post",
+  "filter_modal.select_filter.prompt_new": "Nova kategorija: {name}",
+  "filter_modal.select_filter.search": "Pretraži ili stvori",
+  "filter_modal.select_filter.subtitle": "Odaberite postojeću kategoriju ili stvorite novu",
+  "filter_modal.select_filter.title": "Filtriraj ovu objavu",
+  "filter_modal.title.status": "Filtriraj objavu",
   "follow_recommendations.done": "Učinjeno",
   "follow_recommendations.heading": "Zaprati osobe čije objave želiš vidjeti! Evo nekoliko prijedloga.",
   "follow_recommendations.lead": "Posts from people you follow will show up in chronological order on your home feed. Don't be afraid to make mistakes, you can unfollow people just as easily any time!",
@@ -260,11 +265,11 @@
   "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
   "footer.about": "About",
   "footer.directory": "Profiles directory",
-  "footer.get_app": "Get the app",
+  "footer.get_app": "Preuzmi aplikaciju",
   "footer.invite": "Invite people",
-  "footer.keyboard_shortcuts": "Keyboard shortcuts",
-  "footer.privacy_policy": "Privacy policy",
-  "footer.source_code": "View source code",
+  "footer.keyboard_shortcuts": "Tipkovni prečaci",
+  "footer.privacy_policy": "Pravila o zaštiti privatnosti",
+  "footer.source_code": "Prikaz izvornog koda",
   "generic.saved": "Spremljeno",
   "getting_started.heading": "Počnimo",
   "hashtag.column_header.tag_mode.all": "i {additional}",
@@ -276,8 +281,8 @@
   "hashtag.column_settings.tag_mode.any": "Bilo koji navedeni",
   "hashtag.column_settings.tag_mode.none": "Nijedan navedeni",
   "hashtag.column_settings.tag_toggle": "Uključi dodatne oznake za ovaj stupac",
-  "hashtag.follow": "Follow hashtag",
-  "hashtag.unfollow": "Unfollow hashtag",
+  "hashtag.follow": "Prati hashtag",
+  "hashtag.unfollow": "Prestani pratiti hashtag",
   "home.column_settings.basic": "Osnovno",
   "home.column_settings.show_reblogs": "Pokaži boostove",
   "home.column_settings.show_replies": "Pokaži odgovore",
@@ -448,19 +453,19 @@
   "privacy.direct.short": "Direct",
   "privacy.private.long": "Vidljivo samo pratiteljima",
   "privacy.private.short": "Followers-only",
-  "privacy.public.long": "Visible for all",
+  "privacy.public.long": "Vidljivo svima",
   "privacy.public.short": "Javno",
   "privacy.unlisted.long": "Visible for all, but opted-out of discovery features",
   "privacy.unlisted.short": "Neprikazano",
-  "privacy_policy.last_updated": "Last updated {date}",
-  "privacy_policy.title": "Privacy Policy",
+  "privacy_policy.last_updated": "Zadnje ažurirannje {date}",
+  "privacy_policy.title": "Pravila o zaštiti privatnosti",
   "refresh": "Osvježi",
   "regeneration_indicator.label": "Učitavanje…",
   "regeneration_indicator.sublabel": "Priprema se Vaša početna stranica!",
   "relative_time.days": "{number}d",
   "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago",
   "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago",
-  "relative_time.full.just_now": "just now",
+  "relative_time.full.just_now": "upravo sad",
   "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago",
   "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago",
   "relative_time.hours": "{number}h",
@@ -469,29 +474,29 @@
   "relative_time.seconds": "{number}s",
   "relative_time.today": "danas",
   "reply_indicator.cancel": "Otkaži",
-  "report.block": "Block",
-  "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.",
-  "report.categories.other": "Other",
+  "report.block": "Blokiraj",
+  "report.block_explanation": "Nećete vidjeti njihove objave. Oni neće vidjeti vaše objave i neće vas moći pratiti. Moći će vidjeti da su blokirani.",
+  "report.categories.other": "Drugo",
   "report.categories.spam": "Spam",
-  "report.categories.violation": "Content violates one or more server rules",
+  "report.categories.violation": "Sadržaj krši jedno ili više pravila poslužitelja",
   "report.category.subtitle": "Choose the best match",
-  "report.category.title": "Tell us what's going on with this {type}",
-  "report.category.title_account": "profile",
-  "report.category.title_status": "post",
-  "report.close": "Done",
-  "report.comment.title": "Is there anything else you think we should know?",
+  "report.category.title": "Recite nam što nije u redu s {type}",
+  "report.category.title_account": "profilom",
+  "report.category.title_status": "objavom",
+  "report.close": "Gotovo",
+  "report.comment.title": "Postoji li još nešto što bismo trebali znati?",
   "report.forward": "Proslijedi {target}",
   "report.forward_hint": "Račun je s drugog poslužitelja. Poslati anonimiziranu kopiju prijave i tamo?",
-  "report.mute": "Mute",
-  "report.mute_explanation": "You will not see their posts. They can still follow you and see your posts and will not know that they are muted.",
-  "report.next": "Next",
+  "report.mute": "Utišaj",
+  "report.mute_explanation": "Nećete vidjeti njihove objave. Oni će vas i dalje moći pratiti i vidjeti vaše objave i neće znati da su utišani.",
+  "report.next": "Sljedeće",
   "report.placeholder": "Dodatni komentari",
-  "report.reasons.dislike": "I don't like it",
-  "report.reasons.dislike_description": "It is not something you want to see",
-  "report.reasons.other": "It's something else",
-  "report.reasons.other_description": "The issue does not fit into other categories",
-  "report.reasons.spam": "It's spam",
-  "report.reasons.spam_description": "Malicious links, fake engagement, or repetitive replies",
+  "report.reasons.dislike": "Ne sviđa mi se",
+  "report.reasons.dislike_description": "Nije nešto što želiš vidjeti",
+  "report.reasons.other": "Nešto drugo",
+  "report.reasons.other_description": "Problem ne spada u nijednu drugu kategoriju",
+  "report.reasons.spam": "Spam je",
+  "report.reasons.spam_description": "Zlonamjerne poveznice, lažni angažman ili repetitivni odgovori",
   "report.reasons.violation": "It violates server rules",
   "report.reasons.violation_description": "You are aware that it breaks specific rules",
   "report.rules.subtitle": "Select all that apply",
@@ -528,42 +533,43 @@
   "search_results.title": "Search for {q}",
   "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
   "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)",
-  "server_banner.active_users": "active users",
+  "server_banner.active_users": "aktivni korisnici",
   "server_banner.administered_by": "Administered by:",
   "server_banner.introduction": "{domain} is part of the decentralized social network powered by {mastodon}.",
-  "server_banner.learn_more": "Learn more",
+  "server_banner.learn_more": "Saznaj više",
   "server_banner.server_stats": "Server stats:",
-  "sign_in_banner.create_account": "Create account",
-  "sign_in_banner.sign_in": "Sign in",
+  "sign_in_banner.create_account": "Stvori račun",
+  "sign_in_banner.sign_in": "Prijavi se",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
-  "status.bookmark": "Bookmark",
+  "status.bookmark": "Dodaj u favorite",
   "status.cancel_reblog_private": "Unboost",
   "status.cannot_reblog": "Ova objava ne može biti boostana",
   "status.copy": "Copy link to status",
   "status.delete": "Obriši",
   "status.detailed_status": "Detailed conversation view",
   "status.direct": "Direct message @{name}",
-  "status.edit": "Edit",
-  "status.edited": "Edited {date}",
+  "status.edit": "Uredi",
+  "status.edited": "Uređeno {date}",
   "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}",
-  "status.embed": "Embed",
+  "status.embed": "Umetni",
   "status.favourite": "Označi favoritom",
-  "status.filter": "Filter this post",
-  "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
-  "status.history.created": "{name} created {date}",
-  "status.history.edited": "{name} edited {date}",
+  "status.filter": "Filtriraj ovu objavu",
+  "status.filtered": "Filtrirano",
+  "status.hide": "Sakrij objavu",
+  "status.history.created": "Kreirao/la {name} prije {date}",
+  "status.history.edited": "Uredio/la {name} prije {date}",
   "status.load_more": "Učitaj više",
   "status.media_hidden": "Sakriven medijski sadržaj",
   "status.mention": "Spomeni @{name}",
-  "status.more": "More",
-  "status.mute": "Mute @{name}",
+  "status.more": "Više",
+  "status.mute": "Utišaj @{name}",
   "status.mute_conversation": "Utišaj razgovor",
   "status.open": "Proširi ovaj toot",
-  "status.pin": "Pin on profile",
+  "status.pin": "Prikvači na profil",
   "status.pinned": "Pinned toot",
   "status.read_more": "Pročitajte više",
   "status.reblog": "Boostaj",
@@ -572,25 +578,25 @@
   "status.reblogs.empty": "Nitko još nije boostao ovaj toot. Kada netko to učini, ovdje će biti prikazani.",
   "status.redraft": "Izbriši i ponovno uredi",
   "status.remove_bookmark": "Ukloni knjižnu oznaku",
-  "status.replied_to": "Replied to {name}",
+  "status.replied_to": "Odgovorio/la je {name}",
   "status.reply": "Odgovori",
   "status.replyAll": "Odgovori na niz",
   "status.report": "Prijavi @{name}",
   "status.sensitive_warning": "Osjetljiv sadržaj",
   "status.share": "Podijeli",
-  "status.show_filter_reason": "Show anyway",
+  "status.show_filter_reason": "Svejedno prikaži",
   "status.show_less": "Pokaži manje",
   "status.show_less_all": "Show less for all",
   "status.show_more": "Pokaži više",
   "status.show_more_all": "Show more for all",
-  "status.show_original": "Show original",
-  "status.translate": "Translate",
-  "status.translated_from_with": "Translated from {lang} using {provider}",
+  "status.show_original": "Prikaži original",
+  "status.translate": "Prevedi",
+  "status.translated_from_with": "Prevedno s {lang} koristeći {provider}",
   "status.uncached_media_warning": "Nije dostupno",
   "status.unmute_conversation": "Poništi utišavanje razgovora",
   "status.unpin": "Otkvači s profila",
   "subscribed_languages.lead": "Only posts in selected languages will appear on your home and list timelines after the change. Select none to receive posts in all languages.",
-  "subscribed_languages.save": "Save changes",
+  "subscribed_languages.save": "Spremi promjene",
   "subscribed_languages.target": "Change subscribed languages for {target}",
   "suggestions.dismiss": "Odbaci prijedlog",
   "suggestions.header": "Možda Vas zanima…",
@@ -619,23 +625,23 @@
   "upload_error.poll": "Prijenos datoteka nije dopušten kod anketa.",
   "upload_form.audio_description": "Opišite za ljude sa slabim sluhom",
   "upload_form.description": "Opišite za ljude sa slabim vidom",
-  "upload_form.description_missing": "No description added",
+  "upload_form.description_missing": "Bez opisa",
   "upload_form.edit": "Uredi",
   "upload_form.thumbnail": "Promijeni pretpregled",
   "upload_form.undo": "Obriši",
   "upload_form.video_description": "Opišite za ljude sa slabim sluhom ili vidom",
   "upload_modal.analyzing_picture": "Analiza slike…",
   "upload_modal.apply": "Primijeni",
-  "upload_modal.applying": "Applying…",
+  "upload_modal.applying": "Primjenjivanje…",
   "upload_modal.choose_image": "Odaberite sliku",
-  "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
+  "upload_modal.description_placeholder": "Gojazni đačić s biciklom drži hmelj i finu vatu u džepu nošnje",
   "upload_modal.detect_text": "Detektiraj tekst sa slike",
   "upload_modal.edit_media": "Uređivanje medija",
   "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
   "upload_modal.preparing_ocr": "Preparing OCR…",
-  "upload_modal.preview_label": "Preview ({ratio})",
+  "upload_modal.preview_label": "Pretpregled ({ratio})",
   "upload_progress.label": "Prenošenje...",
-  "upload_progress.processing": "Processing…",
+  "upload_progress.processing": "Obrada…",
   "video.close": "Zatvori video",
   "video.download": "Preuzmi datoteku",
   "video.exit_fullscreen": "Izađi iz cijelog zaslona",
diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json
index f16841923..7c91ff568 100644
--- a/app/javascript/mastodon/locales/hu.json
+++ b/app/javascript/mastodon/locales/hu.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Bejegyzések és válaszok",
   "account.report": "@{name} jelentése",
   "account.requested": "Jóváhagysára vár. Kattints a követési kérés visszavonásához",
+  "account.requested_follow": "{name} kérte, hogy követhessen téged",
   "account.share": "@{name} profiljának megosztása",
   "account.show_reblogs": "@{name} megtolásainak mutatása",
   "account.statuses_counter": "{count, plural, one {{counter} Bejegyzés} other {{counter} Bejegyzés}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Nyelv keresése...",
   "compose_form.direct_message_warning_learn_more": "Tudj meg többet",
   "compose_form.encryption_warning": "A bejegyzések Mastodonon nem használnak végpontok közötti titkosítást. Ne ossz meg semmilyen érzékeny információt Mastodonon.",
-  "compose_form.hashtag_warning": "Ez a bejegyzésed nem fog megjelenni semmilyen hashtag alatt, mivel listázatlan. Csak a nyilvános bejegyzések kereshetők hashtaggel.",
+  "compose_form.hashtag_warning": "Ez a bejegyzésed nem fog megjelenni semmilyen hashtag alatt, mivel nem nyilvános. Csak a nyilvános bejegyzések kereshetők hashtaggel.",
   "compose_form.lock_disclaimer": "A fiókod nincs {locked}. Bárki követni tud, hogy megtekintse a kizárólag követőknek szánt bejegyzéseket.",
   "compose_form.lock_disclaimer.lock": "lezárva",
   "compose_form.placeholder": "Mi jár a fejedben?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Veremkiíratás vágólapra másolása",
   "errors.unexpected_crash.report_issue": "Probléma jelentése",
   "explore.search_results": "Keresési találatok",
+  "explore.suggested_follows": "Neked",
   "explore.title": "Felfedezés",
+  "explore.trending_links": "Hírek",
+  "explore.trending_statuses": "Bejegyzések",
+  "explore.trending_tags": "Hashtagek",
   "filter_modal.added.context_mismatch_explanation": "Ez a szűrőkategória nem érvényes abban a környezetben, amelyből elérted ezt a bejegyzést. Ha ebben a környezetben is szűrni szeretnéd a bejegyzést, akkor szerkesztened kell a szűrőt.",
   "filter_modal.added.context_mismatch_title": "Környezeti eltérés.",
   "filter_modal.added.expired_explanation": "Ez a szűrőkategória elévült, a használatához módosítanod kell az elévülési dátumot.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Bejelentkezés",
   "sign_in_banner.text": "Jelentkezz be profilok vagy hashtagek követéséhez, bejegyzések megosztásához, megválaszolásához, vagy kommunikálj a fiókodból más kiszolgálókkal.",
   "status.admin_account": "Moderációs felület megnyitása @{name} fiókhoz",
+  "status.admin_domain": "A következő moderációs felületének megnyitása: @{domain}",
   "status.admin_status": "Bejegyzés megnyitása a moderációs felületen",
   "status.block": "@{name} letiltása",
   "status.bookmark": "Könyvjelzőzés",
diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json
index 285e96636..137983cbc 100644
--- a/app/javascript/mastodon/locales/hy.json
+++ b/app/javascript/mastodon/locales/hy.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Գրառումներ եւ պատասխաններ",
   "account.report": "Բողոքել @{name}֊ի մասին",
   "account.requested": "Հաստատման կարիք ունի։ Սեղմիր՝ հետեւելու հայցը չեղարկելու համար։",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Կիսուել @{name}֊ի էջով",
   "account.show_reblogs": "Ցուցադրել @{name}֊ի տարածածները",
   "account.statuses_counter": "{count, plural, one {{counter} Գրառում} other {{counter} Գրառումներ}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Իմանալ աւելին",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "Այս գրառումը չի հաշուառուի որեւէ պիտակի տակ, քանզի այն ծածուկ է։ Միայն հրապարակային թթերը հնարաւոր է որոնել պիտակներով։",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Քո հաշիւը {locked} չէ։ Իւրաքանչիւրութիւն ոք կարող է հետեւել քեզ եւ տեսնել միայն հետեւողների համար նախատեսուած գրառումները։",
   "compose_form.lock_disclaimer.lock": "փակ",
   "compose_form.placeholder": "Ի՞նչ կայ մտքիդ",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Պատճենել սթաքթրեյսը սեղմատախտակին",
   "errors.unexpected_crash.report_issue": "Զեկուցել խնդրի մասին",
   "explore.search_results": "Որոնման արդիւնքներ",
+  "explore.suggested_follows": "For you",
   "explore.title": "Բացայայտել",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Բացել @{name} օգտատիրոջ մոդերացիայի դիմերէսը։",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Բացել այս գրառումը մոդերատորի դիմերէսի մէջ",
   "status.block": "Արգելափակել @{name}֊ին",
   "status.bookmark": "Էջանիշ",
@@ -553,7 +559,7 @@
   "status.favourite": "Հաւանել",
   "status.filter": "Filter this post",
   "status.filtered": "Զտուած",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Բեռնել աւելին",
diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json
index ae633965a..7ed8a02ab 100644
--- a/app/javascript/mastodon/locales/id.json
+++ b/app/javascript/mastodon/locales/id.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Kiriman dan balasan",
   "account.report": "Laporkan @{name}",
   "account.requested": "Menunggu persetujuan. Klik untuk membatalkan permintaan",
+  "account.requested_follow": "{name} ingin mengikuti Anda",
   "account.share": "Bagikan profil @{name}",
   "account.show_reblogs": "Tampilkan boost dari @{name}",
   "account.statuses_counter": "{count, plural, other {{counter} Kiriman}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Telusuri bahasa...",
   "compose_form.direct_message_warning_learn_more": "Pelajari selengkapnya",
   "compose_form.encryption_warning": "Kiriman di Mastodon tidak dienkripsi end-to-end. Jangan bagikan informasi sensitif melalui Mastodon.",
-  "compose_form.hashtag_warning": "Kiriman ini tidak akan ada dalam daftar tagar mana pun karena telah diatur sebagai tidak terdaftar. Hanya kiriman publik yang bisa dicari dengan tagar.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Akun Anda tidak {locked}. Semua orang dapat mengikuti Anda untuk melihat kiriman khusus untuk pengikut Anda.",
   "compose_form.lock_disclaimer.lock": "terkunci",
   "compose_form.placeholder": "Apa yang ada di pikiran Anda?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Salin stacktrace ke papan klip",
   "errors.unexpected_crash.report_issue": "Laporkan masalah",
   "explore.search_results": "Hasil pencarian",
+  "explore.suggested_follows": "Untuk Anda",
   "explore.title": "Jelajahi",
+  "explore.trending_links": "Berita",
+  "explore.trending_statuses": "Kiriman",
+  "explore.trending_tags": "Tagar",
   "filter_modal.added.context_mismatch_explanation": "Indonesia Translate",
   "filter_modal.added.context_mismatch_title": "Konteks tidak cocok!",
   "filter_modal.added.expired_explanation": "Kategori saringan ini telah kedaluwarsa, Anda harus mengubah tanggal kedaluwarsa untuk diterapkan.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Masuk",
   "sign_in_banner.text": "Masuk untuk mengikuti profil atau tagar, favorit, bagikan, dan balas ke kiriman, atau berinteraksi dari akun Anda di server yang lain.",
   "status.admin_account": "Buka antarmuka moderasi untuk @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Buka kiriman ini dalam antar muka moderasi",
   "status.block": "Blokir @{name}",
   "status.bookmark": "Markah",
@@ -553,7 +559,7 @@
   "status.favourite": "Difavoritkan",
   "status.filter": "Saring kiriman ini",
   "status.filtered": "Disaring",
-  "status.hide": "Sembunyikan toot",
+  "status.hide": "Sembunyikan pos",
   "status.history.created": "{name} membuat {date}",
   "status.history.edited": "{name} mengedit {date}",
   "status.load_more": "Tampilkan semua",
diff --git a/app/javascript/mastodon/locales/ig.json b/app/javascript/mastodon/locales/ig.json
index bf7c7baae..68ba6e91e 100644
--- a/app/javascript/mastodon/locales/ig.json
+++ b/app/javascript/mastodon/locales/ig.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Posts and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval. Click to cancel follow request",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Posts}}",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Kpesa nsogbu",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Kee ebenrụtụakā",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json
index d14750f98..e57d37787 100644
--- a/app/javascript/mastodon/locales/io.json
+++ b/app/javascript/mastodon/locales/io.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Posti e respondi",
   "account.report": "Denuncar @{name}",
   "account.requested": "Vartante aprobo",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Partigez profilo di @{name}",
   "account.show_reblogs": "Montrez busti de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Posto} other {{counter} Posti}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Trovez linguo...",
   "compose_form.direct_message_warning_learn_more": "Lernez pluse",
   "compose_form.encryption_warning": "Posti en Mastodon ne intersequante chifrigesas. Ne partigez irga privata informo che Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Vua konto ne esas {locked}. Irgu povas sequar vu por vidar vua sequanto-nura posti.",
   "compose_form.lock_disclaimer.lock": "klefagesas",
   "compose_form.placeholder": "Quo esas en tua spirito?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopiez amastraso a klipplanko",
   "errors.unexpected_crash.report_issue": "Reportigez problemo",
   "explore.search_results": "Trovuri",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explorez",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Ca filtrilgrupo ne relatesas kun informo de ca acesesita posto. Se vu volas posto filtresar kun ca informo anke, vu bezonas modifikar filtrilo.",
   "filter_modal.added.context_mismatch_title": "Kontenajneparigeso!",
   "filter_modal.added.expired_explanation": "Ca filtrilgrupo expiris, vu bezonas chanjar expirtempo por apliko.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Enirez",
   "sign_in_banner.text": "Enirez por sequar profili o hashtagi, favorizar, partigar e respondizar posti, o interagar de vua konto de diferanta servilo.",
   "status.admin_account": "Apertez jerintervizajo por @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Restriktez @{name}",
   "status.bookmark": "Libromarko",
@@ -553,7 +559,7 @@
   "status.favourite": "Favorizar",
   "status.filter": "Filtragez ca posto",
   "status.filtered": "Filtrita",
-  "status.hide": "Celez posto",
+  "status.hide": "Hide post",
   "status.history.created": "{name} kreis ye {date}",
   "status.history.edited": "{name} modifikis ye {date}",
   "status.load_more": "Kargar pluse",
diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json
index 74211279a..f5271f245 100644
--- a/app/javascript/mastodon/locales/is.json
+++ b/app/javascript/mastodon/locales/is.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Færslur og svör",
   "account.report": "Kæra @{name}",
   "account.requested": "Bíður eftir samþykki. Smelltu til að hætta við beiðni um að fylgjast með",
+  "account.requested_follow": "{name} hefur beðið um að fylgjast með þér",
   "account.share": "Deila notandasniði fyrir @{name}",
   "account.show_reblogs": "Sýna endurbirtingar frá @{name}",
   "account.statuses_counter": "{count, plural, one {Færsla: {counter}} other {Færslur: {counter}}}",
@@ -127,10 +128,10 @@
   "compose.language.search": "Leita að tungumálum...",
   "compose_form.direct_message_warning_learn_more": "Kanna nánar",
   "compose_form.encryption_warning": "Færslur á Mastodon eru ekki enda-í-enda dulritaðar. Ekki deila viðkvæmum upplýsingum á Mastodon.",
-  "compose_form.hashtag_warning": "Þessi færsla verður ekki talin með undir nokkru myllumerki þar sem það er óskráð. Einungis er hægt að leita að opinberum færslum eftir myllumerkjum.",
+  "compose_form.hashtag_warning": "Þessi færsla verður ekki talin með undir nokkru myllumerki þar sem það er ekki opinbert. Einungis er hægt að leita að opinberum færslum eftir myllumerkjum.",
   "compose_form.lock_disclaimer": "Aðgangurinn þinn er ekki {locked}. Hver sem er getur fylgst með þér til að sjá þær færslur sem einungis eru til fylgjenda þinna.",
   "compose_form.lock_disclaimer.lock": "læstur",
-  "compose_form.placeholder": "Hvað varstu að hugsa?",
+  "compose_form.placeholder": "Hvað liggur þér á hjarta?",
   "compose_form.poll.add_option": "Bæta við valkosti",
   "compose_form.poll.duration": "Tímalengd könnunar",
   "compose_form.poll.option_placeholder": "Valkostur {number}",
@@ -224,7 +225,7 @@
   "empty_column.home": "Heimatímalínan þín er tóm! Fylgstu með fleira fólki til að fylla hana. {suggestions}",
   "empty_column.home.suggestions": "Skoðaðu nokkrar tillögur",
   "empty_column.list": "Það er ennþá ekki neitt á þessum lista. Þegar meðlimir á listanum senda inn nýjar færslur, munu þær birtast hér.",
-  "empty_column.lists": "Þú ert ennþá ekki með neina lista. Þegar þú byrð til einhvern lista, munu hann birtast hér.",
+  "empty_column.lists": "Þú ert ennþá ekki með neina lista. Þegar þú býrð til einhvern lista, munu hann birtast hér.",
   "empty_column.mutes": "Þú hefur ekki þaggað niður í neinum notendum ennþá.",
   "empty_column.notifications": "Þú ert ekki ennþá með neinar tilkynningar. Vertu í samskiptum við aðra til að umræður fari af stað.",
   "empty_column.public": "Það er ekkert hér! Skrifaðu eitthvað opinberlega, eða fylgstu með notendum á öðrum netþjónum til að fylla upp í þetta",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Afrita rakningarupplýsingar (stacktrace) á klippispjald",
   "errors.unexpected_crash.report_issue": "Tilkynna vandamál",
   "explore.search_results": "Leitarniðurstöður",
+  "explore.suggested_follows": "Fyrir þig",
   "explore.title": "Kanna",
+  "explore.trending_links": "Fréttir",
+  "explore.trending_statuses": "Færslur",
+  "explore.trending_tags": "Myllumerki",
   "filter_modal.added.context_mismatch_explanation": "Þessi síuflokkur á ekki við í því samhengi sem aðgangur þinn að þessari færslu felur í sér. Ef þú vilt að færslan sé einnig síuð í þessu samhengi, þá þarftu að breyta síunni.",
   "filter_modal.added.context_mismatch_title": "Misræmi í samhengi!",
   "filter_modal.added.expired_explanation": "Þessi síuflokkur er útrunninn, þú þarft að breyta gidistímanum svo hann geti átt við.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Skrá inn",
   "sign_in_banner.text": "Skráðu þig inn til að fylgjast með notendum eða myllumerkjum, svara færslum, deila þeim eða setja í eftirlæti, eða eiga í samskiptum á aðgangnum þínum á öðrum netþjónum.",
   "status.admin_account": "Opna umsjónarviðmót fyrir @{name}",
+  "status.admin_domain": "Opna umsjónarviðmót fyrir @{domain}",
   "status.admin_status": "Opna þessa færslu í umsjónarviðmótinu",
   "status.block": "Útiloka @{name}",
   "status.bookmark": "Bókamerki",
diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json
index 2e6c9e1e3..080bfafbd 100644
--- a/app/javascript/mastodon/locales/it.json
+++ b/app/javascript/mastodon/locales/it.json
@@ -12,7 +12,7 @@
   "about.powered_by": "Social media decentralizzato alimentato da {mastodon}",
   "about.rules": "Regole del server",
   "account.account_note_header": "Nota",
-  "account.add_or_remove_from_list": "Aggiungi o togli dalle liste",
+  "account.add_or_remove_from_list": "Aggiungi o Rimuovi dalle liste",
   "account.badges.bot": "Bot",
   "account.badges.group": "Gruppo",
   "account.block": "Blocca @{name}",
@@ -32,7 +32,7 @@
   "account.follow": "Segui",
   "account.followers": "Follower",
   "account.followers.empty": "Ancora nessuno segue questo utente.",
-  "account.followers_counter": "{count, plural, one {{counter} Seguace} other {{counter} Seguaci}}",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Follower}}",
   "account.following": "Seguiti",
   "account.following_counter": "{count, plural, one {{counter} Seguiti} other {{counter} Seguiti}}",
   "account.follows.empty": "Questo utente non segue ancora nessuno.",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Post e risposte",
   "account.report": "Segnala @{name}",
   "account.requested": "In attesa d'approvazione. Clicca per annullare la richiesta di seguire",
+  "account.requested_follow": "{name} ha richiesto di seguirti",
   "account.share": "Condividi il profilo di @{name}",
   "account.show_reblogs": "Mostra potenziamenti da @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Post}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Cerca lingue...",
   "compose_form.direct_message_warning_learn_more": "Scopri di più",
   "compose_form.encryption_warning": "I post su Mastodon non sono crittografati end-to-end. Non condividere alcuna informazione sensibile su Mastodon.",
-  "compose_form.hashtag_warning": "Questo post non sarà elencato sotto alcun hashtag, non avendo una lista. Solo i post pubblici possono esser cercati per hashtag.",
+  "compose_form.hashtag_warning": "Questo post non sarà elencato sotto alcun hashtag, poiché non è pubblico. Solo i post pubblici possono essere cercati per hashtag.",
   "compose_form.lock_disclaimer": "Il tuo profilo non è {locked}. Chiunque può seguirti per visualizzare i tuoi post per soli seguaci.",
   "compose_form.lock_disclaimer.lock": "bloccato",
   "compose_form.placeholder": "Cos'hai in mente?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copia stacktrace negli appunti",
   "errors.unexpected_crash.report_issue": "Segnala un problema",
   "explore.search_results": "Risultati della ricerca",
+  "explore.suggested_follows": "Per te",
   "explore.title": "Esplora",
+  "explore.trending_links": "Novità",
+  "explore.trending_statuses": "Post",
+  "explore.trending_tags": "Hashtag",
   "filter_modal.added.context_mismatch_explanation": "La categoria di questo filtro non si applica al contesto in cui hai acceduto a questo post. Se desideri che il post sia filtrato anche in questo contesto, dovrai modificare il filtro.",
   "filter_modal.added.context_mismatch_title": "Contesto non corrispondente!",
   "filter_modal.added.expired_explanation": "La categoria di questo filtro è scaduta, dovrvai modificarne la data di scadenza per applicarlo.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Accedi",
   "sign_in_banner.text": "Accedi per seguire profili o hashtag, salvare tra i preferiti, condividere e rispondere ai post, o interagire dal tuo profilo su un server differente.",
   "status.admin_account": "Apri interfaccia di moderazione per @{name}",
+  "status.admin_domain": "Apri l'interfaccia di moderazione per {domain}",
   "status.admin_status": "Apri questo post nell'interfaccia di moderazione",
   "status.block": "Blocca @{name}",
   "status.bookmark": "Aggiungi segnalibro",
@@ -553,8 +559,8 @@
   "status.favourite": "Salva preferito",
   "status.filter": "Filtra questo post",
   "status.filtered": "Filtrato",
-  "status.hide": "Nascondi toot",
-  "status.history.created": "{name} ha creato {date}",
+  "status.hide": "Nascondi il post",
+  "status.history.created": "Creato da {name} il {date}",
   "status.history.edited": "Modificato da {name} il {date}",
   "status.load_more": "Carica altro",
   "status.media_hidden": "Media nascosto",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index ea4810318..2a24e6934 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "投稿と返信",
   "account.report": "@{name}さんを通報",
   "account.requested": "フォロー承認待ちです。クリックしてキャンセル",
+  "account.requested_follow": "{name} さんがあなたにフォローリクエストしました",
   "account.share": "@{name}さんのプロフィールを共有する",
   "account.show_reblogs": "@{name}さんからのブーストを表示",
   "account.statuses_counter": "{counter} 投稿",
@@ -131,7 +132,7 @@
   "compose.language.search": "言語を検索...",
   "compose_form.direct_message_warning_learn_more": "もっと詳しく",
   "compose_form.encryption_warning": "Mastodonの投稿はエンドツーエンド暗号化に対応していません。安全に送受信されるべき情報をMastodonで共有しないでください。",
-  "compose_form.hashtag_warning": "この投稿は公開設定ではないのでハッシュタグの一覧に表示されません。公開投稿だけがハッシュタグで検索できます。",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "あなたのアカウントは{locked}になっていません。誰でもあなたをフォローすることができ、フォロワー限定の投稿を見ることができます。",
   "compose_form.lock_disclaimer.lock": "承認制",
   "compose_form.placeholder": "今なにしてる?",
@@ -239,7 +240,11 @@
   "errors.unexpected_crash.copy_stacktrace": "スタックトレースをクリップボードにコピー",
   "errors.unexpected_crash.report_issue": "問題を報告",
   "explore.search_results": "検索結果",
+  "explore.suggested_follows": "おすすめ",
   "explore.title": "エクスプローラー",
+  "explore.trending_links": "ニュース",
+  "explore.trending_statuses": "投稿",
+  "explore.trending_tags": "ハッシュタグ",
   "filter_modal.added.context_mismatch_explanation": "このフィルターカテゴリーはあなたがアクセスした投稿のコンテキストには適用されません。この投稿のコンテキストでもフィルターを適用するにはフィルターを編集する必要があります。",
   "filter_modal.added.context_mismatch_title": "コンテキストが一致しません!",
   "filter_modal.added.expired_explanation": "このフィルターカテゴリーは有効期限が切れています。適用するには有効期限を更新してください。",
@@ -365,7 +370,7 @@
   "mute_modal.duration": "ミュートする期間",
   "mute_modal.hide_notifications": "このユーザーからの通知を隠しますか?",
   "mute_modal.indefinite": "無期限",
-  "navigation_bar.about": "About",
+  "navigation_bar.about": "概要",
   "navigation_bar.blocks": "ブロックしたユーザー",
   "navigation_bar.bookmarks": "ブックマーク",
   "navigation_bar.community_timeline": "ローカルタイムライン",
@@ -541,6 +546,7 @@
   "sign_in_banner.sign_in": "ログイン",
   "sign_in_banner.text": "ログインしてプロファイルやハッシュタグ、お気に入りをフォローしたり、投稿を共有したり、返信したり、別のサーバーのアカウントと交流したりできます。",
   "status.admin_account": "@{name}さんのモデレーション画面を開く",
+  "status.admin_domain": "{domain}のモデレーション画面を開く",
   "status.admin_status": "この投稿をモデレーション画面で開く",
   "status.block": "@{name}さんをブロック",
   "status.bookmark": "ブックマーク",
@@ -622,7 +628,7 @@
   "upload_error.limit": "アップロードできる上限を超えています。",
   "upload_error.poll": "アンケートではファイルをアップロードできません。",
   "upload_form.audio_description": "聴き取りが難しいユーザーへの説明",
-  "upload_form.description": "閲覧が難しいユーザーへの説明",
+  "upload_form.description": "視覚障害者向けの説明",
   "upload_form.description_missing": "説明を追加していません",
   "upload_form.edit": "説明",
   "upload_form.thumbnail": "サムネイルを変更",
diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json
index ffdd38cfd..64e726321 100644
--- a/app/javascript/mastodon/locales/ka.json
+++ b/app/javascript/mastodon/locales/ka.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "ტუტები და პასუხები",
   "account.report": "დაარეპორტე @{name}",
   "account.requested": "დამტკიცების მოლოდინში. დააწკაპუნეთ რომ უარყოთ დადევნების მოთხონვა",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "გააზიარე @{name}-ის პროფილი",
   "account.show_reblogs": "აჩვენე ბუსტები @{name}-სგან",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "გაიგე მეტი",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "ეს ტუტი არ მოექცევა ჰეშტეგების ქვეს, რამეთუ ის არაა მითითებული. მხოლოდ ღია ტუტები მოიძებნება ჰეშტეგით.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "თქვენი ანგარიში არაა {locked}. ნებისმიერს შეიძლია გამოგყვეთ, რომ იხილოს თქვენი მიმდევრებზე გათვლილი პოსტები.",
   "compose_form.lock_disclaimer.lock": "ჩაკეტილი",
   "compose_form.placeholder": "რაზე ფიქრობ?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "დაბლოკე @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "ფავორიტი",
   "status.filter": "Filter this post",
   "status.filtered": "ფილტრირებული",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "მეტის ჩატვირთვა",
diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json
index f823a55dd..609c29540 100644
--- a/app/javascript/mastodon/locales/kab.json
+++ b/app/javascript/mastodon/locales/kab.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Tisuffaɣ d tririyin",
   "account.report": "Cetki ɣef @{name}",
   "account.requested": "Di laɛḍil ad yettwaqbel. Ssit i wakken ad yefsex usuter n uḍfar",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Bḍu amaɣnu n @{name}",
   "account.show_reblogs": "Ssken-d inebḍa n @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Nadi tutlayin …",
   "compose_form.direct_message_warning_learn_more": "Issin ugar",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Amiḍan-ik·im ur yelli ara {locked}. Menwala yezmer ad k·kem-yeḍfeṛ akken ad iẓer acu tbeṭṭuḍ akked yimeḍfaṛen-ik·im.",
   "compose_form.lock_disclaimer.lock": "yettwacekkel",
   "compose_form.placeholder": "D acu i itezzin deg wallaɣ?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Nɣel stacktrace ɣef wafus",
   "errors.unexpected_crash.report_issue": "Mmel ugur",
   "explore.search_results": "Igemmaḍ n unadi",
+  "explore.suggested_follows": "For you",
   "explore.title": "Snirem",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Qqen",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Seḥbes @{name}",
   "status.bookmark": "Creḍ",
@@ -553,7 +559,7 @@
   "status.favourite": "Rnu ɣer yismenyifen",
   "status.filter": "Filter this post",
   "status.filtered": "Yettwasizdeg",
-  "status.hide": "Ffer tajewwiqt",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Sali ugar",
diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json
index e3b2a436c..d1f5faf6d 100644
--- a/app/javascript/mastodon/locales/kk.json
+++ b/app/javascript/mastodon/locales/kk.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Жазбалар мен жауаптар",
   "account.report": "Шағымдану @{name}",
   "account.requested": "Растауын күтіңіз. Жазылудан бас тарту үшін басыңыз",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "@{name} профилін бөлісу\"",
   "account.show_reblogs": "@{name} бөліскендерін көрсету",
   "account.statuses_counter": "{count, plural, one {{counter} Пост} other {{counter} Пост}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Көбірек білу",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "Бұл пост іздеуде хэштегпен шықпайды, өйткені ол бәріне ашық емес. Тек ашық жазбаларды ғана хэштег арқылы іздеп табуға болады.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Аккаунтыңыз {locked} емес. Кез келген адам жазылып, сізді оқи алады.",
   "compose_form.lock_disclaimer.lock": "жабық",
   "compose_form.placeholder": "Не бөліскіңіз келеді?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Жиынтықты көшіріп ал клипбордқа",
   "errors.unexpected_crash.report_issue": "Мәселені хабарла",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "@{name} үшін модерация интерфейсін аш",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Бұл жазбаны модерация интерфейсінде аш",
   "status.block": "Бұғаттау @{name}",
   "status.bookmark": "Бетбелгі",
@@ -553,7 +559,7 @@
   "status.favourite": "Таңдаулы",
   "status.filter": "Filter this post",
   "status.filtered": "Фильтрленген",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Тағы әкел",
diff --git a/app/javascript/mastodon/locales/kn.json b/app/javascript/mastodon/locales/kn.json
index 4e1bcbdc6..c6f8322df 100644
--- a/app/javascript/mastodon/locales/kn.json
+++ b/app/javascript/mastodon/locales/kn.json
@@ -1,9 +1,9 @@
 {
-  "about.blocks": "Moderated servers",
-  "about.contact": "Contact:",
-  "about.disclaimer": "Mastodon is free, open-source software, and a trademark of Mastodon gGmbH.",
-  "about.domain_blocks.no_reason_available": "Reason not available",
-  "about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.",
+  "about.blocks": "ನಿಯಂತ್ರಿತ ಸರ್ವರ್‌ಗಳು",
+  "about.contact": "ಸಂಪರ್ಕ:",
+  "about.disclaimer": "ಮಾಸ್ಟೋಡಾನ್ ಇದು ಉಚಿತ, ಮುಕ್ತ ತಂತ್ರಾಂಶ ಮತ್ತು Mastodon gGmbH ಇದರ ನೊಂದಾಯಿತ ಗುರುತು.",
+  "about.domain_blocks.no_reason_available": "ಕಾರಣ ಲಭ್ಯವಿಲ್ಲ",
+  "about.domain_blocks.preamble": "ಸಾಮಾನ್ಯವಾಗಿ ಮಾಸ್ಟೊಡಾನ್ ನಿಮಗೆ ಇತರೆ ಬಳಕೆದಾರರಿಂದ ಹಂಚಲ್ಪಟ್ಟ ವಿಷಯಗಳನ್ನು ನೋಡಲು ಮತ್ತು ಅವರೊಂದಿಗೆ ಸಂಭಾಷಿಸಲು ಅನುಮತಿಸುತ್ತದೆ.\nಆದರೆ ಈ ಸರ್ವ್ರರ್‌ನಲ್ಲಿ ಅಳವಡಿಸಲಾದ ಕೆಲವು ವಿನಾಯಿತಿಗಳು ಇಂತಿವೆ.",
   "about.domain_blocks.silenced.explanation": "You will generally not see profiles and content from this server, unless you explicitly look it up or opt into it by following.",
   "about.domain_blocks.silenced.title": "Limited",
   "about.domain_blocks.suspended.explanation": "No data from this server will be processed, stored or exchanged, making any interaction or communication with users from this server impossible.",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Learn more",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
   "compose_form.placeholder": "What is on your mind?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json
index 30a1bfe94..a94801ad8 100644
--- a/app/javascript/mastodon/locales/ko.json
+++ b/app/javascript/mastodon/locales/ko.json
@@ -9,7 +9,7 @@
   "about.domain_blocks.suspended.explanation": "이 서버의 어떤 데이터도 처리되거나, 저장 되거나 공유되지 않고, 이 서버의 어떤 유저와도 상호작용 하거나 대화할 수 없습니다.",
   "about.domain_blocks.suspended.title": "정지됨",
   "about.not_available": "이 정보는 이 서버에서 사용할 수 없습니다.",
-  "about.powered_by": "{mastodon}에 의해 구동되는 분산화된 소셜 미디어",
+  "about.powered_by": "{mastodon}으로 구동되는 분산 소셜 미디어",
   "about.rules": "서버 규칙",
   "account.account_note_header": "노트",
   "account.add_or_remove_from_list": "리스트에 추가 혹은 삭제",
@@ -48,12 +48,13 @@
   "account.moved_to": "{name} 님은 자신의 새 계정이 다음과 같다고 표시했습니다:",
   "account.mute": "@{name} 뮤트",
   "account.mute_notifications": "@{name}의 알림을 뮤트",
-  "account.muted": "뮤트 됨",
+  "account.muted": "뮤트됨",
   "account.open_original_page": "원본 페이지 열기",
   "account.posts": "게시물",
   "account.posts_with_replies": "게시물과 답장",
   "account.report": "@{name} 신고",
   "account.requested": "승인 대기 중. 클릭해서 취소하기",
+  "account.requested_follow": "{name} 님이 팔로우 요청을 보냈습니다",
   "account.share": "@{name}의 프로필 공유",
   "account.show_reblogs": "@{name}의 부스트 보기",
   "account.statuses_counter": "{counter} 게시물",
@@ -127,7 +128,7 @@
   "compose.language.search": "언어 검색...",
   "compose_form.direct_message_warning_learn_more": "더 알아보기",
   "compose_form.encryption_warning": "마스토돈의 게시물들은 종단간 암호화가 되지 않습니다. 민감한 정보를 마스토돈을 통해 전달하지 마세요.",
-  "compose_form.hashtag_warning": "이 게시물은 어떤 해시태그로도 검색 되지 않습니다. 전체공개로 게시 된 게시물만이 해시태그로 검색 될 수 있습니다.",
+  "compose_form.hashtag_warning": "이 게시물은 전체공개가 아니기 때문에 어떤 해시태그로도 검색 되지 않습니다. 전체공개로 게시 된 게시물만이 해시태그로 검색될 수 있습니다.",
   "compose_form.lock_disclaimer": "이 계정은 {locked}상태가 아닙니다. 누구나 이 계정을 팔로우 하여 팔로워 전용의 게시물을 볼 수 있습니다.",
   "compose_form.lock_disclaimer.lock": "비공개",
   "compose_form.placeholder": "지금 무슨 생각을 하고 있나요?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "에러 내용을 클립보드에 복사",
   "errors.unexpected_crash.report_issue": "문제 신고",
   "explore.search_results": "검색 결과",
+  "explore.suggested_follows": "추천",
   "explore.title": "둘러보기",
+  "explore.trending_links": "소식",
+  "explore.trending_statuses": "게시물",
+  "explore.trending_tags": "해시태그",
   "filter_modal.added.context_mismatch_explanation": "이 필터 카테고리는 당신이 이 게시물에 접근한 문맥에 적용되지 않습니다. 만약 이 문맥에서도 필터되길 원한다면, 필터를 수정해야 합니다.",
   "filter_modal.added.context_mismatch_title": "문맥 불일치!",
   "filter_modal.added.expired_explanation": "이 필터 카테고리는 만료되었습니다, 적용하려면 만료 일자를 변경할 필요가 있습니다.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "로그인",
   "sign_in_banner.text": "로그인을 통해 프로필이나 해시태그를 팔로우하거나 마음에 들어하거나 공유하고 답글을 달 수 있습니다, 혹은 다른 서버에 있는 본인의 계정을 통해 참여할 수도 있습니다.",
   "status.admin_account": "@{name}에 대한 중재 화면 열기",
+  "status.admin_domain": "{domain}에 대한 중재 화면 열기",
   "status.admin_status": "중재 화면에서 이 게시물 열기",
   "status.block": "@{name} 차단",
   "status.bookmark": "북마크",
@@ -553,7 +559,7 @@
   "status.favourite": "좋아요",
   "status.filter": "이 게시물을 필터",
   "status.filtered": "필터로 걸러짐",
-  "status.hide": "툿 숨기기",
+  "status.hide": "게시물 숨기기",
   "status.history.created": "{name} 님이 {date}에 생성함",
   "status.history.edited": "{name} 님이 {date}에 수정함",
   "status.load_more": "더 보기",
diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json
index 02ac43d57..7dbb34591 100644
--- a/app/javascript/mastodon/locales/ku.json
+++ b/app/javascript/mastodon/locales/ku.json
@@ -18,7 +18,7 @@
   "account.block": "@{name} asteng bike",
   "account.block_domain": "Navpera {domain} asteng bike",
   "account.blocked": "Astengkirî",
-  "account.browse_more_on_origin_server": "Li pelên resen bêhtir bigere",
+  "account.browse_more_on_origin_server": "Li pelên resen bêtir bigere",
   "account.cancel_follow_request": "Daxwaza şopandinê vekişîne",
   "account.direct": "Peyamekê bişîne @{name}",
   "account.disable_notifications": "Êdî min agahdar neke gava @{name} diweşîne",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Şandî û bersiv",
   "account.report": "@{name} ragihîne",
   "account.requested": "Li benda erêkirinê ye. Ji bo betal kirina daxwazê pêl bikin",
+  "account.requested_follow": "{name} dixwaze te bişopîne",
   "account.share": "Profîla @{name} parve bike",
   "account.show_reblogs": "Bilindkirinên ji @{name} nîşan bike",
   "account.statuses_counter": "{count, plural,one {{counter} Şandî}other {{counter} Şandî}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Li zimanan bigere...",
   "compose_form.direct_message_warning_learn_more": "Bêtir fêr bibe",
   "compose_form.encryption_warning": "Şandiyên li ser Mastodon dawî-bi-dawî ne şîfrekirî ne. Li ser Mastodon zanyariyên hestyar parve neke.",
-  "compose_form.hashtag_warning": "Ev şandî ji ber ku nehatiye tomarkirin dê di binê hashtagê de neyê tomar kirin. Tenê peyamên gelemperî dikarin bi hashtagê werin lêgerîn.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Ajimêrê te ne {locked}. Herkes dikare te bişopîne da ku şandiyên te yên tenê ji şopînerên re têne xuyakirin bibînin.",
   "compose_form.lock_disclaimer.lock": "girtî ye",
   "compose_form.placeholder": "Çi di hişê te derbas dibe?",
@@ -190,8 +191,8 @@
   "dismissable_banner.explore_statuses": "Ev şandiyên ji vê û rajekarên din ên di tora nenavendî de niha li ser vê rajekarê balê dikşînin.",
   "dismissable_banner.explore_tags": "Ev hashtagên ji vê û rajekarên din ên di tora nenavendî de niha li ser vê rajekarê balê dikşînin.",
   "dismissable_banner.public_timeline": "Ev şandiyên gelemperî herî dawî yên mirovên li ser vê û rajekarên din ên tora nenavendî ne ku ev rajekar pê tê nasîn.",
-  "embed.instructions": "Bi jêgirtina koda jêrîn vê şandiyê li ser malpera xwe bicîh bikin.",
-  "embed.preview": "Wa ye wê wusa xuya bike:",
+  "embed.instructions": "Bi jêgirtina koda jêrîn vê şandiyê li ser malpera xwe bi cih bike.",
+  "embed.preview": "Ew ê çawa xuya bibe li vir tê nîşandan:",
   "emoji_button.activity": "Çalakî",
   "emoji_button.clear": "Pak bike",
   "emoji_button.custom": "Kesanekirî",
@@ -230,12 +231,16 @@
   "empty_column.public": "Li vir tiştekî tuneye! Ji raya giştî re tiştekî binivîsîne, an ji bo tijîkirinê ji rajekerên din bikarhêneran bi destan bişopînin",
   "error.unexpected_crash.explanation": "Ji ber xeletîyeke di koda me da an jî ji ber mijara lihevhatina gerokan, ev rûpel rast nehat nîşandan.",
   "error.unexpected_crash.explanation_addons": "Ev rûpel bi awayekî rast nehat nîşandan. Ev çewtî mimkûn e ji ber lêzêdekirina gerokan an jî amûrên wergera xweberî pêk tê.",
-  "error.unexpected_crash.next_steps": "Nûkirina rûpelê biceribîne. Heke ev bi kêr neyê, dibe ku te hîn jî bi riya gerokeke cuda an jî sepana xwecîhê Mastodonê bi kar bîne.",
-  "error.unexpected_crash.next_steps_addons": "Ne çalak kirin û nûkirina rûpelê biceribîne. Heke ev bi kêr neyê, dibe ku te hîn jî bi riya gerokeke cuda an jî sepana xwecîhê Mastodonê bi kar bîne.",
+  "error.unexpected_crash.next_steps": "Nûkirina rûpelê biceribîne. Ku ev bi kêr neyê, dibe ku te hîn jî bi riya gerokeke cuda an jî sepana xwecîhî ya Mastodon bi kar bînî.",
+  "error.unexpected_crash.next_steps_addons": "Neçalakkirin û nûkirina rûpelê biceribîne. Ku ev bi kêr neyê, dibe ku te hîn jî bi riya gerokeke cuda an jî sepana xwecihî ya Mastodon bi kar bînî.",
   "errors.unexpected_crash.copy_stacktrace": "Şopa gemara (stacktrace) tûrikê ra jê bigire",
   "errors.unexpected_crash.report_issue": "Pirsgirêkekê ragihîne",
   "explore.search_results": "Encamên lêgerînê",
+  "explore.suggested_follows": "Ji bo te",
   "explore.title": "Vekole",
+  "explore.trending_links": "Nûçe",
+  "explore.trending_statuses": "Şandî",
+  "explore.trending_tags": "Hashtag",
   "filter_modal.added.context_mismatch_explanation": "Ev beşa parzûnê ji bo naveroka ku te tê de xwe gihandiye vê şandiyê nayê sepandin. Ku tu dixwazî şandî di vê naverokê de jî werê parzûnkirin, divê tu parzûnê biguherînî.",
   "filter_modal.added.context_mismatch_title": "Naverok li hev nagire!",
   "filter_modal.added.expired_explanation": "Ev beşa parzûnê qediya ye, ji bo ku tu bikaribe wê biguherîne divê tu dema qedandinê biguherînî.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Têkeve",
   "sign_in_banner.text": "Têkeve ji bo şopandina profîlan an hashtagan, bijartekirin, parvekirin û bersivdana şandiyan, an ji ajimêrê xwe li ser rajekarek cuda têkilî deyine.",
   "status.admin_account": "Ji bo @{name} navrûya venihêrtinê veke",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Vê şandîyê di navrûya venihêrtinê de veke",
   "status.block": "@{name} asteng bike",
   "status.bookmark": "Şûnpel",
@@ -549,11 +555,11 @@
   "status.edit": "Serrast bike",
   "status.edited": "Di {date} de hate serrastkirin",
   "status.edited_x_times": "{count, plural, one {{count} car} other {{count} car}} hate serrastkirin",
-  "status.embed": "Hedimandî",
+  "status.embed": "Bi cih bike",
   "status.favourite": "Bijarte bike",
   "status.filter": "Vê şandiyê parzûn bike",
   "status.filtered": "Parzûnkirî",
-  "status.hide": "Şandiyê veşêre",
+  "status.hide": "Hide post",
   "status.history.created": "{name} {date} afirand",
   "status.history.edited": "{name} {date} serrast kir",
   "status.load_more": "Bêtir bar bike",
diff --git a/app/javascript/mastodon/locales/kw.json b/app/javascript/mastodon/locales/kw.json
index 8e937979f..f56974d2b 100644
--- a/app/javascript/mastodon/locales/kw.json
+++ b/app/javascript/mastodon/locales/kw.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Postow ha gorthebow",
   "account.report": "Reportya @{name}",
   "account.requested": "Ow kortos komendyans. Klyckyewgh dhe hedhi govyn holya",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Kevrenna profil @{name}",
   "account.show_reblogs": "Diskwedhes kenerthow a @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Tout} other {{counter} Tout}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Dyski moy",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "Ny vydh an post ma diskwedhys yn-dann vòlnos vyth awos y vos mes a rol. Ny yllir hwilas saw poblow postek dre vòlnos.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Nyns yw agas akont {locked}. Piwpynag a yll agas holya dhe weles agas postow holyoryon-hepken.",
   "compose_form.lock_disclaimer.lock": "Alhwedhys",
   "compose_form.placeholder": "Pyth eus yn agas brys?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Dasskrifa daslergh dhe'n astel glypp",
   "errors.unexpected_crash.report_issue": "Reportya kudyn",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Ygeri ynterfas koswa rag @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Ygeri an post ma y'n ynterfas koswa",
   "status.block": "Lettya @{name}",
   "status.bookmark": "Folennos",
@@ -553,7 +559,7 @@
   "status.favourite": "Merkya vel drudh",
   "status.filter": "Filter this post",
   "status.filtered": "Sidhlys",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Karga moy",
diff --git a/app/javascript/mastodon/locales/la.json b/app/javascript/mastodon/locales/la.json
new file mode 100644
index 000000000..1a54cc90d
--- /dev/null
+++ b/app/javascript/mastodon/locales/la.json
@@ -0,0 +1,655 @@
+{
+  "about.blocks": "Moderated servers",
+  "about.contact": "Ratio:",
+  "about.disclaimer": "Mastodon is free, open-source software, and a trademark of Mastodon gGmbH.",
+  "about.domain_blocks.no_reason_available": "Reason not available",
+  "about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.",
+  "about.domain_blocks.silenced.explanation": "You will generally not see profiles and content from this server, unless you explicitly look it up or opt into it by following.",
+  "about.domain_blocks.silenced.title": "Limited",
+  "about.domain_blocks.suspended.explanation": "No data from this server will be processed, stored or exchanged, making any interaction or communication with users from this server impossible.",
+  "about.domain_blocks.suspended.title": "Suspended",
+  "about.not_available": "This information has not been made available on this server.",
+  "about.powered_by": "Decentralized social media powered by {mastodon}",
+  "about.rules": "Server rules",
+  "account.account_note_header": "Annotatio",
+  "account.add_or_remove_from_list": "Add or Remove from lists",
+  "account.badges.bot": "Robotum",
+  "account.badges.group": "Congregatio",
+  "account.block": "Impedire @{name}",
+  "account.block_domain": "Imperire dominium {domain}",
+  "account.blocked": "Impeditum est",
+  "account.browse_more_on_origin_server": "Browse more on the original profile",
+  "account.cancel_follow_request": "Withdraw follow request",
+  "account.direct": "Direct message @{name}",
+  "account.disable_notifications": "Stop notifying me when @{name} posts",
+  "account.domain_blocked": "Dominium impeditum",
+  "account.edit_profile": "Recolere notionem",
+  "account.enable_notifications": "Notify me when @{name} posts",
+  "account.endorse": "Feature on profile",
+  "account.featured_tags.last_status_at": "Last post on {date}",
+  "account.featured_tags.last_status_never": "Nulla contributa",
+  "account.featured_tags.title": "{name}'s featured hashtags",
+  "account.follow": "Follow",
+  "account.followers": "Followers",
+  "account.followers.empty": "No one follows this user yet.",
+  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
+  "account.following": "Following",
+  "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
+  "account.follows.empty": "This user doesn't follow anyone yet.",
+  "account.follows_you": "Follows you",
+  "account.go_to_profile": "Go to profile",
+  "account.hide_reblogs": "Hide boosts from @{name}",
+  "account.joined_short": "Joined",
+  "account.languages": "Change subscribed languages",
+  "account.link_verified_on": "Ownership of this link was checked on {date}",
+  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.media": "Media",
+  "account.mention": "Mention @{name}",
+  "account.moved_to": "{name} has indicated that their new account is now:",
+  "account.mute": "Mute @{name}",
+  "account.mute_notifications": "Mute notifications from @{name}",
+  "account.muted": "Confutatus",
+  "account.open_original_page": "Open original page",
+  "account.posts": "Posts",
+  "account.posts_with_replies": "Posts and replies",
+  "account.report": "Report @{name}",
+  "account.requested": "Awaiting approval. Click to cancel follow request",
+  "account.requested_follow": "{name} has requested to follow you",
+  "account.share": "Share @{name}'s profile",
+  "account.show_reblogs": "Show boosts from @{name}",
+  "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Posts}}",
+  "account.unblock": "Unblock @{name}",
+  "account.unblock_domain": "Unblock domain {domain}",
+  "account.unblock_short": "Solvere impedimentum",
+  "account.unendorse": "Don't feature on profile",
+  "account.unfollow": "Unfollow",
+  "account.unmute": "Unmute @{name}",
+  "account.unmute_notifications": "Unmute notifications from @{name}",
+  "account.unmute_short": "Unmute",
+  "account_note.placeholder": "Click to add a note",
+  "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
+  "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
+  "admin.dashboard.retention.average": "Mediocritas",
+  "admin.dashboard.retention.cohort": "Sign-up month",
+  "admin.dashboard.retention.cohort_size": "New users",
+  "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
+  "alert.rate_limited.title": "Rate limited",
+  "alert.unexpected.message": "An unexpected error occurred.",
+  "alert.unexpected.title": "Oops!",
+  "announcement.announcement": "Proclamatio",
+  "attachments_list.unprocessed": "(unprocessed)",
+  "audio.hide": "Hide audio",
+  "autosuggest_hashtag.per_week": "{count} per week",
+  "boost_modal.combo": "You can press {combo} to skip this next time",
+  "bundle_column_error.copy_stacktrace": "Copy error report",
+  "bundle_column_error.error.body": "The requested page could not be rendered. It could be due to a bug in our code, or a browser compatibility issue.",
+  "bundle_column_error.error.title": "Eheu!",
+  "bundle_column_error.network.body": "There was an error when trying to load this page. This could be due to a temporary problem with your internet connection or this server.",
+  "bundle_column_error.network.title": "Network error",
+  "bundle_column_error.retry": "Retemptare",
+  "bundle_column_error.return": "Go back home",
+  "bundle_column_error.routing.body": "The requested page could not be found. Are you sure the URL in the address bar is correct?",
+  "bundle_column_error.routing.title": "CCCCIIII",
+  "bundle_modal_error.close": "Claudere",
+  "bundle_modal_error.message": "Something went wrong while loading this component.",
+  "bundle_modal_error.retry": "Retemptare",
+  "closed_registrations.other_server_instructions": "Since Mastodon is decentralized, you can create an account on another server and still interact with this one.",
+  "closed_registrations_modal.description": "Creating an account on {domain} is currently not possible, but please keep in mind that you do not need an account specifically on {domain} to use Mastodon.",
+  "closed_registrations_modal.find_another_server": "Find another server",
+  "closed_registrations_modal.preamble": "Mastodon is decentralized, so no matter where you create your account, you will be able to follow and interact with anyone on this server. You can even self-host it!",
+  "closed_registrations_modal.title": "Signing up on Mastodon",
+  "column.about": "De",
+  "column.blocks": "Blocked users",
+  "column.bookmarks": "Signa paginales",
+  "column.community": "Local timeline",
+  "column.direct": "Direct messages",
+  "column.directory": "Browse profiles",
+  "column.domain_blocks": "Blocked domains",
+  "column.favourites": "Dilecti",
+  "column.follow_requests": "Follow requests",
+  "column.home": "Domi",
+  "column.lists": "Catalogi",
+  "column.mutes": "Muted users",
+  "column.notifications": "Notifications",
+  "column.pins": "Pinned post",
+  "column.public": "Federated timeline",
+  "column_back_button.label": "Back",
+  "column_header.hide_settings": "Hide settings",
+  "column_header.moveLeft_settings": "Move column to the left",
+  "column_header.moveRight_settings": "Move column to the right",
+  "column_header.pin": "Pin",
+  "column_header.show_settings": "Show settings",
+  "column_header.unpin": "Unpin",
+  "column_subheading.settings": "Settings",
+  "community.column_settings.local_only": "Local only",
+  "community.column_settings.media_only": "Media only",
+  "community.column_settings.remote_only": "Remote only",
+  "compose.language.change": "Mutare linguam",
+  "compose.language.search": "Quaerere linguas...",
+  "compose_form.direct_message_warning_learn_more": "Discere plura",
+  "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
+  "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
+  "compose_form.lock_disclaimer.lock": "clausum",
+  "compose_form.placeholder": "What is on your mind?",
+  "compose_form.poll.add_option": "Add a choice",
+  "compose_form.poll.duration": "Poll duration",
+  "compose_form.poll.option_placeholder": "Choice {number}",
+  "compose_form.poll.remove_option": "Remove this choice",
+  "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
+  "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
+  "compose_form.publish": "Barrire",
+  "compose_form.publish_form": "Barrire",
+  "compose_form.publish_loud": "{publish}!",
+  "compose_form.save_changes": "Save changes",
+  "compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}",
+  "compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}",
+  "compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}",
+  "compose_form.spoiler.marked": "Text is hidden behind warning",
+  "compose_form.spoiler.unmarked": "Text is not hidden",
+  "compose_form.spoiler_placeholder": "Write your warning here",
+  "confirmation_modal.cancel": "Cancel",
+  "confirmations.block.block_and_report": "Block & Report",
+  "confirmations.block.confirm": "Impedire",
+  "confirmations.block.message": "Are you sure you want to block {name}?",
+  "confirmations.cancel_follow_request.confirm": "Withdraw request",
+  "confirmations.cancel_follow_request.message": "Are you sure you want to withdraw your request to follow {name}?",
+  "confirmations.delete.confirm": "Oblitterare",
+  "confirmations.delete.message": "Are you sure you want to delete this status?",
+  "confirmations.delete_list.confirm": "Oblitterare",
+  "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
+  "confirmations.discard_edit_media.confirm": "Discard",
+  "confirmations.discard_edit_media.message": "You have unsaved changes to the media description or preview, discard them anyway?",
+  "confirmations.domain_block.confirm": "Hide entire domain",
+  "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
+  "confirmations.logout.confirm": "Log out",
+  "confirmations.logout.message": "Are you sure you want to log out?",
+  "confirmations.mute.confirm": "Confutare",
+  "confirmations.mute.explanation": "This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.",
+  "confirmations.mute.message": "Are you sure you want to mute {name}?",
+  "confirmations.redraft.confirm": "Delete & redraft",
+  "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
+  "confirmations.reply.confirm": "Respondere",
+  "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
+  "confirmations.unfollow.confirm": "Unfollow",
+  "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
+  "conversation.delete": "Delete conversation",
+  "conversation.mark_as_read": "Mark as read",
+  "conversation.open": "View conversation",
+  "conversation.with": "With {names}",
+  "copypaste.copied": "Copied",
+  "copypaste.copy": "Copy",
+  "directory.federated": "From known fediverse",
+  "directory.local": "From {domain} only",
+  "directory.new_arrivals": "New arrivals",
+  "directory.recently_active": "Recently active",
+  "disabled_account_banner.account_settings": "Account settings",
+  "disabled_account_banner.text": "Your account {disabledAccount} is currently disabled.",
+  "dismissable_banner.community_timeline": "These are the most recent public posts from people whose accounts are hosted by {domain}.",
+  "dismissable_banner.dismiss": "Dismiss",
+  "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
+  "dismissable_banner.explore_statuses": "These posts from this and other servers in the decentralized network are gaining traction on this server right now.",
+  "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
+  "dismissable_banner.public_timeline": "These are the most recent public posts from people on this and other servers of the decentralized network that this server knows about.",
+  "embed.instructions": "Embed this status on your website by copying the code below.",
+  "embed.preview": "Here is what it will look like:",
+  "emoji_button.activity": "Activity",
+  "emoji_button.clear": "Clear",
+  "emoji_button.custom": "Custom",
+  "emoji_button.flags": "Flags",
+  "emoji_button.food": "Food & Drink",
+  "emoji_button.label": "Insert emoji",
+  "emoji_button.nature": "Nature",
+  "emoji_button.not_found": "No matching emojis found",
+  "emoji_button.objects": "Objects",
+  "emoji_button.people": "Homines",
+  "emoji_button.recent": "Frequently used",
+  "emoji_button.search": "Quaerere...",
+  "emoji_button.search_results": "Search results",
+  "emoji_button.symbols": "Symbols",
+  "emoji_button.travel": "Travel & Places",
+  "empty_column.account_suspended": "Account suspended",
+  "empty_column.account_timeline": "Hic nulla contributa!",
+  "empty_column.account_unavailable": "Notio non impetrabilis",
+  "empty_column.blocks": "You haven't blocked any users yet.",
+  "empty_column.bookmarked_statuses": "You don't have any bookmarked posts yet. When you bookmark one, it will show up here.",
+  "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
+  "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
+  "empty_column.domain_blocks": "There are no blocked domains yet.",
+  "empty_column.explore_statuses": "Nothing is trending right now. Check back later!",
+  "empty_column.favourited_statuses": "You don't have any favourite posts yet. When you favourite one, it will show up here.",
+  "empty_column.favourites": "No one has favourited this post yet. When someone does, they will show up here.",
+  "empty_column.follow_recommendations": "Looks like no suggestions could be generated for you. You can try using search to look for people you might know or explore trending hashtags.",
+  "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
+  "empty_column.hashtag": "There is nothing in this hashtag yet.",
+  "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
+  "empty_column.home.suggestions": "See some suggestions",
+  "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
+  "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
+  "empty_column.mutes": "You haven't muted any users yet.",
+  "empty_column.notifications": "You don't have any notifications yet. When other people interact with you, you will see it here.",
+  "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
+  "error.unexpected_crash.explanation": "Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.",
+  "error.unexpected_crash.explanation_addons": "This page could not be displayed correctly. This error is likely caused by a browser add-on or automatic translation tools.",
+  "error.unexpected_crash.next_steps": "Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
+  "error.unexpected_crash.next_steps_addons": "Try disabling them and refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.",
+  "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
+  "errors.unexpected_crash.report_issue": "Report issue",
+  "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
+  "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Contributa",
+  "explore.trending_tags": "Hashtags",
+  "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
+  "filter_modal.added.context_mismatch_title": "Context mismatch!",
+  "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
+  "filter_modal.added.expired_title": "Expired filter!",
+  "filter_modal.added.review_and_configure": "To review and further configure this filter category, go to the {settings_link}.",
+  "filter_modal.added.review_and_configure_title": "Filter settings",
+  "filter_modal.added.settings_link": "settings page",
+  "filter_modal.added.short_explanation": "This post has been added to the following filter category: {title}.",
+  "filter_modal.added.title": "Filter added!",
+  "filter_modal.select_filter.context_mismatch": "does not apply to this context",
+  "filter_modal.select_filter.expired": "expired",
+  "filter_modal.select_filter.prompt_new": "New category: {name}",
+  "filter_modal.select_filter.search": "Search or create",
+  "filter_modal.select_filter.subtitle": "Use an existing category or create a new one",
+  "filter_modal.select_filter.title": "Filter this post",
+  "filter_modal.title.status": "Filter a post",
+  "follow_recommendations.done": "Confectum",
+  "follow_recommendations.heading": "Follow people you'd like to see posts from! Here are some suggestions.",
+  "follow_recommendations.lead": "Posts from people you follow will show up in chronological order on your home feed. Don't be afraid to make mistakes, you can unfollow people just as easily any time!",
+  "follow_request.authorize": "Authorize",
+  "follow_request.reject": "Reject",
+  "follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
+  "footer.about": "About",
+  "footer.directory": "Profiles directory",
+  "footer.get_app": "Get the app",
+  "footer.invite": "Invite people",
+  "footer.keyboard_shortcuts": "Keyboard shortcuts",
+  "footer.privacy_policy": "Privacy policy",
+  "footer.source_code": "View source code",
+  "generic.saved": "Saved",
+  "getting_started.heading": "Getting started",
+  "hashtag.column_header.tag_mode.all": "and {additional}",
+  "hashtag.column_header.tag_mode.any": "or {additional}",
+  "hashtag.column_header.tag_mode.none": "without {additional}",
+  "hashtag.column_settings.select.no_options_message": "No suggestions found",
+  "hashtag.column_settings.select.placeholder": "Enter hashtags…",
+  "hashtag.column_settings.tag_mode.all": "All of these",
+  "hashtag.column_settings.tag_mode.any": "Any of these",
+  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
+  "hashtag.follow": "Follow hashtag",
+  "hashtag.unfollow": "Unfollow hashtag",
+  "home.column_settings.basic": "Basic",
+  "home.column_settings.show_reblogs": "Show boosts",
+  "home.column_settings.show_replies": "Show replies",
+  "home.hide_announcements": "Hide announcements",
+  "home.show_announcements": "Show announcements",
+  "interaction_modal.description.favourite": "With an account on Mastodon, you can favourite this post to let the author know you appreciate it and save it for later.",
+  "interaction_modal.description.follow": "With an account on Mastodon, you can follow {name} to receive their posts in your home feed.",
+  "interaction_modal.description.reblog": "With an account on Mastodon, you can boost this post to share it with your own followers.",
+  "interaction_modal.description.reply": "With an account on Mastodon, you can respond to this post.",
+  "interaction_modal.on_another_server": "On a different server",
+  "interaction_modal.on_this_server": "On this server",
+  "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favourite Mastodon app or the web interface of your Mastodon server.",
+  "interaction_modal.preamble": "Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.",
+  "interaction_modal.title.favourite": "Favourite {name}'s post",
+  "interaction_modal.title.follow": "Follow {name}",
+  "interaction_modal.title.reblog": "Boost {name}'s post",
+  "interaction_modal.title.reply": "Reply to {name}'s post",
+  "intervals.full.days": "{number, plural, one {# day} other {# days}}",
+  "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
+  "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
+  "keyboard_shortcuts.back": "to navigate back",
+  "keyboard_shortcuts.blocked": "to open blocked users list",
+  "keyboard_shortcuts.boost": "to boost",
+  "keyboard_shortcuts.column": "to focus a status in one of the columns",
+  "keyboard_shortcuts.compose": "to focus the compose textarea",
+  "keyboard_shortcuts.description": "Descriptio",
+  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.down": "to move down in the list",
+  "keyboard_shortcuts.enter": "Aperire contributum",
+  "keyboard_shortcuts.favourite": "to favourite",
+  "keyboard_shortcuts.favourites": "to open favourites list",
+  "keyboard_shortcuts.federated": "to open federated timeline",
+  "keyboard_shortcuts.heading": "Keyboard Shortcuts",
+  "keyboard_shortcuts.home": "to open home timeline",
+  "keyboard_shortcuts.hotkey": "Hotkey",
+  "keyboard_shortcuts.legend": "to display this legend",
+  "keyboard_shortcuts.local": "to open local timeline",
+  "keyboard_shortcuts.mention": "to mention author",
+  "keyboard_shortcuts.muted": "to open muted users list",
+  "keyboard_shortcuts.my_profile": "to open your profile",
+  "keyboard_shortcuts.notifications": "to open notifications column",
+  "keyboard_shortcuts.open_media": "to open media",
+  "keyboard_shortcuts.pinned": "to open pinned posts list",
+  "keyboard_shortcuts.profile": "to open author's profile",
+  "keyboard_shortcuts.reply": "Respondere ad contributum",
+  "keyboard_shortcuts.requests": "to open follow requests list",
+  "keyboard_shortcuts.search": "to focus search",
+  "keyboard_shortcuts.spoilers": "to show/hide CW field",
+  "keyboard_shortcuts.start": "to open \"get started\" column",
+  "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
+  "keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
+  "keyboard_shortcuts.toot": "to start a brand new post",
+  "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
+  "keyboard_shortcuts.up": "to move up in the list",
+  "lightbox.close": "Claudere",
+  "lightbox.compress": "Compress image view box",
+  "lightbox.expand": "Expand image view box",
+  "lightbox.next": "Secundum",
+  "lightbox.previous": "Previous",
+  "limited_account_hint.action": "Show profile anyway",
+  "limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
+  "lists.account.add": "Add to list",
+  "lists.account.remove": "Remove from list",
+  "lists.delete": "Delete list",
+  "lists.edit": "Edit list",
+  "lists.edit.submit": "Change title",
+  "lists.new.create": "Add list",
+  "lists.new.title_placeholder": "New list title",
+  "lists.replies_policy.followed": "Any followed user",
+  "lists.replies_policy.list": "Members of the list",
+  "lists.replies_policy.none": "No one",
+  "lists.replies_policy.title": "Show replies to:",
+  "lists.search": "Search among people you follow",
+  "lists.subheading": "Your lists",
+  "load_pending": "{count, plural, one {# new item} other {# new items}}",
+  "loading_indicator.label": "Loading...",
+  "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}",
+  "missing_indicator.label": "Not found",
+  "missing_indicator.sublabel": "This resource could not be found",
+  "moved_to_account_banner.text": "Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.",
+  "mute_modal.duration": "Duration",
+  "mute_modal.hide_notifications": "Hide notifications from this user?",
+  "mute_modal.indefinite": "Indefinite",
+  "navigation_bar.about": "About",
+  "navigation_bar.blocks": "Blocked users",
+  "navigation_bar.bookmarks": "Bookmarks",
+  "navigation_bar.community_timeline": "Local timeline",
+  "navigation_bar.compose": "Compose new post",
+  "navigation_bar.direct": "Direct messages",
+  "navigation_bar.discover": "Discover",
+  "navigation_bar.domain_blocks": "Hidden domains",
+  "navigation_bar.edit_profile": "Edit profile",
+  "navigation_bar.explore": "Explore",
+  "navigation_bar.favourites": "Favourites",
+  "navigation_bar.filters": "Muted words",
+  "navigation_bar.follow_requests": "Follow requests",
+  "navigation_bar.follows_and_followers": "Follows and followers",
+  "navigation_bar.lists": "Lists",
+  "navigation_bar.logout": "Logout",
+  "navigation_bar.mutes": "Muted users",
+  "navigation_bar.personal": "Personal",
+  "navigation_bar.pins": "Pinned posts",
+  "navigation_bar.preferences": "Preferences",
+  "navigation_bar.public_timeline": "Federated timeline",
+  "navigation_bar.search": "Search",
+  "navigation_bar.security": "Security",
+  "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
+  "notification.admin.report": "{name} reported {target}",
+  "notification.admin.sign_up": "{name} signed up",
+  "notification.favourite": "{name} favourited your status",
+  "notification.follow": "{name} followed you",
+  "notification.follow_request": "{name} has requested to follow you",
+  "notification.mention": "{name} mentioned you",
+  "notification.own_poll": "Your poll has ended",
+  "notification.poll": "A poll you have voted in has ended",
+  "notification.reblog": "{name} boosted your status",
+  "notification.status": "{name} just posted",
+  "notification.update": "{name} edited a post",
+  "notifications.clear": "Clear notifications",
+  "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
+  "notifications.column_settings.admin.report": "New reports:",
+  "notifications.column_settings.admin.sign_up": "New sign-ups:",
+  "notifications.column_settings.alert": "Desktop notifications",
+  "notifications.column_settings.favourite": "Favourites:",
+  "notifications.column_settings.filter_bar.advanced": "Display all categories",
+  "notifications.column_settings.filter_bar.category": "Quick filter bar",
+  "notifications.column_settings.filter_bar.show_bar": "Show filter bar",
+  "notifications.column_settings.follow": "New followers:",
+  "notifications.column_settings.follow_request": "New follow requests:",
+  "notifications.column_settings.mention": "Mentions:",
+  "notifications.column_settings.poll": "Poll results:",
+  "notifications.column_settings.push": "Push notifications",
+  "notifications.column_settings.reblog": "Boosts:",
+  "notifications.column_settings.show": "Show in column",
+  "notifications.column_settings.sound": "Play sound",
+  "notifications.column_settings.status": "New posts:",
+  "notifications.column_settings.unread_notifications.category": "Unread notifications",
+  "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications",
+  "notifications.column_settings.update": "Edits:",
+  "notifications.filter.all": "Omnia",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
+  "notifications.filter.polls": "Eventus electionis",
+  "notifications.filter.statuses": "Updates from people you follow",
+  "notifications.grant_permission": "Grant permission.",
+  "notifications.group": "{count} notifications",
+  "notifications.mark_as_read": "Mark every notification as read",
+  "notifications.permission_denied": "Desktop notifications are unavailable due to previously denied browser permissions request",
+  "notifications.permission_denied_alert": "Desktop notifications can't be enabled, as browser permission has been denied before",
+  "notifications.permission_required": "Desktop notifications are unavailable because the required permission has not been granted.",
+  "notifications_permission_banner.enable": "Enable desktop notifications",
+  "notifications_permission_banner.how_to_control": "To receive notifications when Mastodon isn't open, enable desktop notifications. You can control precisely which types of interactions generate desktop notifications through the {icon} button above once they're enabled.",
+  "notifications_permission_banner.title": "Never miss a thing",
+  "picture_in_picture.restore": "Put it back",
+  "poll.closed": "Clausum",
+  "poll.refresh": "Refresh",
+  "poll.total_people": "{count, plural, one {# person} other {# people}}",
+  "poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
+  "poll.vote": "Eligere",
+  "poll.voted": "Elegisti hoc responsum",
+  "poll.votes": "{votes, plural, one {# vote} other {# votes}}",
+  "poll_button.add_poll": "Addere electionem",
+  "poll_button.remove_poll": "Auferre electionem",
+  "privacy.change": "Adjust status privacy",
+  "privacy.direct.long": "Visible for mentioned users only",
+  "privacy.direct.short": "Direct",
+  "privacy.private.long": "Visible for followers only",
+  "privacy.private.short": "Followers-only",
+  "privacy.public.long": "Coram publico",
+  "privacy.public.short": "Coram publico",
+  "privacy.unlisted.long": "Visible for all, but opted-out of discovery features",
+  "privacy.unlisted.short": "Unlisted",
+  "privacy_policy.last_updated": "Last updated {date}",
+  "privacy_policy.title": "Privacy Policy",
+  "refresh": "Refresh",
+  "regeneration_indicator.label": "Loading…",
+  "regeneration_indicator.sublabel": "Your home feed is being prepared!",
+  "relative_time.days": "{number}d",
+  "relative_time.full.days": "{number, plural, one {# day} other {# days}} ago",
+  "relative_time.full.hours": "{number, plural, one {# hour} other {# hours}} ago",
+  "relative_time.full.just_now": "nunc",
+  "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago",
+  "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago",
+  "relative_time.hours": "{number}h",
+  "relative_time.just_now": "nunc",
+  "relative_time.minutes": "{number}m",
+  "relative_time.seconds": "{number}s",
+  "relative_time.today": "hodie",
+  "reply_indicator.cancel": "Cancel",
+  "report.block": "Impedimentum",
+  "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.",
+  "report.categories.other": "Altera",
+  "report.categories.spam": "Spam",
+  "report.categories.violation": "Content violates one or more server rules",
+  "report.category.subtitle": "Choose the best match",
+  "report.category.title": "Tell us what's going on with this {type}",
+  "report.category.title_account": "notio",
+  "report.category.title_status": "contributum",
+  "report.close": "Confectum",
+  "report.comment.title": "Is there anything else you think we should know?",
+  "report.forward": "Forward to {target}",
+  "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
+  "report.mute": "Confutare",
+  "report.mute_explanation": "You will not see their posts. They can still follow you and see your posts and will not know that they are muted.",
+  "report.next": "Secundum",
+  "report.placeholder": "Type or paste additional comments",
+  "report.reasons.dislike": "I don't like it",
+  "report.reasons.dislike_description": "It is not something you want to see",
+  "report.reasons.other": "It's something else",
+  "report.reasons.other_description": "The issue does not fit into other categories",
+  "report.reasons.spam": "It's spam",
+  "report.reasons.spam_description": "Malicious links, fake engagement, or repetitive replies",
+  "report.reasons.violation": "It violates server rules",
+  "report.reasons.violation_description": "You are aware that it breaks specific rules",
+  "report.rules.subtitle": "Select all that apply",
+  "report.rules.title": "Which rules are being violated?",
+  "report.statuses.subtitle": "Select all that apply",
+  "report.statuses.title": "Are there any posts that back up this report?",
+  "report.submit": "Mittere",
+  "report.target": "Report {target}",
+  "report.thanks.take_action": "Here are your options for controlling what you see on Mastodon:",
+  "report.thanks.take_action_actionable": "While we review this, you can take action against @{name}:",
+  "report.thanks.title": "Don't want to see this?",
+  "report.thanks.title_actionable": "Thanks for reporting, we'll look into this.",
+  "report.unfollow": "Unfollow @{name}",
+  "report.unfollow_explanation": "You are following this account. To not see their posts in your home feed anymore, unfollow them.",
+  "report_notification.attached_statuses": "{count, plural, one {{count} post} other {{count} posts}} attached",
+  "report_notification.categories.other": "Altera",
+  "report_notification.categories.spam": "Spam",
+  "report_notification.categories.violation": "Rule violation",
+  "report_notification.open": "Open report",
+  "search.placeholder": "Quaerere",
+  "search.search_or_paste": "Search or paste URL",
+  "search_popout.search_format": "Advanced search format",
+  "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
+  "search_popout.tips.hashtag": "hashtag",
+  "search_popout.tips.status": "status",
+  "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
+  "search_popout.tips.user": "user",
+  "search_results.accounts": "People",
+  "search_results.all": "All",
+  "search_results.hashtags": "Hashtags",
+  "search_results.nothing_found": "Could not find anything for these search terms",
+  "search_results.statuses": "Posts",
+  "search_results.statuses_fts_disabled": "Searching posts by their content is not enabled on this Mastodon server.",
+  "search_results.title": "Search for {q}",
+  "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
+  "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)",
+  "server_banner.active_users": "active users",
+  "server_banner.administered_by": "Administered by:",
+  "server_banner.introduction": "{domain} is part of the decentralized social network powered by {mastodon}.",
+  "server_banner.learn_more": "Discere plura",
+  "server_banner.server_stats": "Server stats:",
+  "sign_in_banner.create_account": "Create account",
+  "sign_in_banner.sign_in": "Sign in",
+  "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
+  "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
+  "status.admin_status": "Open this status in the moderation interface",
+  "status.block": "Impedire @{name}",
+  "status.bookmark": "Signa paginaris",
+  "status.cancel_reblog_private": "Unboost",
+  "status.cannot_reblog": "This post cannot be boosted",
+  "status.copy": "Copy link to status",
+  "status.delete": "Oblitterare",
+  "status.detailed_status": "Detailed conversation view",
+  "status.direct": "Direct message @{name}",
+  "status.edit": "Recolere",
+  "status.edited": "Recultum {date}",
+  "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}",
+  "status.embed": "Embed",
+  "status.favourite": "Favourite",
+  "status.filter": "Filter this post",
+  "status.filtered": "Filtered",
+  "status.hide": "Hide post",
+  "status.history.created": "{name} created {date}",
+  "status.history.edited": "{name} edited {date}",
+  "status.load_more": "Load more",
+  "status.media_hidden": "Media hidden",
+  "status.mention": "Mention @{name}",
+  "status.more": "More",
+  "status.mute": "Mute @{name}",
+  "status.mute_conversation": "Mute conversation",
+  "status.open": "Expand this status",
+  "status.pin": "Pin on profile",
+  "status.pinned": "Pinned post",
+  "status.read_more": "Read more",
+  "status.reblog": "Boost",
+  "status.reblog_private": "Boost with original visibility",
+  "status.reblogged_by": "{name} boosted",
+  "status.reblogs.empty": "No one has boosted this post yet. When someone does, they will show up here.",
+  "status.redraft": "Delete & re-draft",
+  "status.remove_bookmark": "Remove bookmark",
+  "status.replied_to": "Replied to {name}",
+  "status.reply": "Reply",
+  "status.replyAll": "Reply to thread",
+  "status.report": "Report @{name}",
+  "status.sensitive_warning": "Sensitive content",
+  "status.share": "Share",
+  "status.show_filter_reason": "Show anyway",
+  "status.show_less": "Show less",
+  "status.show_less_all": "Show less for all",
+  "status.show_more": "Show more",
+  "status.show_more_all": "Show more for all",
+  "status.show_original": "Show original",
+  "status.translate": "Translate",
+  "status.translated_from_with": "Translated from {lang} using {provider}",
+  "status.uncached_media_warning": "Not available",
+  "status.unmute_conversation": "Unmute conversation",
+  "status.unpin": "Unpin from profile",
+  "subscribed_languages.lead": "Only posts in selected languages will appear on your home and list timelines after the change. Select none to receive posts in all languages.",
+  "subscribed_languages.save": "Save changes",
+  "subscribed_languages.target": "Change subscribed languages for {target}",
+  "suggestions.dismiss": "Dismiss suggestion",
+  "suggestions.header": "You might be interested in…",
+  "tabs_bar.federated_timeline": "Foederatum",
+  "tabs_bar.home": "Domi",
+  "tabs_bar.local_timeline": "Local",
+  "tabs_bar.notifications": "Notifications",
+  "time_remaining.days": "{number, plural, one {# day} other {# days}} left",
+  "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
+  "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
+  "time_remaining.moments": "Moments remaining",
+  "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
+  "timeline_hint.remote_resource_not_displayed": "{resource} from other servers are not displayed.",
+  "timeline_hint.resources.followers": "Followers",
+  "timeline_hint.resources.follows": "Follows",
+  "timeline_hint.resources.statuses": "Contributa pristina",
+  "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {{days} days}}",
+  "trends.trending_now": "Trending now",
+  "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
+  "units.short.billion": "{count}B",
+  "units.short.million": "{count}M",
+  "units.short.thousand": "{count}K",
+  "upload_area.title": "Drag & drop to upload",
+  "upload_button.label": "Add images, a video or an audio file",
+  "upload_error.limit": "File upload limit exceeded.",
+  "upload_error.poll": "File upload not allowed with polls.",
+  "upload_form.audio_description": "Describe for people who are hard of hearing",
+  "upload_form.description": "Describe for people who are blind or have low vision",
+  "upload_form.description_missing": "No description added",
+  "upload_form.edit": "Recolere",
+  "upload_form.thumbnail": "Change thumbnail",
+  "upload_form.undo": "Oblitterare",
+  "upload_form.video_description": "Describe for people who are deaf, hard of hearing, blind or have low vision",
+  "upload_modal.analyzing_picture": "Analyzing picture…",
+  "upload_modal.apply": "Apply",
+  "upload_modal.applying": "Applying…",
+  "upload_modal.choose_image": "Choose image",
+  "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
+  "upload_modal.detect_text": "Detect text from picture",
+  "upload_modal.edit_media": "Edit media",
+  "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
+  "upload_modal.preparing_ocr": "Preparing OCR…",
+  "upload_modal.preview_label": "Preview ({ratio})",
+  "upload_progress.label": "Uploading…",
+  "upload_progress.processing": "Processing…",
+  "video.close": "Close video",
+  "video.download": "Download file",
+  "video.exit_fullscreen": "Exit full screen",
+  "video.expand": "Expand video",
+  "video.fullscreen": "Full screen",
+  "video.hide": "Hide video",
+  "video.mute": "Confutare soni",
+  "video.pause": "Pause",
+  "video.play": "Play",
+  "video.unmute": "Unmute sound"
+}
diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json
index bff4aaedd..1d4923254 100644
--- a/app/javascript/mastodon/locales/lt.json
+++ b/app/javascript/mastodon/locales/lt.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Pranešti apie @{name}",
   "account.requested": "Awaiting approval",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Learn more",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
   "compose_form.placeholder": "What is on your mind?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json
index 3949654f5..a593ab501 100644
--- a/app/javascript/mastodon/locales/lv.json
+++ b/app/javascript/mastodon/locales/lv.json
@@ -1,19 +1,19 @@
 {
   "about.blocks": "Moderētie serveri",
   "about.contact": "Kontakts:",
-  "about.disclaimer": "Mastodon ir bezmaksas atvērtā pirmkoda programmatūra un Mastodon gGmbH preču zīme.",
+  "about.disclaimer": "Mastodon ir bezmaksas atklātā pirmkoda programmatūra un Mastodon gGmbH preču zīme.",
   "about.domain_blocks.no_reason_available": "Iemesls nav norādīts",
   "about.domain_blocks.preamble": "Mastodon parasti ļauj apskatīt saturu un mijiedarboties ar lietotājiem no jebkura cita federācijas servera. Šie ir izņēmumi, kas veikti šajā konkrētajā serverī.",
   "about.domain_blocks.silenced.explanation": "Parasti tu neredzēsi profilus un saturu no šī servera, ja vien tu nepārprotami izvēlēsies to pārskatīt vai sekot.",
-  "about.domain_blocks.silenced.title": "Ierobežotās",
+  "about.domain_blocks.silenced.title": "Ierobežotie",
   "about.domain_blocks.suspended.explanation": "Nekādi dati no šī servera netiks apstrādāti, uzglabāti vai apmainīti, padarot neiespējamu mijiedarbību vai saziņu ar lietotājiem no šī servera.",
   "about.domain_blocks.suspended.title": "Apturētie",
   "about.not_available": "Šī informācija šajā serverī nav bijusi pieejama.",
-  "about.powered_by": "Decentralizētu sociālo multividi nodrošina {mastodon}",
+  "about.powered_by": "Decentralizētu sociālo tīklu nodrošina {mastodon}",
   "about.rules": "Servera noteikumi",
   "account.account_note_header": "Piezīme",
   "account.add_or_remove_from_list": "Pievienot vai noņemt no saraksta",
-  "account.badges.bot": "Bots",
+  "account.badges.bot": "Robots",
   "account.badges.group": "Grupa",
   "account.block": "Bloķēt @{name}",
   "account.block_domain": "Bloķēt domēnu {domain}",
@@ -34,14 +34,14 @@
   "account.followers.empty": "Šim lietotājam vēl nav sekotāju.",
   "account.followers_counter": "{count, plural, zero {{counter} sekotāju} one {{counter} sekotājs} other {{counter} sekotāji}}",
   "account.following": "Seko",
-  "account.following_counter": "{count, plural, one {{counter} Sekojamais} other {{counter} Sekojamie}}",
+  "account.following_counter": "{count, plural, one {{counter} sekojamais} other {{counter} sekojamie}}",
   "account.follows.empty": "Šis lietotājs pagaidām nevienam neseko.",
   "account.follows_you": "Seko tev",
   "account.go_to_profile": "Doties uz profilu",
-  "account.hide_reblogs": "Paslēpt pastiprinātos ierakstus no lietotāja @{name}",
+  "account.hide_reblogs": "Slēpt @{name} izceltas ziņas",
   "account.joined_short": "Pievienojās",
   "account.languages": "Mainīt abonētās valodas",
-  "account.link_verified_on": "Šīs saites piederība ir pārbaudīta {date}",
+  "account.link_verified_on": "Šīs saites piederība tika pārbaudīta {date}",
   "account.locked_info": "Šī konta privātuma statuss ir slēgts. Īpašnieks izskatīs, kurš viņam drīkst sekot.",
   "account.media": "Multivide",
   "account.mention": "Pieminēt @{name}",
@@ -53,11 +53,12 @@
   "account.posts": "Ieraksti",
   "account.posts_with_replies": "Ieraksti un atbildes",
   "account.report": "Sūdzēties par @{name}",
-  "account.requested": "Gaidām apstiprinājumu. Nospied lai atceltu sekošanas pieparasījumu",
+  "account.requested": "Gaida apstiprinājumu. Nospied, lai atceltu sekošanas pieparasījumu",
+  "account.requested_follow": "{name} nosūtīja tev sekošanas pieprasījumu",
   "account.share": "Dalīties ar @{name} profilu",
   "account.show_reblogs": "Parādīt @{name} pastiprinātos ierakstus",
   "account.statuses_counter": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}}",
-  "account.unblock": "Atbloķēt lietotāju @{name}",
+  "account.unblock": "Atbloķēt @{name}",
   "account.unblock_domain": "Atbloķēt domēnu {domain}",
   "account.unblock_short": "Atbloķēt",
   "account.unendorse": "Neizcelt profilā",
@@ -65,7 +66,7 @@
   "account.unmute": "Noņemt apklusinājumu @{name}",
   "account.unmute_notifications": "Rādīt paziņojumus no @{name}",
   "account.unmute_short": "Noņemt apklusinājumu",
-  "account_note.placeholder": "Noklikšķiniet, lai pievienotu piezīmi",
+  "account_note.placeholder": "Noklikšķini, lai pievienotu piezīmi",
   "admin.dashboard.daily_retention": "Lietotāju saglabāšanas rādītājs dienā pēc reģistrēšanās",
   "admin.dashboard.monthly_retention": "Lietotāju saglabāšanas rādītājs mēnesī pēc reģistrēšanās",
   "admin.dashboard.retention.average": "Vidēji",
@@ -127,8 +128,8 @@
   "compose.language.search": "Meklēt valodas...",
   "compose_form.direct_message_warning_learn_more": "Uzzināt vairāk",
   "compose_form.encryption_warning": "Ziņas vietnē Mastodon nav pilnībā šifrētas. Nedalies ar sensitīvu informāciju caur Mastodon.",
-  "compose_form.hashtag_warning": "Šo ziņu nebūs iespējams atrast tēmturos, jo tā ir nerindota. Tēmturos ir redzamas tikai publiskas ziņas.",
-  "compose_form.lock_disclaimer": "Tavs konts nav {locked}. Ikviens var Tev sekot lai apskatītu tikai sekotājiem paredzētos ziņojumus.",
+  "compose_form.hashtag_warning": "Šī ziņa netiks norādīta zem nevienas atsauces, jo tā nav publiska. Tikai publiskās ziņās var meklēt pēc atsauces.",
+  "compose_form.lock_disclaimer": "Tavs konts nav {locked}. Ikviens var tev piesekot un redzēt tikai sekotājiem paredzētos ziņojumus.",
   "compose_form.lock_disclaimer.lock": "slēgts",
   "compose_form.placeholder": "Kas tev padomā?",
   "compose_form.poll.add_option": "Pievienot izvēli",
@@ -206,7 +207,7 @@
   "emoji_button.search": "Meklēt...",
   "emoji_button.search_results": "Meklēšanas rezultāti",
   "emoji_button.symbols": "Simboli",
-  "emoji_button.travel": "Ceļošana & Vietas",
+  "emoji_button.travel": "Ceļošana un vietas",
   "empty_column.account_suspended": "Konta darbība ir apturēta",
   "empty_column.account_timeline": "Šeit ziņojumu nav!",
   "empty_column.account_unavailable": "Profils nav pieejams",
@@ -216,10 +217,10 @@
   "empty_column.direct": "Pašreiz tev nav privātu ziņu. Tiklīdz tādu nosūtīsi vai saņemsi, tās parādīsies šeit.",
   "empty_column.domain_blocks": "Vēl nav neviena bloķēta domēna.",
   "empty_column.explore_statuses": "Pašlaik nekā aktuāla nav. Pārbaudi vēlāk!",
-  "empty_column.favourited_statuses": "Patreiz tev nav neviena izceltā ieraksta. Kad kādu izcelsi, tas parādīsies šeit.",
+  "empty_column.favourited_statuses": "Pašreiz tev nav neviena izceltā ieraksta. Kad kādu izcelsi, tas parādīsies šeit.",
   "empty_column.favourites": "Neviens šo ziņojumu vel nav izcēlis. Kad kāds to izdarīs, tas parādīsies šeit.",
   "empty_column.follow_recommendations": "Neizdevās ģenerēt tev pielāgotus ieteikumus. Vari mēģināt izmantot meklēšanu, lai meklētu cilvēkus, kurus tu varētu pazīt, vai izpētīt populārākos tēmturus.",
-  "empty_column.follow_requests": "Šobrīd neviens nav pieteicies tev sekot. Kad kāds pieteiksies tas parādīsies šeit.",
+  "empty_column.follow_requests": "Šobrīd tev nav sekošanas pieprasījumu. Kad kāds pieteiksies tev sekot, pieprasījums parādīsies šeit.",
   "empty_column.hashtag": "Ar šo tēmturi nekas nav atrodams.",
   "empty_column.home": "Tava mājas laika līnija ir tukša! Lai to aizpildītu, pieseko vairāk cilvēkiem. {suggestions}",
   "empty_column.home.suggestions": "Apskatīt dažus ieteikumus",
@@ -230,16 +231,20 @@
   "empty_column.public": "Šeit vēl nekā nav! Ieraksti ko publiski vai pieseko lietotājiem no citiem serveriem",
   "error.unexpected_crash.explanation": "Koda kļūdas vai pārlūkprogrammas saderības problēmas dēļ šo lapu nevarēja parādīt pareizi.",
   "error.unexpected_crash.explanation_addons": "Šo lapu nevarēja parādīt pareizi. Šo kļūdu, iespējams, izraisīja pārlūkprogrammas papildinājums vai automātiskās tulkošanas rīki.",
-  "error.unexpected_crash.next_steps": "Mēģini atsvaidzināt lapu. Ja tas nepalīdz, iespējams, varēsi lietot Mastodon, izmantojot citu pārlūkprogrammu vai vietējo lietotni.",
-  "error.unexpected_crash.next_steps_addons": "Mēģini tos atspējot un atsvaidzināt lapu. Ja tas nepalīdz, iespējams, varēsi lietot Mastodon, izmantojot citu pārlūkprogrammu vai vietējo lietotni.",
+  "error.unexpected_crash.next_steps": "Mēģini atsvaidzināt lapu. Ja tas nepalīdz, iespējams, varēsi lietot Mastodon, izmantojot citu pārlūkprogrammu vai lietotni.",
+  "error.unexpected_crash.next_steps_addons": "Mēģini tos atspējot un atsvaidzināt lapu. Ja tas nepalīdz, iespējams, varēsi lietot Mastodon, izmantojot citu pārlūkprogrammu vai lietotni.",
   "errors.unexpected_crash.copy_stacktrace": "Kopēt stacktrace uz starpliktuvi",
   "errors.unexpected_crash.report_issue": "Ziņot par problēmu",
   "explore.search_results": "Meklēšanas rezultāti",
+  "explore.suggested_follows": "Tev",
   "explore.title": "Pārlūkot",
+  "explore.trending_links": "Jaunumi",
+  "explore.trending_statuses": "Ziņas",
+  "explore.trending_tags": "Tēmturi",
   "filter_modal.added.context_mismatch_explanation": "Šī filtra kategorija neattiecas uz kontekstu, kurā esi piekļuvis šai ziņai. Ja vēlies, lai ziņa tiktu filtrēta arī šajā kontekstā, tev būs jārediģē filtrs.",
   "filter_modal.added.context_mismatch_title": "Konteksta neatbilstība!",
   "filter_modal.added.expired_explanation": "Šai filtra kategorijai ir beidzies derīguma termiņš. Lai to lietotu, tev būs jāmaina derīguma termiņš.",
-  "filter_modal.added.expired_title": "Filtrs beidzies!",
+  "filter_modal.added.expired_title": "Filtra termiņš beidzies!",
   "filter_modal.added.review_and_configure": "Lai pārskatītu un tālāk konfigurētu šo filtru kategoriju, dodies uz {settings_link}.",
   "filter_modal.added.review_and_configure_title": "Filtra iestatījumi",
   "filter_modal.added.settings_link": "iestatījumu lapu",
@@ -281,11 +286,11 @@
   "home.column_settings.basic": "Pamata",
   "home.column_settings.show_reblogs": "Rādīt pastiprinātos ierakstus",
   "home.column_settings.show_replies": "Rādīt atbildes",
-  "home.hide_announcements": "Slēpt paziņojumus",
-  "home.show_announcements": "Rādīt paziņojumus",
+  "home.hide_announcements": "Slēpt anonsus",
+  "home.show_announcements": "Rādīt anonsus",
   "interaction_modal.description.favourite": "Ar Mastodon kontu tu vari pievienot šo ziņu izlasei, lai informētu autoru, ka to novērtē, un saglabātu to vēlākai lasīšanai.",
   "interaction_modal.description.follow": "Ar Mastodon kontu tu vari sekot {name}, lai saņemtu viņu ziņas savā mājas plūsmā.",
-  "interaction_modal.description.reblog": "Ar Mastodon kontu tu vari pastiprināt šo ierakstu, lai kopīgotu to ar saviem sekotājiem.",
+  "interaction_modal.description.reblog": "Izmantojot kontu Mastodon, tu vari izcelt šo ziņu, lai kopīgotu to ar saviem sekotājiem.",
   "interaction_modal.description.reply": "Ar Mastodon kontu tu vari atbildēt uz šo ziņu.",
   "interaction_modal.on_another_server": "Citā serverī",
   "interaction_modal.on_this_server": "Šajā serverī",
@@ -305,7 +310,7 @@
   "keyboard_shortcuts.compose": "Fokusēt veidojamā teksta lauku",
   "keyboard_shortcuts.description": "Apraksts",
   "keyboard_shortcuts.direct": "lai atvērtu privāto ziņojumu kolonnu",
-  "keyboard_shortcuts.down": "Pārvietot sarakstā uz leju",
+  "keyboard_shortcuts.down": "Pārvietoties lejup sarakstā",
   "keyboard_shortcuts.enter": "Atvērt ziņu",
   "keyboard_shortcuts.favourite": "Pievienot izlasei",
   "keyboard_shortcuts.favourites": "Atvērt izlašu sarakstu",
@@ -331,7 +336,7 @@
   "keyboard_shortcuts.toggle_sensitivity": "Rādīt/slēpt multividi",
   "keyboard_shortcuts.toot": "Sākt jaunu ziņu",
   "keyboard_shortcuts.unfocus": "Atfokusēt veidojamā teksta/meklēšanas lauku",
-  "keyboard_shortcuts.up": "Pārvietot sarakstā uz augšu",
+  "keyboard_shortcuts.up": "Pārvietoties augšup sarakstā",
   "lightbox.close": "Aizvērt",
   "lightbox.compress": "Saspiest attēla skata lodziņu",
   "lightbox.expand": "Izvērst attēla skata lodziņu",
@@ -408,7 +413,7 @@
   "notifications.column_settings.follow": "Jauni sekotāji:",
   "notifications.column_settings.follow_request": "Jauni sekošanas pieprasījumi:",
   "notifications.column_settings.mention": "Pieminējumi:",
-  "notifications.column_settings.poll": "Aptaujas rezultāti:",
+  "notifications.column_settings.poll": "Aptauju rezultāti:",
   "notifications.column_settings.push": "Uznirstošie paziņojumi",
   "notifications.column_settings.reblog": "Pastiprinātie ieraksti:",
   "notifications.column_settings.show": "Rādīt kolonnā",
@@ -420,18 +425,18 @@
   "notifications.filter.all": "Visi",
   "notifications.filter.boosts": "Pastiprinātie ieraksti",
   "notifications.filter.favourites": "Izlases",
-  "notifications.filter.follows": "Seko",
+  "notifications.filter.follows": "Sekošana",
   "notifications.filter.mentions": "Pieminējumi",
-  "notifications.filter.polls": "Aptaujas rezultāti",
+  "notifications.filter.polls": "Aptauju rezultāti",
   "notifications.filter.statuses": "Jaunumi no cilvēkiem, kuriem tu seko",
   "notifications.grant_permission": "Piešķirt atļauju.",
   "notifications.group": "{count} paziņojumi",
-  "notifications.mark_as_read": "Atzīmēt katru paziņojumu kā izlasītu",
+  "notifications.mark_as_read": "Atzīmēt visus paziņojumus kā izlasītus",
   "notifications.permission_denied": "Darbvirsmas paziņojumi nav pieejami, jo iepriekš tika noraidīts pārlūka atļauju pieprasījums",
   "notifications.permission_denied_alert": "Darbvirsmas paziņojumus nevar iespējot, jo pārlūkprogrammai atļauja tika iepriekš atteikta",
   "notifications.permission_required": "Darbvirsmas paziņojumi nav pieejami, jo nav piešķirta nepieciešamā atļauja.",
   "notifications_permission_banner.enable": "Iespējot darbvirsmas paziņojumus",
-  "notifications_permission_banner.how_to_control": "Lai saņemtu paziņojumus, kad Mastodon nav atvērts, iespējo darbvirsmas paziņojumus. Vari precīzi kontrolēt, kāda veida mijiedarbības ģenerē darbvirsmas paziņojumus, izmantojot augstāk redzamo pogu {icon}, kad tie būs iespējoti.",
+  "notifications_permission_banner.how_to_control": "Lai saņemtu paziņojumus, kad Mastodon nav atvērts, iespējo darbvirsmas paziņojumus. Vari precīzi kontrolēt, kāda veida mijiedarbības rada darbvirsmas paziņojumus, izmantojot augstāk redzamo pogu {icon}, kad tie būs iespējoti.",
   "notifications_permission_banner.title": "Nekad nepalaid neko garām",
   "picture_in_picture.restore": "Novietot atpakaļ",
   "poll.closed": "Pabeigta",
@@ -448,9 +453,9 @@
   "privacy.direct.short": "Tikai minētie cilvēki",
   "privacy.private.long": "Redzama tikai sekotājiem",
   "privacy.private.short": "Tikai sekotājiem",
-  "privacy.public.long": "Redzama visiem",
+  "privacy.public.long": "Redzams visiem",
   "privacy.public.short": "Publiska",
-  "privacy.unlisted.long": "Redzama visiem, bet izslēgta no satura atklāšanas funkcijām",
+  "privacy.unlisted.long": "Redzams visiem, bet izslēgts no satura atklāšanas funkcijām",
   "privacy.unlisted.short": "Nerindota",
   "privacy_policy.last_updated": "Pēdējo reizi atjaunināta {date}",
   "privacy_policy.title": "Privātuma politika",
@@ -477,7 +482,7 @@
   "report.category.subtitle": "Izvēlieties labāko atbilstību",
   "report.category.title": "Pastāsti mums, kas notiek ar šo {type}",
   "report.category.title_account": "profilu",
-  "report.category.title_status": "ierakstu",
+  "report.category.title_status": "ziņu",
   "report.close": "Darīts",
   "report.comment.title": "Vai, tavuprāt, mums vēl būtu kas jāzina?",
   "report.forward": "Pārsūtīt {target}",
@@ -487,7 +492,7 @@
   "report.next": "Tālāk",
   "report.placeholder": "Papildu komentāri",
   "report.reasons.dislike": "Man tas nepatīk",
-  "report.reasons.dislike_description": "Tas nav kaut kas, ko tu vēlies redzēt",
+  "report.reasons.dislike_description": "Tas ir kaut kas, ko tu nevēlies redzēt",
   "report.reasons.other": "Tas ir kaut kas cits",
   "report.reasons.other_description": "Šī sūdzība neatbilst pārējām kategorijām",
   "report.reasons.spam": "Tas ir spams",
@@ -497,16 +502,16 @@
   "report.rules.subtitle": "Atlasi visus atbilstošos",
   "report.rules.title": "Kuri noteikumi tiek pārkāpti?",
   "report.statuses.subtitle": "Atlasi visus atbilstošos",
-  "report.statuses.title": "Vai ir kādas ziņas, kas atbalsta šo sūdzību?",
+  "report.statuses.title": "Vai ir kādi ieraksti, kas atbalsta šo sūdzību?",
   "report.submit": "Iesniegt",
   "report.target": "Sūdzība par {target}",
-  "report.thanks.take_action": "Tālāk ir norādītas iespējas, kā kontrolēt Mastodon redzamo saturu:",
+  "report.thanks.take_action": "Vari veikt šīs darbības, lai kontrolētu Mastodon redzamo saturu:",
   "report.thanks.take_action_actionable": "Kamēr mēs to izskatām, tu vari veikt darbības pret @{name}:",
   "report.thanks.title": "Vai nevēlies to redzēt?",
   "report.thanks.title_actionable": "Paldies, ka ziņoji, mēs to izskatīsim.",
-  "report.unfollow": "Pārtraukt sekošanu @{name}",
+  "report.unfollow": "Pārtraukt sekot @{name}",
   "report.unfollow_explanation": "Tu seko šim kontam. Lai vairs neredzētu viņu ziņas savā mājas plūsmā, pārtrauc viņiem sekot.",
-  "report_notification.attached_statuses": "{count, plural, zero {Pievienota {count} ierakstu} one {Pievienots {count} ieraksts} other {Pievienoti {count} ieraksti}}",
+  "report_notification.attached_statuses": "{count, plural, one {Pievienots {count} ieraksts} other {Pievienoti {count} ieraksti}}",
   "report_notification.categories.other": "Cita",
   "report_notification.categories.spam": "Spams",
   "report_notification.categories.violation": "Noteikumu pārkāpums",
@@ -537,11 +542,12 @@
   "sign_in_banner.sign_in": "Pierakstīties",
   "sign_in_banner.text": "Pieraksties, lai sekotu profiliem vai atsaucēm, pievienotu ziņas izlasei, kopīgotu ziņas un atbildētu uz tām vai mijiedarbotos no sava konta citā serverī.",
   "status.admin_account": "Atvērt @{name} moderēšanas saskarni",
+  "status.admin_domain": "Atvērt {domain} moderēšanas saskarni",
   "status.admin_status": "Atvērt šo ziņu moderācijas saskarnē",
   "status.block": "Bloķēt @{name}",
   "status.bookmark": "Grāmatzīme",
-  "status.cancel_reblog_private": "Noņemt pastiprinājumu",
-  "status.cannot_reblog": "Nevar pastiprināt šo ierakstu",
+  "status.cancel_reblog_private": "Neizcelt",
+  "status.cannot_reblog": "Šo ziņu nevar izcelt",
   "status.copy": "Kopēt saiti uz ziņu",
   "status.delete": "Dzēst",
   "status.detailed_status": "Detalizēts sarunas skats",
@@ -557,14 +563,14 @@
   "status.history.created": "{name} izveidoja {date}",
   "status.history.edited": "{name} rediģēja {date}",
   "status.load_more": "Ielādēt vairāk",
-  "status.media_hidden": "Medijs ir paslēpts",
+  "status.media_hidden": "Multivides ir paslēpts",
   "status.mention": "Pieminēt @{name}",
   "status.more": "Vairāk",
   "status.mute": "Apklusināt @{name}",
   "status.mute_conversation": "Apklusināt sarunu",
   "status.open": "Paplašināt šo ziņu",
   "status.pin": "Piespraust profilam",
-  "status.pinned": "Piespraustā ziņa",
+  "status.pinned": "Piespraustais ieraksts",
   "status.read_more": "Lasīt vairāk",
   "status.reblog": "Pastiprināt",
   "status.reblog_private": "Pastiprināt, nemainot redzamību",
@@ -574,7 +580,7 @@
   "status.remove_bookmark": "Noņemt grāmatzīmi",
   "status.replied_to": "Atbildēja {name}",
   "status.reply": "Atbildēt",
-  "status.replyAll": "Atbildēt uz tematu",
+  "status.replyAll": "Atbildēt uz pavedienu",
   "status.report": "Sūdzēties par @{name}",
   "status.sensitive_warning": "Sensitīvs saturs",
   "status.share": "Kopīgot",
@@ -588,12 +594,12 @@
   "status.translated_from_with": "Tulkots no {lang}, izmantojot {provider}",
   "status.uncached_media_warning": "Nav pieejams",
   "status.unmute_conversation": "Noņemt sarunas apklusinājumu",
-  "status.unpin": "Noņemt no profila",
+  "status.unpin": "Noņemt profila piespraudumu",
   "subscribed_languages.lead": "Pēc izmaiņu veikšanas tavā mājas un sarakstu laika līnijā tiks rādītas tikai ziņas atlasītajās valodās. Neatlasi nevienu, lai saņemtu ziņas visās valodās.",
   "subscribed_languages.save": "Saglabāt izmaiņas",
   "subscribed_languages.target": "Mainīt abonētās valodas priekš {target}",
   "suggestions.dismiss": "Noraidīt ieteikumu",
-  "suggestions.header": "Jūs varētu interesēt arī…",
+  "suggestions.header": "Tevi varētu interesēt arī…",
   "tabs_bar.federated_timeline": "Apvienotā",
   "tabs_bar.home": "Sākums",
   "tabs_bar.local_timeline": "Vietējā",
@@ -630,7 +636,7 @@
   "upload_modal.choose_image": "Izvēlēties attēlu",
   "upload_modal.description_placeholder": "Raibais runcis Rīgā ratu rumbā rūc",
   "upload_modal.detect_text": "Noteikt tekstu no attēla",
-  "upload_modal.edit_media": "Rediģēt mediju",
+  "upload_modal.edit_media": "Rediģēt multividi",
   "upload_modal.hint": "Noklikšķini vai velc apli priekšskatījumā, lai izvēlētos fokusa punktu, kas vienmēr būs redzams visos sīktēlos.",
   "upload_modal.preparing_ocr": "Sagatavo OCR…",
   "upload_modal.preview_label": "Priekšskatīt ({ratio})",
diff --git a/app/javascript/mastodon/locales/mk.json b/app/javascript/mastodon/locales/mk.json
index 2acf78bbc..62be86557 100644
--- a/app/javascript/mastodon/locales/mk.json
+++ b/app/javascript/mastodon/locales/mk.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Тутови и реплики",
   "account.report": "Пријави @{name}",
   "account.requested": "Се чека одобрување. Кликни за да одкажиш барање за следење",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Сподели @{name} профил",
   "account.show_reblogs": "Прикажи бустови од @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Научи повеќе",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "заклучен",
   "compose_form.placeholder": "Што имате на ум?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Пријавете проблем",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json
index a936c8dba..ee33be4a4 100644
--- a/app/javascript/mastodon/locales/ml.json
+++ b/app/javascript/mastodon/locales/ml.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "പോസ്റ്റുകളും മറുപടികളും",
   "account.report": "റിപ്പോർട്ട് ചെയ്യുക @{name}",
   "account.requested": "അനുവാദത്തിനായി കാത്തിരിക്കുന്നു. പിന്തുടരാനുള്ള അപേക്ഷ റദ്ദാക്കുവാൻ ഞെക്കുക",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "@{name} ന്റെ പ്രൊഫൈൽ പങ്കിടുക",
   "account.show_reblogs": "@{name} ൽ നിന്നുള്ള ബൂസ്റ്റുകൾ കാണിക്കുക",
   "account.statuses_counter": "{count, plural, one {{counter} ടൂട്ട്} other {{counter} ടൂട്ടുകൾ}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "ഭാഷകൾ തിരയുക...",
   "compose_form.direct_message_warning_learn_more": "കൂടുതൽ പഠിക്കുക",
   "compose_form.encryption_warning": "Mastodon-ലെ പോസ്റ്റുകൾ എൻഡ്-ടു-എൻഡ് എൻക്രിപ്റ്റ് ചെയ്തവയല്ല. അതിനാൽ Mastodon-ൽ പ്രധാനപ്പെട്ട വിവരങ്ങളൊന്നും പങ്കിടരുത്.",
-  "compose_form.hashtag_warning": "ഈ ടൂട്ട് പട്ടികയിൽ ഇല്ലാത്തതിനാൽ ഒരു ചർച്ചാവിഷയത്തിന്റെ പട്ടികയിലും പെടുകയില്ല. പരസ്യമായ ടൂട്ടുകൾ മാത്രമേ ചർച്ചാവിഷയം അടിസ്ഥാനമാക്കി തിരയുവാൻ സാധിക്കുകയുള്ളു.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "ലോക്കുചെയ്തു",
   "compose_form.placeholder": "നിങ്ങളുടെ മനസ്സിൽ എന്താണ്?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "പ്രശ്നം അറിയിക്കുക",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "പര്യവേക്ഷണം നടത്തുക",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "@{name} -നെ തടയുക",
   "status.bookmark": "ബുക്ക്മാർക്ക്",
@@ -553,7 +559,7 @@
   "status.favourite": "പ്രിയപ്പെട്ടത്",
   "status.filter": "Filter this post",
   "status.filtered": "ഫിൽട്ടർ ചെയ്‌തു",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "കൂടുതൽ ലോഡു ചെയ്യുക",
diff --git a/app/javascript/mastodon/locales/mr.json b/app/javascript/mastodon/locales/mr.json
index 65a4cd8af..c0028e2d4 100644
--- a/app/javascript/mastodon/locales/mr.json
+++ b/app/javascript/mastodon/locales/mr.json
@@ -1,81 +1,82 @@
 {
-  "about.blocks": "Moderated servers",
-  "about.contact": "Contact:",
-  "about.disclaimer": "Mastodon is free, open-source software, and a trademark of Mastodon gGmbH.",
-  "about.domain_blocks.no_reason_available": "Reason not available",
-  "about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.",
-  "about.domain_blocks.silenced.explanation": "You will generally not see profiles and content from this server, unless you explicitly look it up or opt into it by following.",
-  "about.domain_blocks.silenced.title": "Limited",
-  "about.domain_blocks.suspended.explanation": "No data from this server will be processed, stored or exchanged, making any interaction or communication with users from this server impossible.",
-  "about.domain_blocks.suspended.title": "Suspended",
-  "about.not_available": "This information has not been made available on this server.",
-  "about.powered_by": "Decentralized social media powered by {mastodon}",
-  "about.rules": "Server rules",
-  "account.account_note_header": "Note",
+  "about.blocks": "नियंत्रित सर्व्हर",
+  "about.contact": "संपर्क:",
+  "about.disclaimer": "Mastodon हे विनामूल्य, मुक्त-स्रोत सॉफ्टवेअर आहे आणि Mastodon gGmbH चे ट्रेडमार्क आहे.",
+  "about.domain_blocks.no_reason_available": "कारण उपलब्ध नाही",
+  "about.domain_blocks.preamble": "मास्टोडॉन तुम्हाला सामान्यत: फेडिव्हर्समधील इतर कोणत्याही सर्व्हरवरील वापरकर्त्यांवरील मजकूर पाहण्याची आणि त्यांच्याशी संवाद साधण्याची परवानगी देते. या विशिष्ट सर्व्हरवर केलेले हे अपवाद आहेत.",
+  "about.domain_blocks.silenced.explanation": "जोपर्यंत तुम्ही ते स्पष्टपणे शोधत नाही किंवा अनुसरण करून निवड करत नाही तोपर्यंत तुम्हाला या सर्व्हरवरील प्रोफाइल आणि मजकूर दिसणार नाही.",
+  "about.domain_blocks.silenced.title": "मर्यादित",
+  "about.domain_blocks.suspended.explanation": "या सर्व्हरवरील कोणत्याही डेटावर प्रक्रिया, संचयित किंवा देवाणघेवाण केली जाणार नाही, ज्यामुळे या सर्व्हरवरील वापरकर्त्यांशी कोणताही संवाद किंवा परस्पर क्रिया अशक्य होईल.",
+  "about.domain_blocks.suspended.title": "निलंबित",
+  "about.not_available": "ही माहिती या सर्व्हरवर उपलब्ध करून देण्यात आलेली नाही.",
+  "about.powered_by": "{mastodon} द्वारा समर्थित विकेंद्रित सोशल मीडिया",
+  "about.rules": "सर्व्हर नियम",
+  "account.account_note_header": "नोंद",
   "account.add_or_remove_from_list": "यादीत घाला किंवा यादीतून काढून टाका",
   "account.badges.bot": "स्वयंचलित खाते",
-  "account.badges.group": "Group",
+  "account.badges.group": "गट",
   "account.block": "@{name} यांना ब्लॉक करा",
   "account.block_domain": "{domain} पासून सर्व लपवा",
   "account.blocked": "ब्लॉक केले आहे",
-  "account.browse_more_on_origin_server": "Browse more on the original profile",
-  "account.cancel_follow_request": "Withdraw follow request",
+  "account.browse_more_on_origin_server": "मूळ प्रोफाइलवर अधिक ब्राउझ करा",
+  "account.cancel_follow_request": "फॉलो विनंती मागे घ्या",
   "account.direct": "थेट संदेश @{name}",
-  "account.disable_notifications": "Stop notifying me when @{name} posts",
+  "account.disable_notifications": "जेव्हा @{name} पोस्ट करतात तेव्हा मला सूचित करणे थांबवा",
   "account.domain_blocked": "Domain hidden",
   "account.edit_profile": "प्रोफाइल एडिट करा",
-  "account.enable_notifications": "Notify me when @{name} posts",
-  "account.endorse": "Feature on profile",
-  "account.featured_tags.last_status_at": "Last post on {date}",
-  "account.featured_tags.last_status_never": "No posts",
-  "account.featured_tags.title": "{name}'s featured hashtags",
+  "account.enable_notifications": "जेव्हा @{name} पोस्ट करते तेव्हा मला सूचित करा",
+  "account.endorse": "प्रोफाइलवरील वैशिष्ट्य",
+  "account.featured_tags.last_status_at": "शेवटचे पोस्ट {date} रोजी",
+  "account.featured_tags.last_status_never": "पोस्ट नाहीत",
+  "account.featured_tags.title": "{name} चे वैशिष्ट्यीकृत हॅशटॅग",
   "account.follow": "अनुयायी व्हा",
   "account.followers": "अनुयायी",
   "account.followers.empty": "ह्या वापरकर्त्याचा आतापर्यंत कोणी अनुयायी नाही.",
-  "account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
-  "account.following": "Following",
-  "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
+  "account.followers_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
+  "account.following": "अनुसरण",
+  "account.following_counter": "{count, plural, one {{counter} following} other {{counter} following}}",
   "account.follows.empty": "हा वापरकर्ता अजूनपर्यंत कोणाचा अनुयायी नाही.",
   "account.follows_you": "तुमचा अनुयायी आहे",
-  "account.go_to_profile": "Go to profile",
+  "account.go_to_profile": "प्रोफाइल वर जा",
   "account.hide_reblogs": "@{name} पासून सर्व बूस्ट लपवा",
-  "account.joined_short": "Joined",
-  "account.languages": "Change subscribed languages",
-  "account.link_verified_on": "Ownership of this link was checked on {date}",
-  "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
+  "account.joined_short": "सामील झाले",
+  "account.languages": "सदस्यता घेतलेल्या भाषा बदला",
+  "account.link_verified_on": "या लिंकची मालकी {date} रोजी तपासली गेली",
+  "account.locked_info": "या खात्याची गोपनीयता स्थिती लॉक वर सेट केली आहे. त्यांचे अनुसरण कोण करू शकते याचे मालक स्वतः पुनरावलोकन करतात.",
   "account.media": "दृक्‌‌श्राव्य मजकूर",
   "account.mention": "@{name} चा उल्लेख करा",
-  "account.moved_to": "{name} has indicated that their new account is now:",
+  "account.moved_to": "{name} ने सूचित केले आहे की त्यांचे नवीन खाते आता आहे:",
   "account.mute": "@{name} ला मूक कारा",
-  "account.mute_notifications": "Mute notifications from @{name}",
-  "account.muted": "Muted",
-  "account.open_original_page": "Open original page",
+  "account.mute_notifications": "@{name} कडील सूचना नि: शब्द करा",
+  "account.muted": "मौन",
+  "account.open_original_page": "मूळ पृष्ठ उघडा",
   "account.posts": "Toots",
   "account.posts_with_replies": "Toots and replies",
-  "account.report": "Report @{name}",
+  "account.report": "@{name} ची तक्रार करा",
   "account.requested": "Awaiting approval",
-  "account.share": "Share @{name}'s profile",
+  "account.requested_follow": "{name} has requested to follow you",
+  "account.share": "@{name} चे प्रोफाइल शेअर करा",
   "account.show_reblogs": "{name}चे सर्व बुस्ट्स दाखवा",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "@{name} ला ब्लॉक करा",
   "account.unblock_domain": "उघड करा {domain}",
-  "account.unblock_short": "Unblock",
-  "account.unendorse": "Don't feature on profile",
+  "account.unblock_short": "अनब्लॉक करा",
+  "account.unendorse": "प्रोफाइलवर वैशिष्ट्य देऊ नका",
   "account.unfollow": "अनुयायी असणे थांबवा",
-  "account.unmute": "Unmute @{name}",
-  "account.unmute_notifications": "Unmute notifications from @{name}",
-  "account.unmute_short": "Unmute",
+  "account.unmute": "@{name} अनम्यूट करा",
+  "account.unmute_notifications": "@{name} कडील सूचना अनम्यूट करा",
+  "account.unmute_short": "अनम्यूट करा",
   "account_note.placeholder": "Click to add a note",
-  "admin.dashboard.daily_retention": "User retention rate by day after sign-up",
-  "admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
-  "admin.dashboard.retention.average": "Average",
-  "admin.dashboard.retention.cohort": "Sign-up month",
-  "admin.dashboard.retention.cohort_size": "New users",
-  "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
-  "alert.rate_limited.title": "Rate limited",
-  "alert.unexpected.message": "An unexpected error occurred.",
+  "admin.dashboard.daily_retention": "साइन अप केल्यानंतर दिवसा वापरकर्ता धारणा दर",
+  "admin.dashboard.monthly_retention": "साइन अप केल्यानंतर महिन्यानुसार वापरकर्ता धारणा दर",
+  "admin.dashboard.retention.average": "सरासरी",
+  "admin.dashboard.retention.cohort": "साइन-अप महिना",
+  "admin.dashboard.retention.cohort_size": "नवीन वापरकर्ता",
+  "alert.rate_limited.message": "कृपया {retry_time, time, medium} नंतर पुन्हा प्रयत्न करा.",
+  "alert.rate_limited.title": "दर मर्यादित",
+  "alert.unexpected.message": "एक अनपेक्षित त्रुटी आली.",
   "alert.unexpected.title": "अरेरे!",
-  "announcement.announcement": "Announcement",
+  "announcement.announcement": "घोषणा",
   "attachments_list.unprocessed": "(unprocessed)",
   "audio.hide": "Hide audio",
   "autosuggest_hashtag.per_week": "{count} प्रतिसप्ताह",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "अधिक जाणून घ्या",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
   "compose_form.placeholder": "आपल्या मनात काय आहे?",
@@ -162,8 +163,8 @@
   "confirmations.domain_block.confirm": "संपूर्ण डोमेन लपवा",
   "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
   "confirmations.logout.confirm": "Log out",
-  "confirmations.logout.message": "Are you sure you want to log out?",
-  "confirmations.mute.confirm": "Mute",
+  "confirmations.logout.message": "तुमची खात्री आहे की तुम्ही लॉग आउट करू इच्छिता?",
+  "confirmations.mute.confirm": "आवाज बंद करा",
   "confirmations.mute.explanation": "This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.",
   "confirmations.mute.message": "Are you sure you want to mute {name}?",
   "confirmations.redraft.confirm": "Delete & redraft",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -272,29 +277,29 @@
   "hashtag.column_header.tag_mode.none": "without {additional}",
   "hashtag.column_settings.select.no_options_message": "No suggestions found",
   "hashtag.column_settings.select.placeholder": "Enter hashtags…",
-  "hashtag.column_settings.tag_mode.all": "All of these",
-  "hashtag.column_settings.tag_mode.any": "Any of these",
-  "hashtag.column_settings.tag_mode.none": "None of these",
+  "hashtag.column_settings.tag_mode.all": "यातील सर्व",
+  "hashtag.column_settings.tag_mode.any": "यापैकी कोणतेही",
+  "hashtag.column_settings.tag_mode.none": "यापैकी एकही नाही",
   "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
-  "hashtag.follow": "Follow hashtag",
-  "hashtag.unfollow": "Unfollow hashtag",
-  "home.column_settings.basic": "Basic",
-  "home.column_settings.show_reblogs": "Show boosts",
-  "home.column_settings.show_replies": "Show replies",
-  "home.hide_announcements": "Hide announcements",
-  "home.show_announcements": "Show announcements",
-  "interaction_modal.description.favourite": "With an account on Mastodon, you can favourite this post to let the author know you appreciate it and save it for later.",
-  "interaction_modal.description.follow": "With an account on Mastodon, you can follow {name} to receive their posts in your home feed.",
-  "interaction_modal.description.reblog": "With an account on Mastodon, you can boost this post to share it with your own followers.",
-  "interaction_modal.description.reply": "With an account on Mastodon, you can respond to this post.",
-  "interaction_modal.on_another_server": "On a different server",
-  "interaction_modal.on_this_server": "On this server",
-  "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favourite Mastodon app or the web interface of your Mastodon server.",
-  "interaction_modal.preamble": "Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.",
-  "interaction_modal.title.favourite": "Favourite {name}'s post",
-  "interaction_modal.title.follow": "Follow {name}",
-  "interaction_modal.title.reblog": "Boost {name}'s post",
-  "interaction_modal.title.reply": "Reply to {name}'s post",
+  "hashtag.follow": "हॅशटॅग फॉलो करा",
+  "hashtag.unfollow": "हॅशटॅग अनफॉलो करा",
+  "home.column_settings.basic": "मूळ",
+  "home.column_settings.show_reblogs": "बूस्ट दाखवा",
+  "home.column_settings.show_replies": "उत्तरे दाखवा",
+  "home.hide_announcements": "घोषणा लपवा",
+  "home.show_announcements": "घोषणा दाखवा",
+  "interaction_modal.description.favourite": "मॅस्टोडॉनवरील खात्यासह, तुम्ही हे पोस्ट आवडते म्हणून लेखकाला कळवून तुम्ही त्याचे कौतुक करू शकता आणि ते नंतरसाठी जतन करू शकता.",
+  "interaction_modal.description.follow": "मॅस्टोडॉन वरील खात्यासह, तुम्ही त्यांच्या पोस्ट तुमच्या होम फीडमध्ये प्राप्त करण्यासाठी {name} चे अनुसरण करू शकता.",
+  "interaction_modal.description.reblog": "मॅस्टोडॉन वरील खात्यासह, तुम्ही ही पोस्ट तुमच्या स्वतःच्या अनुयायांसह शेअर करण्यासाठी बूस्ट करू शकता.",
+  "interaction_modal.description.reply": "मॅस्टोडॉनवरील खात्यासह, तुम्ही या पोस्टला प्रतिसाद देऊ शकता.",
+  "interaction_modal.on_another_server": "वेगळ्या सर्व्हरवर",
+  "interaction_modal.on_this_server": "या सर्व्हरवर",
+  "interaction_modal.other_server_instructions": "तुमच्या आवडत्या मॅस्टोडॉन अँपच्या सर्च फिल्डमध्ये किंवा तुमच्या मॅस्टोडॉन सर्व्हरच्या वेब इंटरफेसमध्ये ही URL कॉपी आणि पेस्ट करा.",
+  "interaction_modal.preamble": "मास्टोडॉन विकेंद्रित असल्याने, तुमचे खाते नसेल तर तुम्ही दुसरे मॅस्टोडॉन सर्व्हर किंवा सुसंगत प्लॅटफॉर्मद्वारे होस्ट केलेले तुमचे विद्यमान खाते वापरू शकता.",
+  "interaction_modal.title.favourite": "आवडत्या {name} ची पोस्ट",
+  "interaction_modal.title.follow": "{name} चे अनुसरण करा",
+  "interaction_modal.title.reblog": "{name} ची पोस्ट बूस्ट करा",
+  "interaction_modal.title.reply": "{name} च्या पोस्टला उत्तर द्या",
   "intervals.full.days": "{number, plural, one {# day} other {# days}}",
   "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
   "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
@@ -303,8 +308,8 @@
   "keyboard_shortcuts.boost": "to boost",
   "keyboard_shortcuts.column": "to focus a status in one of the columns",
   "keyboard_shortcuts.compose": "to focus the compose textarea",
-  "keyboard_shortcuts.description": "Description",
-  "keyboard_shortcuts.direct": "to open direct messages column",
+  "keyboard_shortcuts.description": "वर्णन",
+  "keyboard_shortcuts.direct": "थेट संदेश स्तंभ उघडण्यासाठी",
   "keyboard_shortcuts.down": "to move down in the list",
   "keyboard_shortcuts.enter": "to open status",
   "keyboard_shortcuts.favourite": "to favourite",
@@ -312,7 +317,7 @@
   "keyboard_shortcuts.federated": "to open federated timeline",
   "keyboard_shortcuts.heading": "Keyboard Shortcuts",
   "keyboard_shortcuts.home": "to open home timeline",
-  "keyboard_shortcuts.hotkey": "Hotkey",
+  "keyboard_shortcuts.hotkey": "हॉटकी",
   "keyboard_shortcuts.legend": "to display this legend",
   "keyboard_shortcuts.local": "to open local timeline",
   "keyboard_shortcuts.mention": "to mention author",
@@ -332,28 +337,28 @@
   "keyboard_shortcuts.toot": "to start a brand new toot",
   "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
   "keyboard_shortcuts.up": "to move up in the list",
-  "lightbox.close": "Close",
-  "lightbox.compress": "Compress image view box",
-  "lightbox.expand": "Expand image view box",
-  "lightbox.next": "Next",
-  "lightbox.previous": "Previous",
-  "limited_account_hint.action": "Show profile anyway",
-  "limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
-  "lists.account.add": "Add to list",
-  "lists.account.remove": "Remove from list",
-  "lists.delete": "Delete list",
-  "lists.edit": "Edit list",
-  "lists.edit.submit": "Change title",
-  "lists.new.create": "Add list",
-  "lists.new.title_placeholder": "New list title",
-  "lists.replies_policy.followed": "Any followed user",
-  "lists.replies_policy.list": "Members of the list",
-  "lists.replies_policy.none": "No one",
-  "lists.replies_policy.title": "Show replies to:",
-  "lists.search": "Search among people you follow",
-  "lists.subheading": "Your lists",
+  "lightbox.close": "बंद करा",
+  "lightbox.compress": "प्रतिमा दृश्य बॉक्स कॉम्प्रेस करा",
+  "lightbox.expand": "प्रतिमा दृश्य बॉक्स विस्तृत करा",
+  "lightbox.next": "पुढे",
+  "lightbox.previous": "मागील",
+  "limited_account_hint.action": "तरीही प्रोफाइल दाखवा",
+  "limited_account_hint.title": "हे प्रोफाइल {domain} च्या नियंत्रकांनी लपवले आहे.",
+  "lists.account.add": "यादीमध्ये जोडा",
+  "lists.account.remove": "यादीमधून काढा",
+  "lists.delete": "सूची हटवा",
+  "lists.edit": "सूची संपादित करा",
+  "lists.edit.submit": "शीर्षक बदला",
+  "lists.new.create": "यादी जोडा",
+  "lists.new.title_placeholder": "नवीन सूची शीर्षक",
+  "lists.replies_policy.followed": "कोणताही फॉलो केलेला वापरकर्ता",
+  "lists.replies_policy.list": "यादीतील सदस्य",
+  "lists.replies_policy.none": "कोणीच नाही",
+  "lists.replies_policy.title": "यांना उत्तरे दाखवा:",
+  "lists.search": "तुम्ही फॉलो करत असलेल्या लोकांमध्ये शोधा",
+  "lists.subheading": "तुमच्या याद्या",
   "load_pending": "{count, plural, one {# new item} other {# new items}}",
-  "loading_indicator.label": "Loading...",
+  "loading_indicator.label": "लोड करत आहे...",
   "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}",
   "missing_indicator.label": "Not found",
   "missing_indicator.sublabel": "This resource could not be found",
@@ -409,21 +414,21 @@
   "notifications.column_settings.follow_request": "New follow requests:",
   "notifications.column_settings.mention": "Mentions:",
   "notifications.column_settings.poll": "Poll results:",
-  "notifications.column_settings.push": "Push notifications",
-  "notifications.column_settings.reblog": "Boosts:",
-  "notifications.column_settings.show": "Show in column",
-  "notifications.column_settings.sound": "Play sound",
+  "notifications.column_settings.push": "सूचना",
+  "notifications.column_settings.reblog": "बूस्ट:",
+  "notifications.column_settings.show": "स्तंभात दाखवा",
+  "notifications.column_settings.sound": "ध्वनी प्ले करा",
   "notifications.column_settings.status": "New toots:",
-  "notifications.column_settings.unread_notifications.category": "Unread notifications",
-  "notifications.column_settings.unread_notifications.highlight": "Highlight unread notifications",
-  "notifications.column_settings.update": "Edits:",
-  "notifications.filter.all": "All",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.follows": "Follows",
-  "notifications.filter.mentions": "Mentions",
-  "notifications.filter.polls": "Poll results",
-  "notifications.filter.statuses": "Updates from people you follow",
+  "notifications.column_settings.unread_notifications.category": "अपठित अधिसूचना",
+  "notifications.column_settings.unread_notifications.highlight": "न वाचलेल्या सूचना हायलाइट करा",
+  "notifications.column_settings.update": "संपादने:",
+  "notifications.filter.all": "सर्व",
+  "notifications.filter.boosts": "बूस्ट",
+  "notifications.filter.favourites": "आवडते",
+  "notifications.filter.follows": "अनुयायी आहे",
+  "notifications.filter.mentions": "उल्लेख केलेले",
+  "notifications.filter.polls": "मतदान परिणाम",
+  "notifications.filter.statuses": "तुम्ही फॉलो करत असलेल्या लोकांकडून अपडेट",
   "notifications.grant_permission": "Grant permission.",
   "notifications.group": "{count} notifications",
   "notifications.mark_as_read": "Mark every notification as read",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json
index e3dcf46a1..715c59f7e 100644
--- a/app/javascript/mastodon/locales/ms.json
+++ b/app/javascript/mastodon/locales/ms.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Hantaran dan balasan",
   "account.report": "Laporkan @{name}",
   "account.requested": "Menunggu kelulusan. Klik untuk batalkan permintaan ikut",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Kongsi profil @{name}",
   "account.show_reblogs": "Tunjukkan galakan daripada @{name}",
   "account.statuses_counter": "{count, plural, other {{counter} kiriman}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Cari bahasa...",
   "compose_form.direct_message_warning_learn_more": "Ketahui lebih lanjut",
   "compose_form.encryption_warning": "Hantaran pada Mastodon tidak disulitkan hujung ke hujung. Jangan berkongsi sebarang maklumat sensitif melalui Mastodon.",
-  "compose_form.hashtag_warning": "Hantaran ini tidak akan disenaraikan di bawah mana-mana tanda pagar kerana ia tidak tersenarai. Hanya hantaran awam sahaja boleh dicari menggunakan tanda pagar.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Akaun anda tidak {locked}. Sesiapa pun boleh mengikuti anda untuk melihat hantaran pengikut-sahaja anda.",
   "compose_form.lock_disclaimer.lock": "dikunci",
   "compose_form.placeholder": "Apakah yang sedang anda fikirkan?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Salin surih tindanan ke papan keratan",
   "errors.unexpected_crash.report_issue": "Laporkan masalah",
   "explore.search_results": "Hasil carian",
+  "explore.suggested_follows": "For you",
   "explore.title": "Terokai",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Kumpulan penapis ini tidak terpakai pada konteks di mana anda mengakses hantaran ini. Jika anda ingin hantaran ini untuk ditapis dalam konteks ini juga, anda perlu menyunting penapis tersebut.",
   "filter_modal.added.context_mismatch_title": "Konteks tidak sepadan!",
   "filter_modal.added.expired_explanation": "Kumpulan filter ini telah tamat tempoh, anda perlu mengubah tarikh luput untuk melaksanakannya.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Daftar masuk",
   "sign_in_banner.text": "Daftar masuk untuk mengikut profil atau tanda pagar, menggemari, mengkongsi dan membalas kepada hantaran, atau berinteraksi daripada akaun anda pada pelayan lain.",
   "status.admin_account": "Buka antara muka penyederhanaan untuk @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Buka hantaran ini dalam antara muka penyederhanaan",
   "status.block": "Sekat @{name}",
   "status.bookmark": "Tanda buku",
@@ -553,7 +559,7 @@
   "status.favourite": "Kegemaran",
   "status.filter": "Tapiskan hantaran ini",
   "status.filtered": "Ditapis",
-  "status.hide": "Sembunyikan siaran",
+  "status.hide": "Hide post",
   "status.history.created": "{name} mencipta pada {date}",
   "status.history.edited": "{name} menyunting pada {date}",
   "status.load_more": "Muatkan lagi",
diff --git a/app/javascript/mastodon/locales/my.json b/app/javascript/mastodon/locales/my.json
index 1e55e8dee..31e250047 100644
--- a/app/javascript/mastodon/locales/my.json
+++ b/app/javascript/mastodon/locales/my.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Posts and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval. Click to cancel follow request",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Posts}}",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json
index 4e2579c57..479573e84 100644
--- a/app/javascript/mastodon/locales/nl.json
+++ b/app/javascript/mastodon/locales/nl.json
@@ -16,7 +16,7 @@
   "account.badges.bot": "Bot",
   "account.badges.group": "Groep",
   "account.block": "@{name} blokkeren",
-  "account.block_domain": "Alles van {domain} verbergen",
+  "account.block_domain": "Alles van {domain} blokkeren",
   "account.blocked": "Geblokkeerd",
   "account.browse_more_on_origin_server": "Zie meer op het originele profiel",
   "account.cancel_follow_request": "Volgverzoek annuleren",
@@ -54,11 +54,12 @@
   "account.posts_with_replies": "Berichten en reacties",
   "account.report": "@{name} rapporteren",
   "account.requested": "Wachten op goedkeuring. Klik om het volgverzoek te annuleren",
+  "account.requested_follow": "{name} wil je graag volgen",
   "account.share": "Profiel van @{name} delen",
   "account.show_reblogs": "Boosts van @{name} tonen",
   "account.statuses_counter": "{count, plural, one {{counter} bericht} other {{counter} berichten}}",
   "account.unblock": "@{name} deblokkeren",
-  "account.unblock_domain": "{domain} niet langer verbergen",
+  "account.unblock_domain": "{domain} niet langer blokkeren",
   "account.unblock_short": "Deblokkeren",
   "account.unendorse": "Niet op profiel weergeven",
   "account.unfollow": "Ontvolgen",
@@ -127,7 +128,7 @@
   "compose.language.search": "Talen zoeken...",
   "compose_form.direct_message_warning_learn_more": "Meer leren",
   "compose_form.encryption_warning": "Berichten op Mastodon worden, net zoals op andere social media, niet end-to-end versleuteld. Deel daarom geen gevoelige informatie via Mastodon.",
-  "compose_form.hashtag_warning": "Dit bericht valt niet onder een hashtag te bekijken, omdat deze niet op openbare tijdlijnen wordt getoond. Alleen openbare berichten kunnen via hashtags gevonden worden.",
+  "compose_form.hashtag_warning": "Dit bericht valt niet onder een hashtag te bekijken, omdat deze niet op openbaar is. Alleen openbare berichten kunnen via hashtags gevonden worden.",
   "compose_form.lock_disclaimer": "Jouw account is niet {locked}. Iedereen kan jou volgen en kan de berichten zien die je alleen aan jouw volgers hebt gericht.",
   "compose_form.lock_disclaimer.lock": "besloten",
   "compose_form.placeholder": "Wat wil je kwijt?",
@@ -159,8 +160,8 @@
   "confirmations.delete_list.message": "Weet je zeker dat je deze lijst definitief wilt verwijderen?",
   "confirmations.discard_edit_media.confirm": "Weggooien",
   "confirmations.discard_edit_media.message": "Je hebt niet-opgeslagen wijzigingen in de mediabeschrijving of voorvertonning, wil je deze toch weggooien?",
-  "confirmations.domain_block.confirm": "Verberg alles van deze server",
-  "confirmations.domain_block.message": "Weet je het echt heel erg zeker dat je alles van {domain} wilt negeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en beter. Je zult geen berichten van deze server op openbare tijdlijnen zien of in jouw meldingen. Jouw volgers van deze server worden verwijderd.",
+  "confirmations.domain_block.confirm": "Blokkeer alles van deze server",
+  "confirmations.domain_block.message": "Weet je het echt heel erg zeker dat je alles van {domain} wilt blokkeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en beter. Je zult geen berichten van deze server op openbare tijdlijnen zien of in jouw meldingen. Jouw volgers van deze server worden verwijderd.",
   "confirmations.logout.confirm": "Uitloggen",
   "confirmations.logout.message": "Weet je zeker dat je wilt uitloggen?",
   "confirmations.mute.confirm": "Negeren",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Stacktrace naar klembord kopiëren",
   "errors.unexpected_crash.report_issue": "Technisch probleem melden",
   "explore.search_results": "Zoekresultaten",
+  "explore.suggested_follows": "Voor jou",
   "explore.title": "Verkennen",
+  "explore.trending_links": "Nieuws",
+  "explore.trending_statuses": "Berichten",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Deze filtercategorie is niet van toepassing op de context waarin je dit bericht hebt benaderd. Als je wilt dat het bericht ook in deze context wordt gefilterd, moet je het filter bewerken.",
   "filter_modal.added.context_mismatch_title": "Context komt niet overeen!",
   "filter_modal.added.expired_explanation": "Deze filtercategorie is verlopen. Je moet de vervaldatum wijzigen om de categorie toe te kunnen passen.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Inloggen",
   "sign_in_banner.text": "Wanneer je een account op deze server hebt, kun je inloggen om mensen of hashtags te volgen, op berichten te reageren of om deze te delen. Wanneer je een account op een andere server hebt, kun je daar inloggen en daar interactie met mensen op deze server hebben.",
   "status.admin_account": "Moderatie-omgeving van @{name} openen",
+  "status.admin_domain": "Moderatie-omgeving van {domain} openen",
   "status.admin_status": "Dit bericht in de moderatie-omgeving tonen",
   "status.block": "@{name} blokkeren",
   "status.bookmark": "Bladwijzer toevoegen",
@@ -617,13 +623,13 @@
   "upload_button.label": "Afbeeldingen, een video- of een geluidsbestand toevoegen",
   "upload_error.limit": "Uploadlimiet van bestand overschreden.",
   "upload_error.poll": "Het uploaden van bestanden is in polls niet toegestaan.",
-  "upload_form.audio_description": "Omschrijf dit voor mensen met een auditieve beperking",
-  "upload_form.description": "Omschrijf dit voor mensen met een visuele beperking",
+  "upload_form.audio_description": "Omschrijf dit voor dove of slechthorende mensen",
+  "upload_form.description": "Omschrijf dit voor blinde of slechtziende mensen",
   "upload_form.description_missing": "Geen omschrijving toegevoegd",
   "upload_form.edit": "Omschrijf",
   "upload_form.thumbnail": "Miniatuurafbeelding wijzigen",
   "upload_form.undo": "Verwijderen",
-  "upload_form.video_description": "Omschrijf dit voor mensen met een auditieve of visuele beperking",
+  "upload_form.video_description": "Omschrijf dit voor dove, slechthorende, blinde of slechtziende mensen",
   "upload_modal.analyzing_picture": "Afbeelding analyseren…",
   "upload_modal.apply": "Toepassen",
   "upload_modal.applying": "Aan het toepassen…",
diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json
index 0342b66c7..e158f67b0 100644
--- a/app/javascript/mastodon/locales/nn.json
+++ b/app/javascript/mastodon/locales/nn.json
@@ -34,7 +34,7 @@
   "account.followers.empty": "Ingen fylgjer denne brukaren enno.",
   "account.followers_counter": "{count, plural, one {{counter} fylgjar} other {{counter} fylgjarar}}",
   "account.following": "Fylgjer",
-  "account.following_counter": "{count, plural, one {{counter} fylgjar} other {{counter} fylgjar}}",
+  "account.following_counter": "{count, plural, one {Fylgjar {counter}} other {Fylgjar {counter}}}",
   "account.follows.empty": "Denne brukaren fylgjer ikkje nokon enno.",
   "account.follows_you": "Fylgjer deg",
   "account.go_to_profile": "Gå til profil",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Tut og svar",
   "account.report": "Rapporter @{name}",
   "account.requested": "Ventar på aksept. Klikk for å avbryta fylgjeførespurnaden",
+  "account.requested_follow": "{name} har bedt om å få fylgja deg",
   "account.share": "Del @{name} sin profil",
   "account.show_reblogs": "Vis framhevingar frå @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} tut} other {{counter} tut}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Søk språk...",
   "compose_form.direct_message_warning_learn_more": "Lær meir",
   "compose_form.encryption_warning": "Innlegg på Mastodon er ikkje ende-til-ende-krypterte. Ikkje del eventuell ømtolig informasjon via Mastodon.",
-  "compose_form.hashtag_warning": "Dette tutet vert ikkje oppført under nokon emneknagg sidan ingen emneknagg er oppført. Det er kun emneknaggar som er søkbare i offentlege tutar.",
+  "compose_form.hashtag_warning": "Dette innlegget vert ikkje lista under nokre emneknaggar av di det ikkje er offentleg. Berre offentlege innlegg kan verte søkt opp med emneknagg.",
   "compose_form.lock_disclaimer": "Kontoen din er ikkje {locked}. Kven som helst kan fylgja deg for å sjå innlegga dine.",
   "compose_form.lock_disclaimer.lock": "låst",
   "compose_form.placeholder": "Kva har du på hjarta?",
@@ -137,10 +138,10 @@
   "compose_form.poll.remove_option": "Fjern dette valet",
   "compose_form.poll.switch_to_multiple": "Endre rundspørjinga til å tillate fleire val",
   "compose_form.poll.switch_to_single": "Endre rundspørjinga til å tillate berre eitt val",
-  "compose_form.publish": "Publisér",
-  "compose_form.publish_form": "Publisér",
+  "compose_form.publish": "Legg ut",
+  "compose_form.publish_form": "Legg ut",
   "compose_form.publish_loud": "{publish}!",
-  "compose_form.save_changes": "Lagre endringar",
+  "compose_form.save_changes": "Gøym",
   "compose_form.sensitive.hide": "{count, plural, one {Marker mediet som ømtolig} other {Marker media som ømtolige}}",
   "compose_form.sensitive.marked": "{count, plural, one {Mediet er markert som ømtolig} other {Media er markerte som ømtolige}}",
   "compose_form.sensitive.unmarked": "{count, plural, one {Mediet er ikkje markert som ømtolig} other {Media er ikkje markerte som ømtolige}}",
@@ -177,7 +178,7 @@
   "conversation.open": "Sjå samtale",
   "conversation.with": "Med {names}",
   "copypaste.copied": "Kopiert",
-  "copypaste.copy": "Kopiér",
+  "copypaste.copy": "Kopier",
   "directory.federated": "Frå den kjende allheimen",
   "directory.local": "Berre frå {domain}",
   "directory.new_arrivals": "Nyleg tilkomne",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopier stacktrace til utklippstavla",
   "errors.unexpected_crash.report_issue": "Rapporter problem",
   "explore.search_results": "Søkeresultat",
+  "explore.suggested_follows": "For deg",
   "explore.title": "Utforsk",
+  "explore.trending_links": "Nytt",
+  "explore.trending_statuses": "Innlegg",
+  "explore.trending_tags": "Emneknaggar",
   "filter_modal.added.context_mismatch_explanation": "Denne filterkategorien gjeld ikkje i den samanhengen du har lese dette innlegget. Viss du vil at innlegget skal filtrerast i denne samanhengen òg, må du endra filteret.",
   "filter_modal.added.context_mismatch_title": "Konteksten passar ikkje!",
   "filter_modal.added.expired_explanation": "Denne filterkategorien har gått ut på dato. Du må endre best før datoen for at den skal gjelde.",
@@ -265,7 +270,7 @@
   "footer.keyboard_shortcuts": "Snøggtastar",
   "footer.privacy_policy": "Personvernsreglar",
   "footer.source_code": "Vis kjeldekode",
-  "generic.saved": "Lagra",
+  "generic.saved": "Gøymt",
   "getting_started.heading": "Kom i gang",
   "hashtag.column_header.tag_mode.all": "og {additional}",
   "hashtag.column_header.tag_mode.any": "eller {additional}",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Logg inn",
   "sign_in_banner.text": "Logg inn for å fylgje profiler eller emneknaggar, markere, framheve og svare på innlegg – eller samhandle med aktivitet på denne tenaren frå kontoen din på ein annan tenar.",
   "status.admin_account": "Opne moderasjonsgrensesnitt for @{name}",
+  "status.admin_domain": "Opna moderatorgrensesnittet for {domain}",
   "status.admin_status": "Opne denne statusen i moderasjonsgrensesnittet",
   "status.block": "Blokker @{name}",
   "status.bookmark": "Set bokmerke",
@@ -553,7 +559,7 @@
   "status.favourite": "Favoritt",
   "status.filter": "Filtrer dette innlegget",
   "status.filtered": "Filtrert",
-  "status.hide": "Gøym innlegg",
+  "status.hide": "Skjul innlegget",
   "status.history.created": "{name} oppretta {date}",
   "status.history.edited": "{name} redigerte {date}",
   "status.load_more": "Last inn meir",
@@ -590,7 +596,7 @@
   "status.unmute_conversation": "Opphev målbinding av samtalen",
   "status.unpin": "Løys frå profil",
   "subscribed_languages.lead": "Kun innlegg på valde språk vil bli dukke opp i heimestraumen din og i listene dine etter denne endringa. For å motta innlegg på alle språk, la vere å velje nokon.",
-  "subscribed_languages.save": "Lagre endringar",
+  "subscribed_languages.save": "Gøym",
   "subscribed_languages.target": "Endre abonnerte språk for {target}",
   "suggestions.dismiss": "Avslå forslag",
   "suggestions.header": "Du er kanskje interessert i…",
@@ -618,7 +624,7 @@
   "upload_error.limit": "Du har gått over opplastingsgrensa.",
   "upload_error.poll": "Filopplasting er ikkje lov for rundspørjingar.",
   "upload_form.audio_description": "Skildre for dei med nedsett høyrsel",
-  "upload_form.description": "Skildre for dei om har redusert syn",
+  "upload_form.description": "Skildre for blinde og svaksynte",
   "upload_form.description_missing": "Inga skildring er lagt til",
   "upload_form.edit": "Rediger",
   "upload_form.thumbnail": "Bytt miniatyrbilete",
diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json
index 1c33c8a99..53de4ce00 100644
--- a/app/javascript/mastodon/locales/no.json
+++ b/app/javascript/mastodon/locales/no.json
@@ -2,21 +2,21 @@
   "about.blocks": "Modererte tjenere",
   "about.contact": "Kontakt:",
   "about.disclaimer": "Mastodon er gratis, åpen kildekode-programvare og et varemerke fra Mastodon gGmbH.",
-  "about.domain_blocks.no_reason_available": "Årsak ikke oppgitt",
-  "about.domain_blocks.preamble": "Mastodon lar deg normalt sett se innholdet fra og samhandle med brukere fra enhver annen server i fødiverset. Dette er unntakene som har blitt lagt inn på denne serveren.",
-  "about.domain_blocks.silenced.explanation": "Du vil vanligvis ikke se profiler og innhold fra denne serveren, med mindre du eksplisitt søker dem opp eller velger å følge dem.",
+  "about.domain_blocks.no_reason_available": "Årsak ikke tilgjengelig",
+  "about.domain_blocks.preamble": "Mastodon lar deg normalt sett se innholdet fra og samhandle med brukere fra enhver annen tjener i fødiverset. Dette er unntakene som har blitt lagt inn på denne tjeneren.",
+  "about.domain_blocks.silenced.explanation": "Du vil vanligvis ikke se profiler og innhold fra denne tjeneren, med mindre du eksplisitt søker dem opp eller velger å følge dem.",
   "about.domain_blocks.silenced.title": "Begrenset",
-  "about.domain_blocks.suspended.explanation": "Ikke noe innhold fra denne serveren vil bli behandlet, lagret eller utvekslet. Det gjør det umulig å samhandle eller kommunisere med brukere fra denne serveren.",
+  "about.domain_blocks.suspended.explanation": "Ikke noe innhold fra denne tjeneren vil bli behandlet, lagret eller utvekslet. Det gjør det umulig å samhandle eller kommunisere med brukere fra denne tjeneren.",
   "about.domain_blocks.suspended.title": "Suspendert",
-  "about.not_available": "Denne informasjonen er ikke gjort tilgjengelig på denne serveren.",
+  "about.not_available": "Denne informasjonen er ikke gjort tilgjengelig på denne tjeneren.",
   "about.powered_by": "Desentraliserte sosiale medier drevet av {mastodon}",
-  "about.rules": "Regler for serveren",
+  "about.rules": "Regler for tjeneren",
   "account.account_note_header": "Notat",
   "account.add_or_remove_from_list": "Legg til eller fjern fra lister",
   "account.badges.bot": "Bot",
   "account.badges.group": "Gruppe",
-  "account.block": "Blokkér @{name}",
-  "account.block_domain": "Blokkér domenet {domain}",
+  "account.block": "Blokker @{name}",
+  "account.block_domain": "Blokker domenet {domain}",
   "account.blocked": "Blokkert",
   "account.browse_more_on_origin_server": "Bla mer på den opprinnelige profilen",
   "account.cancel_follow_request": "Trekk tilbake følge-forespørselen",
@@ -52,8 +52,9 @@
   "account.open_original_page": "Gå til originalsiden",
   "account.posts": "Innlegg",
   "account.posts_with_replies": "Innlegg med svar",
-  "account.report": "Rapportér @{name}",
+  "account.report": "Rapporter @{name}",
   "account.requested": "Venter på godkjennelse. Klikk for å avbryte forespørselen",
+  "account.requested_follow": "{name} har bedt om å få følge deg",
   "account.share": "Del @{name}s profil",
   "account.show_reblogs": "Vis fremhevinger fra @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} innlegg} other {{counter} innlegg}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Søk etter språk...",
   "compose_form.direct_message_warning_learn_more": "Lær mer",
   "compose_form.encryption_warning": "Innlegg på Mastodon er ikke ende-til-ende-krypterte. Ikke del sensitive opplysninger via Mastodon.",
-  "compose_form.hashtag_warning": "Dette innlegget blir vist under noen emneknagger da det er uoppført. Kun offentlige innlegg kan søkes opp med emneknagg.",
+  "compose_form.hashtag_warning": "Dette innlegget blir ikke vist under noen emneknagger siden det ikke er offentlig. Bare offentlige innlegg kan søkes opp med emneknagger.",
   "compose_form.lock_disclaimer": "Din konto er ikke {locked}. Hvem som helst kan følge deg og se dine private poster.",
   "compose_form.lock_disclaimer.lock": "låst",
   "compose_form.placeholder": "Hva har du på hjertet?",
@@ -166,7 +167,7 @@
   "confirmations.mute.confirm": "Demp",
   "confirmations.mute.explanation": "Dette vil skjule innlegg fra dem og innlegg som nevner dem, men det vil fortsatt la dem se dine innlegg og å følge deg.",
   "confirmations.mute.message": "Er du sikker på at du vil dempe {name}?",
-  "confirmations.redraft.confirm": "Slett og drøft på nytt",
+  "confirmations.redraft.confirm": "Slett og skriv på nytt",
   "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
   "confirmations.reply.confirm": "Svar",
   "confirmations.reply.message": "Å svare nå vil overskrive meldingen du skriver for øyeblikket. Er du sikker på at du vil fortsette?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopier stacktrace-en til utklippstavlen",
   "errors.unexpected_crash.report_issue": "Rapporter en feil",
   "explore.search_results": "Søkeresultater",
+  "explore.suggested_follows": "For deg",
   "explore.title": "Utforsk",
+  "explore.trending_links": "Nyheter",
+  "explore.trending_statuses": "Innlegg",
+  "explore.trending_tags": "Emneknagger",
   "filter_modal.added.context_mismatch_explanation": "Denne filterkategorien gjelder ikke for den konteksten du har åpnet dette innlegget i. Hvis du vil at innlegget skal filtreres i denne konteksten også, må du redigere filteret.",
   "filter_modal.added.context_mismatch_title": "Feil sammenheng!",
   "filter_modal.added.expired_explanation": "Denne filterkategorien er utløpt, du må endre utløpsdato for at den skal gjelde.",
@@ -255,13 +260,13 @@
   "follow_recommendations.done": "Utført",
   "follow_recommendations.heading": "Følg folk du ønsker å se innlegg fra! Her er noen forslag.",
   "follow_recommendations.lead": "Innlegg fra mennesker du følger vil vises i kronologisk rekkefølge på hjemmefeed. Ikke vær redd for å gjøre feil, du kan slutte å følge folk like enkelt som alt!",
-  "follow_request.authorize": "Autorisér",
+  "follow_request.authorize": "Autoriser",
   "follow_request.reject": "Avvis",
   "follow_requests.unlocked_explanation": "Selv om kontoen din ikke er låst, tror {domain} ansatte at du kanskje vil gjennomgå forespørsler fra disse kontoene manuelt.",
   "footer.about": "Om",
   "footer.directory": "Profilkatalog",
   "footer.get_app": "Last ned appen",
-  "footer.invite": "Invitér folk",
+  "footer.invite": "Inviter folk",
   "footer.keyboard_shortcuts": "Hurtigtaster",
   "footer.privacy_policy": "Personvernregler",
   "footer.source_code": "Vis kildekode",
@@ -344,7 +349,7 @@
   "lists.delete": "Slett listen",
   "lists.edit": "Rediger listen",
   "lists.edit.submit": "Endre tittel",
-  "lists.new.create": "Ligg til liste",
+  "lists.new.create": "Legg til liste",
   "lists.new.title_placeholder": "Ny listetittel",
   "lists.replies_policy.followed": "Enhver fulgt bruker",
   "lists.replies_policy.list": "Medlemmer i listen",
@@ -443,7 +448,7 @@
   "poll.votes": "{votes, plural, one {# stemme} other {# stemmer}}",
   "poll_button.add_poll": "Legg til en avstemning",
   "poll_button.remove_poll": "Fjern avstemningen",
-  "privacy.change": "Justér synlighet",
+  "privacy.change": "Juster synlighet",
   "privacy.direct.long": "Post kun til nevnte brukere",
   "privacy.direct.short": "Kun nevnte personer",
   "privacy.private.long": "Post kun til følgere",
@@ -537,8 +542,9 @@
   "sign_in_banner.sign_in": "Logg inn",
   "sign_in_banner.text": "Logg inn for å følge profiler eller hashtags, like, dele og svare på innlegg eller interagere fra din konto på en annen server.",
   "status.admin_account": "Åpne moderatorgrensesnittet for @{name}",
+  "status.admin_domain": "Åpne moderatorgrensesnittet for {domain}",
   "status.admin_status": "Åpne denne statusen i moderatorgrensesnittet",
-  "status.block": "Blokkér @{name}",
+  "status.block": "Blokker @{name}",
   "status.bookmark": "Bokmerke",
   "status.cancel_reblog_private": "Fjern fremheving",
   "status.cannot_reblog": "Denne posten kan ikke fremheves",
@@ -546,7 +552,7 @@
   "status.delete": "Slett",
   "status.detailed_status": "Detaljert samtalevisning",
   "status.direct": "Send direktemelding til @{name}",
-  "status.edit": "Redigér",
+  "status.edit": "Rediger",
   "status.edited": "Redigert {date}",
   "status.edited_x_times": "Redigert {count, plural,one {{count} gang} other {{count} ganger}}",
   "status.embed": "Bygge inn",
@@ -570,7 +576,7 @@
   "status.reblog_private": "Fremhev til det opprinnelige publikummet",
   "status.reblogged_by": "Fremhevet av {name}",
   "status.reblogs.empty": "Ingen har fremhevet dette innlegget enda. Når noen gjør det, vil de dukke opp her.",
-  "status.redraft": "Slett og drøft på nytt",
+  "status.redraft": "Slett og skriv på nytt",
   "status.remove_bookmark": "Fjern bokmerke",
   "status.replied_to": "Som svar til {name}",
   "status.reply": "Svar",
diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json
index 446e0cd22..4865843dd 100644
--- a/app/javascript/mastodon/locales/oc.json
+++ b/app/javascript/mastodon/locales/oc.json
@@ -2,7 +2,7 @@
   "about.blocks": "Servidors moderats",
   "about.contact": "Contacte :",
   "about.disclaimer": "Mastodon es gratuit, un logicial libre e una marca de Mastodon gGmbH.",
-  "about.domain_blocks.no_reason_available": "Reason not available",
+  "about.domain_blocks.no_reason_available": "Rason pas disponibla",
   "about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.",
   "about.domain_blocks.silenced.explanation": "You will generally not see profiles and content from this server, unless you explicitly look it up or opt into it by following.",
   "about.domain_blocks.silenced.title": "Limitats",
@@ -49,11 +49,12 @@
   "account.mute": "Rescondre @{name}",
   "account.mute_notifications": "Rescondre las notificacions de @{name}",
   "account.muted": "Mes en silenci",
-  "account.open_original_page": "Open original page",
+  "account.open_original_page": "Dobrir la pagina d’origina",
   "account.posts": "Tuts",
   "account.posts_with_replies": "Tuts e responsas",
   "account.report": "Senhalar @{name}",
   "account.requested": "Invitacion mandada. Clicatz per anullar",
+  "account.requested_follow": "{name} a demandat a vos sègre",
   "account.share": "Partejar lo perfil a @{name}",
   "account.show_reblogs": "Mostrar los partatges de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Tut} other {{counter} Tuts}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Recercar de lengas...",
   "compose_form.direct_message_warning_learn_more": "Ne saber mai",
   "compose_form.encryption_warning": "Las publicacions sus Mastodon son pas chifradas del cap a la fin. Partegetz pas d’informacions sensiblas sus Mastodon.",
-  "compose_form.hashtag_warning": "Aqueste tut serà pas ligat a cap d’etiqueta estant qu’es pas listat. Òm pòt pas cercar que los tuts publics per etiqueta.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Vòstre compte es pas {locked}. Tot lo mond pòt vos sègre e veire los estatuts reservats als seguidors.",
   "compose_form.lock_disclaimer.lock": "clavat",
   "compose_form.placeholder": "A de qué pensatz ?",
@@ -138,7 +139,7 @@
   "compose_form.poll.switch_to_multiple": "Cambiar lo sondatge per permetre de causidas multiplas",
   "compose_form.poll.switch_to_single": "Cambiar lo sondatge per permetre una sola causida",
   "compose_form.publish": "Publicar",
-  "compose_form.publish_form": "Publish",
+  "compose_form.publish_form": "Publicar",
   "compose_form.publish_loud": "{publish} !",
   "compose_form.save_changes": "Salvar los cambiaments",
   "compose_form.sensitive.hide": "Marcar coma sensible",
@@ -184,12 +185,12 @@
   "directory.recently_active": "Actius fa res",
   "disabled_account_banner.account_settings": "Paramètres de compte",
   "disabled_account_banner.text": "Vòstre compte {disabledAccount} es actualament desactivat.",
-  "dismissable_banner.community_timeline": "These are the most recent public posts from people whose accounts are hosted by {domain}.",
+  "dismissable_banner.community_timeline": "Vaquí las publicacions mai recentas del monde amb un compte albergat per {domain}.",
   "dismissable_banner.dismiss": "Ignorar",
-  "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
-  "dismissable_banner.explore_statuses": "These posts from this and other servers in the decentralized network are gaining traction on this server right now.",
+  "dismissable_banner.explore_links": "Aquestas istòrias ne parlan lo monde d’aqueste servidor e dels autres servidors del malhum descentralizat d’aquesta passa.",
+  "dismissable_banner.explore_statuses": "Aquí las publicacions d’aqueste servidor e dels autres del malhum descentralizat que ganhan en popularitat d’aquesta passa.",
   "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
-  "dismissable_banner.public_timeline": "These are the most recent public posts from people on this and other servers of the decentralized network that this server knows about.",
+  "dismissable_banner.public_timeline": "Vaquí las publicacions mai recentas del monde d’aqueste servidor e dels servidors descentralizats del malhum qu’aqueste servidor coneis.",
   "embed.instructions": "Embarcar aqueste estatut per lo far veire sus un site Internet en copiar lo còdi çai-jos.",
   "embed.preview": "Semblarà aquò :",
   "emoji_button.activity": "Activitats",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copiar las traças al quichapapièrs",
   "errors.unexpected_crash.report_issue": "Senhalar un problèma",
   "explore.search_results": "Resultats de recèrca",
+  "explore.suggested_follows": "Per vos",
   "explore.title": "Explorar",
+  "explore.trending_links": "Novèlas",
+  "explore.trending_statuses": "Publicacions",
+  "explore.trending_tags": "Etiquetas",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -496,7 +501,7 @@
   "report.reasons.violation_description": "You are aware that it breaks specific rules",
   "report.rules.subtitle": "Select all that apply",
   "report.rules.title": "Which rules are being violated?",
-  "report.statuses.subtitle": "Select all that apply",
+  "report.statuses.subtitle": "Seleccionatz çò que s’aplica",
   "report.statuses.title": "Are there any posts that back up this report?",
   "report.submit": "Mandar",
   "report.target": "Senhalar {target}",
@@ -508,8 +513,8 @@
   "report.unfollow_explanation": "You are following this account. To not see their posts in your home feed anymore, unfollow them.",
   "report_notification.attached_statuses": "{count, plural, one {{count} publicacion junta} other {{count} publicacions juntas}}",
   "report_notification.categories.other": "Autre",
-  "report_notification.categories.spam": "Spam",
-  "report_notification.categories.violation": "Rule violation",
+  "report_notification.categories.spam": "Messatge indesirable",
+  "report_notification.categories.violation": "Violacion de las règlas",
   "report_notification.open": "Dobrir lo senhalament",
   "search.placeholder": "Recercar",
   "search.search_or_paste": "Recercar o picar una URL",
@@ -534,9 +539,10 @@
   "server_banner.learn_more": "Ne saber mai",
   "server_banner.server_stats": "Estatisticas del servidor :",
   "sign_in_banner.create_account": "Crear un compte",
-  "sign_in_banner.sign_in": "Se marcar",
+  "sign_in_banner.sign_in": "Se connectar",
   "sign_in_banner.text": "Connectatz-vos per sègre perfils o etiquetas, apondre als favorits, partejar e respondre als messatges o interagir de vòstre compte estant d’un autre servidor.",
   "status.admin_account": "Dobrir l’interfàcia de moderacion per @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Dobrir aqueste estatut dins l’interfàcia de moderacion",
   "status.block": "Blocar @{name}",
   "status.bookmark": "Marcador",
@@ -553,7 +559,7 @@
   "status.favourite": "Apondre als favorits",
   "status.filter": "Filtrar aquesta publicacion",
   "status.filtered": "Filtrat",
-  "status.hide": "Amagar aqueste tut",
+  "status.hide": "Hide post",
   "status.history.created": "{name} o creèt lo {date}",
   "status.history.edited": "{name} o modifiquèt lo {date}",
   "status.load_more": "Cargar mai",
diff --git a/app/javascript/mastodon/locales/pa.json b/app/javascript/mastodon/locales/pa.json
index 693991651..e646ef83c 100644
--- a/app/javascript/mastodon/locales/pa.json
+++ b/app/javascript/mastodon/locales/pa.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Learn more",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
   "compose_form.placeholder": "What is on your mind?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json
index 9de1ccf16..eff34bcdd 100644
--- a/app/javascript/mastodon/locales/pl.json
+++ b/app/javascript/mastodon/locales/pl.json
@@ -43,7 +43,7 @@
   "account.languages": "Zmień subskrybowane języki",
   "account.link_verified_on": "Własność tego odnośnika została potwierdzona {date}",
   "account.locked_info": "To konto jest prywatne. Właściciel ręcznie wybiera kto może go obserwować.",
-  "account.media": "Zawartość multimedialna",
+  "account.media": "Multimedia",
   "account.mention": "Wspomnij o @{name}",
   "account.moved_to": "{name} jako swoje nowe konto wskazał/a:",
   "account.mute": "Wycisz @{name}",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Wpisy i odpowiedzi",
   "account.report": "Zgłoś @{name}",
   "account.requested": "Oczekująca prośba, kliknij aby anulować",
+  "account.requested_follow": "{name} poprosił(a) o możliwość zaobserwowania twojego profilu",
   "account.share": "Udostępnij profil @{name}",
   "account.show_reblogs": "Pokazuj podbicia od @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} wpis} few {{counter} wpisy} many {{counter} wpisów} other {{counter} wpisów}}",
@@ -125,13 +126,13 @@
   "column_subheading.navigation": "Nawigacja",
   "column_subheading.settings": "Ustawienia",
   "community.column_settings.local_only": "Tylko Lokalne",
-  "community.column_settings.media_only": "Tylko zawartość multimedialna",
+  "community.column_settings.media_only": "Tylko multimedia",
   "community.column_settings.remote_only": "Tylko Zdalne",
   "compose.language.change": "Zmień język",
   "compose.language.search": "Szukaj języków...",
   "compose_form.direct_message_warning_learn_more": "Dowiedz się więcej",
   "compose_form.encryption_warning": "Posty na Mastodon nie są szyfrowane end-to-end. Nie udostępniaj żadnych wrażliwych informacji przez Mastodon.",
-  "compose_form.hashtag_warning": "Ten wpis nie będzie widoczny pod podanymi hasztagami, ponieważ jest oznaczony jako niewidoczny. Tylko publiczne wpisy mogą zostać znalezione z użyciem hasztagów.",
+  "compose_form.hashtag_warning": "Ten wpis nie będzie widoczny pod podanymi hasztagami, ponieważ jest oznaczony jako niepubliczny. Tylko publiczne wpisy mogą zostać znalezione z użyciem hasztagów.",
   "compose_form.lock_disclaimer": "Twoje konto nie jest {locked}. Każdy, kto Cię obserwuje, może wyświetlać Twoje wpisy przeznaczone tylko dla obserwujących.",
   "compose_form.lock_disclaimer.lock": "zablokowane",
   "compose_form.placeholder": "Co Ci chodzi po głowie?",
@@ -145,9 +146,9 @@
   "compose_form.publish_form": "Publikuj",
   "compose_form.publish_loud": "{publish}!",
   "compose_form.save_changes": "Zapisz zmiany",
-  "compose_form.sensitive.hide": "Oznacz multimedia jako wrażliwe",
-  "compose_form.sensitive.marked": "Zawartość multimedia jest oznaczona jako wrażliwa",
-  "compose_form.sensitive.unmarked": "Zawartość multimedialna nie jest oznaczona jako wrażliwa",
+  "compose_form.sensitive.hide": "{count, plural, one {Oznacz treść multimedialną jako wrażliwą} other {Oznacz treści multimedialne jako wrażliwe}}",
+  "compose_form.sensitive.marked": "{count, plural, one {Treść multimedialna jest oznaczona jako wrażliwa} other {Treści multimedialne są oznaczone jako wrażliwe}}",
+  "compose_form.sensitive.unmarked": "{count, plural, one {Treść multimedialna nie jest oznaczona jako wrażliwa} other {Treści multimedialne nie są oznaczone jako wrażliwe}}",
   "compose_form.spoiler.marked": "Tekst jest ukryty za ostrzeżeniem",
   "compose_form.spoiler.unmarked": "Tekst nie jest ukryty",
   "compose_form.spoiler_placeholder": "Wprowadź swoje ostrzeżenie o zawartości",
@@ -239,7 +240,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Skopiuj ślad stosu do schowka",
   "errors.unexpected_crash.report_issue": "Zgłoś problem",
   "explore.search_results": "Wyniki wyszukiwania",
+  "explore.suggested_follows": "Dla Ciebie",
   "explore.title": "Odkrywaj",
+  "explore.trending_links": "Aktualności",
+  "explore.trending_statuses": "Posty",
+  "explore.trending_tags": "Hasztagi",
   "filter_modal.added.context_mismatch_explanation": "Ta kategoria filtrów nie ma zastosowania do kontekstu, w którym uzyskałeś dostęp do tego wpisu. Jeśli chcesz, aby wpis został przefiltrowany również w tym kontekście, będziesz musiał edytować filtr.",
   "filter_modal.added.context_mismatch_title": "Niezgodność kontekstów!",
   "filter_modal.added.expired_explanation": "Ta kategoria filtra wygasła, będziesz musiał zmienić datę wygaśnięcia, aby ją zastosować.",
@@ -323,7 +328,7 @@
   "keyboard_shortcuts.muted": "aby przejść do listy wyciszonych użytkowników",
   "keyboard_shortcuts.my_profile": "aby otworzyć własny profil",
   "keyboard_shortcuts.notifications": "aby otworzyć kolumnę powiadomień",
-  "keyboard_shortcuts.open_media": "aby otworzyć zawartość multimedialną",
+  "keyboard_shortcuts.open_media": "Otwórz multimedia",
   "keyboard_shortcuts.pinned": "aby przejść do listy przypiętych wpisów",
   "keyboard_shortcuts.profile": "aby przejść do profilu autora wpisu",
   "keyboard_shortcuts.reply": "aby odpowiedzieć",
@@ -332,7 +337,7 @@
   "keyboard_shortcuts.spoilers": "aby pokazać/ukryć pole CW",
   "keyboard_shortcuts.start": "aby otworzyć kolumnę „Rozpocznij”",
   "keyboard_shortcuts.toggle_hidden": "aby wyświetlić lub ukryć wpis spod CW",
-  "keyboard_shortcuts.toggle_sensitivity": "by pokazać/ukryć multimedia",
+  "keyboard_shortcuts.toggle_sensitivity": "Pokaż/ukryj multimedia",
   "keyboard_shortcuts.toot": "Stwórz nowy post",
   "keyboard_shortcuts.unfocus": "aby opuścić pole wyszukiwania/pisania",
   "keyboard_shortcuts.up": "aby przejść na górę listy",
@@ -475,7 +480,7 @@
   "relative_time.today": "dzisiaj",
   "reply_indicator.cancel": "Anuluj",
   "report.block": "Zablokuj",
-  "report.block_explanation": "Nie zobaczysz ich postów. Nie będą mogli zobaczyć Twoich postów ani cię obserwować. Będą mogli domyślić się, że są zablokowani.",
+  "report.block_explanation": "Nie zobaczysz ich wpisów. Nie będą mogli zobaczyć Twoich postów ani cię obserwować. Będą mogli domyślić się, że są zablokowani.",
   "report.categories.other": "Inne",
   "report.categories.spam": "Spam",
   "report.categories.violation": "Zawartość narusza co najmniej jedną zasadę serwera",
@@ -542,6 +547,7 @@
   "sign_in_banner.sign_in": "Zaloguj się",
   "sign_in_banner.text": "Zaloguj się, aby obserwować profile lub hasztagi, jak również dodawaj wpisy do ulubionych, udostępniaj je dalej i odpowiadaj na nie lub wchodź w interakcje z kontem na innym serwerze.",
   "status.admin_account": "Otwórz interfejs moderacyjny dla @{name}",
+  "status.admin_domain": "Otwórz interfejs moderacyjny dla {domain}",
   "status.admin_status": "Otwórz ten wpis w interfejsie moderacyjnym",
   "status.block": "Zablokuj @{name}",
   "status.bookmark": "Dodaj zakładkę",
@@ -558,11 +564,11 @@
   "status.favourite": "Dodaj do ulubionych",
   "status.filter": "Filtruj ten wpis",
   "status.filtered": "Filtrowany(-a)",
-  "status.hide": "Schowaj toota",
+  "status.hide": "Ukryj post",
   "status.history.created": "{name} utworzył(a) {date}",
   "status.history.edited": "{name} edytował(a) {date}",
   "status.load_more": "Załaduj więcej",
-  "status.media_hidden": "Zawartość multimedialna ukryta",
+  "status.media_hidden": "Multimedia ukryte",
   "status.mention": "Wspomnij o @{name}",
   "status.more": "Więcej",
   "status.mute": "Wycisz @{name}",
@@ -619,7 +625,7 @@
   "units.short.million": "{count} mln",
   "units.short.thousand": "{count} tys.",
   "upload_area.title": "Przeciągnij i upuść aby wysłać",
-  "upload_button.label": "Dodaj zawartość multimedialną (JPEG, PNG, GIF, WebM, MP4, MOV)",
+  "upload_button.label": "Dodaj zdjęcia, filmy lub audio",
   "upload_error.limit": "Przekroczono limit plików do wysłania.",
   "upload_error.poll": "Dołączanie plików nie dozwolone z głosowaniami.",
   "upload_form.audio_description": "Opisz dla osób niesłyszących i niedosłyszących",
diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json
index b42871558..c1ab913d9 100644
--- a/app/javascript/mastodon/locales/pt-BR.json
+++ b/app/javascript/mastodon/locales/pt-BR.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Com respostas",
   "account.report": "Denunciar @{name}",
   "account.requested": "Aguardando aprovação. Clique para cancelar a solicitação",
+  "account.requested_follow": "{name} quer te seguir",
   "account.share": "Compartilhar perfil de @{name}",
   "account.show_reblogs": "Mostrar boosts de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -88,7 +89,7 @@
   "bundle_column_error.retry": "Tente novamente",
   "bundle_column_error.return": "Voltar à página inicial",
   "bundle_column_error.routing.body": "A página solicitada não foi encontrada. Tem certeza de que a URL na barra de endereços está correta?",
-  "bundle_column_error.routing.title": "Erro 404",
+  "bundle_column_error.routing.title": "404",
   "bundle_modal_error.close": "Fechar",
   "bundle_modal_error.message": "Erro ao carregar este componente.",
   "bundle_modal_error.retry": "Tente novamente",
@@ -127,7 +128,7 @@
   "compose.language.search": "Pesquisar idiomas...",
   "compose_form.direct_message_warning_learn_more": "Saiba mais",
   "compose_form.encryption_warning": "As publicações no Mastodon não são criptografadas de ponta-a-ponta. Não compartilhe nenhuma informação sensível no Mastodon.",
-  "compose_form.hashtag_warning": "Este toot não aparecerá em nenhuma hashtag porque está como não-listado. Somente toots públicos podem ser pesquisados por hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Seu perfil não está {locked}. Qualquer um pode te seguir e ver os toots privados.",
   "compose_form.lock_disclaimer.lock": "trancado",
   "compose_form.placeholder": "No que você está pensando?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copiar dados do erro para área de transferência",
   "errors.unexpected_crash.report_issue": "Reportar problema",
   "explore.search_results": "Resultado da pesquisa",
+  "explore.suggested_follows": "Para você",
   "explore.title": "Explorar",
+  "explore.trending_links": "Notícias",
+  "explore.trending_statuses": "Publicações",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Esta categoria de filtro não se aplica ao contexto no qual você acessou esta publicação. Se quiser que a publicação seja filtrada nesse contexto também, você terá que editar o filtro.",
   "filter_modal.added.context_mismatch_title": "Incompatibilidade de contexto!",
   "filter_modal.added.expired_explanation": "Esta categoria de filtro expirou, você precisará alterar a data de expiração para aplicar.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Entrar",
   "sign_in_banner.text": "Entre para seguir perfis ou hashtags, favoritar, compartilhar e responder publicações, interagir a partir da sua conta em um servidor diferente.",
   "status.admin_account": "Abrir interface de moderação para @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Abrir este toot na interface de moderação",
   "status.block": "Bloquear @{name}",
   "status.bookmark": "Salvar",
@@ -553,7 +559,7 @@
   "status.favourite": "Favoritar",
   "status.filter": "Filtrar esta publicação",
   "status.filtered": "Filtrado",
-  "status.hide": "Ocultar publicação",
+  "status.hide": "Hide post",
   "status.history.created": "{name} criou {date}",
   "status.history.edited": "{name} editou {date}",
   "status.load_more": "Ver mais",
diff --git a/app/javascript/mastodon/locales/pt-PT.json b/app/javascript/mastodon/locales/pt-PT.json
index 8dd5b446c..6a7560262 100644
--- a/app/javascript/mastodon/locales/pt-PT.json
+++ b/app/javascript/mastodon/locales/pt-PT.json
@@ -28,7 +28,7 @@
   "account.endorse": "Destacar no perfil",
   "account.featured_tags.last_status_at": "Última publicação em {date}",
   "account.featured_tags.last_status_never": "Sem publicações",
-  "account.featured_tags.title": "Hashtags destacadas por {name}",
+  "account.featured_tags.title": "#Etiquetas destacadas por {name}",
   "account.follow": "Seguir",
   "account.followers": "Seguidores",
   "account.followers.empty": "Ainda ninguém segue este utilizador.",
@@ -40,8 +40,8 @@
   "account.go_to_profile": "Ir para o perfil",
   "account.hide_reblogs": "Esconder partilhas de @{name}",
   "account.joined_short": "Juntou-se a",
-  "account.languages": "Alterar idiomas subscritos",
-  "account.link_verified_on": "A posse deste link foi verificada em {date}",
+  "account.languages": "Alterar línguas subscritas",
+  "account.link_verified_on": "A posse desta ligação foi verificada em {date}",
   "account.locked_info": "Esta conta é privada. O proprietário revê manualmente quem a pode seguir.",
   "account.media": "Média",
   "account.mention": "Mencionar @{name}",
@@ -50,19 +50,20 @@
   "account.mute_notifications": "Silenciar notificações de @{name}",
   "account.muted": "Silenciada",
   "account.open_original_page": "Abrir a página original",
-  "account.posts": "Toots",
+  "account.posts": "Publicações",
   "account.posts_with_replies": "Publicações e respostas",
   "account.report": "Denunciar @{name}",
-  "account.requested": "A aguardar aprovação. Clique para cancelar o pedido de seguidor",
+  "account.requested": "A aguardar aprovação. Clique para cancelar o pedido para seguir",
+  "account.requested_follow": "{name} pediu para segui-lo",
   "account.share": "Partilhar o perfil @{name}",
   "account.show_reblogs": "Mostrar partilhas de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
   "account.unblock": "Desbloquear @{name}",
-  "account.unblock_domain": "Mostrar {domain}",
+  "account.unblock_domain": "Desbloquear o domínio {domain}",
   "account.unblock_short": "Desbloquear",
-  "account.unendorse": "Não mostrar no perfil",
+  "account.unendorse": "Não destacar no perfil",
   "account.unfollow": "Deixar de seguir",
-  "account.unmute": "Não silenciar @{name}",
+  "account.unmute": "Deixar de silenciar @{name}",
   "account.unmute_notifications": "Deixar de silenciar @{name}",
   "account.unmute_short": "Deixar de silenciar",
   "account_note.placeholder": "Clique para adicionar nota",
@@ -81,8 +82,8 @@
   "autosuggest_hashtag.per_week": "{count} por semana",
   "boost_modal.combo": "Pode clicar {combo} para não voltar a ver",
   "bundle_column_error.copy_stacktrace": "Copiar relatório de erros",
-  "bundle_column_error.error.body": "A página solicitada não pôde ser renderizada. Isto pode ser devido a uma falha no nosso código ou a um problema de compatibilidade com o navegador.",
-  "bundle_column_error.error.title": "Oh, não!",
+  "bundle_column_error.error.body": "A página solicitada não pôde ser sintetizada. Isto pode ser devido a uma falha no nosso código ou a um problema de compatibilidade com o navegador.",
+  "bundle_column_error.error.title": "Ó, não!",
   "bundle_column_error.network.body": "Houve um erro ao tentar carregar esta página. Isto pode ocorrer devido a um problema temporário com a sua conexão à internet ou a este servidor.",
   "bundle_column_error.network.title": "Erro de rede",
   "bundle_column_error.retry": "Tente de novo",
@@ -95,48 +96,48 @@
   "closed_registrations.other_server_instructions": "Visto que o Mastodon é descentralizado, pode criar uma conta noutro servidor e interagir com este na mesma.",
   "closed_registrations_modal.description": "Neste momento não é possível criar uma conta em {domain}, mas lembramos que não é preciso ter uma conta especificamente em {domain} para usar o Mastodon.",
   "closed_registrations_modal.find_another_server": "Procurar outro servidor",
-  "closed_registrations_modal.preamble": "O Mastodon é descentralizado, por isso não importa onde a sua conta é criada, continuará a poder acompanhar e interagir com qualquer um neste servidor. Pode até alojar o seu próprio servidor!",
+  "closed_registrations_modal.preamble": "O Mastodon é descentralizado, por isso não importa onde a sua conta é criada, pois continuará a poder acompanhar e interagir com qualquer um neste servidor. Pode até alojar o seu próprio servidor!",
   "closed_registrations_modal.title": "Inscrevendo-se no Mastodon",
   "column.about": "Sobre",
   "column.blocks": "Utilizadores Bloqueados",
-  "column.bookmarks": "Itens salvos",
+  "column.bookmarks": "Marcadores",
   "column.community": "Cronologia local",
   "column.direct": "Mensagens diretas",
-  "column.directory": "Procurar perfis",
-  "column.domain_blocks": "Domínios escondidos",
-  "column.favourites": "Favoritos",
+  "column.directory": "Explorar perfis",
+  "column.domain_blocks": "Domínios bloqueados",
+  "column.favourites": "Preferidos",
   "column.follow_requests": "Seguidores pendentes",
   "column.home": "Início",
   "column.lists": "Listas",
   "column.mutes": "Utilizadores silenciados",
   "column.notifications": "Notificações",
-  "column.pins": "Publicações fixas",
+  "column.pins": "Publicações afixadas",
   "column.public": "Cronologia federada",
-  "column_back_button.label": "Voltar",
+  "column_back_button.label": "Retroceder",
   "column_header.hide_settings": "Esconder configurações",
   "column_header.moveLeft_settings": "Mover coluna para a esquerda",
   "column_header.moveRight_settings": "Mover coluna para a direita",
-  "column_header.pin": "Fixar",
+  "column_header.pin": "Afixar",
   "column_header.show_settings": "Mostrar configurações",
   "column_header.unpin": "Desafixar",
   "column_subheading.settings": "Configurações",
-  "community.column_settings.local_only": "Local apenas",
-  "community.column_settings.media_only": "Somente media",
-  "community.column_settings.remote_only": "Remoto apenas",
-  "compose.language.change": "Alterar idioma",
-  "compose.language.search": "Pesquisar idiomas...",
+  "community.column_settings.local_only": "Apenas local",
+  "community.column_settings.media_only": "Apenas média",
+  "community.column_settings.remote_only": "Apenas remoto",
+  "compose.language.change": "Alterar língua",
+  "compose.language.search": "Pesquisar línguas...",
   "compose_form.direct_message_warning_learn_more": "Conhecer mais",
-  "compose_form.encryption_warning": "As publicações no Mastodon não são encriptadas ponta a ponta. Não partilhe nenhuma informação sensível através do Mastodon.",
-  "compose_form.hashtag_warning": "Este toot não será listado em nenhuma hashtag por ser não listado. Apenas toots públics podem ser pesquisados por hashtag.",
+  "compose_form.encryption_warning": "As publicações no Mastodon não são criptografadas de ponta a ponta. Não partilhe nenhuma informação sensível através do Mastodon.",
+  "compose_form.hashtag_warning": "Esta publicação não será listada em qualquer etiqueta, pois não é pública. Apenas as publicações públicas podem ser pesquisadas por etiquetas.",
   "compose_form.lock_disclaimer": "A sua conta não é {locked}. Qualquer pessoa pode segui-lo e ver as publicações direcionadas apenas a seguidores.",
-  "compose_form.lock_disclaimer.lock": "bloqueado",
+  "compose_form.lock_disclaimer.lock": "fechada",
   "compose_form.placeholder": "Em que está a pensar?",
   "compose_form.poll.add_option": "Adicionar uma opção",
-  "compose_form.poll.duration": "Duração da votação",
+  "compose_form.poll.duration": "Duração do inquérito",
   "compose_form.poll.option_placeholder": "Opção {number}",
   "compose_form.poll.remove_option": "Eliminar esta opção",
-  "compose_form.poll.switch_to_multiple": "Alterar a votação para permitir múltiplas escolhas",
-  "compose_form.poll.switch_to_single": "Alterar a votação para permitir uma única escolha",
+  "compose_form.poll.switch_to_multiple": "Alterar o inquérito para permitir várias respostas",
+  "compose_form.poll.switch_to_single": "Alterar o inquérito para permitir uma única resposta",
   "compose_form.publish": "Publicar",
   "compose_form.publish_form": "Publicar",
   "compose_form.publish_loud": "{publish}!",
@@ -145,7 +146,7 @@
   "compose_form.sensitive.marked": "Media marcada como sensível",
   "compose_form.sensitive.unmarked": "Media não está marcada como sensível",
   "compose_form.spoiler.marked": "Texto escondido atrás de aviso",
-  "compose_form.spoiler.unmarked": "O texto não está escondido",
+  "compose_form.spoiler.unmarked": "Juntar um aviso de conteúdo",
   "compose_form.spoiler_placeholder": "Escreva o seu aviso aqui",
   "confirmation_modal.cancel": "Cancelar",
   "confirmations.block.block_and_report": "Bloquear e Denunciar",
@@ -158,16 +159,16 @@
   "confirmations.delete_list.confirm": "Eliminar",
   "confirmations.delete_list.message": "Tens a certeza de que deseja eliminar permanentemente esta lista?",
   "confirmations.discard_edit_media.confirm": "Descartar",
-  "confirmations.discard_edit_media.message": "Tem alterações não salvas na descrição ou pré-visualização da media. Descartar mesmo assim?",
+  "confirmations.discard_edit_media.message": "Tem alterações por guardar na descrição ou pré-visualização do conteúdo. Descartar mesmo assim?",
   "confirmations.domain_block.confirm": "Esconder tudo deste domínio",
   "confirmations.domain_block.message": "De certeza que queres bloquear completamente o domínio {domain}? Na maioria dos casos, silenciar ou bloquear alguns utilizadores é suficiente e é o recomendado. Não irás ver conteúdo daquele domínio em cronologia alguma nem nas tuas notificações. Os teus seguidores daquele domínio serão removidos.",
   "confirmations.logout.confirm": "Terminar sessão",
-  "confirmations.logout.message": "Deseja terminar a sessão?",
+  "confirmations.logout.message": "Tem a certeza de que quer terminar a sessão?",
   "confirmations.mute.confirm": "Silenciar",
   "confirmations.mute.explanation": "Isto irá esconder publicações deles ou publicações que os mencionem, mas irá permitir que vejam as suas publicações e sejam seus seguidores.",
   "confirmations.mute.message": "De certeza que queres silenciar {name}?",
   "confirmations.redraft.confirm": "Eliminar & reescrever",
-  "confirmations.redraft.message": "Tem a certeza que quer eliminar e reescrever esta publicação? Os favoritos e partilhas perder-se-ão e as respostas à publicação original ficarão órfãs.",
+  "confirmations.redraft.message": "Tem a certeza de que quer eliminar e reescrever esta publicação? Os favoritos e partilhas perder-se-ão e as respostas à publicação original ficarão órfãs.",
   "confirmations.reply.confirm": "Responder",
   "confirmations.reply.message": "Responder agora irá reescrever a mensagem que está a compor actualmente. Tem a certeza que quer continuar?",
   "confirmations.unfollow.confirm": "Deixar de seguir",
@@ -183,12 +184,12 @@
   "directory.new_arrivals": "Recém chegados",
   "directory.recently_active": "Com actividade recente",
   "disabled_account_banner.account_settings": "Definições da conta",
-  "disabled_account_banner.text": "A sua conta {disabledAccount} está, no momento, desativada.",
+  "disabled_account_banner.text": "A sua conta {disabledAccount} está presentemente desativada.",
   "dismissable_banner.community_timeline": "Estas são as publicações públicas mais recentes de pessoas cujas contas são hospedadas por {domain}.",
   "dismissable_banner.dismiss": "Descartar",
   "dismissable_banner.explore_links": "Essas histórias de notícias estão, no momento, a ser faladas por pessoas neste e noutros servidores da rede descentralizada.",
   "dismissable_banner.explore_statuses": "Estas publicações, deste e de outros servidores na rede descentralizada, estão, neste momento, a ganhar atenção neste servidor.",
-  "dismissable_banner.explore_tags": "Estas hashtags estão, neste momento, a ganhar atenção entre as pessoas neste e outros servidores da rede descentralizada.",
+  "dismissable_banner.explore_tags": "Estas #etiquetas estão presentemente a ganhar atenção entre as pessoas neste e noutros servidores da rede descentralizada.",
   "dismissable_banner.public_timeline": "Estas são as publicações públicas mais recentes de pessoas neste e outros servidores da rede descentralizada que esse servidor conhece.",
   "embed.instructions": "Incorpore esta publicação no seu site copiando o código abaixo.",
   "embed.preview": "Podes ver aqui como irá ficar:",
@@ -199,7 +200,7 @@
   "emoji_button.food": "Comida & Bebida",
   "emoji_button.label": "Inserir Emoji",
   "emoji_button.nature": "Natureza",
-  "emoji_button.not_found": "Não tem emojis!! (╯°□°)╯︵ ┻━┻",
+  "emoji_button.not_found": "Nenhum emoji correspondente encontrado",
   "emoji_button.objects": "Objectos",
   "emoji_button.people": "Pessoas",
   "emoji_button.recent": "Utilizados regularmente",
@@ -208,19 +209,19 @@
   "emoji_button.symbols": "Símbolos",
   "emoji_button.travel": "Viagens & Lugares",
   "empty_column.account_suspended": "Conta suspensa",
-  "empty_column.account_timeline": "Sem toots por aqui!",
+  "empty_column.account_timeline": "Sem publicações por aqui!",
   "empty_column.account_unavailable": "Perfil indisponível",
   "empty_column.blocks": "Ainda não bloqueaste qualquer utilizador.",
-  "empty_column.bookmarked_statuses": "Ainda não adicionou nenhum toot aos Itens salvos. Quando adicionar, eles serão exibidos aqui.",
-  "empty_column.community": "A timeline local está vazia. Escreve algo publicamente para começar!",
+  "empty_column.bookmarked_statuses": "Ainda não tem nenhuma publicação nos seus marcadores. Quando tiver, serão exibidas aqui.",
+  "empty_column.community": "A cronologia local está vazia. Escreve algo público para começar!",
   "empty_column.direct": "Ainda não tem qualquer mensagem direta. Quando enviar ou receber alguma, ela irá aparecer aqui.",
   "empty_column.domain_blocks": "Ainda não há qualquer domínio escondido.",
-  "empty_column.explore_statuses": "Nada em destaque por agora. Volte mais tarde!",
-  "empty_column.favourited_statuses": "Ainda não tens quaisquer toots favoritos. Quando tiveres algum, ele irá aparecer aqui.",
-  "empty_column.favourites": "Ainda ninguém marcou este toot como favorito. Quando alguém o fizer, ele irá aparecer aqui.",
-  "empty_column.follow_recommendations": "Parece que não foi possível gerar nenhuma sugestão para si. Pode tentar utilizar a pesquisa para procurar pessoas que conheça ou explorar as hashtags em destaque.",
+  "empty_column.explore_statuses": "Nada está em alta no momento. Volte mais tarde!",
+  "empty_column.favourited_statuses": "Ainda não tens quaisquer publicações nos marcadores. Quando tiveres, aparecerão aqui.",
+  "empty_column.favourites": "Ainda ninguém tem esta publicação nos seus marcadores. Quando alguém o tiver, ele irá aparecer aqui.",
+  "empty_column.follow_recommendations": "Parece que não foi possível gerar nenhuma sugestão para si. Pode tentar utilizar a pesquisa para procurar pessoas que conheça ou explorar as #etiquetas em destaque.",
   "empty_column.follow_requests": "Ainda não tens nenhum pedido de seguidor. Quando receberes algum, ele irá aparecer aqui.",
-  "empty_column.hashtag": "Não foram encontradas publicações com essa hashtag.",
+  "empty_column.hashtag": "Não foram encontradas publicações com essa #etiqueta.",
   "empty_column.home": "Ainda não segues qualquer utilizador. Visita {public} ou utiliza a pesquisa para procurar outros utilizadores.",
   "empty_column.home.suggestions": "Ver algumas sugestões",
   "empty_column.list": "Ainda não existem publicações nesta lista. Quando membros desta lista fizerem novas publicações, elas aparecerão aqui.",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copiar a stacktrace para o clipboard",
   "errors.unexpected_crash.report_issue": "Reportar problema",
   "explore.search_results": "Resultados da pesquisa",
+  "explore.suggested_follows": "Para si",
   "explore.title": "Explorar",
+  "explore.trending_links": "Notícias",
+  "explore.trending_statuses": "Publicações",
+  "explore.trending_tags": "#Etiquetas",
   "filter_modal.added.context_mismatch_explanation": "Esta categoria de filtro não se aplica ao contexto em que acedeu a esta publicação. Se pretender que esta publicação seja filtrada também neste contexto, terá que editar o filtro.",
   "filter_modal.added.context_mismatch_title": "Contexto incoerente!",
   "filter_modal.added.expired_explanation": "Esta categoria de filtro expirou, necessita alterar a data de validade para que ele seja aplicado.",
@@ -271,27 +276,27 @@
   "hashtag.column_header.tag_mode.any": "ou {additional}",
   "hashtag.column_header.tag_mode.none": "sem {additional}",
   "hashtag.column_settings.select.no_options_message": "Não foram encontradas sugestões",
-  "hashtag.column_settings.select.placeholder": "Introduzir as hashtags…",
+  "hashtag.column_settings.select.placeholder": "Inserir #etiquetas…",
   "hashtag.column_settings.tag_mode.all": "Todos estes",
   "hashtag.column_settings.tag_mode.any": "Qualquer destes",
   "hashtag.column_settings.tag_mode.none": "Nenhum destes",
   "hashtag.column_settings.tag_toggle": "Incluir etiquetas adicionais para esta coluna",
-  "hashtag.follow": "Seguir hashtag",
-  "hashtag.unfollow": "Parar de seguir hashtag",
+  "hashtag.follow": "Seguir #etiqueta",
+  "hashtag.unfollow": "Deixar de seguir #etiqueta",
   "home.column_settings.basic": "Básico",
-  "home.column_settings.show_reblogs": "Mostrar boosts",
+  "home.column_settings.show_reblogs": "Mostrar impulsos",
   "home.column_settings.show_replies": "Mostrar respostas",
-  "home.hide_announcements": "Ocultar anúncios",
-  "home.show_announcements": "Exibir anúncios",
-  "interaction_modal.description.favourite": "Com uma conta no Mastodon, pode adicionar esta publicação aos favoritos para que o autor saiba que gostou e salvá-la para mais tarde.",
+  "home.hide_announcements": "Ocultar comunicações",
+  "home.show_announcements": "Exibir comunicações",
+  "interaction_modal.description.favourite": "Com uma conta no Mastodon, pode adicionar esta publicação aos marcadores para que o autor saiba que gostou e guardá-la para mais tarde.",
   "interaction_modal.description.follow": "Com uma conta no Mastodon, pode seguir {name} para receber as suas publicações na sua página inicial.",
   "interaction_modal.description.reblog": "Com uma conta no Mastodon, pode impulsionar esta publicação para compartilhá-lo com os seus seguidores.",
   "interaction_modal.description.reply": "Com uma conta no Mastodon, pode responder a esta publicação.",
   "interaction_modal.on_another_server": "Num servidor diferente",
   "interaction_modal.on_this_server": "Neste servidor",
-  "interaction_modal.other_server_instructions": "Copie e cole este URL no campo de pesquisa do seu aplicativo Mastodon favorito ou da interface web do seu servidor Mastodon.",
-  "interaction_modal.preamble": "Uma vez que o Mastodon é descentralizado, pode utilizar a sua conta existente, hospedada em outro servidor Mastodon ou plataforma compatível, se não tiver uma conta neste servidor.",
-  "interaction_modal.title.favourite": "Adicionar a publicação de {name} aos favoritos",
+  "interaction_modal.other_server_instructions": "Copie e cole este URL no campo de pesquisa da sua aplicação Mastodon preferida, ou da interface web do seu servidor Mastodon.",
+  "interaction_modal.preamble": "Uma vez que o Mastodon é descentralizado, caso não tenha uma conta neste servidor, pode utilizar a sua conta existente noutro servidor Mastodon ou plataforma compatível.",
+  "interaction_modal.title.favourite": "Adicionar a publicação de {name} aos marcadores",
   "interaction_modal.title.follow": "Seguir {name}",
   "interaction_modal.title.reblog": "Impulsionar a publicação de {name}",
   "interaction_modal.title.reply": "Responder à publicação de {name}",
@@ -300,17 +305,17 @@
   "intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",
   "keyboard_shortcuts.back": "para voltar",
   "keyboard_shortcuts.blocked": "para abrir a lista de utilizadores bloqueados",
-  "keyboard_shortcuts.boost": "para partilhar",
+  "keyboard_shortcuts.boost": "Impulsionar a publicação",
   "keyboard_shortcuts.column": "para focar uma publicação numa das colunas",
   "keyboard_shortcuts.compose": "para focar na área de publicação",
   "keyboard_shortcuts.description": "Descrição",
   "keyboard_shortcuts.direct": "para abrir a coluna das mensagens diretas",
   "keyboard_shortcuts.down": "para mover para baixo na lista",
   "keyboard_shortcuts.enter": "para expandir uma publicação",
-  "keyboard_shortcuts.favourite": "para adicionar aos favoritos",
-  "keyboard_shortcuts.favourites": "para abrir a lista dos favoritos",
+  "keyboard_shortcuts.favourite": "Juntar aos marcadores",
+  "keyboard_shortcuts.favourites": "Abrir lista de marcadores",
   "keyboard_shortcuts.federated": "para abrir a cronologia federada",
-  "keyboard_shortcuts.heading": "Atalhos do teclado",
+  "keyboard_shortcuts.heading": "Atalhos de teclado",
   "keyboard_shortcuts.home": "para abrir a cronologia inicial",
   "keyboard_shortcuts.hotkey": "Atalho",
   "keyboard_shortcuts.legend": "para mostrar esta legenda",
@@ -393,7 +398,7 @@
   "notification.mention": "{name} mencionou-te",
   "notification.own_poll": "A sua votação terminou",
   "notification.poll": "Uma votação em que participaste chegou ao fim",
-  "notification.reblog": "{name} partilhou a tua publicação",
+  "notification.reblog": "{name} reforçou a tua publicação",
   "notification.status": "{name} acabou de publicar",
   "notification.update": "{name} editou uma publicação",
   "notifications.clear": "Limpar notificações",
@@ -401,34 +406,34 @@
   "notifications.column_settings.admin.report": "Novas denúncias:",
   "notifications.column_settings.admin.sign_up": "Novas inscrições:",
   "notifications.column_settings.alert": "Notificações no ambiente de trabalho",
-  "notifications.column_settings.favourite": "Favoritos:",
+  "notifications.column_settings.favourite": "Marcadores:",
   "notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorias",
   "notifications.column_settings.filter_bar.category": "Barra de filtros rápidos",
   "notifications.column_settings.filter_bar.show_bar": "Mostrar barra de filtros",
   "notifications.column_settings.follow": "Novos seguidores:",
   "notifications.column_settings.follow_request": "Novos pedidos de seguidor:",
   "notifications.column_settings.mention": "Menções:",
-  "notifications.column_settings.poll": "Resultados da votação:",
+  "notifications.column_settings.poll": "Resultados do inquérito:",
   "notifications.column_settings.push": "Notificações Push",
-  "notifications.column_settings.reblog": "Boosts:",
+  "notifications.column_settings.reblog": "Reforços:",
   "notifications.column_settings.show": "Mostrar na coluna",
   "notifications.column_settings.sound": "Reproduzir som",
-  "notifications.column_settings.status": "Novos toots:",
-  "notifications.column_settings.unread_notifications.category": "Notificações não lidas",
-  "notifications.column_settings.unread_notifications.highlight": "Destacar notificações não lidas",
+  "notifications.column_settings.status": "Novas publicações:",
+  "notifications.column_settings.unread_notifications.category": "Notificações por ler",
+  "notifications.column_settings.unread_notifications.highlight": "Destacar notificações por ler",
   "notifications.column_settings.update": "Edições:",
   "notifications.filter.all": "Todas",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.favourites": "Favoritos",
+  "notifications.filter.boosts": "Reforços",
+  "notifications.filter.favourites": "Marcadores",
   "notifications.filter.follows": "Seguidores",
   "notifications.filter.mentions": "Menções",
-  "notifications.filter.polls": "Votações",
+  "notifications.filter.polls": "Resultados do inquérito",
   "notifications.filter.statuses": "Atualizações de pessoas que você segue",
-  "notifications.grant_permission": "Conceder permissões.",
+  "notifications.grant_permission": "Conceder permissão.",
   "notifications.group": "{count} notificações",
   "notifications.mark_as_read": "Marcar todas as notificações como lidas",
   "notifications.permission_denied": "Notificações no ambiente de trabalho não estão disponíveis porque a permissão, solicitada pelo navegador, foi recusada anteriormente",
-  "notifications.permission_denied_alert": "Notificações no ambinente de trabalho não podem ser ativadas, pois a permissão do navegador foi recusada anteriormente",
+  "notifications.permission_denied_alert": "Notificações no ambiente de trabalho não podem ser ativadas, pois a permissão do navegador foi recusada anteriormente",
   "notifications.permission_required": "Notificações no ambiente de trabalho não estão disponíveis porque a permissão necessária não foi concedida.",
   "notifications_permission_banner.enable": "Ativar notificações no ambiente de trabalho",
   "notifications_permission_banner.how_to_control": "Para receber notificações quando o Mastodon não estiver aberto, ative as notificações no ambiente de trabalho. Depois da sua ativação, pode controlar precisamente quais tipos de interações geram notificações, através do botão {icon} acima.",
@@ -442,7 +447,7 @@
   "poll.voted": "Votaste nesta resposta",
   "poll.votes": "{votes, plural, one {# voto } other {# votos}}",
   "poll_button.add_poll": "Adicionar votação",
-  "poll_button.remove_poll": "Remover votação",
+  "poll_button.remove_poll": "Remover sondagem",
   "privacy.change": "Ajustar a privacidade da publicação",
   "privacy.direct.long": "Apenas para utilizadores mencionados",
   "privacy.direct.short": "Apenas pessoas mencionadas",
@@ -453,7 +458,7 @@
   "privacy.unlisted.long": "Visível para todos, mas não incluir em funcionalidades de divulgação",
   "privacy.unlisted.short": "Não listar",
   "privacy_policy.last_updated": "Última atualização em {date}",
-  "privacy_policy.title": "Política de Privacidade",
+  "privacy_policy.title": "Política de privacidade",
   "refresh": "Actualizar",
   "regeneration_indicator.label": "A carregar…",
   "regeneration_indicator.sublabel": "A tua página inicial está a ser preparada!",
@@ -470,7 +475,7 @@
   "relative_time.today": "hoje",
   "reply_indicator.cancel": "Cancelar",
   "report.block": "Bloquear",
-  "report.block_explanation": "Não verá as publicações deles. Eles não serão capazes de ver suas publicações ou de o seguir. Eles vão conseguir saber que estão bloqueados.",
+  "report.block_explanation": "Não verá as suas publicações. Eles deixarão de poder ver suas publicações ou segui-lo. Eles poderão perceber que estão bloqueados.",
   "report.categories.other": "Outro",
   "report.categories.spam": "Spam",
   "report.categories.violation": "O conteúdo viola uma ou mais regras do servidor",
@@ -479,19 +484,19 @@
   "report.category.title_account": "perfil",
   "report.category.title_status": "publicação",
   "report.close": "Concluído",
-  "report.comment.title": "Há algo mais que pensa que devemos saber?",
-  "report.forward": "Reenviar para {target}",
-  "report.forward_hint": "A conta é de outro servidor. Enviar uma cópia anónima da denúncia para lá também?",
+  "report.comment.title": "Há algo mais que ache de que deveríamos saber?",
+  "report.forward": "Reencaminhar para {target}",
+  "report.forward_hint": "A conta é de outro servidor. Enviar uma cópia da anónima da denúncia para lá também?",
   "report.mute": "Silenciar",
-  "report.mute_explanation": "Não verá as publicações deles. Eles ainda poderão segui-lo e ver as suas publicações e não saberão que estão silenciados.",
+  "report.mute_explanation": "Não verá as suas publicações. Eles ainda poderão segui-lo e ver as suas publicações, e não saberão que estão silenciados.",
   "report.next": "Seguinte",
   "report.placeholder": "Comentários adicionais",
-  "report.reasons.dislike": "Não gosto disso",
+  "report.reasons.dislike": "Não gosto disto",
   "report.reasons.dislike_description": "Não é algo que deseje ver",
   "report.reasons.other": "É outra coisa",
   "report.reasons.other_description": "O problema não se encaixa nas outras categorias",
   "report.reasons.spam": "É spam",
-  "report.reasons.spam_description": "Links maliciosos, contactos falsos, ou respostas repetitivas",
+  "report.reasons.spam_description": "Hiperligações maliciosas, contactos falsos, ou respostas repetitivas",
   "report.reasons.violation": "Viola as regras do servidor",
   "report.reasons.violation_description": "Está ciente de que infringe regras específicas",
   "report.rules.subtitle": "Selecione tudo o que se aplicar",
@@ -503,7 +508,7 @@
   "report.thanks.take_action": "Aqui estão as suas opções para controlar o que vê no Mastodon:",
   "report.thanks.take_action_actionable": "Enquanto revemos a sua denúncia, pode tomar medidas contra @{name}:",
   "report.thanks.title": "Não quer ver isto?",
-  "report.thanks.title_actionable": "Obrigado por reportar, vamos analisar.",
+  "report.thanks.title_actionable": "Obrigado por denunciar. Iremos analisar.",
   "report.unfollow": "Deixar de seguir @{name}",
   "report.unfollow_explanation": "Está a seguir esta conta. Para não ver mais as publicações desta conta na sua página inicial, deixe de segui-la.",
   "report_notification.attached_statuses": "{count, plural,one {{count} publicação} other {{count} publicações}} em anexo",
@@ -514,17 +519,17 @@
   "search.placeholder": "Pesquisar",
   "search.search_or_paste": "Pesquisar ou introduzir URL",
   "search_popout.search_format": "Formato avançado de pesquisa",
-  "search_popout.tips.full_text": "Texto simples devolve publicações que escreveu, marcou como favorita, partilhou ou em que foi mencionado, tal como nomes de utilizador, alcunhas e hashtags.",
-  "search_popout.tips.hashtag": "hashtag",
+  "search_popout.tips.full_text": "Texto simples devolve publicações que escreveu, marcou, reforçou, ou em que foi mencionado, tal como nomes de utilizador, alcunhas e #etiquetas.",
+  "search_popout.tips.hashtag": "etiqueta",
   "search_popout.tips.status": "publicação",
-  "search_popout.tips.text": "O texto simples retorna a correspondência de nomes, utilizadores e hashtags",
+  "search_popout.tips.text": "O texto simples retorna a correspondência de nomes, utilizadores e #etiquetas",
   "search_popout.tips.user": "utilizador",
   "search_results.accounts": "Pessoas",
   "search_results.all": "Tudo",
-  "search_results.hashtags": "Hashtags",
+  "search_results.hashtags": "Etiquetas",
   "search_results.nothing_found": "Não foi possível encontrar resultados para as expressões pesquisadas",
-  "search_results.statuses": "Toots",
-  "search_results.statuses_fts_disabled": "A pesquisa de toots pelo seu conteúdo não está disponível nesta instância Mastodon.",
+  "search_results.statuses": "Publicações",
+  "search_results.statuses_fts_disabled": "A pesquisa de publicações pelo seu conteúdo não está disponível nesta instância Mastodon.",
   "search_results.title": "Pesquisar por {q}",
   "search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
   "server_banner.about_active_users": "Pessoas que utilizaram este servidor nos últimos 30 dias (Utilizadores Ativos Mensais)",
@@ -535,25 +540,26 @@
   "server_banner.server_stats": "Estatísticas do servidor:",
   "sign_in_banner.create_account": "Criar conta",
   "sign_in_banner.sign_in": "Iniciar sessão",
-  "sign_in_banner.text": "Inicie sessão para seguir perfis ou hashtags, favoritos, partilhar e responder às publicações ou interagir através da sua conta noutro servidor.",
+  "sign_in_banner.text": "Inicie sessão para seguir perfis ou #etiquetas, ou marcadores, para partilhar ou responder às publicações, ou interagir através da sua conta noutro servidor.",
   "status.admin_account": "Abrir a interface de moderação para @{name}",
+  "status.admin_domain": "Abrir interface de moderação para {domain}",
   "status.admin_status": "Abrir esta publicação na interface de moderação",
   "status.block": "Bloquear @{name}",
-  "status.bookmark": "Salvar",
-  "status.cancel_reblog_private": "Remover boost",
-  "status.cannot_reblog": "Não é possível fazer boost a esta publicação",
-  "status.copy": "Copiar o link para a publicação",
+  "status.bookmark": "Guardar nos marcadores",
+  "status.cancel_reblog_private": "Deixar de reforçar",
+  "status.cannot_reblog": "Não é possível reforçar esta publicação",
+  "status.copy": "Copiar ligação para a publicação",
   "status.delete": "Eliminar",
-  "status.detailed_status": "Vista de conversação detalhada",
+  "status.detailed_status": "Vista pormenorizada da conversa",
   "status.direct": "Mensagem direta @{name}",
   "status.edit": "Editar",
   "status.edited": "Editado em {date}",
   "status.edited_x_times": "Editado {count, plural,one {{count} vez} other {{count} vezes}}",
-  "status.embed": "Incorporar",
-  "status.favourite": "Adicionar aos favoritos",
+  "status.embed": "Embutir",
+  "status.favourite": "Adicionar aos marcadores",
   "status.filter": "Filtrar esta publicação",
   "status.filtered": "Filtrada",
-  "status.hide": "Esconder publicação",
+  "status.hide": "Ocultar publicação",
   "status.history.created": "{name} criado em {date}",
   "status.history.edited": "{name} editado em {date}",
   "status.load_more": "Carregar mais",
@@ -563,20 +569,20 @@
   "status.mute": "Silenciar @{name}",
   "status.mute_conversation": "Silenciar conversa",
   "status.open": "Expandir",
-  "status.pin": "Fixar no perfil",
-  "status.pinned": "Publicação fixa",
+  "status.pin": "Afixar no perfil",
+  "status.pinned": "Publicação afixada",
   "status.read_more": "Ler mais",
-  "status.reblog": "Partilhar",
-  "status.reblog_private": "Fazer boost com a audiência original",
-  "status.reblogged_by": "{name} fez boost",
-  "status.reblogs.empty": "Ainda ninguém fez boost a este toot. Quando alguém o fizer, ele irá aparecer aqui.",
+  "status.reblog": "Reforçar",
+  "status.reblog_private": "Reforçar com a visibilidade de origem",
+  "status.reblogged_by": "{name} reforçou",
+  "status.reblogs.empty": "Ainda ninguém reforçou esta publicação. Quando alguém o fizer, ele irá aparecer aqui.",
   "status.redraft": "Apagar & reescrever",
-  "status.remove_bookmark": "Remover dos itens salvos",
+  "status.remove_bookmark": "Retirar dos marcadores",
   "status.replied_to": "Respondeu a {name}",
   "status.reply": "Responder",
   "status.replyAll": "Responder à conversa",
   "status.report": "Denunciar @{name}",
-  "status.sensitive_warning": "Conteúdo sensível",
+  "status.sensitive_warning": "Conteúdo problemático",
   "status.share": "Partilhar",
   "status.show_filter_reason": "Mostrar mesmo assim",
   "status.show_less": "Mostrar menos",
@@ -586,14 +592,14 @@
   "status.show_original": "Mostrar original",
   "status.translate": "Traduzir",
   "status.translated_from_with": "Traduzido do {lang} usando {provider}",
-  "status.uncached_media_warning": "Não disponível",
+  "status.uncached_media_warning": "Indisponível",
   "status.unmute_conversation": "Deixar de silenciar esta conversa",
-  "status.unpin": "Não fixar no perfil",
-  "subscribed_languages.lead": "Após a alteração, apenas as publicações nos idiomas selecionados aparecerão na sua página inicial e listas. Não selecione nenhuma para receber publicações de todos os idiomas.",
+  "status.unpin": "Desafixar do perfil",
+  "subscribed_languages.lead": "Após a alteração, apenas as publicações nas línguas seleccionadas aparecerão na sua página inicial e listas. Não selecione nenhuma para receber publicações de todas as línguas.",
   "subscribed_languages.save": "Guardar alterações",
-  "subscribed_languages.target": "Alterar idiomas subscritos para {target}",
+  "subscribed_languages.target": "Alterar línguas assinadas para {target}",
   "suggestions.dismiss": "Dispensar a sugestão",
-  "suggestions.header": "Tu podes estar interessado em…",
+  "suggestions.header": "Poderá estar interessado em…",
   "tabs_bar.federated_timeline": "Federada",
   "tabs_bar.home": "Início",
   "tabs_bar.local_timeline": "Local",
@@ -606,19 +612,19 @@
   "timeline_hint.remote_resource_not_displayed": "{resource} de outros servidores não são exibidos.",
   "timeline_hint.resources.followers": "Seguidores",
   "timeline_hint.resources.follows": "Seguindo",
-  "timeline_hint.resources.statuses": "Toots antigos",
+  "timeline_hint.resources.statuses": "Publicações mais antigas",
   "trends.counter_by_accounts": "{count, plural, one {{counter} pessoa} other {{counter} pessoas}} {days, plural, one {no último dia} other {nos últimos {days} dias}}",
-  "trends.trending_now": "Tendências atuais",
+  "trends.trending_now": "Em alta neste momento",
   "ui.beforeunload": "O teu rascunho será perdido se abandonares o Mastodon.",
   "units.short.billion": "{count}MM",
   "units.short.million": "{count}M",
   "units.short.thousand": "{count}m",
   "upload_area.title": "Arraste e solte para enviar",
-  "upload_button.label": "Adicionar media",
+  "upload_button.label": "Juntar imagens, um vídeo, ou um ficheiro de som",
   "upload_error.limit": "Limite máximo do ficheiro a carregar excedido.",
-  "upload_error.poll": "Carregamento de ficheiros não é permitido em votações.",
+  "upload_error.poll": "O carregamento de ficheiros não é permitido em sondagens.",
   "upload_form.audio_description": "Descreva para pessoas com diminuição da acuidade auditiva",
-  "upload_form.description": "Descrição da imagem para pessoas com dificuldades visuais",
+  "upload_form.description": "Descreva para pessoas com diminuição da acuidade visual",
   "upload_form.description_missing": "Nenhuma descrição adicionada",
   "upload_form.edit": "Editar",
   "upload_form.thumbnail": "Alterar miniatura",
@@ -632,18 +638,18 @@
   "upload_modal.detect_text": "Detectar texto na imagem",
   "upload_modal.edit_media": "Editar media",
   "upload_modal.hint": "Clique ou arraste o círculo na pré-visualização para escolher o ponto focal que será sempre visível em todas as miniaturas.",
-  "upload_modal.preparing_ocr": "A preparar OCR…",
+  "upload_modal.preparing_ocr": "A preparar o reconhecimento de caracteres (OCR)…",
   "upload_modal.preview_label": "Pré-visualizar ({ratio})",
   "upload_progress.label": "A enviar...",
   "upload_progress.processing": "A processar…",
   "video.close": "Fechar vídeo",
   "video.download": "Descarregar ficheiro",
-  "video.exit_fullscreen": "Sair de full screen",
+  "video.exit_fullscreen": "Sair do modo ecrã inteiro",
   "video.expand": "Expandir vídeo",
   "video.fullscreen": "Ecrã completo",
   "video.hide": "Esconder vídeo",
   "video.mute": "Silenciar",
   "video.pause": "Pausar",
   "video.play": "Reproduzir",
-  "video.unmute": "Remover de silêncio"
+  "video.unmute": "Deixar de silenciar"
 }
diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json
index 69ab4fb9b..6e5674bd1 100644
--- a/app/javascript/mastodon/locales/ro.json
+++ b/app/javascript/mastodon/locales/ro.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Postări și răspunsuri",
   "account.report": "Raportează pe @{name}",
   "account.requested": "Se așteaptă aprobarea. Apasă pentru a anula cererea de urmărire",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Distribuie profilul lui @{name}",
   "account.show_reblogs": "Arată impulsurile de la @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Căutare limbi…",
   "compose_form.direct_message_warning_learn_more": "Află mai multe",
   "compose_form.encryption_warning": "Postările pe Mastodon nu sunt criptate în ambele părți. Nu împărtășiți nici o informație sensibilă pe Mastodon.",
-  "compose_form.hashtag_warning": "Această postare nu va fi listată sub niciun hashtag deoarece este nelistată. Doar postările publice pot fi căutate cu un hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Contul tău nu este {locked}. Oricine se poate abona la tine pentru a îți vedea postările numai pentru abonați.",
   "compose_form.lock_disclaimer.lock": "privat",
   "compose_form.placeholder": "La ce te gândești?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copiere stacktrace în clipboard",
   "errors.unexpected_crash.report_issue": "Raportează o problemă",
   "explore.search_results": "Rezultatele căutării",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explorează",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "Această categorie de filtre nu se aplică în contextul în care ați accesat acestă postare. Dacă doriți ca postarea să fie filtrată și în acest context, va trebui să editați filtrul.",
   "filter_modal.added.context_mismatch_title": "Nepotrivire contextuală!",
   "filter_modal.added.expired_explanation": "Această categorie de filtre a expirat, va trebui să modifici data de expirare pentru ca aceasta să se aplice.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Conectează-te",
   "sign_in_banner.text": "Conectează-te pentru a te abona la profiluri și haștaguri, pentru a aprecia, distribui și a răspunde postărilor, sau interacționează folosindu-ți contul de pe un alt server.",
   "status.admin_account": "Deschide interfața de moderare pentru @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Deschide această stare în interfața de moderare",
   "status.block": "Blochează pe @{name}",
   "status.bookmark": "Marchează",
@@ -553,7 +559,7 @@
   "status.favourite": "Favorite",
   "status.filter": "Filtrează această postare",
   "status.filtered": "Sortate",
-  "status.hide": "Ascunde postarea",
+  "status.hide": "Hide post",
   "status.history.created": "creată de {name} pe {date}",
   "status.history.edited": "modificată de {name} pe {date}",
   "status.load_more": "Încarcă mai multe",
diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json
index 506622e7f..890b62bf4 100644
--- a/app/javascript/mastodon/locales/ru.json
+++ b/app/javascript/mastodon/locales/ru.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Посты и ответы",
   "account.report": "Пожаловаться на @{name}",
   "account.requested": "Ожидает подтверждения. Нажмите для отмены запроса",
+  "account.requested_follow": "{name} отправил(а) вам запрос на подписку",
   "account.share": "Поделиться профилем @{name}",
   "account.show_reblogs": "Показывать продвижения от @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} пост} many {{counter} постов} other {{counter} поста}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Поиск языков...",
   "compose_form.direct_message_warning_learn_more": "Подробнее",
   "compose_form.encryption_warning": "Посты в Mastodon не защищены сквозным шифрованием. Не делитесь конфиденциальной информацией через Mastodon.",
-  "compose_form.hashtag_warning": "Так как этот пост не публичный, он не отобразится в поиске по хэштегам.",
+  "compose_form.hashtag_warning": "Этот пост не будет виден ни под одним из хэштегов, так как он не публичный. Только публичные посты можно найти по хэштегу.",
   "compose_form.lock_disclaimer": "Ваша учётная запись {locked}. Любой пользователь сможет подписаться на вас и просматривать посты для подписчиков.",
   "compose_form.lock_disclaimer.lock": "не закрыта",
   "compose_form.placeholder": "О чём думаете?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Скопировать диагностическую информацию",
   "errors.unexpected_crash.report_issue": "Сообщить о проблеме",
   "explore.search_results": "Результаты поиска",
+  "explore.suggested_follows": "Для вас",
   "explore.title": "Обзор",
+  "explore.trending_links": "Новости",
+  "explore.trending_statuses": "Посты",
+  "explore.trending_tags": "Хэштеги",
   "filter_modal.added.context_mismatch_explanation": "Эта категория не применяется к контексту, в котором вы получили доступ к этому посту. Если вы хотите, чтобы пост был отфильтрован в этом контексте, вам придётся отредактировать фильтр.",
   "filter_modal.added.context_mismatch_title": "Несоответствие контекста!",
   "filter_modal.added.expired_explanation": "Эта категория фильтра устарела, вам нужно изменить дату окончания фильтра, чтобы применить его.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Войти",
   "sign_in_banner.text": "Войдите, чтобы следить за профилями, хэштегами или избранным, делиться сообщениями и отвечать на них или взаимодействовать с вашей учётной записью на другом сервере.",
   "status.admin_account": "Открыть интерфейс модератора для @{name}",
+  "status.admin_domain": "Открыть интерфейс модерации {domain}",
   "status.admin_status": "Открыть этот пост в интерфейсе модератора",
   "status.block": "Заблокировать @{name}",
   "status.bookmark": "Сохранить в закладки",
diff --git a/app/javascript/mastodon/locales/sa.json b/app/javascript/mastodon/locales/sa.json
index 0507010cc..c4e51431b 100644
--- a/app/javascript/mastodon/locales/sa.json
+++ b/app/javascript/mastodon/locales/sa.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "दौत्यानि प्रत्युत्तराणि च",
   "account.report": "आविद्यताम् @{name}",
   "account.requested": "स्वीकृतिः प्रतीक्ष्यते । नश्यतामित्यस्मिन्नुद्यतां निराकर्तुम् ।",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "@{name} मित्रस्य विवरणं विभाज्यताम्",
   "account.show_reblogs": "@{name} मित्रस्य प्रकाशनानि दृश्यन्ताम्",
   "account.statuses_counter": "{count, plural, one {{counter} दौत्यम्} two {{counter} दौत्ये} other {{counter} दौत्यानि}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "अधिकं ज्ञायताम्",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "न कस्मिन्नपि प्रचलितवस्तुषु सूचितमिदं दौत्यम् । केवलं सार्वजनिकदौत्यानि प्रचलितवस्तुचिह्नेन अन्वेषयितुं शक्यते ।",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "तव लेखा न प्रवेष्टुमशक्या {locked} । कोऽप्यनुसर्ता ते केवलमनुसर्तृृणां कृते स्थितानि दौत्यानि द्रष्टुं शक्नोति ।",
   "compose_form.lock_disclaimer.lock": "अवरुद्धः",
   "compose_form.placeholder": "मनसि ते किमस्ति?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json
index 4990d6813..f56f2d5bd 100644
--- a/app/javascript/mastodon/locales/sc.json
+++ b/app/javascript/mastodon/locales/sc.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Publicatziones e rispostas",
   "account.report": "Signala @{name}",
   "account.requested": "Abetende s'aprovatzione. Incarca pro annullare sa rechesta de sighidura",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Cumpartzi su profilu de @{name}",
   "account.show_reblogs": "Ammustra is cumpartziduras de @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} publicatzione} other {{counter} publicatziones}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Àteras informatziones",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "Custa publicatzione no at a èssere ammustrada in peruna eticheta, dae chi no est listada. Isceti is publicatziones pùblicas podent èssere chircadas cun etichetas.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Su contu tuo no est {locked}. Cale si siat persone ti podet sighire pro bìdere is messàgios tuos chi imbies a sa gente chi ti sighit.",
   "compose_form.lock_disclaimer.lock": "blocadu",
   "compose_form.placeholder": "A ite ses pensende?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Còpia stacktrace in punta de billete",
   "errors.unexpected_crash.report_issue": "Sinnala unu problema",
   "explore.search_results": "Resurtados de sa chirca",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Aberi s'interfache de moderatzione pro @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Aberi custa publicatzione in s'interfache de moderatzione",
   "status.block": "Bloca a @{name}",
   "status.bookmark": "Sinnalibru",
@@ -553,7 +559,7 @@
   "status.favourite": "Preferidos",
   "status.filter": "Filter this post",
   "status.filtered": "Filtradu",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Càrriga·nde àteros",
diff --git a/app/javascript/mastodon/locales/sco.json b/app/javascript/mastodon/locales/sco.json
index deb2aca76..5e13c89a5 100644
--- a/app/javascript/mastodon/locales/sco.json
+++ b/app/javascript/mastodon/locales/sco.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Posts an repones",
   "account.report": "Clype @{name}",
   "account.requested": "Haudin fir approval. Chap tae cancel follae request",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Shaw heezes frae @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Post} other {{counter} Posts}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Seirch leids...",
   "compose_form.direct_message_warning_learn_more": "Lairn mair",
   "compose_form.encryption_warning": "Posts on Mastodon isnae en-tae-en encryptit. Dinnae share onie sensitive information ower Mastodon.",
-  "compose_form.hashtag_warning": "This post wulnae be listit unner onie hashtag seein it is no listit. Ainly public posts kin be seirchit oot bi hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Yer accoont isnae {locked}. Awbody kin follae ye for tae luik at yer follaer-ainly posts.",
   "compose_form.lock_disclaimer.lock": "lockit",
   "compose_form.placeholder": "Whit's on yer mind?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace tae yer clipboord",
   "errors.unexpected_crash.report_issue": "Sen in a issue",
   "explore.search_results": "Seirch finnins",
+  "explore.suggested_follows": "For you",
   "explore.title": "Splore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter caitegory disnae apply tae the context thit ye'v uised tae access this post. Gin ye'r wantin the post tae be filtert in this context tae, ye'll hae tae edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context disnae match!",
   "filter_modal.added.expired_explanation": "This filter caitegory haes expirit, ye'll hae tae chynge the expiration date fir it tae apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in fir tae follae profiles o hashtags, favourite, shaire an reply tae posts, or interack fae yer accoont on a different server.",
   "status.admin_account": "Open moderation interface fir @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this post in the moderation interface",
   "status.block": "Dingie @{name}",
   "status.bookmark": "Buikmairk",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtert",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} creatit {date}",
   "status.history.edited": "{name} editit {date}",
   "status.load_more": "Load mair",
diff --git a/app/javascript/mastodon/locales/si.json b/app/javascript/mastodon/locales/si.json
index a7d66a25f..631fe3f31 100644
--- a/app/javascript/mastodon/locales/si.json
+++ b/app/javascript/mastodon/locales/si.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "ටූට්ස් සහ පිළිතුරු",
   "account.report": "@{name} වාර්තා කරන්න",
   "account.requested": "අනුමැතිය බලාපොරොත්තුවෙන්",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "@{name} ගේ පැතිකඩ බෙදාගන්න",
   "account.show_reblogs": "@{name}සිට බූස්ට් පෙන්වන්න",
   "account.statuses_counter": "{count, plural, one {{counter} ටූට්} other {{counter} ටූට්ස්}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "භාෂා සොයන්න...",
   "compose_form.direct_message_warning_learn_more": "තව දැනගන්න",
   "compose_form.encryption_warning": "Mastodon හි පළ කිරීම් අන්තයේ සිට අවසානය දක්වා සංකේතනය කර නොමැත. Mastodon හරහා කිසිදු සංවේදී තොරතුරක් බෙදා නොගන්න.",
-  "compose_form.hashtag_warning": "මෙම මෙවලම ලැයිස්තුගත කර නොමැති බැවින් කිසිදු හැෂ් ටැගය යටතේ ලැයිස්තුගත නොකෙරේ. හැෂ් ටැග් මගින් සෙවිය හැක්කේ පොදු මෙවලම් පමණි.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "ඔබගේ ගිණුම {locked}නොවේ. ඔබගේ අනුගාමිකයින්ට පමණක් පළ කිරීම් බැලීමට ඕනෑම කෙනෙකුට ඔබව අනුගමනය කළ හැක.",
   "compose_form.lock_disclaimer.lock": "අගුළු දමා ඇත",
   "compose_form.placeholder": "ඔබගේ සිතුවිලි මොනවාද?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "ස්ටැක්ට්රේස් පසුරු පුවරුවට පිටපත් කරන්න",
   "errors.unexpected_crash.report_issue": "ගැටළුව වාර්තාව",
   "explore.search_results": "සෙවුම් ප්‍රතිඵල",
+  "explore.suggested_follows": "For you",
   "explore.title": "ගවේශණය",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "@{name}සඳහා මධ්‍යස්ථ අතුරුමුහුණත විවෘත කරන්න",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "මධ්‍යස්ථ අතුරුමුහුණතෙහි මෙම තත්ත්වය විවෘත කරන්න",
   "status.block": "@{name} අවහිර",
   "status.bookmark": "පොත්යොමුවක්",
@@ -553,7 +559,7 @@
   "status.favourite": "ප්‍රියතම",
   "status.filter": "Filter this post",
   "status.filtered": "පෙරන ලද",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} නිර්මාණය {date}",
   "status.history.edited": "{name} සංස්කරණය {date}",
   "status.load_more": "තව පූරණය",
diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json
index 2dc44367d..efbccdc38 100644
--- a/app/javascript/mastodon/locales/sk.json
+++ b/app/javascript/mastodon/locales/sk.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Príspevky a odpovede",
   "account.report": "Nahlás @{name}",
   "account.requested": "Čaká na schválenie. Klikni pre zrušenie žiadosti",
+  "account.requested_follow": "{name} ťa žiada nasledovať",
   "account.share": "Zdieľaj @{name} profil",
   "account.show_reblogs": "Ukáž vyzdvihnutia od @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Hľadaj medzi jazykmi...",
   "compose_form.direct_message_warning_learn_more": "Zisti viac",
   "compose_form.encryption_warning": "Príspevky na Mastodon nie sú end-to-end šifrované. Nezdieľajte cez Mastodon žiadne citlivé informácie.",
-  "compose_form.hashtag_warning": "Tento toot nebude zobrazený pod žiadným haštagom lebo nieje listovaný. Iba verejné tooty môžu byť nájdené podľa haštagu.",
+  "compose_form.hashtag_warning": "Tento príspevok nebude zobrazený pod žiadným haštagom, lebo nieje verejne listovaný. Iba verejné príspevky môžu byť nájdené podľa haštagu.",
   "compose_form.lock_disclaimer": "Tvoj účet nie je {locked}. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
   "compose_form.lock_disclaimer.lock": "zamknutý",
   "compose_form.placeholder": "Čo máš na mysli?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Skopíruj stacktrace do schránky",
   "errors.unexpected_crash.report_issue": "Nahlás problém",
   "explore.search_results": "Výsledky hľadania",
+  "explore.suggested_follows": "Pre teba",
   "explore.title": "Objavuj",
+  "explore.trending_links": "Novinky",
+  "explore.trending_statuses": "Príspevky",
+  "explore.trending_tags": "Haštagy",
   "filter_modal.added.context_mismatch_explanation": "Táto kategória filtrov sa nevzťahuje na kontext, v ktorom ste získali prístup k tomuto príspevku. Ak chcete, aby sa príspevok filtroval aj v tomto kontexte, budete musieť filter upraviť.",
   "filter_modal.added.context_mismatch_title": "Nesúlad kontextu!",
   "filter_modal.added.expired_explanation": "Platnosť tejto kategórie filtra vypršala, aby sa použila, je potrebné zmeniť dátum vypršania platnosti.",
@@ -509,10 +514,10 @@
   "report_notification.attached_statuses": "{count, plural, one {{count} post} other {{count} posts}} attached",
   "report_notification.categories.other": "Ostatné",
   "report_notification.categories.spam": "Spam",
-  "report_notification.categories.violation": "Rule violation",
-  "report_notification.open": "Open report",
+  "report_notification.categories.violation": "Porušenie pravidla",
+  "report_notification.open": "Otvor hlásenie",
   "search.placeholder": "Hľadaj",
-  "search.search_or_paste": "Search or paste URL",
+  "search.search_or_paste": "Hľadaj, alebo vlož URL adresu",
   "search_popout.search_format": "Pokročilé vyhľadávanie",
   "search_popout.tips.full_text": "Vráti jednoduchý textový výpis príspevkov ktoré si napísal/a, ktoré si obľúbil/a, povýšil/a, alebo aj tých, v ktorých si bol/a spomenutý/á, a potom všetky zadaniu odpovedajúce prezývky, mená a haštagy.",
   "search_popout.tips.hashtag": "haštag",
@@ -525,10 +530,10 @@
   "search_results.nothing_found": "Could not find anything for these search terms",
   "search_results.statuses": "Príspevky",
   "search_results.statuses_fts_disabled": "Vyhľadávanie v obsahu príspevkov nieje na tomto Mastodon serveri povolené.",
-  "search_results.title": "Search for {q}",
+  "search_results.title": "Hľadaj {q}",
   "search_results.total": "{count, number} {count, plural, one {výsledok} many {výsledkov} other {výsledky}}",
   "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)",
-  "server_banner.active_users": "active users",
+  "server_banner.active_users": "aktívni užívatelia",
   "server_banner.administered_by": "Správcom je:",
   "server_banner.introduction": "{domain} is part of the decentralized social network powered by {mastodon}.",
   "server_banner.learn_more": "Zisti viac",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Prihlás sa",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Otvor moderovacie rozhranie užívateľa @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Otvor tento príspevok v moderovacom rozhraní",
   "status.block": "Blokuj @{name}",
   "status.bookmark": "Záložka",
@@ -551,7 +557,7 @@
   "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}",
   "status.embed": "Vložiť",
   "status.favourite": "Páči sa mi",
-  "status.filter": "Filter this post",
+  "status.filter": "Filtrovanie tohto príspevku",
   "status.filtered": "Filtrované",
   "status.hide": "Skry príspevok",
   "status.history.created": "{name} vytvoril/a {date}",
@@ -635,7 +641,7 @@
   "upload_modal.preparing_ocr": "Pripravujem OCR…",
   "upload_modal.preview_label": "Náhľad ({ratio})",
   "upload_progress.label": "Nahráva sa...",
-  "upload_progress.processing": "Processing…",
+  "upload_progress.processing": "Spracovávanie…",
   "video.close": "Zavri video",
   "video.download": "Stiahni súbor",
   "video.exit_fullscreen": "Vypni zobrazenie na celú obrazovku",
diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json
index b49db119b..0c9125acd 100644
--- a/app/javascript/mastodon/locales/sl.json
+++ b/app/javascript/mastodon/locales/sl.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Objave in odgovori",
   "account.report": "Prijavi @{name}",
   "account.requested": "Čakanje na odobritev. Kliknite, da prekličete prošnjo za sledenje",
+  "account.requested_follow": "{name} vam želi slediti",
   "account.share": "Deli profil osebe @{name}",
   "account.show_reblogs": "Pokaži izpostavitve osebe @{name}",
   "account.statuses_counter": "{count, plural, one {{count} tut} two {{count} tuta} few {{count} tuti} other {{count} tutov}}",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopiraj sledenje skladu na odložišče",
   "errors.unexpected_crash.report_issue": "Prijavi težavo",
   "explore.search_results": "Rezultati iskanja",
+  "explore.suggested_follows": "Za vas",
   "explore.title": "Razišči",
+  "explore.trending_links": "Novice",
+  "explore.trending_statuses": "Objave",
+  "explore.trending_tags": "Ključniki",
   "filter_modal.added.context_mismatch_explanation": "Ta kategorija filtra ne velja za kontekst, v katerem ste dostopali do te objave. Če želite, da je objava filtrirana tudi v tem kontekstu, morate urediti filter.",
   "filter_modal.added.context_mismatch_title": "Neujemanje konteksta!",
   "filter_modal.added.expired_explanation": "Ta kategorija filtra je pretekla, morali boste spremeniti datum veljavnosti, da bo veljal še naprej.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Prijava",
   "sign_in_banner.text": "Prijavite se, da sledite profilom ali ključnikom, dodajate med priljubljene, delite z drugimi ter odgovarjate na objave, pa tudi ostajate v interakciji iz svojega računa na drugem strežniku.",
   "status.admin_account": "Odpri vmesnik za moderiranje za @{name}",
+  "status.admin_domain": "Odpri vmesnik za moderiranje za {domain}",
   "status.admin_status": "Odpri to objavo v vmesniku za moderiranje",
   "status.block": "Blokiraj @{name}",
   "status.bookmark": "Dodaj med zaznamke",
@@ -553,7 +559,7 @@
   "status.favourite": "Priljubljen",
   "status.filter": "Filtriraj to objavo",
   "status.filtered": "Filtrirano",
-  "status.hide": "Skrij tut",
+  "status.hide": "Skrij objavo",
   "status.history.created": "{name}: ustvarjeno {date}",
   "status.history.edited": "{name}: urejeno {date}",
   "status.load_more": "Naloži več",
diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json
index a09da3af6..10176e3bc 100644
--- a/app/javascript/mastodon/locales/sq.json
+++ b/app/javascript/mastodon/locales/sq.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Mesazhe dhe përgjigje",
   "account.report": "Raportojeni @{name}",
   "account.requested": "Në pritje të miratimit. Që të anuloni kërkesën për ndjekje, klikojeni",
+  "account.requested_follow": "{name} ka kërkuar t’ju ndjekë",
   "account.share": "Ndajeni profilin e @{name} me të tjerët",
   "account.show_reblogs": "Shfaq përforcime nga @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Mesazh} other {{counter} Mesazhe}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Kërkoni te gjuhët…",
   "compose_form.direct_message_warning_learn_more": "Mësoni më tepër",
   "compose_form.encryption_warning": "Postimet në Mastodon nuk fshehtëzohen skaj-më-skaj. Mos ndani me të tjerë gjëra me spec në Mastodon.",
-  "compose_form.hashtag_warning": "Ky mesazh s’do të paraqitet nën ndonjë hashtag, ngaqë s’i është caktuar ndonjë. Vetëm mesazhet publike mund të kërkohen sipas hashtagësh.",
+  "compose_form.hashtag_warning": "Ky postim s’do të paraqitet nën ndonjë hashtag, ngaqë s’është publik. Vetëm postimet publike mund të kërkohen sipas hashtag-ësh.",
   "compose_form.lock_disclaimer": "Llogaria juaj s’është {locked}. Mund ta ndjekë cilido, për të parë postimet tuaja vetëm për ndjekësit.",
   "compose_form.lock_disclaimer.lock": "e kyçur",
   "compose_form.placeholder": "Ç’bluani në mendje?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopjo stacktrace-in në të papastër",
   "errors.unexpected_crash.report_issue": "Raportoni problemin",
   "explore.search_results": "Përfundime kërkimi",
+  "explore.suggested_follows": "Për ju",
   "explore.title": "Eksploroni",
+  "explore.trending_links": "Lajme",
+  "explore.trending_statuses": "Postime",
+  "explore.trending_tags": "Hashtagë",
   "filter_modal.added.context_mismatch_explanation": "Kjo kategori filtrash nuk aplikohet për kontekstin nën të cilin po merreni me këtë postim. Nëse doni që postimi të filtrohet edhe në këtë kontekst, do t’ju duhet të përpunoni filtrin.",
   "filter_modal.added.context_mismatch_title": "Mospërputhje kontekstesh!",
   "filter_modal.added.expired_explanation": "Kjo kategori filtrash ka skaduar, do t’ju duhet të ndryshoni datën e skadimit për të, pa të aplikohet.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Hyni",
   "sign_in_banner.text": "Që të ndiqni profile ose hashtag-ë, të pëlqeni, të ndani me të tjerë dhe të përgjigjeni në postime, apo të ndërveproni me llogarinë tuaj nga një shërbyes tjetër, bëni hyrjen.",
   "status.admin_account": "Hap ndërfaqe moderimi për @{name}",
+  "status.admin_domain": "Hap ndërfaqe moderimi për {domain}",
   "status.admin_status": "Hape këtë mesazh te ndërfaqja e moderimit",
   "status.block": "Blloko @{name}",
   "status.bookmark": "Faqeruaje",
@@ -553,7 +559,7 @@
   "status.favourite": "I parapëlqyer",
   "status.filter": "Filtroje këtë postim",
   "status.filtered": "I filtruar",
-  "status.hide": "Fshihe mesazhin",
+  "status.hide": "Fshihe postimin",
   "status.history.created": "{name} u krijua më {date}",
   "status.history.edited": "{name} u përpunua më {date}",
   "status.load_more": "Ngarko më tepër",
diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json
index bb9b4ee0f..0feb79691 100644
--- a/app/javascript/mastodon/locales/sr-Latn.json
+++ b/app/javascript/mastodon/locales/sr-Latn.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Objave i odgovori",
   "account.report": "Prijavi @{name}",
   "account.requested": "Čekanje odobrenja. Kliknite za otkazivanje zahteva za praćenje",
+  "account.requested_follow": "{name} je zatražio da vas prati",
   "account.share": "Podeli profil korisnika @{name}",
   "account.show_reblogs": "Prikaži podržavanja od korisnika @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} objavio} few {{counter} objavio} other {{counter} objavio}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Pretraga jezika...",
   "compose_form.direct_message_warning_learn_more": "Saznajte više",
   "compose_form.encryption_warning": "Objave na Mastodon-u nisu potpuno šifrovane. Nemojte deliti nikakve osetljive informacije preko Mastodon-a.",
-  "compose_form.hashtag_warning": "Ova objava neće biti navedena ni pod jednom heš oznakom jer je nenavedena. Samo javne objave mogu se pretraživati po heš oznakama.",
+  "compose_form.hashtag_warning": "Ova objava neće biti navedena ni pod jednom heš oznakom jer nije javna. Samo javne objave se mogu pretraživati po heš oznakama.",
   "compose_form.lock_disclaimer": "Vaš nalog nije {locked}. Svako može da vas prati i da vidi vaše objave namenjene samo za vaše pratioce.",
   "compose_form.lock_disclaimer.lock": "zaključan",
   "compose_form.placeholder": "O čemu razmišljate?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopiraj „stacktrace” u klipbord",
   "errors.unexpected_crash.report_issue": "Prijavi problem",
   "explore.search_results": "Rezultati pretrage",
+  "explore.suggested_follows": "Za tebe",
   "explore.title": "Istraži",
+  "explore.trending_links": "Vesti",
+  "explore.trending_statuses": "Objave",
+  "explore.trending_tags": "Heš oznake",
   "filter_modal.added.context_mismatch_explanation": "Ova kategorija filtera se ne odnosi na kontekst u kojem ste pristupili ovoj objavi. Ako želite da se objava filtrira i u ovom kontekstu, morate urediti filter.",
   "filter_modal.added.context_mismatch_title": "Kontekst se ne podudara!",
   "filter_modal.added.expired_explanation": "Ova kategorija filtera je istekla, morate promeniti datum isteka da bi se primenjivala.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Prijavi se",
   "sign_in_banner.text": "Prijavite se da pratite profile ili heštegove, stavite objave kao omiljene, delite i odgovarate na njih ili komunicirate sa svog naloga sa drugog servera.",
   "status.admin_account": "Otvori moderatorsko okruženje za @{name}",
+  "status.admin_domain": "Otvori moderatorsko okruženje za {domain}",
   "status.admin_status": "Otvori ovu objavu u moderatorskom okruženju",
   "status.block": "Blokiraj @{name}",
   "status.bookmark": "Dodaj u obeleživače",
diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json
index 5660c94ac..ca0f04b34 100644
--- a/app/javascript/mastodon/locales/sr.json
+++ b/app/javascript/mastodon/locales/sr.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Објаве и одговори",
   "account.report": "Пријави @{name}",
   "account.requested": "Чекање одобрења. Кликните за отказивање захтева за праћење",
+  "account.requested_follow": "{name} је затражио да вас прати",
   "account.share": "Подели профил корисника @{name}",
   "account.show_reblogs": "Прикажи подржавања од корисника @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} објавио} few {{counter} објавио} other {{counter} објавио}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Претрага језика...",
   "compose_form.direct_message_warning_learn_more": "Сазнајте више",
   "compose_form.encryption_warning": "Објаве на Mastodon-у нису потпуно шифроване. Немојте делити никакве осетљиве информације преко Mastodon-а.",
-  "compose_form.hashtag_warning": "Ова објава неће бити наведена ни под једном хеш ознаком јер је ненаведена. Само јавне објаве могу се претраживати по хеш ознакама.",
+  "compose_form.hashtag_warning": "Ова објава неће бити наведена ни под једном хеш ознаком јер није јавна. Само јавне објаве се могу претраживати по хеш ознакама.",
   "compose_form.lock_disclaimer": "Ваш налог није {locked}. Свако може да вас прати и да види ваше објаве намењене само за ваше пратиоце.",
   "compose_form.lock_disclaimer.lock": "закључан",
   "compose_form.placeholder": "О чему размишљате?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Копирај „stacktrace” у клипборд",
   "errors.unexpected_crash.report_issue": "Пријави проблем",
   "explore.search_results": "Резултати претраге",
+  "explore.suggested_follows": "За тебе",
   "explore.title": "Истражи",
+  "explore.trending_links": "Вести",
+  "explore.trending_statuses": "Објаве",
+  "explore.trending_tags": "Хеш ознаке",
   "filter_modal.added.context_mismatch_explanation": "Ова категорија филтера се не односи на контекст у којем сте приступили овој објави. Ако желите да се објава филтрира и у овом контексту, морате уредити филтер.",
   "filter_modal.added.context_mismatch_title": "Контекст се не подудара!",
   "filter_modal.added.expired_explanation": "Ова категорија филтера је истекла, морате променити датум истека да би се примењивала.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Пријави се",
   "sign_in_banner.text": "Пријавите се да пратите профиле или хештегове, ставите објаве као омиљене, делите и одговарате на њих или комуницирате са свог налога са другог сервера.",
   "status.admin_account": "Отвори модераторско окружење за @{name}",
+  "status.admin_domain": "Отвори модераторско окружење за {domain}",
   "status.admin_status": "Отвори ову објаву у модераторском окружењу",
   "status.block": "Блокирај @{name}",
   "status.bookmark": "Додај у обележиваче",
diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json
index 5e4da3e55..878911c87 100644
--- a/app/javascript/mastodon/locales/sv.json
+++ b/app/javascript/mastodon/locales/sv.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Inlägg och svar",
   "account.report": "Rapportera @{name}",
   "account.requested": "Inväntar godkännande. Klicka för att ta tillbaka din begäran om att få följa",
+  "account.requested_follow": "{name} har begärt att följa dig",
   "account.share": "Dela @{name}s profil",
   "account.show_reblogs": "Visa boostar från @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Inlägg} other {{counter} Inlägg}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Sök språk...",
   "compose_form.direct_message_warning_learn_more": "Läs mer",
   "compose_form.encryption_warning": "Inlägg på Mastodon är inte obrutet krypterade. Dela inte känslig information på Mastodon.",
-  "compose_form.hashtag_warning": "Detta inlägg kommer inte listas under någon hashtagg eftersom det är olistat. Endast offentliga inlägg kan eftersökas med hashtagg.",
+  "compose_form.hashtag_warning": "Inlägget listas inte under någon hashtag eftersom det inte är offentligt. Endast offentliga inlägg går att söka med en hashtag.",
   "compose_form.lock_disclaimer": "Ditt konto är inte {locked}. Vem som helst kan följa dig för att se dina inlägg som endast är för följare.",
   "compose_form.lock_disclaimer.lock": "låst",
   "compose_form.placeholder": "Vad tänker du på?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Kopiera stacktrace till urklipp",
   "errors.unexpected_crash.report_issue": "Rapportera problem",
   "explore.search_results": "Sökresultat",
+  "explore.suggested_follows": "För dig",
   "explore.title": "Utforska",
+  "explore.trending_links": "Nyheter",
+  "explore.trending_statuses": "Inlägg",
+  "explore.trending_tags": "Hashtaggar",
   "filter_modal.added.context_mismatch_explanation": "Denna filterkategori gäller inte för det sammanhang där du har tillgång till det här inlägget. Om du vill att inlägget ska filtreras även i detta sammanhang måste du redigera filtret.",
   "filter_modal.added.context_mismatch_title": "Misspassning av sammanhang!",
   "filter_modal.added.expired_explanation": "Denna filterkategori har utgått, du måste ändra utgångsdatum för att den ska kunna tillämpas.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Logga in",
   "sign_in_banner.text": "Logga in för att följa profiler eller hashtaggar, favoritmarkera, dela och svara på inlägg eller interagera från ditt konto på en annan server.",
   "status.admin_account": "Öppet modereringsgränssnitt för @{name}",
+  "status.admin_domain": "Öppet modereringsgränssnitt för @{domain}",
   "status.admin_status": "Öppna detta inlägg i modereringsgränssnittet",
   "status.block": "Blockera @{name}",
   "status.bookmark": "Bokmärk",
@@ -553,7 +559,7 @@
   "status.favourite": "Favorit",
   "status.filter": "Filtrera detta inlägg",
   "status.filtered": "Filtrerat",
-  "status.hide": "Göm inlägg",
+  "status.hide": "Dölj inlägg",
   "status.history.created": "{name} skapade {date}",
   "status.history.edited": "{name} redigerade {date}",
   "status.load_more": "Ladda fler",
diff --git a/app/javascript/mastodon/locales/szl.json b/app/javascript/mastodon/locales/szl.json
index 693991651..e646ef83c 100644
--- a/app/javascript/mastodon/locales/szl.json
+++ b/app/javascript/mastodon/locales/szl.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Learn more",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
   "compose_form.placeholder": "What is on your mind?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json
index c3eaf02f3..7013fdbb8 100644
--- a/app/javascript/mastodon/locales/ta.json
+++ b/app/javascript/mastodon/locales/ta.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Toots மற்றும் பதில்கள்",
   "account.report": "@{name} -ஐப் புகாரளி",
   "account.requested": "ஒப்புதலுக்காகக் காத்திருக்கிறது. பின்தொடரும் கோரிக்கையை நீக்க அழுத்தவும்",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "@{name} உடைய விவரத்தை பகிர்",
   "account.show_reblogs": "காட்டு boosts இருந்து @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} டூட்} other {{counter} டூட்டுகள்}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "தேடல் மொழிகள்...",
   "compose_form.direct_message_warning_learn_more": "மேலும் அறிய",
   "compose_form.encryption_warning": "Mastodonல் உள்ள பதிவுகள் முறையாக என்க்ரிப்ட்(encrypt) செய்யபடவில்லை. அதனால் முக்கிய தகவல்களை இங்கே பகிர வேண்டாம்.",
-  "compose_form.hashtag_warning": "இது ஒரு பட்டியலிடப்படாத டூட் என்பதால் எந்த ஹேஷ்டேகின் கீழும் வராது. ஹேஷ்டேகின் மூலம் பொதுவில் உள்ள டூட்டுகளை மட்டுமே தேட முடியும்.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "உங்கள் கணக்கு {locked} செய்யப்படவில்லை. உங்கள் பதிவுகளை யார் வேண்டுமானாலும் பின்தொடர்ந்து காணலாம்.",
   "compose_form.lock_disclaimer.lock": "பூட்டப்பட்டது",
   "compose_form.placeholder": "உங்கள் மனதில் என்ன இருக்கிறது?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Stacktrace-ஐ clipboard-ல் நகலெடு",
   "errors.unexpected_crash.report_issue": "புகாரளி",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "மிதமான இடைமுகத்தை திறக்க @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "மிதமான இடைமுகத்தில் இந்த நிலையை திறக்கவும்",
   "status.block": "@{name} -ஐத் தடு",
   "status.bookmark": "அடையாளம் குறி",
@@ -553,7 +559,7 @@
   "status.favourite": "விருப்பத்துக்குகந்த",
   "status.filter": "Filter this post",
   "status.filtered": "வடிகட்டு",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "அதிகமாய் ஏற்று",
diff --git a/app/javascript/mastodon/locales/tai.json b/app/javascript/mastodon/locales/tai.json
index bf5ad7a4e..d39ca62eb 100644
--- a/app/javascript/mastodon/locales/tai.json
+++ b/app/javascript/mastodon/locales/tai.json
@@ -1,7 +1,7 @@
 {
-  "about.blocks": "Moderated servers",
-  "about.contact": "Contact:",
-  "about.disclaimer": "Mastodon is free, open-source software, and a trademark of Mastodon gGmbH.",
+  "about.blocks": "Siū kuán-tsè ê su-hāu-khì",
+  "about.contact": "Liân-lo̍k:",
+  "about.disclaimer": "Ling-khí-tshiūnn sī tsi̍t-ê khai-guân nńg-thé,i ê siong-phiau sī Mastodon gGmbH.",
   "about.domain_blocks.no_reason_available": "Reason not available",
   "about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.",
   "about.domain_blocks.silenced.explanation": "You will generally not see profiles and content from this server, unless you explicitly look it up or opt into it by following.",
@@ -44,7 +44,7 @@
   "account.link_verified_on": "Ownership of this link was checked on {date}",
   "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
   "account.media": "Mûi-thé",
-  "account.mention": "Mention @{name}",
+  "account.mention": "Thê-khí @{name}",
   "account.moved_to": "{name} has indicated that their new account is now:",
   "account.mute": "Mute @{name}",
   "account.mute_notifications": "Mute notifications from @{name}",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Learn more",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
   "compose_form.placeholder": "What is on your mind?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json
index 0000ffc91..2e199fd39 100644
--- a/app/javascript/mastodon/locales/te.json
+++ b/app/javascript/mastodon/locales/te.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "టూట్లు మరియు ప్రత్యుత్తరములు",
   "account.report": "@{name}పై ఫిర్యాదుచేయు",
   "account.requested": "ఆమోదం కోసం వేచి ఉంది. అభ్యర్థనను రద్దు చేయడానికి క్లిక్ చేయండి",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "@{name} యొక్క ప్రొఫైల్ను పంచుకోండి",
   "account.show_reblogs": "@{name}నుంచి బూస్ట్ లను చూపించు",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "మరింత తెలుసుకోండి",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "ఈ టూట్ అన్లిస్టెడ్ కాబట్టి ఏ హాష్ ట్యాగ్ క్రిందకూ రాదు. పబ్లిక్ టూట్ లను మాత్రమే హాష్ ట్యాగ్ ద్వారా శోధించవచ్చు.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "మీ ఖాతా {locked} చేయబడలేదు. ఎవరైనా మిమ్మల్ని అనుసరించి మీ అనుచరులకు-మాత్రమే పోస్ట్లను వీక్షించవచ్చు.",
   "compose_form.lock_disclaimer.lock": "బిగించబడినది",
   "compose_form.placeholder": "మీ మనస్సులో ఏముంది?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "@{name} కొరకు సమన్వయ వినిమయసీమను తెరువు",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "సమన్వయ వినిమయసీమలో ఈ స్టేటస్ ను తెరవండి",
   "status.block": "@{name} ను బ్లాక్ చేయి",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "ఇష్టపడు",
   "status.filter": "Filter this post",
   "status.filtered": "వడకట్టబడిన",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "మరిన్ని లోడ్ చేయి",
diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json
index 6c3788d51..a0247891f 100644
--- a/app/javascript/mastodon/locales/th.json
+++ b/app/javascript/mastodon/locales/th.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "โพสต์และการตอบกลับ",
   "account.report": "รายงาน @{name}",
   "account.requested": "กำลังรอการอนุมัติ คลิกเพื่อยกเลิกคำขอติดตาม",
+  "account.requested_follow": "{name} ได้ขอติดตามคุณ",
   "account.share": "แบ่งปันโปรไฟล์ของ @{name}",
   "account.show_reblogs": "แสดงการดันจาก @{name}",
   "account.statuses_counter": "{count, plural, other {{counter} โพสต์}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "ค้นหาภาษา...",
   "compose_form.direct_message_warning_learn_more": "เรียนรู้เพิ่มเติม",
   "compose_form.encryption_warning": "โพสต์ใน Mastodon ไม่ได้เข้ารหัสแบบต้นทางถึงปลายทาง อย่าแบ่งปันข้อมูลที่ละเอียดอ่อนใด ๆ ผ่าน Mastodon",
-  "compose_form.hashtag_warning": "จะไม่แสดงรายการโพสต์นี้ภายใต้แฮชแท็กใด ๆ เนื่องจากโพสต์ไม่อยู่ในรายการ เฉพาะโพสต์สาธารณะเท่านั้นที่สามารถค้นหาได้โดยแฮชแท็ก",
+  "compose_form.hashtag_warning": "จะไม่แสดงรายการโพสต์นี้ภายใต้แฮชแท็กใด ๆ เนื่องจากโพสต์ไม่อยู่ในรายการไม่เป็นสาธารณะ เฉพาะโพสต์สาธารณะเท่านั้นที่สามารถค้นหาได้โดยแฮชแท็ก",
   "compose_form.lock_disclaimer": "บัญชีของคุณไม่ได้ {locked} ใครก็ตามสามารถติดตามคุณเพื่อดูโพสต์สำหรับผู้ติดตามเท่านั้นของคุณ",
   "compose_form.lock_disclaimer.lock": "ล็อคอยู่",
   "compose_form.placeholder": "คุณกำลังคิดอะไรอยู่?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "คัดลอกการติดตามสแตกไปยังคลิปบอร์ด",
   "errors.unexpected_crash.report_issue": "รายงานปัญหา",
   "explore.search_results": "ผลลัพธ์การค้นหา",
+  "explore.suggested_follows": "สำหรับคุณ",
   "explore.title": "สำรวจ",
+  "explore.trending_links": "ข่าว",
+  "explore.trending_statuses": "โพสต์",
+  "explore.trending_tags": "แฮชแท็ก",
   "filter_modal.added.context_mismatch_explanation": "หมวดหมู่ตัวกรองนี้ไม่ได้นำไปใช้กับบริบทที่คุณได้เข้าถึงโพสต์นี้ หากคุณต้องการกรองโพสต์ในบริบทนี้ด้วย คุณจะต้องแก้ไขตัวกรอง",
   "filter_modal.added.context_mismatch_title": "บริบทไม่ตรงกัน!",
   "filter_modal.added.expired_explanation": "หมวดหมู่ตัวกรองนี้หมดอายุแล้ว คุณจะต้องเปลี่ยนวันหมดอายุสำหรับหมวดหมู่เพื่อนำไปใช้",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "ลงชื่อเข้า",
   "sign_in_banner.text": "ลงชื่อเข้าเพื่อติดตามโปรไฟล์หรือแฮชแท็ก ชื่นชอบ แบ่งปัน และตอบกลับโพสต์ หรือโต้ตอบจากบัญชีของคุณในเซิร์ฟเวอร์อื่น",
   "status.admin_account": "เปิดส่วนติดต่อการควบคุมสำหรับ @{name}",
+  "status.admin_domain": "เปิดส่วนติดต่อการควบคุมสำหรับ {domain}",
   "status.admin_status": "เปิดโพสต์นี้ในส่วนติดต่อการควบคุม",
   "status.block": "ปิดกั้น @{name}",
   "status.bookmark": "เพิ่มที่คั่นหน้า",
diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json
index cfd542e47..287ba5e63 100644
--- a/app/javascript/mastodon/locales/tr.json
+++ b/app/javascript/mastodon/locales/tr.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Gönderiler ve yanıtlar",
   "account.report": "@{name} adlı kişiyi bildir",
   "account.requested": "Onay bekleniyor. Takip isteğini iptal etmek için tıklayın",
+  "account.requested_follow": "{name} size takip isteği gönderdi",
   "account.share": "@{name} adlı kişinin profilini paylaş",
   "account.show_reblogs": "@{name} kişisinin boostlarını göster",
   "account.statuses_counter": "{count, plural, one {{counter} Gönderi} other {{counter} Gönderi}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Dilleri ara...",
   "compose_form.direct_message_warning_learn_more": "Daha fazla bilgi edinin",
   "compose_form.encryption_warning": "Mastodon gönderileri uçtan uca şifrelemeli değildir. Hassas olabilecek herhangi bir bilgiyi Mastodon'da paylaşmayın.",
-  "compose_form.hashtag_warning": "Bu gönderi liste dışı olduğu için hiç bir etikette yer almayacak. Sadece herkese açık gönderiler etiketlerde bulunabilir.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Hesabın {locked} değil. Yalnızca takipçilere özel gönderilerini görüntülemek için herkes seni takip edebilir.",
   "compose_form.lock_disclaimer.lock": "kilitli",
   "compose_form.placeholder": "Aklında ne var?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Yığın izlemeyi (stacktrace) panoya kopyala",
   "errors.unexpected_crash.report_issue": "Sorun bildir",
   "explore.search_results": "Arama sonuçları",
+  "explore.suggested_follows": "Sizin için",
   "explore.title": "Keşfet",
+  "explore.trending_links": "Haberler",
+  "explore.trending_statuses": "Gönderiler",
+  "explore.trending_tags": "Etiketler",
   "filter_modal.added.context_mismatch_explanation": "Bu filtre kategorisi, bu gönderide eriştiğin bağlama uymuyor. Eğer gönderinin bu bağlamda da filtrelenmesini istiyorsanız, filtreyi düzenlemeniz gerekiyor.",
   "filter_modal.added.context_mismatch_title": "Bağlam uyumsuzluğu!",
   "filter_modal.added.expired_explanation": "Bu filtre kategorisinin süresi dolmuş, filtreyi uygulamak için bitiş tarihini değiştirmeniz gerekiyor.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Giriş yap",
   "sign_in_banner.text": "Profilleri veya etiketleri izlemek, gönderileri beğenmek, paylaşmak ve yanıtlamak için veya başka bir sunucunuzdaki hesabınızla etkileşmek için giriş yapın.",
   "status.admin_account": "@{name} için denetim arayüzünü açın",
+  "status.admin_domain": "{domain} için denetim arayüzünü açın",
   "status.admin_status": "Denetim arayüzünde bu gönderiyi açın",
   "status.block": "@{name} adlı kişiyi engelle",
   "status.bookmark": "Yer işareti ekle",
diff --git a/app/javascript/mastodon/locales/tt.json b/app/javascript/mastodon/locales/tt.json
index 536940a36..d0aaba7e9 100644
--- a/app/javascript/mastodon/locales/tt.json
+++ b/app/javascript/mastodon/locales/tt.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Learn more",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
   "compose_form.placeholder": "What is on your mind?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "@{name} блоклау",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/ug.json b/app/javascript/mastodon/locales/ug.json
index 693991651..e646ef83c 100644
--- a/app/javascript/mastodon/locales/ug.json
+++ b/app/javascript/mastodon/locales/ug.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "Share @{name}'s profile",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "Learn more",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "locked",
   "compose_form.placeholder": "What is on your mind?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json
index ed1e1ad75..8276908b1 100644
--- a/app/javascript/mastodon/locales/uk.json
+++ b/app/javascript/mastodon/locales/uk.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Дописи й відповіді",
   "account.report": "Поскаржитися на @{name}",
   "account.requested": "Очікує підтвердження. Натисніть, щоб скасувати запит на підписку",
+  "account.requested_follow": "{name} надсилає запит на стеження",
   "account.share": "Поділитися профілем @{name}",
   "account.show_reblogs": "Показати поширення від @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} допис} few {{counter} дописи} many {{counter} дописів} other {{counter} дописи}}",
@@ -101,7 +102,7 @@
   "column.blocks": "Заблоковані користувачі",
   "column.bookmarks": "Закладки",
   "column.community": "Локальна стрічка",
-  "column.direct": "Прямі повідомлення",
+  "column.direct": "Особисті повідомлення",
   "column.directory": "Переглянути профілі",
   "column.domain_blocks": "Заблоковані домени",
   "column.favourites": "Вподобане",
@@ -147,7 +148,7 @@
   "compose_form.spoiler.marked": "Прибрати попередження про вміст",
   "compose_form.spoiler.unmarked": "Додати попередження про вміст",
   "compose_form.spoiler_placeholder": "Напишіть своє попередження тут",
-  "confirmation_modal.cancel": "Відмінити",
+  "confirmation_modal.cancel": "Скасувати",
   "confirmations.block.block_and_report": "Заблокувати та поскаржитися",
   "confirmations.block.confirm": "Заблокувати",
   "confirmations.block.message": "Ви впевнені, що хочете заблокувати {name}?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Скопіювати трасування стека у буфер обміну",
   "errors.unexpected_crash.report_issue": "Повідомити про проблему",
   "explore.search_results": "Результати пошуку",
+  "explore.suggested_follows": "Для вас",
   "explore.title": "Огляд",
+  "explore.trending_links": "Новини",
+  "explore.trending_statuses": "Дописи",
+  "explore.trending_tags": "Хештеґи",
   "filter_modal.added.context_mismatch_explanation": "Ця категорія фільтра не застосовується до контексту, в якому ви отримали доступ до цього допису. Якщо ви хочете, щоб дописи також фільтрувалися за цим контекстом, вам доведеться редагувати фільтр.",
   "filter_modal.added.context_mismatch_title": "Невідповідність контексту!",
   "filter_modal.added.expired_explanation": "Категорія цього фільтра застаріла, Вам потрібно змінити дату закінчення терміну дії, щоб застосувати її.",
@@ -366,7 +371,7 @@
   "navigation_bar.bookmarks": "Закладки",
   "navigation_bar.community_timeline": "Локальна стрічка",
   "navigation_bar.compose": "Написати новий допис",
-  "navigation_bar.direct": "Прямі повідомлення",
+  "navigation_bar.direct": "Особисті повідомлення",
   "navigation_bar.discover": "Дослідити",
   "navigation_bar.domain_blocks": "Заблоковані домени",
   "navigation_bar.edit_profile": "Редагувати профіль",
@@ -468,7 +473,7 @@
   "relative_time.minutes": "{number}х",
   "relative_time.seconds": "{number}с",
   "relative_time.today": "сьогодні",
-  "reply_indicator.cancel": "Відмінити",
+  "reply_indicator.cancel": "Скасувати",
   "report.block": "Заблокувати",
   "report.block_explanation": "Ви не будете бачити дописи цього користувача, а вони не зможуть бачити ваші дописи або підписуватися на вас. Вони будуть бачити, що ви їх заблокували.",
   "report.categories.other": "Інше",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Увійти",
   "sign_in_banner.text": "Увійдіть, щоб слідкувати за профілями або хештеґами, вподобаними, ділитися і відповідати на повідомлення або взаємодіяти з вашого облікового запису на іншому сервері.",
   "status.admin_account": "Відкрити інтерфейс модерації для @{name}",
+  "status.admin_domain": "Відкрити інтерфейс модерації для {domain}",
   "status.admin_status": "Відкрити цей допис в інтерфейсі модерації",
   "status.block": "Заблокувати @{name}",
   "status.bookmark": "Додати до закладок",
@@ -553,7 +559,7 @@
   "status.favourite": "Подобається",
   "status.filter": "Фільтрувати цей допис",
   "status.filtered": "Відфільтровано",
-  "status.hide": "Сховати дмух",
+  "status.hide": "Сховати допис",
   "status.history.created": "{name} створює {date}",
   "status.history.edited": "{name} змінює {date}",
   "status.load_more": "Завантажити більше",
diff --git a/app/javascript/mastodon/locales/ur.json b/app/javascript/mastodon/locales/ur.json
index d9881abeb..e411e6015 100644
--- a/app/javascript/mastodon/locales/ur.json
+++ b/app/javascript/mastodon/locales/ur.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "ٹوٹ اور جوابات",
   "account.report": "@{name} اطلاع کریں",
   "account.requested": "منظوری کا منتظر۔ درخواستِ پیروی منسوخ کرنے کیلئے کلک کریں",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "@{name} کے مشخص کو بانٹیں",
   "account.show_reblogs": "@{name} کی افزائشات کو دکھائیں",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "زبان تلاش کریں...",
   "compose_form.direct_message_warning_learn_more": "مزید جانیں",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "چونکہ یہ ٹوٹ غیر مندرجہ ہے لہذا یہ کسی بھی ہیش ٹیگ کے تحت درج نہیں کیا جائے گا. ہیش ٹیگ کے تحت صرف \nعمومی ٹوٹ تلاش کئے جا سکتے ہیں.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "آپ کا اکاؤنٹ {locked} نہیں ہے. کوئی بھی آپ کے مخصوص برائے پیروکار ٹوٹ دیکھنے کی خاطر آپ کی پیروی کر سکتا ہے.",
   "compose_form.lock_disclaimer.lock": "مقفل",
   "compose_form.placeholder": "آپ کیا سوچ رہے ہیں؟",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "مسئلہ کی اطلاع کریں",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "Block @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "Load more",
diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json
index 1b9b34454..7bc505474 100644
--- a/app/javascript/mastodon/locales/vi.json
+++ b/app/javascript/mastodon/locales/vi.json
@@ -10,7 +10,7 @@
   "about.domain_blocks.suspended.title": "Vô hiệu hóa",
   "about.not_available": "Máy chủ này chưa cung cấp thông tin.",
   "about.powered_by": "Mạng xã hội liên hợp {mastodon}",
-  "about.rules": "Quy tắc máy chủ",
+  "about.rules": "Nội quy máy chủ",
   "account.account_note_header": "Ghi chú",
   "account.add_or_remove_from_list": "Thêm hoặc xóa khỏi danh sách",
   "account.badges.bot": "Bot",
@@ -21,7 +21,7 @@
   "account.browse_more_on_origin_server": "Truy cập trang của người này",
   "account.cancel_follow_request": "Thu hồi yêu cầu theo dõi",
   "account.direct": "Nhắn riêng @{name}",
-  "account.disable_notifications": "Tắt thông báo khi @{name} đăng bài viết",
+  "account.disable_notifications": "Tắt thông báo khi @{name} đăng tút",
   "account.domain_blocked": "Tên miền đã chặn",
   "account.edit_profile": "Sửa hồ sơ",
   "account.enable_notifications": "Nhận thông báo khi @{name} đăng tút",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Trả lời",
   "account.report": "Báo cáo @{name}",
   "account.requested": "Đang chờ chấp thuận. Nhấp vào đây để hủy yêu cầu theo dõi",
+  "account.requested_follow": "{name} yêu cầu theo dõi bạn",
   "account.share": "Chia sẻ trang @{name}",
   "account.show_reblogs": "Hiện tút do @{name} đăng lại",
   "account.statuses_counter": "{count, plural, one {{counter} Tút} other {{counter} Tút}}",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Sao chép stacktrace vào clipboard",
   "errors.unexpected_crash.report_issue": "Báo cáo lỗi",
   "explore.search_results": "Kết quả tìm kiếm",
+  "explore.suggested_follows": "Đề xuất",
   "explore.title": "Khám phá",
+  "explore.trending_links": "Tin tức",
+  "explore.trending_statuses": "Tút",
+  "explore.trending_tags": "Hashtag",
   "filter_modal.added.context_mismatch_explanation": "Danh mục bộ lọc này không áp dụng cho ngữ cảnh mà bạn đã truy cập tút này. Nếu bạn muốn tút cũng được lọc trong ngữ cảnh này, bạn sẽ phải chỉnh sửa bộ lọc.",
   "filter_modal.added.context_mismatch_title": "Bối cảnh không phù hợp!",
   "filter_modal.added.expired_explanation": "Danh mục bộ lọc này đã hết hạn, bạn sẽ cần thay đổi ngày hết hạn để áp dụng.",
@@ -394,7 +399,7 @@
   "notification.own_poll": "Cuộc bình chọn của bạn đã kết thúc",
   "notification.poll": "Cuộc bình chọn đã kết thúc",
   "notification.reblog": "{name} đăng lại tút của bạn",
-  "notification.status": "{name} vừa đăng",
+  "notification.status": "{name} đăng tút mới",
   "notification.update": "{name} đã viết lại một tút",
   "notifications.clear": "Xóa hết thông báo",
   "notifications.clear_confirmation": "Bạn thật sự muốn xóa vĩnh viễn tất cả thông báo của mình?",
@@ -473,7 +478,7 @@
   "report.block_explanation": "Bạn sẽ không thấy tút của họ nữa. Họ cũng không thể theo dõi hoặc thấy tút của bạn. Họ sẽ biết là họ đã bị chặn.",
   "report.categories.other": "Khác",
   "report.categories.spam": "Spam",
-  "report.categories.violation": "Vi phạm quy tắc máy chủ",
+  "report.categories.violation": "Vi phạm nội quy máy chủ",
   "report.category.subtitle": "Chọn mục gần khớp nhất",
   "report.category.title": "Có vấn đề gì với {type}",
   "report.category.title_account": "người này",
@@ -492,10 +497,10 @@
   "report.reasons.other_description": "Vấn đề không nằm trong những mục trên",
   "report.reasons.spam": "Đây là spam",
   "report.reasons.spam_description": "Liên kết độc hại, tạo tương tác giả hoặc trả lời lặp đi lặp lại",
-  "report.reasons.violation": "Vi phạm quy tắc máy chủ",
-  "report.reasons.violation_description": "Bạn nhận thấy nó vi phạm quy tắc máy chủ",
+  "report.reasons.violation": "Vi phạm nội quy máy chủ",
+  "report.reasons.violation_description": "Bạn nhận thấy nó vi phạm nội quy máy chủ",
   "report.rules.subtitle": "Chọn tất cả những gì phù hợp",
-  "report.rules.title": "Vi phạm quy tắc nào?",
+  "report.rules.title": "Vi phạm nội quy nào?",
   "report.statuses.subtitle": "Chọn tất cả những gì phù hợp",
   "report.statuses.title": "Bạn muốn gửi tút nào kèm báo cáo này?",
   "report.submit": "Gửi đi",
@@ -509,7 +514,7 @@
   "report_notification.attached_statuses": "{count, plural, other {{count} tút}} đính kèm",
   "report_notification.categories.other": "Khác",
   "report_notification.categories.spam": "Spam",
-  "report_notification.categories.violation": "Vi phạm quy tắc",
+  "report_notification.categories.violation": "Vi phạm nội quy",
   "report_notification.open": "Mở báo cáo",
   "search.placeholder": "Tìm kiếm",
   "search.search_or_paste": "Tìm kiếm hoặc nhập URL",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Đăng nhập",
   "sign_in_banner.text": "Đăng nhập để theo dõi người hoặc hashtag; cũng như thích, chia sẻ và trả lời tút.",
   "status.admin_account": "Mở giao diện quản trị @{name}",
+  "status.admin_domain": "Mở giao diện quản trị @{domain}",
   "status.admin_status": "Mở tút này trong giao diện quản trị",
   "status.block": "Chặn @{name}",
   "status.bookmark": "Lưu",
diff --git a/app/javascript/mastodon/locales/whitelist_la.json b/app/javascript/mastodon/locales/whitelist_la.json
new file mode 100644
index 000000000..0d4f101c7
--- /dev/null
+++ b/app/javascript/mastodon/locales/whitelist_la.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/app/javascript/mastodon/locales/zgh.json b/app/javascript/mastodon/locales/zgh.json
index dd2bd7a06..9b620cde8 100644
--- a/app/javascript/mastodon/locales/zgh.json
+++ b/app/javascript/mastodon/locales/zgh.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "Toots and replies",
   "account.report": "Report @{name}",
   "account.requested": "Awaiting approval",
+  "account.requested_follow": "{name} has requested to follow you",
   "account.share": "ⴱⴹⵓ ⵉⴼⵔⵙ ⵏ @{name}",
   "account.show_reblogs": "Show boosts from @{name}",
   "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
@@ -127,7 +128,7 @@
   "compose.language.search": "Search languages...",
   "compose_form.direct_message_warning_learn_more": "ⵙⵙⵏ ⵓⴳⴳⴰⵔ",
   "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
-  "compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
   "compose_form.lock_disclaimer.lock": "ⵉⵜⵜⵓⵔⴳⵍ",
   "compose_form.placeholder": "ⵎⴰⵢⴷ ⵉⵍⵍⴰⵏ ⴳ ⵉⵅⴼ ⵏⵏⴽ?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "Copy stacktrace to clipboard",
   "errors.unexpected_crash.report_issue": "Report issue",
   "explore.search_results": "Search results",
+  "explore.suggested_follows": "For you",
   "explore.title": "Explore",
+  "explore.trending_links": "News",
+  "explore.trending_statuses": "Posts",
+  "explore.trending_tags": "Hashtags",
   "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.",
   "filter_modal.added.context_mismatch_title": "Context mismatch!",
   "filter_modal.added.expired_explanation": "This filter category has expired, you will need to change the expiration date for it to apply.",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "Sign in",
   "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.",
   "status.admin_account": "Open moderation interface for @{name}",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "Open this status in the moderation interface",
   "status.block": "ⴳⴷⵍ @{name}",
   "status.bookmark": "Bookmark",
@@ -553,7 +559,7 @@
   "status.favourite": "Favourite",
   "status.filter": "Filter this post",
   "status.filtered": "Filtered",
-  "status.hide": "Hide toot",
+  "status.hide": "Hide post",
   "status.history.created": "{name} created {date}",
   "status.history.edited": "{name} edited {date}",
   "status.load_more": "ⵙⵙⵉⵍⵉ ⵓⴳⴳⴰⵔ",
diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json
index 3d9c0ee1a..195c63198 100644
--- a/app/javascript/mastodon/locales/zh-CN.json
+++ b/app/javascript/mastodon/locales/zh-CN.json
@@ -37,7 +37,7 @@
   "account.following_counter": "正在关注 {counter} 人",
   "account.follows.empty": "此用户目前尚未关注任何人。",
   "account.follows_you": "关注了你",
-  "account.go_to_profile": "转到个人资料",
+  "account.go_to_profile": "转到个人资料界面",
   "account.hide_reblogs": "隐藏来自 @{name} 的转贴",
   "account.joined_short": "加入于",
   "account.languages": "更改订阅语言",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "嘟文和回复",
   "account.report": "举报 @{name}",
   "account.requested": "正在等待对方同意。点击以取消发送关注请求",
+  "account.requested_follow": "{name} 已经向你发送了关注请求",
   "account.share": "分享 @{name} 的个人资料页",
   "account.show_reblogs": "显示来自 @{name} 的转嘟",
   "account.statuses_counter": "{counter} 条嘟文",
@@ -199,7 +200,7 @@
   "emoji_button.food": "食物和饮料",
   "emoji_button.label": "插入表情符号",
   "emoji_button.nature": "自然",
-  "emoji_button.not_found": "没有找到匹配的表情符号",
+  "emoji_button.not_found": "木有这个表情符号!(╯°□°)╯︵ ┻━┻",
   "emoji_button.objects": "物体",
   "emoji_button.people": "人物",
   "emoji_button.recent": "常用",
@@ -207,7 +208,7 @@
   "emoji_button.search_results": "搜索结果",
   "emoji_button.symbols": "符号",
   "emoji_button.travel": "旅行和地点",
-  "empty_column.account_suspended": "账户已停用",
+  "empty_column.account_suspended": "账户已被停用",
   "empty_column.account_timeline": "这里没有嘟文!",
   "empty_column.account_unavailable": "个人资料不可用",
   "empty_column.blocks": "你还未屏蔽任何用户。",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "把堆栈跟踪信息复制到剪贴板",
   "errors.unexpected_crash.report_issue": "报告问题",
   "explore.search_results": "搜索结果",
+  "explore.suggested_follows": "为你推荐",
   "explore.title": "探索",
+  "explore.trending_links": "新闻",
+  "explore.trending_statuses": "嘟文",
+  "explore.trending_tags": "话题标签",
   "filter_modal.added.context_mismatch_explanation": "此过滤器分类不适用访问过嘟文的环境中。如果你想要在环境中过滤嘟文,你必须编辑此过滤器。",
   "filter_modal.added.context_mismatch_title": "环境不匹配!",
   "filter_modal.added.expired_explanation": "此过滤器分类已过期,你需要修改到期日期才能应用。",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "登录",
   "sign_in_banner.text": "登录以关注个人资料或话题标签、喜欢、分享和嘟文,或与在不同服务器上的账号进行互动。",
   "status.admin_account": "打开 @{name} 的管理界面",
+  "status.admin_domain": "打开 {domain} 的管理界面",
   "status.admin_status": "打开此帖的管理界面",
   "status.block": "屏蔽 @{name}",
   "status.bookmark": "添加到书签",
@@ -553,7 +559,7 @@
   "status.favourite": "喜欢",
   "status.filter": "过滤此嘟文",
   "status.filtered": "已过滤",
-  "status.hide": "屏蔽嘟文",
+  "status.hide": "隐藏嘟文",
   "status.history.created": "{name} 创建于 {date}",
   "status.history.edited": "{name} 编辑于 {date}",
   "status.load_more": "加载更多",
diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json
index 6c967f414..aa0530da3 100644
--- a/app/javascript/mastodon/locales/zh-HK.json
+++ b/app/javascript/mastodon/locales/zh-HK.json
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "帖文與回覆",
   "account.report": "檢舉 @{name}",
   "account.requested": "正在等待核准。按一下以取消追蹤請求",
+  "account.requested_follow": "{name} 要求追蹤你",
   "account.share": "分享 @{name} 的個人檔案",
   "account.show_reblogs": "顯示 @{name} 的轉推",
   "account.statuses_counter": "{count, plural,one {{counter} 篇}other {{counter} 篇}}帖文",
@@ -127,7 +128,7 @@
   "compose.language.search": "搜尋語言...",
   "compose_form.direct_message_warning_learn_more": "了解更多",
   "compose_form.encryption_warning": "Mastodon 上的帖文並未端對端加密。請不要透過 Mastodon 分享任何敏感資訊。",
-  "compose_form.hashtag_warning": "這文章因為不是公開,所以不會被標籤搜索。只有公開的文章才會被標籤搜索。",
+  "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
   "compose_form.lock_disclaimer": "你的用戶狀態沒有{locked},任何人都能立即關注你,然後看到「只有關注者能看」的文章。",
   "compose_form.lock_disclaimer.lock": "鎖定",
   "compose_form.placeholder": "你在想甚麼?",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "複製 stacktrace 到剪貼簿",
   "errors.unexpected_crash.report_issue": "舉報問題",
   "explore.search_results": "搜尋結果",
+  "explore.suggested_follows": "為您推薦",
   "explore.title": "探索",
+  "explore.trending_links": "最新消息",
+  "explore.trending_statuses": "帖文",
+  "explore.trending_tags": "標籤",
   "filter_modal.added.context_mismatch_explanation": "此過濾器類別不適用於您所存取帖文的情境。如果您想要此帖文被於此情境被過濾,您必須編輯過濾器。",
   "filter_modal.added.context_mismatch_title": "情境不符合!",
   "filter_modal.added.expired_explanation": "此過濾器類別已失效,您需要更新過期日期才能套用。",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "登入",
   "sign_in_banner.text": "登入以追蹤個人檔案、標籤、最愛、分享和回覆帖文,或用你在其他伺服器的帳號進行互動。",
   "status.admin_account": "開啟 @{name} 的管理介面",
+  "status.admin_domain": "Open moderation interface for {domain}",
   "status.admin_status": "在管理介面開啟這篇文章",
   "status.block": "封鎖 @{name}",
   "status.bookmark": "書籤",
@@ -553,7 +559,7 @@
   "status.favourite": "最愛",
   "status.filter": "篩選此帖文",
   "status.filtered": "已過濾",
-  "status.hide": "隱藏帖文",
+  "status.hide": "Hide post",
   "status.history.created": "{name} 於 {date} 建立",
   "status.history.edited": "{name} 於 {date} 編輯",
   "status.load_more": "載入更多",
diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json
index a8d6cb25e..75e423d1c 100644
--- a/app/javascript/mastodon/locales/zh-TW.json
+++ b/app/javascript/mastodon/locales/zh-TW.json
@@ -39,9 +39,9 @@
   "account.follows_you": "跟隨了您",
   "account.go_to_profile": "前往個人檔案",
   "account.hide_reblogs": "隱藏來自 @{name} 的轉嘟",
-  "account.joined_short": "已加入",
+  "account.joined_short": "加入時間",
   "account.languages": "變更訂閱的語言",
-  "account.link_verified_on": "已在 {date} 檢查此連結的擁有者權限",
+  "account.link_verified_on": "已於 {date} 檢查此連結的擁有者權限",
   "account.locked_info": "此帳號的隱私狀態被設為鎖定。該擁有者會手動審核能跟隨此帳號的人。",
   "account.media": "媒體",
   "account.mention": "提及 @{name}",
@@ -54,6 +54,7 @@
   "account.posts_with_replies": "嘟文與回覆",
   "account.report": "檢舉 @{name}",
   "account.requested": "正在等待核准。按一下以取消跟隨請求",
+  "account.requested_follow": "{name} 要求跟隨您",
   "account.share": "分享 @{name} 的個人檔案",
   "account.show_reblogs": "顯示來自 @{name} 的嘟文",
   "account.statuses_counter": "{count, plural,one {{counter} 則}other {{counter} 則}}嘟文",
@@ -110,7 +111,7 @@
   "column.lists": "列表",
   "column.mutes": "已靜音的使用者",
   "column.notifications": "通知",
-  "column.pins": "釘選的嘟文",
+  "column.pins": "釘選嘟文",
   "column.public": "聯邦時間軸",
   "column_back_button.label": "上一頁",
   "column_header.hide_settings": "隱藏設定",
@@ -187,7 +188,7 @@
   "dismissable_banner.community_timeline": "這些是 {domain} 上面託管帳號之最新公開嘟文。",
   "dismissable_banner.dismiss": "關閉",
   "dismissable_banner.explore_links": "這些新聞故事正在被此伺服器以及去中心化網路上的人們熱烈討論著。",
-  "dismissable_banner.explore_statuses": "這些於這裡以及去中心化網路中其他伺服器發出的嘟文正在被此伺服器上的人們熱烈討論著。",
+  "dismissable_banner.explore_statuses": "這些於這個伺服器以及去中心化網路中其他伺服器發出的嘟文正在被此伺服器上的人們熱烈討論著。",
   "dismissable_banner.explore_tags": "這些主題標籤正在被此伺服器以及去中心化網路上的人們熱烈討論著。",
   "dismissable_banner.public_timeline": "這些是來自這裡以及去中心化網路中其他已知伺服器之最新公開嘟文。",
   "embed.instructions": "要在您的網站嵌入此嘟文,請複製以下程式碼。",
@@ -225,7 +226,7 @@
   "empty_column.home.suggestions": "檢視部份建議",
   "empty_column.list": "這份列表下什麼也沒有。當此列表的成員嘟出了新的嘟文時,它們就會顯示於此。",
   "empty_column.lists": "您還沒有建立任何列表。當您建立列表時,它將於此顯示。",
-  "empty_column.mutes": "您尚未靜音任何使用者。",
+  "empty_column.mutes": "您還沒有靜音任何使用者。",
   "empty_column.notifications": "您還沒有收到任何通知,當您和別人開始互動時,它將於此顯示。",
   "empty_column.public": "這裡什麼都沒有!嘗試寫些公開的嘟文,或著自己跟隨其他伺服器的使用者後就會有嘟文出現了",
   "error.unexpected_crash.explanation": "由於發生系統故障或瀏覽器相容性問題,無法正常顯示此頁面。",
@@ -235,7 +236,11 @@
   "errors.unexpected_crash.copy_stacktrace": "複製 stacktrace 到剪貼簿",
   "errors.unexpected_crash.report_issue": "回報問題",
   "explore.search_results": "搜尋結果",
+  "explore.suggested_follows": "為您推薦",
   "explore.title": "探索",
+  "explore.trending_links": "最新消息",
+  "explore.trending_statuses": "嘟文",
+  "explore.trending_tags": "主題標籤",
   "filter_modal.added.context_mismatch_explanation": "此過濾器類別不是用您所存取嘟文的情境。若您想要此嘟文被於此情境被過濾,您必須編輯過濾器。",
   "filter_modal.added.context_mismatch_title": "不符合情境!",
   "filter_modal.added.expired_explanation": "此過濾器類別已失效,您需要更新過期日期以套用。",
@@ -320,7 +325,7 @@
   "keyboard_shortcuts.my_profile": "開啟個人檔案頁面",
   "keyboard_shortcuts.notifications": "開啟通知欄",
   "keyboard_shortcuts.open_media": "開啟媒體",
-  "keyboard_shortcuts.pinned": "開啟釘選的嘟文列表",
+  "keyboard_shortcuts.pinned": "開啟釘選嘟文列表",
   "keyboard_shortcuts.profile": "開啟作者的個人檔案頁面",
   "keyboard_shortcuts.reply": "回應嘟文",
   "keyboard_shortcuts.requests": "開啟跟隨請求列表",
@@ -379,7 +384,7 @@
   "navigation_bar.logout": "登出",
   "navigation_bar.mutes": "靜音的使用者",
   "navigation_bar.personal": "個人",
-  "navigation_bar.pins": "釘選的嘟文",
+  "navigation_bar.pins": "釘選嘟文",
   "navigation_bar.preferences": "偏好設定",
   "navigation_bar.public_timeline": "聯邦時間軸",
   "navigation_bar.search": "搜尋",
@@ -537,6 +542,7 @@
   "sign_in_banner.sign_in": "登入",
   "sign_in_banner.text": "登入以追蹤個人檔案、主題標籤、最愛,分享和回覆嘟文,或以您其他伺服器之帳號進行互動:",
   "status.admin_account": "開啟 @{name} 的管理介面",
+  "status.admin_domain": "開啟 {domain} 的管理介面",
   "status.admin_status": "在管理介面開啟此嘟文",
   "status.block": "封鎖 @{name}",
   "status.bookmark": "書籤",
@@ -564,7 +570,7 @@
   "status.mute_conversation": "靜音對話",
   "status.open": "展開此嘟文",
   "status.pin": "釘選到個人檔案頁面",
-  "status.pinned": "釘選的嘟文",
+  "status.pinned": "釘選嘟文",
   "status.read_more": "閱讀更多",
   "status.reblog": "轉嘟",
   "status.reblog_private": "依照原嘟可見性轉嘟",
@@ -617,13 +623,13 @@
   "upload_button.label": "上傳圖像、影片、或音樂檔案",
   "upload_error.limit": "已達到檔案上傳限制。",
   "upload_error.poll": "不允許在投票中上傳檔案。",
-  "upload_form.audio_description": "描述內容給聽障人士",
+  "upload_form.audio_description": "為聽障人士增加文字說明",
   "upload_form.description": "為視障人士增加文字說明",
   "upload_form.description_missing": "沒有任何描述",
   "upload_form.edit": "編輯",
   "upload_form.thumbnail": "更改預覽圖",
   "upload_form.undo": "刪除",
-  "upload_form.video_description": "描述內容給聽障或視障人士",
+  "upload_form.video_description": "為聽障或視障人士增加文字說明",
   "upload_modal.analyzing_picture": "正在分析圖片…",
   "upload_modal.apply": "套用",
   "upload_modal.applying": "正在套用⋯⋯",
diff --git a/app/javascript/mastodon/middleware/errors.js b/app/javascript/mastodon/middleware/errors.js
index 0a65fd321..708df6bb8 100644
--- a/app/javascript/mastodon/middleware/errors.js
+++ b/app/javascript/mastodon/middleware/errors.js
@@ -14,4 +14,4 @@ export default function errorsMiddleware() {
 
     return next(action);
   };
-};
+}
diff --git a/app/javascript/mastodon/middleware/loading_bar.js b/app/javascript/mastodon/middleware/loading_bar.js
index a98f1bb2b..da8cc4c7d 100644
--- a/app/javascript/mastodon/middleware/loading_bar.js
+++ b/app/javascript/mastodon/middleware/loading_bar.js
@@ -22,4 +22,4 @@ export default function loadingBarMiddleware(config = {}) {
 
     return next(action);
   };
-};
+}
diff --git a/app/javascript/mastodon/middleware/sounds.js b/app/javascript/mastodon/middleware/sounds.js
index 9f1bc02b9..7f2388983 100644
--- a/app/javascript/mastodon/middleware/sounds.js
+++ b/app/javascript/mastodon/middleware/sounds.js
@@ -43,4 +43,4 @@ export default function soundsMiddleware() {
 
     return next(action);
   };
-};
+}
diff --git a/app/javascript/mastodon/permissions.js b/app/javascript/mastodon/permissions.js
index 752ddd6c5..9ea149e5f 100644
--- a/app/javascript/mastodon/permissions.js
+++ b/app/javascript/mastodon/permissions.js
@@ -1,3 +1,4 @@
-export const PERMISSION_INVITE_USERS   = 0x0000000000010000;
-export const PERMISSION_MANAGE_USERS   = 0x0000000000000400;
-export const PERMISSION_MANAGE_REPORTS = 0x0000000000000010;
+export const PERMISSION_INVITE_USERS      = 0x0000000000010000;
+export const PERMISSION_MANAGE_USERS      = 0x0000000000000400;
+export const PERMISSION_MANAGE_FEDERATION = 0x0000000000000020;
+export const PERMISSION_MANAGE_REPORTS    = 0x0000000000000010;
diff --git a/app/javascript/mastodon/reducers/accounts.js b/app/javascript/mastodon/reducers/accounts.js
index b5589668c..44973e939 100644
--- a/app/javascript/mastodon/reducers/accounts.js
+++ b/app/javascript/mastodon/reducers/accounts.js
@@ -35,4 +35,4 @@ export default function accounts(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/accounts_counters.js b/app/javascript/mastodon/reducers/accounts_counters.js
index 9ebf72af9..4e1256d1b 100644
--- a/app/javascript/mastodon/reducers/accounts_counters.js
+++ b/app/javascript/mastodon/reducers/accounts_counters.js
@@ -35,4 +35,4 @@ export default function accountsCounters(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/accounts_map.js b/app/javascript/mastodon/reducers/accounts_map.js
index 444bbda19..8412ad4d0 100644
--- a/app/javascript/mastodon/reducers/accounts_map.js
+++ b/app/javascript/mastodon/reducers/accounts_map.js
@@ -17,4 +17,4 @@ export default function accountsMap(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/alerts.js b/app/javascript/mastodon/reducers/alerts.js
index c62ab0dfd..5b3010a59 100644
--- a/app/javascript/mastodon/reducers/alerts.js
+++ b/app/javascript/mastodon/reducers/alerts.js
@@ -23,4 +23,4 @@ export default function alerts(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/announcements.js b/app/javascript/mastodon/reducers/announcements.js
index 34e08eac8..b53f93a4a 100644
--- a/app/javascript/mastodon/reducers/announcements.js
+++ b/app/javascript/mastodon/reducers/announcements.js
@@ -99,4 +99,4 @@ export default function announcementsReducer(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js
index 1dafb07fd..9ce7e97ed 100644
--- a/app/javascript/mastodon/reducers/compose.js
+++ b/app/javascript/mastodon/reducers/compose.js
@@ -108,7 +108,7 @@ function statusToTextMentions(state, status) {
   }
 
   return set.union(status.get('mentions').filterNot(mention => mention.get('id') === me).map(mention => `@${mention.get('acct')} `)).join('');
-};
+}
 
 function clearAll(state) {
   return state.withMutations(map => {
@@ -126,7 +126,7 @@ function clearAll(state) {
     map.set('poll', null);
     map.set('idempotencyKey', uuid());
   });
-};
+}
 
 function appendMedia(state, media, file) {
   const prevSize = state.get('media_attachments').size;
@@ -146,7 +146,7 @@ function appendMedia(state, media, file) {
       map.set('sensitive', true);
     }
   });
-};
+}
 
 function removeMedia(state, mediaId) {
   const prevSize = state.get('media_attachments').size;
@@ -159,7 +159,7 @@ function removeMedia(state, mediaId) {
       map.set('sensitive', false);
     }
   });
-};
+}
 
 const insertSuggestion = (state, position, token, completion, path) => {
   return state.withMutations(map => {
@@ -330,8 +330,10 @@ export default function compose(state = initialState, action) {
       map.set('preselectDate', new Date());
       map.set('idempotencyKey', uuid());
 
-      if (action.status.get('language')) {
+      if (action.status.get('language') && !action.status.has('translation')) {
         map.set('language', action.status.get('language'));
+      } else {
+        map.set('language', state.get('default_language'));
       }
 
       if (action.status.get('spoiler_text').length > 0) {
@@ -429,6 +431,8 @@ export default function compose(state = initialState, action) {
   case TIMELINE_DELETE:
     if (action.id === state.get('in_reply_to')) {
       return state.set('in_reply_to', null);
+    } else if (action.id === state.get('id')) {
+      return state.set('id', null);
     } else {
       return state;
     }
@@ -520,4 +524,4 @@ export default function compose(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/contexts.js b/app/javascript/mastodon/reducers/contexts.js
index 4c2d6cc8a..7aa95b5d5 100644
--- a/app/javascript/mastodon/reducers/contexts.js
+++ b/app/javascript/mastodon/reducers/contexts.js
@@ -103,4 +103,4 @@ export default function replies(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/conversations.js b/app/javascript/mastodon/reducers/conversations.js
index 975418eda..feccf18f0 100644
--- a/app/javascript/mastodon/reducers/conversations.js
+++ b/app/javascript/mastodon/reducers/conversations.js
@@ -113,4 +113,4 @@ export default function conversations(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/custom_emojis.js b/app/javascript/mastodon/reducers/custom_emojis.js
index d2c801ade..0338c2e53 100644
--- a/app/javascript/mastodon/reducers/custom_emojis.js
+++ b/app/javascript/mastodon/reducers/custom_emojis.js
@@ -12,4 +12,4 @@ export default function custom_emojis(state = initialState, action) {
   }
 
   return state;
-};
+}
diff --git a/app/javascript/mastodon/reducers/domain_lists.js b/app/javascript/mastodon/reducers/domain_lists.js
index eff97fbd6..6bf8cee68 100644
--- a/app/javascript/mastodon/reducers/domain_lists.js
+++ b/app/javascript/mastodon/reducers/domain_lists.js
@@ -22,4 +22,4 @@ export default function domainLists(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/dropdown_menu.js b/app/javascript/mastodon/reducers/dropdown_menu.js
index a78a11acc..51bf9375b 100644
--- a/app/javascript/mastodon/reducers/dropdown_menu.js
+++ b/app/javascript/mastodon/reducers/dropdown_menu.js
@@ -4,12 +4,12 @@ import {
   DROPDOWN_MENU_CLOSE,
 } from '../actions/dropdown_menu';
 
-const initialState = Immutable.Map({ openId: null, placement: null, keyboard: false, scroll_key: null });
+const initialState = Immutable.Map({ openId: null, keyboard: false, scroll_key: null });
 
 export default function dropdownMenu(state = initialState, action) {
   switch (action.type) {
   case DROPDOWN_MENU_OPEN:
-    return state.merge({ openId: action.id, placement: action.placement, keyboard: action.keyboard, scroll_key: action.scroll_key });
+    return state.merge({ openId: action.id, keyboard: action.keyboard, scroll_key: action.scroll_key });
   case DROPDOWN_MENU_CLOSE:
     return state.get('openId') === action.id ? state.set('openId', null).set('scroll_key', null) : state;
   default:
diff --git a/app/javascript/mastodon/reducers/filters.js b/app/javascript/mastodon/reducers/filters.js
index f4f97cd3a..e1f014046 100644
--- a/app/javascript/mastodon/reducers/filters.js
+++ b/app/javascript/mastodon/reducers/filters.js
@@ -41,4 +41,4 @@ export default function filters(state = ImmutableMap(), action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/height_cache.js b/app/javascript/mastodon/reducers/height_cache.js
index 2f5716fae..77a59c8c5 100644
--- a/app/javascript/mastodon/reducers/height_cache.js
+++ b/app/javascript/mastodon/reducers/height_cache.js
@@ -20,4 +20,4 @@ export default function statuses(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/list_adder.js b/app/javascript/mastodon/reducers/list_adder.js
index b8c1b0e26..b144610a5 100644
--- a/app/javascript/mastodon/reducers/list_adder.js
+++ b/app/javascript/mastodon/reducers/list_adder.js
@@ -44,4 +44,4 @@ export default function listAdderReducer(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/list_editor.js b/app/javascript/mastodon/reducers/list_editor.js
index 91e524dd5..6e020dbe6 100644
--- a/app/javascript/mastodon/reducers/list_editor.js
+++ b/app/javascript/mastodon/reducers/list_editor.js
@@ -93,4 +93,4 @@ export default function listEditorReducer(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/lists.js b/app/javascript/mastodon/reducers/lists.js
index f30ffbcbd..ba3e2b3cb 100644
--- a/app/javascript/mastodon/reducers/lists.js
+++ b/app/javascript/mastodon/reducers/lists.js
@@ -34,4 +34,4 @@ export default function lists(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/markers.js b/app/javascript/mastodon/reducers/markers.js
index fb1572ff5..e3d1b1936 100644
--- a/app/javascript/mastodon/reducers/markers.js
+++ b/app/javascript/mastodon/reducers/markers.js
@@ -22,4 +22,4 @@ export default function markers(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/media_attachments.js b/app/javascript/mastodon/reducers/media_attachments.js
index 24119f628..7a155b77f 100644
--- a/app/javascript/mastodon/reducers/media_attachments.js
+++ b/app/javascript/mastodon/reducers/media_attachments.js
@@ -12,4 +12,4 @@ export default function meta(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/meta.js b/app/javascript/mastodon/reducers/meta.js
index 5040a340f..755dd7390 100644
--- a/app/javascript/mastodon/reducers/meta.js
+++ b/app/javascript/mastodon/reducers/meta.js
@@ -19,4 +19,4 @@ export default function meta(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/missed_updates.js b/app/javascript/mastodon/reducers/missed_updates.js
index b71d62d82..a3141d854 100644
--- a/app/javascript/mastodon/reducers/missed_updates.js
+++ b/app/javascript/mastodon/reducers/missed_updates.js
@@ -18,4 +18,4 @@ export default function missed_updates(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/modal.js b/app/javascript/mastodon/reducers/modal.js
index 3eab07d9d..edde2f947 100644
--- a/app/javascript/mastodon/reducers/modal.js
+++ b/app/javascript/mastodon/reducers/modal.js
@@ -36,4 +36,4 @@ export default function modal(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js
index eb5368198..44fa1c613 100644
--- a/app/javascript/mastodon/reducers/notifications.js
+++ b/app/javascript/mastodon/reducers/notifications.js
@@ -303,4 +303,4 @@ export default function notifications(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/picture_in_picture.js b/app/javascript/mastodon/reducers/picture_in_picture.js
index 48772ae7f..10fbc1695 100644
--- a/app/javascript/mastodon/reducers/picture_in_picture.js
+++ b/app/javascript/mastodon/reducers/picture_in_picture.js
@@ -22,4 +22,4 @@ export default function pictureInPicture(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/push_notifications.js b/app/javascript/mastodon/reducers/push_notifications.js
index c48cfb705..6a62ecb81 100644
--- a/app/javascript/mastodon/reducers/push_notifications.js
+++ b/app/javascript/mastodon/reducers/push_notifications.js
@@ -50,4 +50,4 @@ export default function push_subscriptions(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/relationships.js b/app/javascript/mastodon/reducers/relationships.js
index 53949258a..a3b01a0f6 100644
--- a/app/javascript/mastodon/reducers/relationships.js
+++ b/app/javascript/mastodon/reducers/relationships.js
@@ -1,4 +1,7 @@
 import {
+  NOTIFICATIONS_UPDATE,
+} from '../actions/notifications';
+import {
   ACCOUNT_FOLLOW_SUCCESS,
   ACCOUNT_FOLLOW_REQUEST,
   ACCOUNT_FOLLOW_FAIL,
@@ -12,6 +15,8 @@ import {
   ACCOUNT_PIN_SUCCESS,
   ACCOUNT_UNPIN_SUCCESS,
   RELATIONSHIPS_FETCH_SUCCESS,
+  FOLLOW_REQUEST_AUTHORIZE_SUCCESS,
+  FOLLOW_REQUEST_REJECT_SUCCESS,
 } from '../actions/accounts';
 import {
   DOMAIN_BLOCK_SUCCESS,
@@ -44,6 +49,12 @@ const initialState = ImmutableMap();
 
 export default function relationships(state = initialState, action) {
   switch(action.type) {
+  case FOLLOW_REQUEST_AUTHORIZE_SUCCESS:
+    return state.setIn([action.id, 'followed_by'], true).setIn([action.id, 'requested_by'], false);
+  case FOLLOW_REQUEST_REJECT_SUCCESS:
+    return state.setIn([action.id, 'followed_by'], false).setIn([action.id, 'requested_by'], false);
+  case NOTIFICATIONS_UPDATE:
+    return action.notification.type === 'follow_request' ? state.setIn([action.notification.account.id, 'requested_by'], true) : state;
   case ACCOUNT_FOLLOW_REQUEST:
     return state.getIn([action.id, 'following']) ? state : state.setIn([action.id, action.locked ? 'requested' : 'following'], true);
   case ACCOUNT_FOLLOW_FAIL:
@@ -71,4 +82,4 @@ export default function relationships(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/search.js b/app/javascript/mastodon/reducers/search.js
index 7dceac6b9..d3e71da9d 100644
--- a/app/javascript/mastodon/reducers/search.js
+++ b/app/javascript/mastodon/reducers/search.js
@@ -64,4 +64,4 @@ export default function search(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js
index f9d3236e4..f48d58bdc 100644
--- a/app/javascript/mastodon/reducers/settings.js
+++ b/app/javascript/mastodon/reducers/settings.js
@@ -171,4 +171,4 @@ export default function settings(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/status_lists.js b/app/javascript/mastodon/reducers/status_lists.js
index 106f64d32..b1716e9cf 100644
--- a/app/javascript/mastodon/reducers/status_lists.js
+++ b/app/javascript/mastodon/reducers/status_lists.js
@@ -145,4 +145,4 @@ export default function statusLists(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js
index c30c1e2cc..a39ac6b64 100644
--- a/app/javascript/mastodon/reducers/statuses.js
+++ b/app/javascript/mastodon/reducers/statuses.js
@@ -92,4 +92,4 @@ export default function statuses(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/suggestions.js b/app/javascript/mastodon/reducers/suggestions.js
index 1a6e66ee7..0b4bc7789 100644
--- a/app/javascript/mastodon/reducers/suggestions.js
+++ b/app/javascript/mastodon/reducers/suggestions.js
@@ -34,4 +34,4 @@ export default function suggestionsReducer(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/tags.js b/app/javascript/mastodon/reducers/tags.js
index d24098e39..ea73af452 100644
--- a/app/javascript/mastodon/reducers/tags.js
+++ b/app/javascript/mastodon/reducers/tags.js
@@ -22,4 +22,4 @@ export default function tags(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js
index d72109e69..973e3cf18 100644
--- a/app/javascript/mastodon/reducers/timelines.js
+++ b/app/javascript/mastodon/reducers/timelines.js
@@ -223,4 +223,4 @@ export default function timelines(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/trends.js b/app/javascript/mastodon/reducers/trends.js
index 3e01bd07d..3d5f6ecd6 100644
--- a/app/javascript/mastodon/reducers/trends.js
+++ b/app/javascript/mastodon/reducers/trends.js
@@ -43,4 +43,4 @@ export default function trendsReducer(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/reducers/user_lists.js b/app/javascript/mastodon/reducers/user_lists.js
index 88b51fb63..2a80cf639 100644
--- a/app/javascript/mastodon/reducers/user_lists.js
+++ b/app/javascript/mastodon/reducers/user_lists.js
@@ -187,4 +187,4 @@ export default function userLists(state = initialState, action) {
   default:
     return state;
   }
-};
+}
diff --git a/app/javascript/mastodon/store/configureStore.js b/app/javascript/mastodon/store/configureStore.js
index e18af842f..0e0d45c66 100644
--- a/app/javascript/mastodon/store/configureStore.js
+++ b/app/javascript/mastodon/store/configureStore.js
@@ -12,4 +12,4 @@ export default function configureStore() {
     errorsMiddleware(),
     soundsMiddleware(),
   ), window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : f => f));
-};
+}
diff --git a/app/javascript/mastodon/uuid.js b/app/javascript/mastodon/uuid.js
index be1899305..0d2cfaa77 100644
--- a/app/javascript/mastodon/uuid.js
+++ b/app/javascript/mastodon/uuid.js
@@ -1,3 +1,3 @@
 export default function uuid(a) {
   return a ? (a^Math.random() * 16 >> a / 4).toString(16) : ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, uuid);
-};
+}
diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js
index ab7c4a3f3..8017734d5 100644
--- a/app/javascript/packs/public.js
+++ b/app/javascript/packs/public.js
@@ -46,6 +46,18 @@ function main() {
       minute: 'numeric',
     });
 
+    const dateFormat = new Intl.DateTimeFormat(locale, {
+      year: 'numeric',
+      month: 'short',
+      day: 'numeric',
+      timeFormat: false,
+    });
+
+    const timeFormat = new Intl.DateTimeFormat(locale, {
+      timeStyle: 'short',
+      hour12: false,
+    });
+
     [].forEach.call(document.querySelectorAll('.emojify'), (content) => {
       content.innerHTML = emojify(content.innerHTML);
     });
@@ -58,6 +70,32 @@ function main() {
       content.textContent = formattedDate;
     });
 
+    const isToday = date => {
+      const today = new Date();
+
+      return date.getDate() === today.getDate() &&
+        date.getMonth() === today.getMonth() &&
+        date.getFullYear() === today.getFullYear();
+    };
+    const todayFormat = new IntlMessageFormat(messages['relative_format.today'] || 'Today at {time}', locale);
+
+    [].forEach.call(document.querySelectorAll('time.relative-formatted'), (content) => {
+      const datetime = new Date(content.getAttribute('datetime'));
+
+      let formattedContent;
+
+      if (isToday(datetime)) {
+        const formattedTime = timeFormat.format(datetime);
+
+        formattedContent = todayFormat.format({ time: formattedTime });
+      } else {
+        formattedContent = dateFormat.format(datetime);
+      }
+
+      content.title = formattedContent;
+      content.textContent = formattedContent;
+    });
+
     [].forEach.call(document.querySelectorAll('time.time-ago'), (content) => {
       const datetime = new Date(content.getAttribute('datetime'));
       const now      = new Date();
diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss
index 30c8320bf..7449cc785 100644
--- a/app/javascript/styles/mastodon-light/diff.scss
+++ b/app/javascript/styles/mastodon-light/diff.scss
@@ -285,22 +285,8 @@ html {
 .dropdown-menu {
   background: $white;
 
-  &__arrow {
-    &.left {
-      border-left-color: $white;
-    }
-
-    &.top {
-      border-top-color: $white;
-    }
-
-    &.bottom {
-      border-bottom-color: $white;
-    }
-
-    &.right {
-      border-right-color: $white;
-    }
+  &__arrow::before {
+    background-color: $white;
   }
 
   &__item {
diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss
index 2372573d5..4250cf2b6 100644
--- a/app/javascript/styles/mastodon/admin.scss
+++ b/app/javascript/styles/mastodon/admin.scss
@@ -254,10 +254,8 @@ $content-width: 840px;
 
       &__actions {
         display: inline-flex;
-
-        & > :not(:first-child) {
-          margin-left: 5px;
-        }
+        flex-flow: wrap;
+        gap: 5px;
       }
 
       h2 small {
@@ -1218,7 +1216,7 @@ a.name-tag,
 
     path:first-child {
       fill: rgba($highlight-text-color, 0.25) !important;
-      fill-opacity: 100% !important;
+      fill-opacity: 1 !important;
     }
 
     path:last-child {
@@ -1681,6 +1679,15 @@ a.sparkline {
   box-sizing: border-box;
   min-height: 100%;
 
+  a {
+    color: $highlight-text-color;
+    text-decoration: none;
+
+    &:hover {
+      text-decoration: underline;
+    }
+  }
+
   p {
     margin-bottom: 20px;
     unicode-bidi: plaintext;
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 3650e3ec8..d5937643f 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -166,6 +166,30 @@
     &:disabled {
       opacity: 0.5;
     }
+
+    &.button--confirmation {
+      color: $valid-value-color;
+      border-color: $valid-value-color;
+
+      &:active,
+      &:focus,
+      &:hover {
+        background: $valid-value-color;
+        color: $primary-text-color;
+      }
+    }
+
+    &.button--destructive {
+      color: $error-value-color;
+      border-color: $error-value-color;
+
+      &:active,
+      &:focus,
+      &:hover {
+        background: $error-value-color;
+        color: $primary-text-color;
+      }
+    }
   }
 
   &.button--block {
@@ -339,8 +363,8 @@
   }
 }
 
-.dropdown-menu {
-  position: absolute;
+body > [data-popper-placement] {
+  z-index: 3;
 }
 
 .invisible {
@@ -1908,6 +1932,42 @@ a.account__display-name {
   text-decoration: none;
 }
 
+.dropdown-animation {
+  animation: dropdown 300ms cubic-bezier(0.1, 0.7, 0.1, 1);
+
+  @keyframes dropdown {
+    from {
+      opacity: 0;
+      transform: scaleX(0.85) scaleY(0.75);
+    }
+
+    to {
+      opacity: 1;
+      transform: scaleX(1) scaleY(1);
+    }
+  }
+
+  &.top {
+    transform-origin: bottom;
+  }
+
+  &.right {
+    transform-origin: left;
+  }
+
+  &.bottom {
+    transform-origin: top;
+  }
+
+  &.left {
+    transform-origin: right;
+  }
+
+  .reduce-motion & {
+    animation: none;
+  }
+}
+
 .dropdown {
   display: inline-block;
 }
@@ -1992,36 +2052,42 @@ a.account__display-name {
 
 .dropdown-menu__arrow {
   position: absolute;
-  width: 0;
-  height: 0;
-  border: 0 solid transparent;
 
-  &.left {
-    right: -5px;
-    margin-top: -5px;
-    border-width: 5px 0 5px 5px;
-    border-left-color: $ui-secondary-color;
+  &::before {
+    content: '';
+    display: block;
+    width: 14px;
+    height: 5px;
+    background-color: $ui-secondary-color;
+    mask-image: url("data:image/svg+xml;utf8,<svg width='14' height='5' xmlns='http://www.w3.org/2000/svg'><path d='M7 0L0 5h14L7 0z' fill='white'/></svg>");
   }
 
   &.top {
     bottom: -5px;
-    margin-left: -7px;
-    border-width: 5px 7px 0;
-    border-top-color: $ui-secondary-color;
+
+    &::before {
+      transform: rotate(180deg);
+    }
+  }
+
+  &.right {
+    left: -9px;
+
+    &::before {
+      transform: rotate(-90deg);
+    }
   }
 
   &.bottom {
     top: -5px;
-    margin-left: -7px;
-    border-width: 0 7px 5px;
-    border-bottom-color: $ui-secondary-color;
   }
 
-  &.right {
-    left: -5px;
-    margin-top: -5px;
-    border-width: 5px 5px 5px 0;
-    border-right-color: $ui-secondary-color;
+  &.left {
+    right: -9px;
+
+    &::before {
+      transform: rotate(90deg);
+    }
   }
 }
 
@@ -2474,8 +2540,7 @@ $ui-header-height: 55px;
     height: calc(100% - 10px) !important;
   }
 
-  .getting-started__wrapper,
-  .search {
+  .getting-started__wrapper {
     margin-bottom: 10px;
   }
 
@@ -2528,7 +2593,7 @@ $ui-header-height: 55px;
     }
   }
 
-  .ui__header {
+  .layout-single-column .ui__header {
     display: flex;
     background: $ui-base-color;
     border-bottom: 1px solid lighten($ui-base-color, 8%);
@@ -4245,7 +4310,7 @@ a.status-card.compact:hover {
 }
 
 @keyframes heartbeat {
-  from {
+  0% {
     transform: scale(1);
     animation-timing-function: ease-out;
   }
@@ -4315,7 +4380,7 @@ a.status-card.compact:hover {
 
 .emoji-picker-dropdown__menu {
   background: $simple-background-color;
-  position: absolute;
+  position: relative;
   box-shadow: 4px 4px 6px rgba($base-shadow-color, 0.4);
   border-radius: 4px;
   margin-top: 5px;
@@ -4501,7 +4566,6 @@ a.status-card.compact:hover {
 }
 
 .privacy-dropdown__dropdown {
-  position: absolute;
   background: $simple-background-color;
   box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
   border-radius: 4px;
@@ -4607,7 +4671,6 @@ a.status-card.compact:hover {
 
 .language-dropdown {
   &__dropdown {
-    position: absolute;
     background: $simple-background-color;
     box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
     border-radius: 4px;
@@ -4671,6 +4734,7 @@ a.status-card.compact:hover {
 }
 
 .search {
+  margin-bottom: 10px;
   position: relative;
 }
 
@@ -4853,7 +4917,6 @@ a.status-card.compact:hover {
 .modal-root__modal {
   pointer-events: auto;
   display: flex;
-  z-index: 9999;
 }
 
 .video-modal__container {
@@ -6722,7 +6785,8 @@ noscript {
   }
 }
 
-.moved-account-banner {
+.moved-account-banner,
+.follow-request-banner {
   padding: 20px;
   background: lighten($ui-base-color, 4%);
   display: flex;
@@ -6745,6 +6809,7 @@ noscript {
     justify-content: space-between;
     align-items: center;
     gap: 15px;
+    width: 100%;
   }
 
   .detailed-status__display-name {
@@ -6752,6 +6817,10 @@ noscript {
   }
 }
 
+.follow-request-banner .button {
+  width: 100%;
+}
+
 .column-inline-form {
   padding: 15px;
   display: flex;
@@ -7021,7 +7090,6 @@ noscript {
       display: block;
       flex: 0 0 auto;
       width: 94px;
-      margin-left: -2px;
 
       .account__avatar {
         background: darken($ui-base-color, 8%);
@@ -7038,6 +7106,7 @@ noscript {
     padding-top: 10px;
     gap: 8px;
     overflow: hidden;
+    margin-left: -2px; // aligns the pfp with content below
 
     &__buttons {
       display: flex;
@@ -7092,6 +7161,10 @@ noscript {
           font-weight: 400;
           overflow: hidden;
           text-overflow: ellipsis;
+
+          span {
+            user-select: all;
+          }
         }
       }
     }
@@ -7309,7 +7382,7 @@ noscript {
 
       path:first-child {
         fill: rgba($highlight-text-color, 0.25) !important;
-        fill-opacity: 100% !important;
+        fill-opacity: 1 !important;
       }
 
       path:last-child {
@@ -7662,7 +7735,7 @@ noscript {
       left: 0;
       width: 100%;
       height: 100%;
-      border-left: 2px solid $highlight-text-color;
+      border-left: 4px solid $highlight-text-color;
       pointer-events: none;
     }
   }
diff --git a/app/javascript/styles/mastodon/modal.scss b/app/javascript/styles/mastodon/modal.scss
index 6c6de4206..a333926dd 100644
--- a/app/javascript/styles/mastodon/modal.scss
+++ b/app/javascript/styles/mastodon/modal.scss
@@ -1,5 +1,5 @@
 .modal-layout {
-  background: $ui-base-color url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-lighter-color)}"/></svg>') repeat-x bottom fixed;
+  background: $ui-base-color url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 234.80078 31.757813" width="234.80078" height="31.757812"><path d="M19.599609 0c-1.05 0-2.10039.375-2.90039 1.125L0 16.925781v14.832031h234.80078V17.025391l-16.5-15.900391c-1.6-1.5-4.20078-1.5-5.80078 0l-13.80078 13.099609c-1.6 1.5-4.19883 1.5-5.79883 0L179.09961 1.125c-1.6-1.5-4.19883-1.5-5.79883 0L159.5 14.224609c-1.6 1.5-4.20078 1.5-5.80078 0L139.90039 1.125c-1.6-1.5-4.20078-1.5-5.80078 0l-13.79883 13.099609c-1.6 1.5-4.20078 1.5-5.80078 0L100.69922 1.125c-1.600001-1.5-4.198829-1.5-5.798829 0l-13.59961 13.099609c-1.6 1.5-4.200781 1.5-5.800781 0L61.699219 1.125c-1.6-1.5-4.198828-1.5-5.798828 0L42.099609 14.224609c-1.6 1.5-4.198828 1.5-5.798828 0L22.5 1.125C21.7.375 20.649609 0 19.599609 0z" fill="#{hex-color($ui-base-lighter-color)}33"/></svg>') repeat-x bottom fixed;
   display: flex;
   flex-direction: column;
   height: 100vh;
diff --git a/app/javascript/styles/mastodon/polls.scss b/app/javascript/styles/mastodon/polls.scss
index f553c5501..6812d5462 100644
--- a/app/javascript/styles/mastodon/polls.scss
+++ b/app/javascript/styles/mastodon/polls.scss
@@ -279,10 +279,10 @@
   color: $dark-text-color;
 
   &__chart {
-    background: rgba(darken($ui-primary-color, 14%), 0.2);
+    background: rgba(darken($ui-primary-color, 14%), 0.7);
 
     &.leading {
-      background: rgba($ui-highlight-color, 0.2);
+      background: rgba($ui-highlight-color, 0.5);
     }
   }
 }
diff --git a/app/javascript/styles/mastodon/widgets.scss b/app/javascript/styles/mastodon/widgets.scss
index 0e39dc87b..7a25d121b 100644
--- a/app/javascript/styles/mastodon/widgets.scss
+++ b/app/javascript/styles/mastodon/widgets.scss
@@ -39,6 +39,8 @@
       width: 20px;
       height: 20px;
       margin: -3px 0 0;
+      margin-left: 0.075em;
+      margin-right: 0.075em;
     }
 
     p {