diff --git a/Gemfile b/Gemfile
index 233dfe0f..11fd2053 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,7 +1,7 @@
 source 'https://rubygems.org'
 ruby '3.3.6'
 
-gem 'rails', '~> 7.2', '>= 7.2.1'
+gem 'rails', '~> 8.0', '>= 8.0.1'
 
 # The HTTP server running the Rails instance.
 gem 'falcon', '~> 0.48.0'
@@ -33,7 +33,7 @@ gem "omniauth_openid_connect", "~> 0.7.1"
 gem 'will_paginate', '~> 4.0'
 
 # For translation, both for the site UI and for Neopets data.
-gem 'rails-i18n', '~> 7.0', '>= 7.0.7'
+gem 'rails-i18n', '~> 8.0', '>= 8.0.1'
 gem 'http_accept_language', '~> 2.1', '>= 2.1.1'
 
 # For reading and parsing HTML from Neopets.com, like importing Closet pages.
diff --git a/Gemfile.lock b/Gemfile.lock
index dcb3fc44..53d38e6c 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -7,67 +7,67 @@ GIT
 GEM
   remote: https://rubygems.org/
   specs:
-    actioncable (7.2.1)
-      actionpack (= 7.2.1)
-      activesupport (= 7.2.1)
+    actioncable (8.0.1)
+      actionpack (= 8.0.1)
+      activesupport (= 8.0.1)
       nio4r (~> 2.0)
       websocket-driver (>= 0.6.1)
       zeitwerk (~> 2.6)
-    actionmailbox (7.2.1)
-      actionpack (= 7.2.1)
-      activejob (= 7.2.1)
-      activerecord (= 7.2.1)
-      activestorage (= 7.2.1)
-      activesupport (= 7.2.1)
+    actionmailbox (8.0.1)
+      actionpack (= 8.0.1)
+      activejob (= 8.0.1)
+      activerecord (= 8.0.1)
+      activestorage (= 8.0.1)
+      activesupport (= 8.0.1)
       mail (>= 2.8.0)
-    actionmailer (7.2.1)
-      actionpack (= 7.2.1)
-      actionview (= 7.2.1)
-      activejob (= 7.2.1)
-      activesupport (= 7.2.1)
+    actionmailer (8.0.1)
+      actionpack (= 8.0.1)
+      actionview (= 8.0.1)
+      activejob (= 8.0.1)
+      activesupport (= 8.0.1)
       mail (>= 2.8.0)
       rails-dom-testing (~> 2.2)
-    actionpack (7.2.1)
-      actionview (= 7.2.1)
-      activesupport (= 7.2.1)
+    actionpack (8.0.1)
+      actionview (= 8.0.1)
+      activesupport (= 8.0.1)
       nokogiri (>= 1.8.5)
-      racc
-      rack (>= 2.2.4, < 3.2)
+      rack (>= 2.2.4)
       rack-session (>= 1.0.1)
       rack-test (>= 0.6.3)
       rails-dom-testing (~> 2.2)
       rails-html-sanitizer (~> 1.6)
       useragent (~> 0.16)
-    actiontext (7.2.1)
-      actionpack (= 7.2.1)
-      activerecord (= 7.2.1)
-      activestorage (= 7.2.1)
-      activesupport (= 7.2.1)
+    actiontext (8.0.1)
+      actionpack (= 8.0.1)
+      activerecord (= 8.0.1)
+      activestorage (= 8.0.1)
+      activesupport (= 8.0.1)
       globalid (>= 0.6.0)
       nokogiri (>= 1.8.5)
-    actionview (7.2.1)
-      activesupport (= 7.2.1)
+    actionview (8.0.1)
+      activesupport (= 8.0.1)
       builder (~> 3.1)
       erubi (~> 1.11)
       rails-dom-testing (~> 2.2)
       rails-html-sanitizer (~> 1.6)
-    activejob (7.2.1)
-      activesupport (= 7.2.1)
+    activejob (8.0.1)
+      activesupport (= 8.0.1)
       globalid (>= 0.3.6)
-    activemodel (7.2.1)
-      activesupport (= 7.2.1)
-    activerecord (7.2.1)
-      activemodel (= 7.2.1)
-      activesupport (= 7.2.1)
+    activemodel (8.0.1)
+      activesupport (= 8.0.1)
+    activerecord (8.0.1)
+      activemodel (= 8.0.1)
+      activesupport (= 8.0.1)
       timeout (>= 0.4.0)
-    activestorage (7.2.1)
-      actionpack (= 7.2.1)
-      activejob (= 7.2.1)
-      activerecord (= 7.2.1)
-      activesupport (= 7.2.1)
+    activestorage (8.0.1)
+      actionpack (= 8.0.1)
+      activejob (= 8.0.1)
+      activerecord (= 8.0.1)
+      activesupport (= 8.0.1)
       marcel (~> 1.0)
-    activesupport (7.2.1)
+    activesupport (8.0.1)
       base64
+      benchmark (>= 0.3)
       bigdecimal
       concurrent-ruby (~> 1.0, >= 1.3.1)
       connection_pool (>= 2.2.5)
@@ -77,6 +77,7 @@ GEM
       minitest (>= 5.1)
       securerandom (>= 0.3)
       tzinfo (~> 2.0, >= 2.0.5)
+      uri (>= 0.13.1)
     addressable (2.8.7)
       public_suffix (>= 2.0.2, < 7.0)
     aes_key_wrap (1.1.0)
@@ -257,7 +258,7 @@ GEM
       timeout
     net-smtp (0.5.0)
       net-protocol
-    nio4r (2.7.3)
+    nio4r (2.7.4)
     nokogiri (1.16.7)
       mini_portile2 (~> 2.8.2)
       racc (~> 1.4)
@@ -330,20 +331,20 @@ GEM
     rackup (2.1.0)
       rack (>= 3)
       webrick (~> 1.8)
-    rails (7.2.1)
-      actioncable (= 7.2.1)
-      actionmailbox (= 7.2.1)
-      actionmailer (= 7.2.1)
-      actionpack (= 7.2.1)
-      actiontext (= 7.2.1)
-      actionview (= 7.2.1)
-      activejob (= 7.2.1)
-      activemodel (= 7.2.1)
-      activerecord (= 7.2.1)
-      activestorage (= 7.2.1)
-      activesupport (= 7.2.1)
+    rails (8.0.1)
+      actioncable (= 8.0.1)
+      actionmailbox (= 8.0.1)
+      actionmailer (= 8.0.1)
+      actionpack (= 8.0.1)
+      actiontext (= 8.0.1)
+      actionview (= 8.0.1)
+      activejob (= 8.0.1)
+      activemodel (= 8.0.1)
+      activerecord (= 8.0.1)
+      activestorage (= 8.0.1)
+      activesupport (= 8.0.1)
       bundler (>= 1.15.0)
-      railties (= 7.2.1)
+      railties (= 8.0.1)
     rails-dom-testing (2.2.0)
       activesupport (>= 5.0.0)
       minitest
@@ -351,12 +352,12 @@ GEM
     rails-html-sanitizer (1.6.0)
       loofah (~> 2.21)
       nokogiri (~> 1.14)
-    rails-i18n (7.0.9)
+    rails-i18n (8.0.1)
       i18n (>= 0.7, < 2)
-      railties (>= 6.0.0, < 8)
-    railties (7.2.1)
-      actionpack (= 7.2.1)
-      activesupport (= 7.2.1)
+      railties (>= 8.0.0, < 9)
+    railties (8.0.1)
+      actionpack (= 8.0.1)
+      activesupport (= 8.0.1)
       irb (~> 1.13)
       rackup (>= 1.0.0)
       rake (>= 12.2)
@@ -508,7 +509,8 @@ GEM
       crack (>= 0.3.2)
       hashdiff (>= 0.4.0, < 2.0.0)
     webrick (1.8.2)
-    websocket-driver (0.7.6)
+    websocket-driver (0.7.7)
+      base64
       websocket-extensions (>= 0.1.0)
     websocket-extensions (0.1.5)
     will_paginate (4.0.1)
@@ -543,8 +545,8 @@ DEPENDENCIES
   parallel (~> 1.23)
   rack-attack (~> 6.7)
   rack-mini-profiler (~> 3.1)
-  rails (~> 7.2, >= 7.2.1)
-  rails-i18n (~> 7.0, >= 7.0.7)
+  rails (~> 8.0, >= 8.0.1)
+  rails-i18n (~> 8.0, >= 8.0.1)
   rdiscount (~> 2.2, >= 2.2.7.1)
   react-rails (~> 2.7, >= 2.7.1)
   rspec-rails (~> 7.0)
diff --git a/vendor/cache/actioncable-7.2.1.gem b/vendor/cache/actioncable-7.2.1.gem
deleted file mode 100644
index c84ff217..00000000
Binary files a/vendor/cache/actioncable-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/actioncable-8.0.1.gem b/vendor/cache/actioncable-8.0.1.gem
new file mode 100644
index 00000000..225cb408
Binary files /dev/null and b/vendor/cache/actioncable-8.0.1.gem differ
diff --git a/vendor/cache/actionmailbox-7.2.1.gem b/vendor/cache/actionmailbox-7.2.1.gem
deleted file mode 100644
index e1e81686..00000000
Binary files a/vendor/cache/actionmailbox-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/actionmailbox-8.0.1.gem b/vendor/cache/actionmailbox-8.0.1.gem
new file mode 100644
index 00000000..5fed1248
Binary files /dev/null and b/vendor/cache/actionmailbox-8.0.1.gem differ
diff --git a/vendor/cache/actionmailer-7.2.1.gem b/vendor/cache/actionmailer-7.2.1.gem
deleted file mode 100644
index a57fcec9..00000000
Binary files a/vendor/cache/actionmailer-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/actionmailer-8.0.1.gem b/vendor/cache/actionmailer-8.0.1.gem
new file mode 100644
index 00000000..04de3e1b
Binary files /dev/null and b/vendor/cache/actionmailer-8.0.1.gem differ
diff --git a/vendor/cache/actionpack-7.2.1.gem b/vendor/cache/actionpack-7.2.1.gem
deleted file mode 100644
index beb5006b..00000000
Binary files a/vendor/cache/actionpack-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/actionpack-8.0.1.gem b/vendor/cache/actionpack-8.0.1.gem
new file mode 100644
index 00000000..4b677151
Binary files /dev/null and b/vendor/cache/actionpack-8.0.1.gem differ
diff --git a/vendor/cache/actiontext-7.2.1.gem b/vendor/cache/actiontext-7.2.1.gem
deleted file mode 100644
index 007bac12..00000000
Binary files a/vendor/cache/actiontext-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/actiontext-8.0.1.gem b/vendor/cache/actiontext-8.0.1.gem
new file mode 100644
index 00000000..19f29e43
Binary files /dev/null and b/vendor/cache/actiontext-8.0.1.gem differ
diff --git a/vendor/cache/actionview-7.2.1.gem b/vendor/cache/actionview-7.2.1.gem
deleted file mode 100644
index 508f606a..00000000
Binary files a/vendor/cache/actionview-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/actionview-8.0.1.gem b/vendor/cache/actionview-8.0.1.gem
new file mode 100644
index 00000000..728fa4b5
Binary files /dev/null and b/vendor/cache/actionview-8.0.1.gem differ
diff --git a/vendor/cache/activejob-7.2.1.gem b/vendor/cache/activejob-7.2.1.gem
deleted file mode 100644
index 6c61d3e7..00000000
Binary files a/vendor/cache/activejob-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/activejob-8.0.1.gem b/vendor/cache/activejob-8.0.1.gem
new file mode 100644
index 00000000..cadedec0
Binary files /dev/null and b/vendor/cache/activejob-8.0.1.gem differ
diff --git a/vendor/cache/activemodel-7.2.1.gem b/vendor/cache/activemodel-7.2.1.gem
deleted file mode 100644
index 45fcdf1f..00000000
Binary files a/vendor/cache/activemodel-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/activemodel-8.0.1.gem b/vendor/cache/activemodel-8.0.1.gem
new file mode 100644
index 00000000..fb330d9f
Binary files /dev/null and b/vendor/cache/activemodel-8.0.1.gem differ
diff --git a/vendor/cache/activerecord-7.2.1.gem b/vendor/cache/activerecord-7.2.1.gem
deleted file mode 100644
index d509087d..00000000
Binary files a/vendor/cache/activerecord-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/activerecord-8.0.1.gem b/vendor/cache/activerecord-8.0.1.gem
new file mode 100644
index 00000000..f4cee375
Binary files /dev/null and b/vendor/cache/activerecord-8.0.1.gem differ
diff --git a/vendor/cache/activestorage-7.2.1.gem b/vendor/cache/activestorage-7.2.1.gem
deleted file mode 100644
index 97bc24e1..00000000
Binary files a/vendor/cache/activestorage-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/activestorage-8.0.1.gem b/vendor/cache/activestorage-8.0.1.gem
new file mode 100644
index 00000000..ad0ebcc0
Binary files /dev/null and b/vendor/cache/activestorage-8.0.1.gem differ
diff --git a/vendor/cache/activesupport-7.2.1.gem b/vendor/cache/activesupport-7.2.1.gem
deleted file mode 100644
index 11652d22..00000000
Binary files a/vendor/cache/activesupport-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/activesupport-8.0.1.gem b/vendor/cache/activesupport-8.0.1.gem
new file mode 100644
index 00000000..a0f8ce76
Binary files /dev/null and b/vendor/cache/activesupport-8.0.1.gem differ
diff --git a/vendor/cache/nio4r-2.7.3.gem b/vendor/cache/nio4r-2.7.3.gem
deleted file mode 100644
index 60d86590..00000000
Binary files a/vendor/cache/nio4r-2.7.3.gem and /dev/null differ
diff --git a/vendor/cache/nio4r-2.7.4.gem b/vendor/cache/nio4r-2.7.4.gem
new file mode 100644
index 00000000..22b7976a
Binary files /dev/null and b/vendor/cache/nio4r-2.7.4.gem differ
diff --git a/vendor/cache/rails-7.2.1.gem b/vendor/cache/rails-7.2.1.gem
deleted file mode 100644
index eb4cd73e..00000000
Binary files a/vendor/cache/rails-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/rails-8.0.1.gem b/vendor/cache/rails-8.0.1.gem
new file mode 100644
index 00000000..4fbd1905
Binary files /dev/null and b/vendor/cache/rails-8.0.1.gem differ
diff --git a/vendor/cache/rails-i18n-7.0.9.gem b/vendor/cache/rails-i18n-7.0.9.gem
deleted file mode 100644
index f7ebec44..00000000
Binary files a/vendor/cache/rails-i18n-7.0.9.gem and /dev/null differ
diff --git a/vendor/cache/rails-i18n-8.0.1.gem b/vendor/cache/rails-i18n-8.0.1.gem
new file mode 100644
index 00000000..7810b65a
Binary files /dev/null and b/vendor/cache/rails-i18n-8.0.1.gem differ
diff --git a/vendor/cache/railties-7.2.1.gem b/vendor/cache/railties-7.2.1.gem
deleted file mode 100644
index 57fadea8..00000000
Binary files a/vendor/cache/railties-7.2.1.gem and /dev/null differ
diff --git a/vendor/cache/railties-8.0.1.gem b/vendor/cache/railties-8.0.1.gem
new file mode 100644
index 00000000..d2b3eb90
Binary files /dev/null and b/vendor/cache/railties-8.0.1.gem differ
diff --git a/vendor/cache/websocket-driver-0.7.6.gem b/vendor/cache/websocket-driver-0.7.6.gem
deleted file mode 100644
index 920a3969..00000000
Binary files a/vendor/cache/websocket-driver-0.7.6.gem and /dev/null differ
diff --git a/vendor/cache/websocket-driver-0.7.7.gem b/vendor/cache/websocket-driver-0.7.7.gem
new file mode 100644
index 00000000..94be347e
Binary files /dev/null and b/vendor/cache/websocket-driver-0.7.7.gem differ