diff --git a/locales/en.yml b/locales/en.yml
index 13702540..ec3b38de 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -85,6 +85,7 @@ config_page:
vr: VR
others: Others
advanced_settings: Advanced Settings
+ supporters: Supporters
about_vrct: About VRCT
device:
diff --git a/src-ui/app/config_page/setting_section/setting_box/SettingBox.jsx b/src-ui/app/config_page/setting_section/setting_box/SettingBox.jsx
index 8981521a..eba09ff7 100644
--- a/src-ui/app/config_page/setting_section/setting_box/SettingBox.jsx
+++ b/src-ui/app/config_page/setting_section/setting_box/SettingBox.jsx
@@ -8,6 +8,7 @@ import {
Others,
AdvancedSettings,
Vr,
+ Supporters,
AboutVrct,
} from "@setting_box";
@@ -28,6 +29,8 @@ export const SettingBox = () => {
return ;
case "advanced_settings":
return ;
+ case "supporters":
+ return ;
case "about_vrct":
return ;
diff --git a/src-ui/app/config_page/setting_section/setting_box/index.js b/src-ui/app/config_page/setting_section/setting_box/index.js
index 5ff7ec49..489f63ca 100644
--- a/src-ui/app/config_page/setting_section/setting_box/index.js
+++ b/src-ui/app/config_page/setting_section/setting_box/index.js
@@ -5,4 +5,5 @@ export { Transcription } from "./transcription/Transcription";
export { Others, VrcMicMuteSyncContainer } from "./others/Others";
export { AdvancedSettings } from "./advanced_settings/AdvancedSettings";
export { Vr } from "./vr/Vr";
-export { AboutVrct } from "./about_vrct/AboutVrct";
\ No newline at end of file
+export { AboutVrct } from "./about_vrct/AboutVrct";
+export { Supporters } from "./supporters/Supporters";
\ No newline at end of file
diff --git a/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.jsx b/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.jsx
new file mode 100644
index 00000000..d8e72d34
--- /dev/null
+++ b/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.jsx
@@ -0,0 +1,131 @@
+import styles from "./Supporters.module.scss";
+import clsx from "clsx";
+import { useTranslation } from "react-i18next";
+
+const supporter_images = import.meta.glob("@images/supporters/supporters_images/*.{png,jpg,jpeg,svg}", { eager: true });
+const chato_expression_images = import.meta.glob("@images/supporters/chato_expressions/*.{png,jpg,jpeg,svg}", { eager: true });
+import fanbox_img from "@images/supporters/c_fanbox_1620x580.png";
+import vrct_supporters_title from "@images/supporters/vrct_supporters_title.png";
+import fanbox_button from "@images/supporters/fanbox_button.png";
+import kofi_preparing from "@images/supporters/kofi_preparing.png";
+
+const mogu_count = 8;
+const mochi_count = 3;
+const fuwa_count = 4;
+const basic_count = 5;
+const former_count = 2;
+const default_icon_numbers = ["05", "06", "07", "11"];
+
+const supporters_filenames = Array.from({ length: 22 }, (_, index) => `supporter_${String(index + 1).padStart(2, "0")}`);
+const chato_expressions_filenames = Array.from({ length: 7 }, (_, index) => `chato_expression_${String(index + 1).padStart(2, "0")}`);
+
+const shuffleArray = (array) => {
+ return array
+ .map((value) => ({ value, sort: Math.random() }))
+ .sort((a, b) => a.sort - b.sort)
+ .map(({ value }) => value);
+};
+
+const getCategoryImages = (start, count) => {
+ const category_images = supporters_filenames.slice(start, start + count);
+ return shuffleArray(category_images);
+};
+
+const mogu_images = getCategoryImages(0, mogu_count);
+const mochi_images = getCategoryImages(mogu_count, mochi_count);
+const fuwa_images = getCategoryImages(mogu_count + mochi_count, fuwa_count);
+const basic_images = getCategoryImages(mogu_count + mochi_count + fuwa_count, basic_count);
+const former_images = getCategoryImages(mogu_count + mochi_count + fuwa_count + basic_count, former_count);
+
+const getRandomImage = (images) => {
+ const random_index = Math.floor(Math.random() * images.length);
+ return images[random_index];
+};
+
+const getSupportersImageByFileName = (file_name) => {
+ const image_path = Object.keys(supporter_images).find((path) => path.endsWith(file_name + ".png"));
+ return image_path ? supporter_images[image_path]?.default : null;
+};
+
+const getChatoImageByFileName = (file_name) => {
+ const image_path = Object.keys(chato_expression_images).find((path) => path.endsWith(file_name + ".png"));
+ return image_path ? chato_expression_images[image_path]?.default : null;
+};
+
+const getRandomDelay = (min, max) => {
+ const random_value = Math.random() * (max - min) + min;
+ return `${random_value.toFixed(1)}s`;
+};
+
+export const Supporters = () => {
+ return (
+
+
+
+
+ );
+};
+
+const SupportUsContainer = () => {
+ return (
+
+

+
+
+
+

+
Mainly English
+
+
+
+ );
+};
+
+export const SupportersContainer = () => {
+ const renderImages = (image_list, class_name) => {
+ return image_list.map((file_name) => {
+ const img_src = getSupportersImageByFileName(file_name);
+ const is_default_icon = default_icon_numbers.some((default_num) => file_name.endsWith(default_num));
+ const chato_expression_src = is_default_icon
+ ? getChatoImageByFileName(getRandomImage(chato_expressions_filenames))
+ : null;
+ const random_delay = getRandomDelay(0.1, 6);
+
+ return img_src ? (
+
+

+ {chato_expression_src && (
+

+ )}
+
+ ) : null;
+ });
+ };
+
+ return (
+
+

+
{`VRCT3.0のアップデートに向けて、むちゃ大変な開発を支えてくれた "Early Supporters" です。\nThey are the 'Early Supporters' who supported us through the incredibly challenging development toward the VRCT3.0 update.`}
+
+ {renderImages(mogu_images, `${styles.mogu_image}`)}
+ {renderImages(mochi_images)}
+ {renderImages(fuwa_images)}
+ {renderImages(basic_images)}
+ {renderImages(former_images)}
+
+
+ );
+};
diff --git a/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.module.scss b/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.module.scss
new file mode 100644
index 00000000..bd556503
--- /dev/null
+++ b/src-ui/app/config_page/setting_section/setting_box/supporters/Supporters.module.scss
@@ -0,0 +1,131 @@
+.container {
+ display: flex;
+ gap: 1.2rem;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ // background-color: gray;
+}
+
+.support_us_container {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 2rem;
+ width: 100%;
+
+}
+.fanbox_img {
+ width: 60vw;
+}
+
+.support_us_button_wrapper {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ gap: 4.8rem;
+}
+.fanbox_wrapper, .kofi_wrapper {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 1rem;
+}
+.fanbox_button {
+ width: 14rem;
+ transition: all 0.3s ease;
+ &:hover {
+ width: 16rem;
+ }
+}
+.kofi_preparing {
+ width: 6rem;
+}
+
+.mainly_japanese, .mainly_english {
+ font-size: 1.2rem;
+ color: var(--dark_400_color);
+}
+
+
+.supporters_container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-direction: column;
+ gap: 1rem;
+}
+.vrct_supporters_title {
+ height: 6rem;
+}
+.vrct_supporters_desc {
+ font-size: 1.4rem;
+ text-align: start;
+}
+
+.supporters_wrapper {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ align-content: start;
+ flex-wrap: wrap;
+ column-gap: 1.4rem;
+ row-gap: 0.8rem;
+}
+
+.supporter_image_wrapper {
+ position: relative;
+ width: 18rem;
+ overflow: hidden;
+}
+
+.supporter_image {
+ width: 100%;
+}
+
+.mogu_image {
+ position: relative;
+ &::after {
+ content: "";
+ position: absolute;
+ top: -200%;
+ left: -200%;
+ width: 300%;
+ height: 300%;
+ background: linear-gradient(45deg, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0.7) 50%, rgba(255, 255, 255, 0) 70%);
+ transform: rotate(90deg);
+ animation: shine 2.5s infinite;
+ filter: blur(0.4rem);
+ animation-delay: var(--delay, 0s);
+ }
+
+}
+
+@keyframes shine {
+ 0% {
+ top: -200%;
+ left: -200%;
+ }
+ 50% {
+ top: 50%;
+ left: 50%;
+ opacity: 0.7;
+ }
+ 100% {
+ top: 200%;
+ left: 200%;
+ }
+}
+
+.default_chato_expression_image {
+ position: absolute;
+ top: 50%;
+ left: 2.9rem;
+ width: 2.8rem;
+ transform: translate(-50%, -50%) rotate(10deg);
+ opacity: 0.8;
+}
\ No newline at end of file
diff --git a/src-ui/app/config_page/sidebar_section/SidebarSection.jsx b/src-ui/app/config_page/sidebar_section/SidebarSection.jsx
index ec8ca150..2b109910 100644
--- a/src-ui/app/config_page/sidebar_section/SidebarSection.jsx
+++ b/src-ui/app/config_page/sidebar_section/SidebarSection.jsx
@@ -13,6 +13,7 @@ export const SidebarSection = () => {
+
diff --git a/src-ui/assets/supporters/c_fanbox_1620x580.png b/src-ui/assets/supporters/c_fanbox_1620x580.png
new file mode 100644
index 00000000..5c677f49
Binary files /dev/null and b/src-ui/assets/supporters/c_fanbox_1620x580.png differ
diff --git a/src-ui/assets/supporters/chato_expressions/chato_expression_01.png b/src-ui/assets/supporters/chato_expressions/chato_expression_01.png
new file mode 100644
index 00000000..849ce433
Binary files /dev/null and b/src-ui/assets/supporters/chato_expressions/chato_expression_01.png differ
diff --git a/src-ui/assets/supporters/chato_expressions/chato_expression_02.png b/src-ui/assets/supporters/chato_expressions/chato_expression_02.png
new file mode 100644
index 00000000..8274f9b0
Binary files /dev/null and b/src-ui/assets/supporters/chato_expressions/chato_expression_02.png differ
diff --git a/src-ui/assets/supporters/chato_expressions/chato_expression_03.png b/src-ui/assets/supporters/chato_expressions/chato_expression_03.png
new file mode 100644
index 00000000..4cc17cf6
Binary files /dev/null and b/src-ui/assets/supporters/chato_expressions/chato_expression_03.png differ
diff --git a/src-ui/assets/supporters/chato_expressions/chato_expression_04.png b/src-ui/assets/supporters/chato_expressions/chato_expression_04.png
new file mode 100644
index 00000000..e39e830f
Binary files /dev/null and b/src-ui/assets/supporters/chato_expressions/chato_expression_04.png differ
diff --git a/src-ui/assets/supporters/chato_expressions/chato_expression_05.png b/src-ui/assets/supporters/chato_expressions/chato_expression_05.png
new file mode 100644
index 00000000..c0544641
Binary files /dev/null and b/src-ui/assets/supporters/chato_expressions/chato_expression_05.png differ
diff --git a/src-ui/assets/supporters/chato_expressions/chato_expression_06.png b/src-ui/assets/supporters/chato_expressions/chato_expression_06.png
new file mode 100644
index 00000000..21b04d09
Binary files /dev/null and b/src-ui/assets/supporters/chato_expressions/chato_expression_06.png differ
diff --git a/src-ui/assets/supporters/chato_expressions/chato_expression_07.png b/src-ui/assets/supporters/chato_expressions/chato_expression_07.png
new file mode 100644
index 00000000..e53800aa
Binary files /dev/null and b/src-ui/assets/supporters/chato_expressions/chato_expression_07.png differ
diff --git a/src-ui/assets/supporters/fanbox_button.png b/src-ui/assets/supporters/fanbox_button.png
new file mode 100644
index 00000000..7bf90626
Binary files /dev/null and b/src-ui/assets/supporters/fanbox_button.png differ
diff --git a/src-ui/assets/supporters/kofi_preparing.png b/src-ui/assets/supporters/kofi_preparing.png
new file mode 100644
index 00000000..d674b8fb
Binary files /dev/null and b/src-ui/assets/supporters/kofi_preparing.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_01.png b/src-ui/assets/supporters/supporters_images/supporter_01.png
new file mode 100644
index 00000000..d43986e8
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_01.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_02.png b/src-ui/assets/supporters/supporters_images/supporter_02.png
new file mode 100644
index 00000000..013b1f74
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_02.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_03.png b/src-ui/assets/supporters/supporters_images/supporter_03.png
new file mode 100644
index 00000000..b5f47a6d
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_03.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_04.png b/src-ui/assets/supporters/supporters_images/supporter_04.png
new file mode 100644
index 00000000..edf48965
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_04.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_05.png b/src-ui/assets/supporters/supporters_images/supporter_05.png
new file mode 100644
index 00000000..a8874947
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_05.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_06.png b/src-ui/assets/supporters/supporters_images/supporter_06.png
new file mode 100644
index 00000000..c7b10514
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_06.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_07.png b/src-ui/assets/supporters/supporters_images/supporter_07.png
new file mode 100644
index 00000000..bb86cfa0
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_07.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_08.png b/src-ui/assets/supporters/supporters_images/supporter_08.png
new file mode 100644
index 00000000..45ff7330
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_08.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_09.png b/src-ui/assets/supporters/supporters_images/supporter_09.png
new file mode 100644
index 00000000..4564b031
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_09.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_10.png b/src-ui/assets/supporters/supporters_images/supporter_10.png
new file mode 100644
index 00000000..8ce252f0
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_10.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_11.png b/src-ui/assets/supporters/supporters_images/supporter_11.png
new file mode 100644
index 00000000..cfa86fc3
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_11.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_12.png b/src-ui/assets/supporters/supporters_images/supporter_12.png
new file mode 100644
index 00000000..49f34c2d
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_12.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_13.png b/src-ui/assets/supporters/supporters_images/supporter_13.png
new file mode 100644
index 00000000..7bd136a3
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_13.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_14.png b/src-ui/assets/supporters/supporters_images/supporter_14.png
new file mode 100644
index 00000000..9e50bde8
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_14.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_15.png b/src-ui/assets/supporters/supporters_images/supporter_15.png
new file mode 100644
index 00000000..f445a329
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_15.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_16.png b/src-ui/assets/supporters/supporters_images/supporter_16.png
new file mode 100644
index 00000000..815d2f12
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_16.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_17.png b/src-ui/assets/supporters/supporters_images/supporter_17.png
new file mode 100644
index 00000000..b5ddd12e
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_17.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_18.png b/src-ui/assets/supporters/supporters_images/supporter_18.png
new file mode 100644
index 00000000..d63f2288
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_18.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_19.png b/src-ui/assets/supporters/supporters_images/supporter_19.png
new file mode 100644
index 00000000..0f89d1ef
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_19.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_20.png b/src-ui/assets/supporters/supporters_images/supporter_20.png
new file mode 100644
index 00000000..ee1fc327
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_20.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_21.png b/src-ui/assets/supporters/supporters_images/supporter_21.png
new file mode 100644
index 00000000..b76bb6c3
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_21.png differ
diff --git a/src-ui/assets/supporters/supporters_images/supporter_22.png b/src-ui/assets/supporters/supporters_images/supporter_22.png
new file mode 100644
index 00000000..b0006be4
Binary files /dev/null and b/src-ui/assets/supporters/supporters_images/supporter_22.png differ
diff --git a/src-ui/assets/supporters/vrct_supporters_title.png b/src-ui/assets/supporters/vrct_supporters_title.png
new file mode 100644
index 00000000..f606a502
Binary files /dev/null and b/src-ui/assets/supporters/vrct_supporters_title.png differ