diff --git a/README.md b/README.md
index 3d4ba2f12..0e313d9e1 100644
--- a/README.md
+++ b/README.md
@@ -213,6 +213,26 @@ It's also easy for admins to [add their own custom themes](https://docs.gotosoci
Sunset
+
+
+ Hacker dark
+
+
+
+
+ Hacker light
+
+
+
+
+ Programmer socks dark
+
+
+
+
+ Programmer socks light
+
+
### Easy to run
diff --git a/docs/overrides/public/theme-hacker-dark.png b/docs/overrides/public/theme-hacker-dark.png
new file mode 100644
index 000000000..e2ba6ced3
Binary files /dev/null and b/docs/overrides/public/theme-hacker-dark.png differ
diff --git a/docs/overrides/public/theme-hacker-light.png b/docs/overrides/public/theme-hacker-light.png
new file mode 100644
index 000000000..38c780503
Binary files /dev/null and b/docs/overrides/public/theme-hacker-light.png differ
diff --git a/docs/overrides/public/theme-programmer-socks-dark.png b/docs/overrides/public/theme-programmer-socks-dark.png
new file mode 100644
index 000000000..7a0b82b4a
Binary files /dev/null and b/docs/overrides/public/theme-programmer-socks-dark.png differ
diff --git a/docs/overrides/public/theme-programmer-socks-light.png b/docs/overrides/public/theme-programmer-socks-light.png
new file mode 100644
index 000000000..d834e31e0
Binary files /dev/null and b/docs/overrides/public/theme-programmer-socks-light.png differ
diff --git a/web/assets/themes/hacker-auto.css b/web/assets/themes/hacker-auto.css
new file mode 100644
index 000000000..44db6a2ff
--- /dev/null
+++ b/web/assets/themes/hacker-auto.css
@@ -0,0 +1,10 @@
+/*
+ theme-title: Hacker (auto)
+ theme-description: Monospace theme with green highlights (adapts to system light/dark preferences)
+*/
+
+/* Default to dark theme */
+@import url("hacker-dark.css");
+
+@import url("hacker-light.css") screen and (prefers-color-scheme: light);
+@import url("hacker-dark.css") screen and (prefers-color-scheme: dark);
diff --git a/web/assets/themes/hacker-dark.css b/web/assets/themes/hacker-dark.css
new file mode 100644
index 000000000..c01f4b075
--- /dev/null
+++ b/web/assets/themes/hacker-dark.css
@@ -0,0 +1,136 @@
+/*
+ theme-title: Hacker dark
+ theme-description: Dark gray and green monospace theme
+*/
+
+:root {
+ /* Define our cool hacker color palette, I'm in. */
+ --dark-gray: #1b1b1b;
+ --medium-gray: #282828;
+ --light-gray: #8a8a94;
+ --whiteish: #f8f8f8;
+ --terminal-darker: #398224;
+ --terminal: #419629;
+ --terminal-lighter: #5cc93d;
+
+ /* Overwrite orange trim */
+ --orange2: var(--terminal);
+
+ /* Restyle basic colors to use terminal */
+ --blue1: var(--terminal-darker);
+ --blue2: var(--terminal-lighter);
+ --blue3: var(--terminal-lighter);
+
+ /* Basic page styling (background + foreground) */
+ --bg: var(--dark-gray);
+ --bg-accent: var(--medium-gray);
+ --fg: var(--whiteish);
+ --fg-reduced: var(--light-gray);
+
+ /* Profile page styling */
+ --profile-bg: var(--medium-gray);
+
+ /* Hackerize buttons */
+ --button-bg: var(--terminal-darker);
+ --button-fg: var(--whiteish);
+
+ /* Hackerize statuses */
+ --status-bg: var(--medium-gray);
+ --status-focus-bg: var(--medium-gray);
+ --status-info-bg: var(--dark-gray);
+ --status-focus-info-bg: var(--dark-gray);
+
+ /* Used around statuses + other items */
+ --boxshadow-border: 0.15rem solid black;
+
+ /* Straighten borders */
+ --br: 0;
+ --br-inner: 0;
+}
+
+/* Scroll bar + main font */
+html, body {
+ font-family: 'Noto Sans Mono', monospace;
+ scrollbar-color: var(--terminal-lighter) var(--medium-gray);
+}
+
+/* Buttons font */
+button, .button,
+.status .text-spoiler > summary .button {
+ font-family: 'Noto Sans Mono', monospace;
+}
+
+/* Column headers */
+.col-header {
+ border: var(--boxshadow-border);
+}
+.profile .about-user .col-header {
+ border-bottom: none;
+ margin-bottom: 0;
+}
+
+.profile .profile-header {
+ border: var(--boxshadow-border);
+}
+
+/* Fiddle around with borders on about sections */
+.profile .about-user .fields,
+.profile .about-user .bio,
+.profile .about-user .accountstats {
+ border-left: var(--boxshadow-border);
+ border-right: var(--boxshadow-border);
+}
+.profile .about-user .accountstats {
+ border-bottom: var(--boxshadow-border);
+}
+
+.profile .about-user .fields {
+ padding-top: 0;
+}
+
+/* Profile fields */
+.profile .about-user .fields .field {
+ border-bottom: var(--boxshadow-border);
+}
+.profile .about-user .fields .field:first-child {
+ border-top: var(--boxshadow-border);
+}
+
+/* Profile fields */
+.profile .about-user .fields .field {
+ border-bottom: var(--boxshadow-border);
+}
+.profile .about-user .fields .field:first-child {
+ border-top: var(--boxshadow-border);
+}
+
+/* Status media */
+.status .media .media-wrapper {
+ border: var(--boxshadow-border);
+ background: var(--dark-gray);
+}
+.status .media .media-wrapper details .unknown-attachment .placeholder {
+ color: var(--whiteish);
+}
+
+/* Status polls */
+.status .text .poll {
+ background-color: var(--dark-gray);
+ border: var(--boxshadow-border);
+}
+.status .text .poll .poll-info {
+ background-color: var(--medium-gray);
+}
+
+/* Code snippets */
+pre, pre[class*="language-"],
+code, code[class*="language-"] {
+ background: var(--dark-gray);
+ color: var(--whiteish);
+}
+
+/* Block quotes */
+blockquote {
+ background-color: var(--dark-gray);
+ color: var(--whiteish);
+}
diff --git a/web/assets/themes/hacker-light.css b/web/assets/themes/hacker-light.css
new file mode 100644
index 000000000..4c20587bc
--- /dev/null
+++ b/web/assets/themes/hacker-light.css
@@ -0,0 +1,136 @@
+/*
+ theme-title: Hacker light
+ theme-description: Light gray and green monospace theme
+*/
+
+:root {
+ /* Define our cool hacker color palette, I'm in. */
+ --dark-gray: #1b1b1b;
+ --medium-gray: #282828;
+ --light-gray: #d7d7e4;
+ --whiteish: #f8f8f8;
+ --terminal-darker: #327220;
+ --terminal: #347922;
+ --terminal-lighter: #53b638;
+
+ /* Overwrite orange trim */
+ --orange2: var(--terminal);
+
+ /* Restyle basic colors to use terminal */
+ --blue1: var(--terminal);
+ --blue2: var(--terminal);
+ --blue3: var(--terminal-darker);
+
+ /* Basic page styling (background + foreground) */
+ --bg: var(--whiteish);
+ --bg-accent: var(--light-gray);
+ --fg: var(--dark-gray);
+ --fg-reduced: var(--medium-gray);
+
+ /* Profile page styling */
+ --profile-bg: var(--whiteish);
+
+ /* Hackerize buttons */
+ --button-bg: var(--terminal-lighter);
+ --button-fg: var(--dark-gray);
+
+ /* Hackerize statuses */
+ --status-bg: var(--whiteish);
+ --status-focus-bg: var(--whiteish);
+ --status-info-bg: var(--light-gray);
+ --status-focus-info-bg: var(--light-gray);
+
+ /* Used around statuses + other items */
+ --boxshadow-border: 0.15rem solid black;
+
+ /* Straighten borders */
+ --br: 0;
+ --br-inner: 0;
+}
+
+/* Scroll bar + main font */
+html, body {
+ font-family: 'Noto Sans Mono', monospace;
+ scrollbar-color: var(--terminal-lighter) var(--medium-gray);
+}
+
+/* Buttons font */
+button, .button,
+.status .text-spoiler > summary .button {
+ font-family: 'Noto Sans Mono', monospace;
+}
+
+/* Column headers */
+.col-header {
+ border: var(--boxshadow-border);
+}
+.profile .about-user .col-header {
+ border-bottom: none;
+ margin-bottom: 0;
+}
+
+.profile .profile-header {
+ border: var(--boxshadow-border);
+}
+
+/* Fiddle around with borders on about sections */
+.profile .about-user .fields,
+.profile .about-user .bio,
+.profile .about-user .accountstats {
+ border-left: var(--boxshadow-border);
+ border-right: var(--boxshadow-border);
+}
+.profile .about-user .accountstats {
+ border-bottom: var(--boxshadow-border);
+}
+
+.profile .about-user .fields {
+ padding-top: 0;
+}
+
+/* Profile fields */
+.profile .about-user .fields .field {
+ border-bottom: var(--boxshadow-border);
+}
+.profile .about-user .fields .field:first-child {
+ border-top: var(--boxshadow-border);
+}
+
+/* Profile fields */
+.profile .about-user .fields .field {
+ border-bottom: var(--boxshadow-border);
+}
+.profile .about-user .fields .field:first-child {
+ border-top: var(--boxshadow-border);
+}
+
+/* Status media */
+.status .media .media-wrapper {
+ border: var(--boxshadow-border);
+ background: var(--light-gray);
+}
+.status .media .media-wrapper details .unknown-attachment .placeholder {
+ color: var(--dark-gray);
+}
+
+/* Status polls */
+.status .text .poll {
+ background-color: var(--light-gray);
+ border: var(--boxshadow-border);
+}
+.status .text .poll .poll-info {
+ background-color: var(--whiteish);
+}
+
+/* Code snippets */
+pre, pre[class*="language-"],
+code, code[class*="language-"] {
+ background: var(--dark-gray);
+ color: var(--whiteish);
+}
+
+/* Block quotes */
+blockquote {
+ background-color: var(--light-gray);
+ color: var(--dark-gray);
+}
diff --git a/web/assets/themes/programmer-socks-auto.css b/web/assets/themes/programmer-socks-auto.css
new file mode 100644
index 000000000..6fd887eb0
--- /dev/null
+++ b/web/assets/themes/programmer-socks-auto.css
@@ -0,0 +1,10 @@
+/*
+ theme-title: Programmer socks (auto)
+ theme-description: Monospace theme with pink highlights (adapts to system light/dark preferences)
+*/
+
+/* Default to dark theme */
+@import url("programmer-socks-dark.css");
+
+@import url("programmer-socks-light.css") screen and (prefers-color-scheme: light);
+@import url("programmer-socks-dark.css") screen and (prefers-color-scheme: dark);
diff --git a/web/assets/themes/programmer-socks-dark.css b/web/assets/themes/programmer-socks-dark.css
new file mode 100644
index 000000000..2e1b566ed
--- /dev/null
+++ b/web/assets/themes/programmer-socks-dark.css
@@ -0,0 +1,136 @@
+/*
+ theme-title: Programmer socks dark
+ theme-description: Dark gray and pink theme
+*/
+
+:root {
+ /* Define our cool hacker color palette, I'm in. */
+ --dark-gray: #1b1b1b;
+ --medium-gray: #282828;
+ --light-gray: #948a94;
+ --whiteish: #f8f8f8;
+ --terminal-darker: #b434ae;
+ --terminal: #cc39cc;
+ --terminal-lighter: #ef46f5;
+
+ /* Overwrite orange trim */
+ --orange2: var(--terminal);
+
+ /* Restyle basic colors to use terminal */
+ --blue1: var(--terminal-darker);
+ --blue2: var(--terminal-lighter);
+ --blue3: var(--terminal-lighter);
+
+ /* Basic page styling (background + foreground) */
+ --bg: var(--dark-gray);
+ --bg-accent: var(--medium-gray);
+ --fg: var(--whiteish);
+ --fg-reduced: var(--light-gray);
+
+ /* Profile page styling */
+ --profile-bg: var(--medium-gray);
+
+ /* Hackerize buttons */
+ --button-bg: var(--terminal-darker);
+ --button-fg: var(--whiteish);
+
+ /* Hackerize statuses */
+ --status-bg: var(--medium-gray);
+ --status-focus-bg: var(--medium-gray);
+ --status-info-bg: var(--dark-gray);
+ --status-focus-info-bg: var(--dark-gray);
+
+ /* Used around statuses + other items */
+ --boxshadow-border: 0.15rem solid var(--terminal-darker);
+
+ /* Straighten borders */
+ --br: 0;
+ --br-inner: 0;
+}
+
+/* Scroll bar + main font */
+html, body {
+ font-family: 'Noto Sans Mono', monospace;
+ scrollbar-color: var(--terminal-lighter) var(--medium-gray);
+}
+
+/* Buttons font */
+button, .button,
+.status .text-spoiler > summary .button {
+ font-family: 'Noto Sans Mono', monospace;
+}
+
+/* Column headers */
+.col-header {
+ border: var(--boxshadow-border);
+}
+.profile .about-user .col-header {
+ border-bottom: none;
+ margin-bottom: 0;
+}
+
+.profile .profile-header {
+ border: var(--boxshadow-border);
+}
+
+/* Fiddle around with borders on about sections */
+.profile .about-user .fields,
+.profile .about-user .bio,
+.profile .about-user .accountstats {
+ border-left: var(--boxshadow-border);
+ border-right: var(--boxshadow-border);
+}
+.profile .about-user .accountstats {
+ border-bottom: var(--boxshadow-border);
+}
+
+.profile .about-user .fields {
+ padding-top: 0;
+}
+
+/* Profile fields */
+.profile .about-user .fields .field {
+ border-bottom: var(--boxshadow-border);
+}
+.profile .about-user .fields .field:first-child {
+ border-top: var(--boxshadow-border);
+}
+
+/* Profile fields */
+.profile .about-user .fields .field {
+ border-bottom: var(--boxshadow-border);
+}
+.profile .about-user .fields .field:first-child {
+ border-top: var(--boxshadow-border);
+}
+
+/* Status media */
+.status .media .media-wrapper {
+ border: var(--boxshadow-border);
+ background: var(--dark-gray);
+}
+.status .media .media-wrapper details .unknown-attachment .placeholder {
+ color: var(--whiteish);
+}
+
+/* Status polls */
+.status .text .poll {
+ background-color: var(--dark-gray);
+ border: var(--boxshadow-border);
+}
+.status .text .poll .poll-info {
+ background-color: var(--medium-gray);
+}
+
+/* Code snippets */
+pre, pre[class*="language-"],
+code, code[class*="language-"] {
+ background: var(--dark-gray);
+ color: var(--whiteish);
+}
+
+/* Block quotes */
+blockquote {
+ background-color: var(--dark-gray);
+ color: var(--whiteish);
+}
diff --git a/web/assets/themes/programmer-socks-light.css b/web/assets/themes/programmer-socks-light.css
new file mode 100644
index 000000000..6a3d6cbb2
--- /dev/null
+++ b/web/assets/themes/programmer-socks-light.css
@@ -0,0 +1,136 @@
+/*
+ theme-title: Programmer socks light
+ theme-description: Light gray and pink theme
+*/
+
+:root {
+ /* Define our cool hacker color palette, I'm in. */
+ --dark-gray: #1b1b1b;
+ --medium-gray: #282828;
+ --light-gray: #e4d7e3;
+ --whiteish: #f8f8f8;
+ --terminal-darker: #ac30ac;
+ --terminal: #c43abd;
+ --terminal-lighter: #eb48e2;
+
+ /* Overwrite orange trim */
+ --orange2: var(--terminal);
+
+ /* Restyle basic colors to use terminal */
+ --blue1: var(--terminal);
+ --blue2: var(--terminal);
+ --blue3: var(--terminal-darker);
+
+ /* Basic page styling (background + foreground) */
+ --bg: var(--whiteish);
+ --bg-accent: var(--light-gray);
+ --fg: var(--dark-gray);
+ --fg-reduced: var(--medium-gray);
+
+ /* Profile page styling */
+ --profile-bg: var(--whiteish);
+
+ /* Hackerize buttons */
+ --button-bg: var(--terminal-lighter);
+ --button-fg: var(--dark-gray);
+
+ /* Hackerize statuses */
+ --status-bg: var(--whiteish);
+ --status-focus-bg: var(--whiteish);
+ --status-info-bg: var(--light-gray);
+ --status-focus-info-bg: var(--light-gray);
+
+ /* Used around statuses + other items */
+ --boxshadow-border: 0.15rem solid var(--terminal-darker);
+
+ /* Straighten borders */
+ --br: 0;
+ --br-inner: 0;
+}
+
+/* Scroll bar + main font */
+html, body {
+ font-family: 'Noto Sans Mono', monospace;
+ scrollbar-color: var(--terminal-lighter) var(--medium-gray);
+}
+
+/* Buttons font */
+button, .button,
+.status .text-spoiler > summary .button {
+ font-family: 'Noto Sans Mono', monospace;
+}
+
+/* Column headers */
+.col-header {
+ border: var(--boxshadow-border);
+}
+.profile .about-user .col-header {
+ border-bottom: none;
+ margin-bottom: 0;
+}
+
+.profile .profile-header {
+ border: var(--boxshadow-border);
+}
+
+/* Fiddle around with borders on about sections */
+.profile .about-user .fields,
+.profile .about-user .bio,
+.profile .about-user .accountstats {
+ border-left: var(--boxshadow-border);
+ border-right: var(--boxshadow-border);
+}
+.profile .about-user .accountstats {
+ border-bottom: var(--boxshadow-border);
+}
+
+.profile .about-user .fields {
+ padding-top: 0;
+}
+
+/* Profile fields */
+.profile .about-user .fields .field {
+ border-bottom: var(--boxshadow-border);
+}
+.profile .about-user .fields .field:first-child {
+ border-top: var(--boxshadow-border);
+}
+
+/* Profile fields */
+.profile .about-user .fields .field {
+ border-bottom: var(--boxshadow-border);
+}
+.profile .about-user .fields .field:first-child {
+ border-top: var(--boxshadow-border);
+}
+
+/* Status media */
+.status .media .media-wrapper {
+ border: var(--boxshadow-border);
+ background: var(--light-gray);
+}
+.status .media .media-wrapper details .unknown-attachment .placeholder {
+ color: var(--dark-gray);
+}
+
+/* Status polls */
+.status .text .poll {
+ background-color: var(--light-gray);
+ border: var(--boxshadow-border);
+}
+.status .text .poll .poll-info {
+ background-color: var(--whiteish);
+}
+
+/* Code snippets */
+pre, pre[class*="language-"],
+code, code[class*="language-"] {
+ background: var(--dark-gray);
+ color: var(--whiteish);
+}
+
+/* Block quotes */
+blockquote {
+ background-color: var(--light-gray);
+ color: var(--dark-gray);
+}