diff --git a/data/static/badges/link-bsky.webp b/data/static/badges/link-bsky.webp
new file mode 100644
index 0000000..0897694
Binary files /dev/null and b/data/static/badges/link-bsky.webp differ
diff --git a/data/static/badges/link-itch-io.webp b/data/static/badges/link-itch-io.webp
new file mode 100644
index 0000000..ff10977
Binary files /dev/null and b/data/static/badges/link-itch-io.webp differ
diff --git a/data/static/badges/link-mastodon.webp b/data/static/badges/link-mastodon.webp
new file mode 100644
index 0000000..2b88203
Binary files /dev/null and b/data/static/badges/link-mastodon.webp differ
diff --git a/data/static/badges/link-www.webp b/data/static/badges/link-www.webp
new file mode 100644
index 0000000..74b6639
Binary files /dev/null and b/data/static/badges/link-www.webp differ
diff --git a/data/static/badges/pride-asexual.webp b/data/static/badges/pride-asexual.webp
new file mode 100644
index 0000000..7f68ac5
Binary files /dev/null and b/data/static/badges/pride-asexual.webp differ
diff --git a/data/static/badges/pride-intersex.webp b/data/static/badges/pride-intersex.webp
new file mode 100644
index 0000000..bb30453
Binary files /dev/null and b/data/static/badges/pride-intersex.webp differ
diff --git a/data/static/badges/pride-lesbian.webp b/data/static/badges/pride-lesbian.webp
new file mode 100644
index 0000000..6414cd0
Binary files /dev/null and b/data/static/badges/pride-lesbian.webp differ
diff --git a/data/static/badges/pride-nonbinary.webp b/data/static/badges/pride-nonbinary.webp
new file mode 100644
index 0000000..4714289
Binary files /dev/null and b/data/static/badges/pride-nonbinary.webp differ
diff --git a/data/static/badges/pride-progress.webp b/data/static/badges/pride-progress.webp
new file mode 100644
index 0000000..1f3320b
Binary files /dev/null and b/data/static/badges/pride-progress.webp differ
diff --git a/data/static/badges/pride-six.webp b/data/static/badges/pride-six.webp
new file mode 100644
index 0000000..b9532b5
Binary files /dev/null and b/data/static/badges/pride-six.webp differ
diff --git a/data/static/badges/pride-trans.webp b/data/static/badges/pride-trans.webp
new file mode 100644
index 0000000..e6267d9
Binary files /dev/null and b/data/static/badges/pride-trans.webp differ
diff --git a/data/static/badges/pronoun-any-all.webp b/data/static/badges/pronoun-any-all.webp
new file mode 100644
index 0000000..62893e5
Binary files /dev/null and b/data/static/badges/pronoun-any-all.webp differ
diff --git a/data/static/badges/pronoun-fae-faer.webp b/data/static/badges/pronoun-fae-faer.webp
new file mode 100644
index 0000000..13c9638
Binary files /dev/null and b/data/static/badges/pronoun-fae-faer.webp differ
diff --git a/data/static/badges/pronoun-he-him.webp b/data/static/badges/pronoun-he-him.webp
new file mode 100644
index 0000000..455de56
Binary files /dev/null and b/data/static/badges/pronoun-he-him.webp differ
diff --git a/data/static/badges/pronoun-it-its.webp b/data/static/badges/pronoun-it-its.webp
new file mode 100644
index 0000000..6bd3368
Binary files /dev/null and b/data/static/badges/pronoun-it-its.webp differ
diff --git a/data/static/badges/pronoun-no-pronouns.webp b/data/static/badges/pronoun-no-pronouns.webp
new file mode 100644
index 0000000..26f049b
Binary files /dev/null and b/data/static/badges/pronoun-no-pronouns.webp differ
diff --git a/data/static/badges/pronoun-she-her.webp b/data/static/badges/pronoun-she-her.webp
new file mode 100644
index 0000000..b17dfee
Binary files /dev/null and b/data/static/badges/pronoun-she-her.webp differ
diff --git a/data/static/badges/pronoun-they-them.webp b/data/static/badges/pronoun-they-them.webp
new file mode 100644
index 0000000..5c8f42c
Binary files /dev/null and b/data/static/badges/pronoun-they-them.webp differ
diff --git a/data/static/badges/pronoun-xe-xem.webp b/data/static/badges/pronoun-xe-xem.webp
new file mode 100644
index 0000000..1bbf9c0
Binary files /dev/null and b/data/static/badges/pronoun-xe-xem.webp differ
diff --git a/data/static/badges/pronoun-xe-xir.webp b/data/static/badges/pronoun-xe-xir.webp
new file mode 100644
index 0000000..babe62b
Binary files /dev/null and b/data/static/badges/pronoun-xe-xir.webp differ
diff --git a/data/static/css/style.css b/data/static/css/style.css
index 59de496..0dd3641 100644
--- a/data/static/css/style.css
+++ b/data/static/css/style.css
@@ -60,10 +60,11 @@ body {
color: black;
}
-a:link {
+:where(a:link) {
color: #c11c1c;
}
-a:visited {
+
+:where(a:visited) {
color: #730c0c;
}
@@ -116,7 +117,7 @@ a:visited {
font-size: 3rem;
margin: 0 20px;
text-decoration: none;
- color: black !important;
+ color: black;
}
.thread-title {
@@ -133,7 +134,7 @@ a:visited {
.post {
display: grid;
- grid-template-columns: 200px 1fr;
+ grid-template-columns: 230px 1fr;
grid-template-rows: 1fr;
gap: 0;
grid-auto-flow: row;
@@ -710,7 +711,7 @@ blockquote {
button, input[type=submit], .linkbutton {
display: inline-block;
background-color: rgb(177, 206, 204.5);
- color: black !important;
+ color: black;
}
button:hover, input[type=submit]:hover, .linkbutton:hover {
background-color: rgb(192.6, 215.8, 214.6);
@@ -731,7 +732,7 @@ button.icon, input[type=submit].icon, .linkbutton.icon {
}
button.critical, input[type=submit].critical, .linkbutton.critical {
background-color: red;
- color: white !important;
+ color: white;
}
button.critical:hover, input[type=submit].critical:hover, .linkbutton.critical:hover {
background-color: #ff3333;
@@ -752,7 +753,7 @@ button.critical.icon, input[type=submit].critical.icon, .linkbutton.critical.ico
}
button.warn, input[type=submit].warn, .linkbutton.warn {
background-color: #fbfb8d;
- color: black !important;
+ color: black;
}
button.warn:hover, input[type=submit].warn:hover, .linkbutton.warn:hover {
background-color: rgb(251.8, 251.8, 163.8);
@@ -774,7 +775,7 @@ button.warn.icon, input[type=submit].warn.icon, .linkbutton.warn.icon {
input[type=file]::file-selector-button {
background-color: rgb(177, 206, 204.5);
- color: black !important;
+ color: black;
}
input[type=file]::file-selector-button:hover {
background-color: rgb(192.6, 215.8, 214.6);
@@ -803,7 +804,7 @@ p {
.pagebutton {
background-color: rgb(177, 206, 204.5);
- color: black !important;
+ color: black;
}
.pagebutton:hover {
background-color: rgb(192.6, 215.8, 214.6);
@@ -963,10 +964,6 @@ textarea {
gap: 5px;
}
-.thread-info-bookmark-button {
- margin-left: auto !important;
-}
-
.thread-info-post-preview {
overflow: hidden;
text-overflow: ellipsis;
@@ -1131,7 +1128,7 @@ textarea {
.tab-button {
background-color: rgb(177, 206, 204.5);
- color: black !important;
+ color: black;
}
.tab-button:hover {
background-color: rgb(192.6, 215.8, 214.6);
@@ -1292,7 +1289,7 @@ footer {
.reaction-button.active {
background-color: #beb1ce;
- color: black !important;
+ color: black;
}
.reaction-button.active:hover {
background-color: rgb(203, 192.6, 215.8);
@@ -1473,3 +1470,56 @@ a.mention:hover, a.mention:visited:hover {
h1 {
margin: 0;
}
+
+.settings-badge-container {
+ display: flex;
+ align-items: baseline;
+ gap: 5px;
+ border: 1px solid black;
+ border-radius: 4px;
+ padding: 5px 10px;
+ margin: 10px 0;
+}
+.settings-badge-container:has(input:invalid) {
+ border: 2px dashed red;
+}
+.settings-badge-container input:invalid {
+ border: 2px dashed red;
+}
+
+.settings-badge-file-picker {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+.settings-badge-file-picker input.hidden[type=file] {
+ width: 100%;
+}
+.settings-badge-file-picker input.hidden[type=file]::file-selector-button {
+ display: none;
+}
+.settings-badge-file-picker.hidden {
+ display: none;
+}
+
+.settings-badge-select {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ align-items: center;
+ min-width: 200px;
+}
+
+img.badge-button {
+ min-width: 88px;
+ min-height: 31px;
+ max-width: 88px;
+ max-height: 31px;
+}
+
+.badges-container {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 5px;
+}
diff --git a/data/static/css/theme-otomotone.css b/data/static/css/theme-otomotone.css
index c647df0..fbf958e 100644
--- a/data/static/css/theme-otomotone.css
+++ b/data/static/css/theme-otomotone.css
@@ -60,10 +60,11 @@ body {
color: #e6e6e6;
}
-a:link {
+:where(a:link) {
color: #e87fe1;
}
-a:visited {
+
+:where(a:visited) {
color: #ed4fb1;
}
@@ -116,7 +117,7 @@ a:visited {
font-size: 3rem;
margin: 0 20px;
text-decoration: none;
- color: white !important;
+ color: white;
}
.thread-title {
@@ -133,7 +134,7 @@ a:visited {
.post {
display: grid;
- grid-template-columns: 200px 1fr;
+ grid-template-columns: 230px 1fr;
grid-template-rows: 1fr;
gap: 0;
grid-auto-flow: row;
@@ -710,7 +711,7 @@ blockquote {
button, input[type=submit], .linkbutton {
display: inline-block;
background-color: #3c283c;
- color: #e6e6e6 !important;
+ color: #e6e6e6;
}
button:hover, input[type=submit]:hover, .linkbutton:hover {
background-color: rgb(109.2, 72.8, 109.2);
@@ -731,7 +732,7 @@ button.icon, input[type=submit].icon, .linkbutton.icon {
}
button.critical, input[type=submit].critical, .linkbutton.critical {
background-color: #d53232;
- color: #e6e6e6 !important;
+ color: #e6e6e6;
}
button.critical:hover, input[type=submit].critical:hover, .linkbutton.critical:hover {
background-color: rgb(221.4, 91, 91);
@@ -752,7 +753,7 @@ button.critical.icon, input[type=submit].critical.icon, .linkbutton.critical.ico
}
button.warn, input[type=submit].warn, .linkbutton.warn {
background-color: #eaea6a;
- color: black !important;
+ color: black;
}
button.warn:hover, input[type=submit].warn:hover, .linkbutton.warn:hover {
background-color: rgb(238.2, 238.2, 135.8);
@@ -774,7 +775,7 @@ button.warn.icon, input[type=submit].warn.icon, .linkbutton.warn.icon {
input[type=file]::file-selector-button {
background-color: #3c283c;
- color: #e6e6e6 !important;
+ color: #e6e6e6;
}
input[type=file]::file-selector-button:hover {
background-color: rgb(109.2, 72.8, 109.2);
@@ -803,7 +804,7 @@ p {
.pagebutton {
background-color: #3c283c;
- color: #e6e6e6 !important;
+ color: #e6e6e6;
}
.pagebutton:hover {
background-color: rgb(109.2, 72.8, 109.2);
@@ -963,10 +964,6 @@ textarea {
gap: 5px;
}
-.thread-info-bookmark-button {
- margin-left: auto !important;
-}
-
.thread-info-post-preview {
overflow: hidden;
text-overflow: ellipsis;
@@ -1131,7 +1128,7 @@ textarea {
.tab-button {
background-color: #3c283c;
- color: #e6e6e6 !important;
+ color: #e6e6e6;
}
.tab-button:hover {
background-color: rgb(109.2, 72.8, 109.2);
@@ -1292,7 +1289,7 @@ footer {
.reaction-button.active {
background-color: #8a5584;
- color: #e6e6e6 !important;
+ color: #e6e6e6;
}
.reaction-button.active:hover {
background-color: rgb(167.4843049327, 112.9156950673, 161.3067264574);
@@ -1474,6 +1471,59 @@ h1 {
margin: 0;
}
+.settings-badge-container {
+ display: flex;
+ align-items: baseline;
+ gap: 5px;
+ border: 1px solid black;
+ border-radius: 8px;
+ padding: 5px 10px;
+ margin: 10px 0;
+}
+.settings-badge-container:has(input:invalid) {
+ border: 2px dashed red;
+}
+.settings-badge-container input:invalid {
+ border: 2px dashed red;
+}
+
+.settings-badge-file-picker {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+.settings-badge-file-picker input.hidden[type=file] {
+ width: 100%;
+}
+.settings-badge-file-picker input.hidden[type=file]::file-selector-button {
+ display: none;
+}
+.settings-badge-file-picker.hidden {
+ display: none;
+}
+
+.settings-badge-select {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ align-items: center;
+ min-width: 200px;
+}
+
+img.badge-button {
+ min-width: 88px;
+ min-height: 31px;
+ max-width: 88px;
+ max-height: 31px;
+}
+
+.badges-container {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 5px;
+}
+
#topnav {
margin-bottom: 10px;
border: 10px solid rgb(40, 40, 40);
diff --git a/data/static/css/theme-peachy.css b/data/static/css/theme-peachy.css
index ade51cb..840e6af 100644
--- a/data/static/css/theme-peachy.css
+++ b/data/static/css/theme-peachy.css
@@ -60,10 +60,11 @@ body {
color: black;
}
-a:link {
+:where(a:link) {
color: black;
}
-a:visited {
+
+:where(a:visited) {
color: black;
}
@@ -116,7 +117,7 @@ a:visited {
font-size: 3rem;
margin: 0 12px;
text-decoration: none;
- color: black !important;
+ color: black;
}
.thread-title {
@@ -133,7 +134,7 @@ a:visited {
.post {
display: grid;
- grid-template-columns: 200px 1fr;
+ grid-template-columns: 230px 1fr;
grid-template-rows: 1fr;
gap: 0;
grid-auto-flow: row;
@@ -710,7 +711,7 @@ blockquote {
button, input[type=submit], .linkbutton {
display: inline-block;
background-color: #f27a5a;
- color: black !important;
+ color: black;
}
button:hover, input[type=submit]:hover, .linkbutton:hover {
background-color: rgb(244.6, 148.6, 123);
@@ -731,7 +732,7 @@ button.icon, input[type=submit].icon, .linkbutton.icon {
}
button.critical, input[type=submit].critical, .linkbutton.critical {
background-color: #f73030;
- color: white !important;
+ color: white;
}
button.critical:hover, input[type=submit].critical:hover, .linkbutton.critical:hover {
background-color: rgb(248.6, 89.4, 89.4);
@@ -752,7 +753,7 @@ button.critical.icon, input[type=submit].critical.icon, .linkbutton.critical.ico
}
button.warn, input[type=submit].warn, .linkbutton.warn {
background-color: #fbfb8d;
- color: black !important;
+ color: black;
}
button.warn:hover, input[type=submit].warn:hover, .linkbutton.warn:hover {
background-color: rgb(251.8, 251.8, 163.8);
@@ -774,7 +775,7 @@ button.warn.icon, input[type=submit].warn.icon, .linkbutton.warn.icon {
input[type=file]::file-selector-button {
background-color: #f27a5a;
- color: black !important;
+ color: black;
}
input[type=file]::file-selector-button:hover {
background-color: rgb(244.6, 148.6, 123);
@@ -803,7 +804,7 @@ p {
.pagebutton {
background-color: #f27a5a;
- color: black !important;
+ color: black;
}
.pagebutton:hover {
background-color: rgb(244.6, 148.6, 123);
@@ -963,10 +964,6 @@ textarea {
gap: 3px;
}
-.thread-info-bookmark-button {
- margin-left: auto !important;
-}
-
.thread-info-post-preview {
overflow: hidden;
text-overflow: ellipsis;
@@ -1131,7 +1128,7 @@ textarea {
.tab-button {
background-color: #f27a5a;
- color: black !important;
+ color: black;
}
.tab-button:hover {
background-color: rgb(244.6, 148.6, 123);
@@ -1292,7 +1289,7 @@ footer {
.reaction-button.active {
background-color: #b54444;
- color: white !important;
+ color: white;
}
.reaction-button.active:hover {
background-color: rgb(197.978313253, 103.221686747, 103.221686747);
@@ -1474,14 +1471,65 @@ h1 {
margin: 0;
}
+.settings-badge-container {
+ display: flex;
+ align-items: baseline;
+ gap: 3px;
+ border: 1px solid black;
+ border-radius: 16px;
+ padding: 3px 6px;
+ margin: 6px 0;
+}
+.settings-badge-container:has(input:invalid) {
+ border: 2px dashed red;
+}
+.settings-badge-container input:invalid {
+ border: 2px dashed red;
+}
+
+.settings-badge-file-picker {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+.settings-badge-file-picker input.hidden[type=file] {
+ width: 100%;
+}
+.settings-badge-file-picker input.hidden[type=file]::file-selector-button {
+ display: none;
+}
+.settings-badge-file-picker.hidden {
+ display: none;
+}
+
+.settings-badge-select {
+ display: flex;
+ flex-direction: column;
+ gap: 3px;
+ align-items: center;
+ min-width: 200px;
+}
+
+img.badge-button {
+ min-width: 88px;
+ min-height: 31px;
+ max-width: 88px;
+ max-height: 31px;
+}
+
+.badges-container {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 3px;
+}
+
#topnav {
border-top-left-radius: 16px;
border-top-right-radius: 16px;
}
#bottomnav {
- border-bottom-left-radius: 16px;
- border-bottom-right-radius: 16px;
color: white;
}
@@ -1489,9 +1537,10 @@ textarea {
padding: 12px 16px;
}
-footer {
- margin-top: 10px;
+#footer {
border-radius: 16px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
border: none;
text-align: center;
}
diff --git a/data/static/css/theme-snow-white.css b/data/static/css/theme-snow-white.css
index 87399c8..cce6fc6 100644
--- a/data/static/css/theme-snow-white.css
+++ b/data/static/css/theme-snow-white.css
@@ -48,7 +48,7 @@
font-family: "Cadman", sans-serif;
text-decoration: none;
border: 1px solid black;
- border-radius: 8px;
+ border-radius: 4px;
padding: 5px 20px;
margin: 10px 0;
}
@@ -60,10 +60,11 @@ body {
color: black;
}
-a:link {
+:where(a:link) {
color: #711579;
}
-a:visited {
+
+:where(a:visited) {
color: #4a144f;
}
@@ -116,7 +117,7 @@ a:visited {
font-size: 3rem;
margin: 0 20px;
text-decoration: none;
- color: black !important;
+ color: black;
}
.thread-title {
@@ -133,7 +134,7 @@ a:visited {
.post {
display: grid;
- grid-template-columns: 200px 1fr;
+ grid-template-columns: 230px 1fr;
grid-template-rows: 1fr;
gap: 0;
grid-auto-flow: row;
@@ -604,14 +605,14 @@ pre code { /* Literal.Number.Integer.Long */ }
padding: 5px 10px;
display: inline-block;
margin: 4px;
- border-radius: 8px;
+ border-radius: 4px;
font-size: 1rem;
white-space: pre;
}
#delete-dialog, .lightbox-dialog {
padding: 0;
- border-radius: 8px;
+ border-radius: 4px;
border: 2px solid black;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.25);
}
@@ -648,7 +649,7 @@ pre code { /* Literal.Number.Integer.Long */ }
blockquote {
padding: 10px 20px;
margin: 10px;
- border-radius: 8px;
+ border-radius: 4px;
border-left: 10px solid rgb(239.24, 241, 244.36);
background-color: rgba(0, 0, 0, 0.1490196078);
}
@@ -710,7 +711,7 @@ blockquote {
button, input[type=submit], .linkbutton {
display: inline-block;
background-color: #eecee9;
- color: black !important;
+ color: black;
}
button:hover, input[type=submit]:hover, .linkbutton:hover {
background-color: rgb(241.4, 215.8, 237.4);
@@ -731,7 +732,7 @@ button.icon, input[type=submit].icon, .linkbutton.icon {
}
button.critical, input[type=submit].critical, .linkbutton.critical {
background-color: red;
- color: white !important;
+ color: white;
}
button.critical:hover, input[type=submit].critical:hover, .linkbutton.critical:hover {
background-color: #ff3333;
@@ -752,7 +753,7 @@ button.critical.icon, input[type=submit].critical.icon, .linkbutton.critical.ico
}
button.warn, input[type=submit].warn, .linkbutton.warn {
background-color: #fbfb8d;
- color: black !important;
+ color: black;
}
button.warn:hover, input[type=submit].warn:hover, .linkbutton.warn:hover {
background-color: rgb(251.8, 251.8, 163.8);
@@ -774,7 +775,7 @@ button.warn.icon, input[type=submit].warn.icon, .linkbutton.warn.icon {
input[type=file]::file-selector-button {
background-color: #eecee9;
- color: black !important;
+ color: black;
}
input[type=file]::file-selector-button:hover {
background-color: rgb(241.4, 215.8, 237.4);
@@ -803,7 +804,7 @@ p {
.pagebutton {
background-color: #eecee9;
- color: black !important;
+ color: black;
}
.pagebutton:hover {
background-color: rgb(241.4, 215.8, 237.4);
@@ -852,7 +853,7 @@ p {
input[type=text], input[type=password], textarea, select {
border: 1px solid black;
- border-radius: 8px;
+ border-radius: 4px;
padding: 7px 10px;
width: 100%;
resize: vertical;
@@ -963,10 +964,6 @@ textarea {
gap: 5px;
}
-.thread-info-bookmark-button {
- margin-left: auto !important;
-}
-
.thread-info-post-preview {
overflow: hidden;
text-overflow: ellipsis;
@@ -1131,7 +1128,7 @@ textarea {
.tab-button {
background-color: #eecee9;
- color: black !important;
+ color: black;
}
.tab-button:hover {
background-color: rgb(241.4, 215.8, 237.4);
@@ -1170,9 +1167,9 @@ textarea {
background-color: rgb(231.4, 224.9375, 212.6);
border: 1px solid black;
padding: 10px;
- border-top-right-radius: 8px;
- border-bottom-right-radius: 8px;
- border-bottom-left-radius: 8px;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
}
ul, ol {
@@ -1199,7 +1196,7 @@ ul.horizontal li, ol.horizontal li {
border: 1px solid black;
background-color: #81a3e6;
padding: 20px 15px;
- border-radius: 8px;
+ border-radius: 4px;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.25);
}
@@ -1209,8 +1206,8 @@ ul.horizontal li, ol.horizontal li {
}
.accordion {
- border-top-right-radius: 8px;
- border-top-left-radius: 8px;
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
border: 1px solid black;
margin: 10px 5px;
overflow: hidden;
@@ -1281,7 +1278,7 @@ ul.horizontal li, ol.horizontal li {
transform: translateX(-50%);
margin: 0;
border: none;
- border-radius: 8px;
+ border-radius: 4px;
background-color: rgba(0, 0, 0, 0.5019607843);
padding: 5px 10px;
}
@@ -1292,7 +1289,7 @@ footer {
.reaction-button.active {
background-color: #eee3ce;
- color: black !important;
+ color: black;
}
.reaction-button.active:hover {
background-color: rgb(241.4, 232.6, 215.8);
@@ -1316,7 +1313,7 @@ footer {
position: relative;
margin: 0;
border: none;
- border-radius: 8px;
+ border-radius: 4px;
background-color: rgba(0, 0, 0, 0.5019607843);
padding: 5px 10px;
width: 250px;
@@ -1341,7 +1338,7 @@ footer {
.bookmarks-dropdown {
background-color: #ced9ee;
border: 1px solid black;
- border-radius: 8px;
+ border-radius: 4px;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.25);
position: absolute;
margin: 0;
@@ -1359,7 +1356,7 @@ footer {
margin: 10px 0;
cursor: pointer;
border: 1px solid black;
- border-radius: 8px;
+ border-radius: 4px;
color: black;
background-color: #eecee9;
}
@@ -1438,7 +1435,7 @@ a.mention, a.mention:visited {
color: white;
background-color: rgb(136.0836363636, 149.3636363636, 174.7163636364);
padding: 5px;
- border-radius: 8px;
+ border-radius: 4px;
text-decoration: none;
}
a.mention.display, a.mention:visited.display {
@@ -1462,7 +1459,7 @@ a.mention:hover, a.mention:visited:hover {
}
.settings-grid fieldset {
border: 1px solid white;
- border-radius: 8px;
+ border-radius: 4px;
background-color: rgb(187.6595454545, 188.3232954545, 189.5904545455);
}
@@ -1473,3 +1470,56 @@ a.mention:hover, a.mention:visited:hover {
h1 {
margin: 0;
}
+
+.settings-badge-container {
+ display: flex;
+ align-items: baseline;
+ gap: 5px;
+ border: 1px solid black;
+ border-radius: 4px;
+ padding: 5px 10px;
+ margin: 10px 0;
+}
+.settings-badge-container:has(input:invalid) {
+ border: 2px dashed red;
+}
+.settings-badge-container input:invalid {
+ border: 2px dashed red;
+}
+
+.settings-badge-file-picker {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+.settings-badge-file-picker input.hidden[type=file] {
+ width: 100%;
+}
+.settings-badge-file-picker input.hidden[type=file]::file-selector-button {
+ display: none;
+}
+.settings-badge-file-picker.hidden {
+ display: none;
+}
+
+.settings-badge-select {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ align-items: center;
+ min-width: 200px;
+}
+
+img.badge-button {
+ min-width: 88px;
+ min-height: 31px;
+ max-width: 88px;
+ max-height: 31px;
+}
+
+.badges-container {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 5px;
+}
diff --git a/data/static/js/bitties/pyrom-bitty.js b/data/static/js/bitties/pyrom-bitty.js
index c5312e2..e79cc8f 100644
--- a/data/static/js/bitties/pyrom-bitty.js
+++ b/data/static/js/bitties/pyrom-bitty.js
@@ -1,4 +1,5 @@
const bookmarkMenuHrefTemplate = '/hyperapi/bookmarks-dropdown';
+const badgeEditorEndpoint = '/hyperapi/badge-editor';
const previewEndpoint = '/api/babycode-preview';
const userEndpoint = '/api/current-user';
@@ -277,3 +278,200 @@ export default class {
}
}
}
+
+export class BadgeEditorForm {
+ #badgeTemplate = undefined;
+ async loadBadgeEditor(ev, el) {
+ const badges = await this.api.getHTML(badgeEditorEndpoint);
+ if (!badges.value) {
+ return;
+ }
+ if (this.#badgeTemplate === undefined){
+ const badge = await this.api.getHTML(`${badgeEditorEndpoint}/template`)
+ if (!badge.value){
+ return;
+ }
+ this.#badgeTemplate= badge.value;
+ }
+ el.replaceChildren();
+ const addButton = `
Add badge `;
+ const submitButton = `
`;
+ const controls = `
${addButton} ${submitButton} BADGECOUNT/10 `
+ const badgeCount = badges.value.querySelectorAll('.settings-badge-container').length;
+ const subs = [
+ ['BADGECOUNT', badgeCount],
+ ['DISABLE_IF_MAX', badgeCount === 10 ? 'disabled' : ''],
+ ];
+ el.appendChild(this.api.makeHTML(controls, subs));
+ el.appendChild(badges.value);
+ }
+
+ addBadge(ev, el) {
+ if (this.#badgeTemplate === undefined) {
+ return;
+ }
+ const badge = this.#badgeTemplate.cloneNode(true);
+ el.appendChild(badge);
+ this.api.localTrigger('updateBadgeCount');
+ }
+
+ deleteBadge(ev, el) {
+ if (!el.contains(el.sender)) {
+ return;
+ }
+ el.remove();
+ this.api.localTrigger('updateBadgeCount');
+ }
+
+ updateBadgeCount(_ev, el) {
+ const badgeCount = el.parentNode.parentNode.querySelectorAll('.settings-badge-container').length;
+ if (el.dsInt('disableIfMax') === 1) {
+ el.disabled = badgeCount === 10;
+ } else if (el.dsInt('count') === 1) {
+ el.textContent = `${badgeCount}/10`;
+ }
+ }
+
+ badgeEditorPrepareSubmit(ev, el) {
+ if (ev.type !== 'submit') {
+ return;
+ }
+ ev.preventDefault();
+
+ const badges = el.querySelectorAll('.settings-badge-container').length;
+
+ const noUploads = el.querySelectorAll('.settings-badge-file-picker.hidden input[type=file]');
+ noUploads.forEach(e => {
+ e.value = null;
+ })
+ // console.log(noUploads);
+ el.submit();
+ // console.log('would submit now');
+ }
+}
+
+const validateBase64Img = dataURL => new Promise(resolve => {
+ const img = new Image();
+ img.onload = () => {
+ resolve(img.width === 88 && img.height === 31);
+ };
+ img.src = dataURL;
+});
+
+export class BadgeEditorBadge {
+ #badgeCustomImageData = null;
+ badgeUpdatePreview(ev, el) {
+ if (ev.type !== 'change') {
+ return;
+ }
+ // TODO: el.sender doesn't have a bittyParentBittyId
+ const selectBittyParent = el.sender.closest('bitty-7-0');
+ if (el.bittyParentBittyId !== selectBittyParent.dataset.bittyid) {
+ return;
+ }
+
+ if (ev.val === 'custom') {
+ if (this.#badgeCustomImageData) {
+ el.src = this.#badgeCustomImageData;
+ } else {
+ el.removeAttribute('src');
+ }
+ return;
+ }
+ const option = el.sender.selectedOptions[0];
+ el.src = option.dataset.filePath;
+ }
+
+ async badgeUpdatePreviewCustom(ev, el) {
+ if (ev.type !== 'change') {
+ return;
+ }
+ if (el.bittyParentBittyId !== el.sender.bittyParentBittyId) {
+ return;
+ }
+
+ const file = ev.target.files[0];
+ if (file.size >= 1000 * 500) {
+ this.api.trigger('badgeErrorSize');
+ this.#badgeCustomImageData = null;
+ el.removeAttribute('src');
+ return;
+ }
+
+ const reader = new FileReader();
+
+ reader.onload = async e => {
+ const dimsValid = await validateBase64Img(e.target.result);
+ if (!dimsValid) {
+ this.api.trigger('badgeErrorDim');
+ this.#badgeCustomImageData = null;
+ el.removeAttribute('src');
+ return;
+ }
+ this.#badgeCustomImageData = e.target.result;
+ el.src = this.#badgeCustomImageData;
+ this.api.trigger('badgeHideErrors');
+ }
+
+ reader.readAsDataURL(file);
+ }
+
+ badgeToggleFilePicker(ev, el) {
+ if (ev.type !== 'change') {
+ return;
+ }
+ // TODO: el.sender doesn't have a bittyParentBittyId
+ const selectBittyParent = el.sender.closest('bitty-7-0');
+ if (el.bittyParentBittyId !== selectBittyParent.dataset.bittyid) {
+ return;
+ }
+ const filePicker = el.querySelector('input[type=file]');
+ if (ev.val === 'custom') {
+ el.classList.remove('hidden');
+ if (filePicker.dataset.validity) {
+ filePicker.setCustomValidity(filePicker.dataset.validity);
+ }
+ filePicker.required = true;
+ } else {
+ el.classList.add('hidden');
+ filePicker.setCustomValidity('');
+ filePicker.required = false;
+ }
+ }
+
+ openBadgeFilePicker(ev, el) {
+ // TODO: el.sender doesn't have a bittyParentBittyId
+ if (el.sender.parentNode !== el.parentNode) {
+ return;
+ }
+ el.click();
+ }
+
+ badgeErrorSize(_ev, el) {
+ if (el.sender !== el.bittyParent) {
+ return;
+ }
+ const validity = "Image can't be over 500KB."
+ el.dataset.validity = validity;
+ el.setCustomValidity(validity);
+ el.reportValidity();
+ }
+
+ badgeErrorDim(_ev, el) {
+ if (el.sender !== el.bittyParent) {
+ return;
+ }
+ const validity = "Image must be exactly 88x31 pixels."
+ el.dataset.validity = validity;
+ el.setCustomValidity(validity);
+ el.reportValidity();
+ }
+
+ badgeHideErrors(_ev, el) {
+ if (el.sender !== el.bittyParent) {
+ return;
+ }
+ delete el.dataset.validity;
+ el.setCustomValidity('');
+ }
+}
diff --git a/sass/_default.scss b/sass/_default.scss
index ad9de0f..7bba579 100644
--- a/sass/_default.scss
+++ b/sass/_default.scss
@@ -133,7 +133,7 @@ $icon_button_padding_left: $BIG_PADDING - 4px !default;
@mixin button($color, $font_color) {
@extend %button-base;
background-color: $color;
- color: $font_color !important; //!important because linkbutton is an
+ color: $font_color;
&:hover {
background-color: color.scale($color, $lightness: 20%);
@@ -180,13 +180,11 @@ body {
$link_color: #c11c1c !default;
$link_color_visited: #730c0c !default;
-a{
- &:link {
- color: $link_color;
- }
- &:visited {
- color: $link_color_visited;
- }
+:where(a:link){
+ color: $link_color;
+}
+:where(a:visited) {
+ color: $link_color_visited;
}
.big {
@@ -233,7 +231,7 @@ $site_title_color: $DEFAULT_FONT_COLOR !default;
font-size: $site_title_size;
margin: $site_title_margin;
text-decoration: none;
- color: $site_title_color !important;
+ color: $site_title_color;
}
$thread_title_margin: $ZERO_PADDING !default;
@@ -251,7 +249,7 @@ $thread_actions_gap: $SMALL_PADDING !default;
gap: $thread_actions_gap;
}
-$post_usercard_width: 200px !default;
+$post_usercard_width: 230px !default;
$post_border: 2px outset $DARK_2 !default;
.post {
display: grid;
@@ -836,10 +834,6 @@ $thread_info_header_gap: $SMALL_PADDING !default;
gap: $thread_info_header_gap;
}
-.thread-info-bookmark-button {
- margin-left: auto !important; // :(
-}
-
$thread_info_post_preview_margin_right: $post_inner_padding_right !default;
.thread-info-post-preview {
overflow: hidden;
@@ -1446,3 +1440,74 @@ $compact_h1_margin: $ZERO_PADDING !default;
h1 {
margin: $compact_h1_margin;
}
+
+$settings_badge_container_gap: $SMALL_PADDING !default;
+$settings_badge_container_border: $DEFAULT_BORDER !default;
+$settings_badge_container_border_invalid: 2px dashed red !default;
+$settings_badge_container_border_radius: $DEFAULT_BORDER_RADIUS !default;
+$settings_badge_container_padding: $SMALL_PADDING $MEDIUM_PADDING !default;
+$settings_badge_container_margin: $MEDIUM_PADDING $ZERO_PADDING !default;
+.settings-badge-container {
+ display: flex;
+ align-items: baseline;
+ gap: $settings_badge_container_gap;
+ border: $settings_badge_container_border;
+ border-radius: $settings_badge_container_border_radius;
+ padding: $settings_badge_container_padding;
+ margin: $settings_badge_container_margin;
+
+ // the file picker's validity is managed by js
+ // so we got lucky here. when the file picker
+ // is hidden, its set to be valid. it's only invalid
+ // when, well, invalid.
+ &:has(input:invalid) {
+ border: $settings_badge_container_border_invalid;
+ }
+
+ input:invalid {
+ border: $settings_badge_container_border_invalid;
+ }
+}
+
+.settings-badge-file-picker {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ & input.hidden[type=file] {
+ width: 100%;
+
+ &::file-selector-button {
+ display: none;
+ }
+ }
+
+ &.hidden {
+ display: none;
+ }
+}
+
+$settings_badge_select_gap: $SMALL_PADDING !default;
+$settings_badge_select_min_width: 200px !default;
+.settings-badge-select {
+ display: flex;
+ flex-direction: column;
+ gap: $settings_badge_select_gap;
+ align-items: center;
+ min-width: $settings_badge_select_min_width;
+}
+
+img.badge-button {
+ min-width: 88px;
+ min-height: 31px;
+ max-width: 88px;
+ max-height: 31px;
+}
+
+$badges_container_gap: $SMALL_PADDING !default;
+.badges-container {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: $badges_container_gap;
+}
diff --git a/sass/otomotone.scss b/sass/otomotone.scss
index e5edbb1..bd92a76 100644
--- a/sass/otomotone.scss
+++ b/sass/otomotone.scss
@@ -82,6 +82,8 @@ $br: 8px;
$bookmarks_dropdown_background_color: $lightish_accent,
$mention_font_color: $fc,
+
+ // $settings_badge_container_border_invalid: 2px dashed $crit,
);
#topnav {
diff --git a/sass/peachy.scss b/sass/peachy.scss
index 619b5fd..4dccf8f 100644
--- a/sass/peachy.scss
+++ b/sass/peachy.scss
@@ -73,9 +73,6 @@ $br: 16px;
}
#bottomnav {
- border-bottom-left-radius: $br;
- border-bottom-right-radius: $br;
-
color: white;
}
@@ -83,9 +80,10 @@ textarea {
padding: 12px 16px;
}
-footer {
- margin-top: 10px;
+#footer {
border-radius: $br;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
border: none;
text-align: center;
}