From 3aa48ac9b0e21c127ca2aec0aae436438df62fea Mon Sep 17 00:00:00 2001 From: Euigyom Kim Date: Wed, 14 Jan 2026 19:59:54 +0900 Subject: [PATCH 1/2] Add matcha core theme --- src/App.tsx | 9 +- src/ui/styles/themes/dark.css | 242 +++++++++++++++++++++++++++++++++ src/ui/styles/themes/light.css | 119 ++++++++++++++++ 3 files changed, 368 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index ce5f9b2..47dc3aa 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -836,10 +836,14 @@ const TimelineSection = ({ ); }; -type ThemeMode = "default" | "christmas" | "sky-pink" | "monochrome"; +type ThemeMode = "default" | "christmas" | "sky-pink" | "monochrome" | "matcha-core"; const isThemeMode = (value: string): value is ThemeMode => - value === "default" || value === "christmas" || value === "sky-pink" || value === "monochrome"; + value === "default" || + value === "christmas" || + value === "sky-pink" || + value === "monochrome" || + value === "matcha-core"; const getStoredTheme = (): ThemeMode => { const storedTheme = localStorage.getItem("textodon.theme"); @@ -1881,6 +1885,7 @@ onAccountChange={setSectionAccount} +
diff --git a/src/ui/styles/themes/dark.css b/src/ui/styles/themes/dark.css index 85ec74e..7f3f287 100644 --- a/src/ui/styles/themes/dark.css +++ b/src/ui/styles/themes/dark.css @@ -494,6 +494,127 @@ --color-image-modal-delete-bg: #c62828; --color-image-modal-delete-text: #fff5f5; } + + :root:not([data-color-scheme="light"])[data-theme="matcha-core"] { + --page-background: radial-gradient(circle at top left, #0f1a13, #0a120e 55%, #060b08); + --color-text-primary: #c6f3d0; + --scrollbar-thumb: #3b6e50; + --notification-badge-ring: #0d120f; + --color-overlay-backdrop: rgba(4, 12, 8, 0.6); + --color-panel-bg: #0c1410cc; + --color-panel-border: #1f3a2b; + --shadow-panel: 0 18px 40px rgba(0, 0, 0, 0.55); + --color-timeline-column-bg: #0b130f; + --color-timeline-column-border: #1f3a2b; + --shadow-timeline-column: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 12px 24px rgba(0, 0, 0, 0.45); + --color-status-bg: #0b130f; + --color-status-border: #1f3a2b; + --color-status-header: #a8e4b6; + --color-app-header-text: #a8e4b6; + --color-status-header-strong: #d8fde0; + --color-status-meta: #7edc93; + --color-status-time: #7edc93; + --color-status-warning-bg: #132019; + --color-status-warning-text: #9fe8b3; + --color-status-link: #6ce48b; + --color-link-preview-bg: #0b130f; + --color-link-preview-border: #1f3a2b; + --color-link-preview-text: #a8e4b6; + --color-link-preview-strong: #d8fde0; + --color-link-preview-url: #6ce48b; + --color-reaction-text: #c6f3d0; + --color-reaction-border: #2b4a38; + --color-reaction-active-bg: #13271c; + --color-reaction-active-border: #2b4a38; + --color-reaction-active-text: #e6ffee; + --color-account-add-button-bg: #39b56b; + --color-account-add-button-text: #0b140f; + --color-account-add-panel-bg: rgba(11, 19, 15, 0.88); + --color-account-add-panel-text: #c6f3d0; + --color-account-add-panel-border: #1f3a2b; + --shadow-account-add-panel: 0 18px 40px rgba(0, 0, 0, 0.55); + --color-section-menu-bg: rgba(11, 19, 15, 0.88); + --color-section-menu-text: #c6f3d0; + --color-section-menu-border: #1f3a2b; + --shadow-section-menu: 0 18px 40px rgba(0, 0, 0, 0.55); + --color-section-menu-danger: #e07a6d; + --color-toast-success-bg: #133021; + --color-toast-success-border: #2f8a5d; + --color-toast-success-text: #c9f5d6; + --color-toast-info-bg: #0c1410; + --color-toast-info-border: #1f3a2b; + --color-toast-info-text: #c6f3d0; + --color-toast-error-bg: #3a1b1a; + --color-toast-error-border: #e07a6d; + --color-toast-error-text: #f6d4cf; + --color-account-selector-bg: #0b130f; + --color-account-selector-border: #1f3a2b; + --shadow-account-selector: 0 18px 40px rgba(0, 0, 0, 0.55); + --color-account-selector-placeholder: #8cd49a; + --color-account-handle: #a8e4b6; + --color-file-button-bg: #163126; + --color-file-button-text: #d7f6df; + --color-secondary-button-bg: #163126; + --color-secondary-button-text: #d7f6df; + --color-secondary-button-border: #1f3a2b; + --color-emoji-panel-bg: #0b130f; + --color-emoji-panel-border: #1f3a2b; + --color-emoji-toggle-bg: #13271c; + --color-emoji-toggle-text: #c6f3d0; + --color-emoji-toggle-border: #1f3a2b; + --color-emoji-count-bg: #1f3a2b; + --color-emoji-count-text: #d8fde0; + --color-emoji-button-bg: #13271c; + --color-emoji-button-border: #1f3a2b; + --color-emoji-empty-text: #7fb88f; + --color-compose-busy-backdrop: rgba(5, 12, 8, 0.65); + --color-compose-busy-bg: #0c1410; + --color-compose-busy-border: #1f3a2b; + --color-compose-busy-text: #a8e4b6; + --color-compose-busy-spinner-border: #1f3a2b; + --color-compose-busy-spinner-active: #6ce48b; + --color-input-bg: #0a120e; + --color-input-border: #1f3a2b; + --color-input-text: #c6f3d0; + --color-input-placeholder: #6f9f7f; + --color-settings-select-bg: #0a120e; + --color-settings-select-border: #1f3a2b; + --color-settings-select-text: #c6f3d0; + --color-compose-input-bg: #0a120e; + --color-attachments-bg: #101c15; + --color-attachments-border: #1f3a2b; + --color-attachment-add-border: #6ce48b; + --color-attachment-add-text: #8cd49a; + --color-action-bg: #39b56b; + --color-action-text: #0b140f; + --color-action-danger-bg: #b5463b; + --color-action-danger-text: #fff6f0; + --color-action-active-bg: #6ce48b; + --color-action-active-text: #0c1a12; + --color-action-ghost-text: #6ce48b; + --color-link: #6ce48b; + --color-sidebar-description: #a8e4b6; + --color-brand-text: #a8e4b6; + --color-oss-list: #a8e4b6; + --color-sidebar-description-link: #6ce48b; + --color-sidebar-link: #6ce48b; + --color-sidebar-divider: #1f3a2b; + --color-settings-item-border: #1f3a2b; + --color-settings-item-text: #a8e4b6; + --color-status-backdrop: rgba(5, 12, 8, 0.7); + --color-status-modal-bg: #0c1410; + --color-status-modal-border: #1f3a2b; + --color-status-modal-divider: #1f3a2b; + --color-status-modal-title: #c6f3d0; + --color-boosted-by: #7edc93; + --color-notification-actor: #7edc93; + --color-reply-info: #7edc93; + --color-character-count-normal: #a8e4b6; + --color-delete-button-bg: #b5463b; + --color-delete-button-text: #fff6f0; + --color-image-modal-delete-bg: #b5463b; + --color-image-modal-delete-text: #fff6f0; + } } :root[data-color-scheme="dark"] { @@ -991,3 +1112,124 @@ --color-image-modal-delete-bg: #c62828; --color-image-modal-delete-text: #fff5f5; } + +:root[data-color-scheme="dark"][data-theme="matcha-core"] { + --page-background: radial-gradient(circle at top left, #0f1a13, #0a120e 55%, #060b08); + --color-text-primary: #c6f3d0; + --scrollbar-thumb: #3b6e50; + --notification-badge-ring: #0d120f; + --color-overlay-backdrop: rgba(4, 12, 8, 0.6); + --color-panel-bg: #0c1410cc; + --color-panel-border: #1f3a2b; + --shadow-panel: 0 18px 40px rgba(0, 0, 0, 0.55); + --color-timeline-column-bg: #0b130f; + --color-timeline-column-border: #1f3a2b; + --shadow-timeline-column: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 12px 24px rgba(0, 0, 0, 0.45); + --color-status-bg: #0b130f; + --color-status-border: #1f3a2b; + --color-status-header: #a8e4b6; + --color-app-header-text: #a8e4b6; + --color-status-header-strong: #d8fde0; + --color-status-meta: #7edc93; + --color-status-time: #7edc93; + --color-status-warning-bg: #132019; + --color-status-warning-text: #9fe8b3; + --color-status-link: #6ce48b; + --color-link-preview-bg: #0b130f; + --color-link-preview-border: #1f3a2b; + --color-link-preview-text: #a8e4b6; + --color-link-preview-strong: #d8fde0; + --color-link-preview-url: #6ce48b; + --color-reaction-text: #c6f3d0; + --color-reaction-border: #2b4a38; + --color-reaction-active-bg: #13271c; + --color-reaction-active-border: #2b4a38; + --color-reaction-active-text: #e6ffee; + --color-account-add-button-bg: #39b56b; + --color-account-add-button-text: #0b140f; + --color-account-add-panel-bg: rgba(11, 19, 15, 0.88); + --color-account-add-panel-text: #c6f3d0; + --color-account-add-panel-border: #1f3a2b; + --shadow-account-add-panel: 0 18px 40px rgba(0, 0, 0, 0.55); + --color-section-menu-bg: rgba(11, 19, 15, 0.88); + --color-section-menu-text: #c6f3d0; + --color-section-menu-border: #1f3a2b; + --shadow-section-menu: 0 18px 40px rgba(0, 0, 0, 0.55); + --color-section-menu-danger: #e07a6d; + --color-toast-success-bg: #133021; + --color-toast-success-border: #2f8a5d; + --color-toast-success-text: #c9f5d6; + --color-toast-info-bg: #0c1410; + --color-toast-info-border: #1f3a2b; + --color-toast-info-text: #c6f3d0; + --color-toast-error-bg: #3a1b1a; + --color-toast-error-border: #e07a6d; + --color-toast-error-text: #f6d4cf; + --color-account-selector-bg: #0b130f; + --color-account-selector-border: #1f3a2b; + --shadow-account-selector: 0 18px 40px rgba(0, 0, 0, 0.55); + --color-account-selector-placeholder: #8cd49a; + --color-account-handle: #a8e4b6; + --color-file-button-bg: #163126; + --color-file-button-text: #d7f6df; + --color-secondary-button-bg: #163126; + --color-secondary-button-text: #d7f6df; + --color-secondary-button-border: #1f3a2b; + --color-emoji-panel-bg: #0b130f; + --color-emoji-panel-border: #1f3a2b; + --color-emoji-toggle-bg: #13271c; + --color-emoji-toggle-text: #c6f3d0; + --color-emoji-toggle-border: #1f3a2b; + --color-emoji-count-bg: #1f3a2b; + --color-emoji-count-text: #d8fde0; + --color-emoji-button-bg: #13271c; + --color-emoji-button-border: #1f3a2b; + --color-emoji-empty-text: #7fb88f; + --color-compose-busy-backdrop: rgba(5, 12, 8, 0.65); + --color-compose-busy-bg: #0c1410; + --color-compose-busy-border: #1f3a2b; + --color-compose-busy-text: #a8e4b6; + --color-compose-busy-spinner-border: #1f3a2b; + --color-compose-busy-spinner-active: #6ce48b; + --color-input-bg: #0a120e; + --color-input-border: #1f3a2b; + --color-input-text: #c6f3d0; + --color-input-placeholder: #6f9f7f; + --color-settings-select-bg: #0a120e; + --color-settings-select-border: #1f3a2b; + --color-settings-select-text: #c6f3d0; + --color-compose-input-bg: #0a120e; + --color-attachments-bg: #101c15; + --color-attachments-border: #1f3a2b; + --color-attachment-add-border: #6ce48b; + --color-attachment-add-text: #8cd49a; + --color-action-bg: #39b56b; + --color-action-text: #0b140f; + --color-action-danger-bg: #b5463b; + --color-action-danger-text: #fff6f0; + --color-action-active-bg: #6ce48b; + --color-action-active-text: #0c1a12; + --color-action-ghost-text: #6ce48b; + --color-link: #6ce48b; + --color-sidebar-description: #a8e4b6; + --color-brand-text: #a8e4b6; + --color-oss-list: #a8e4b6; + --color-sidebar-description-link: #6ce48b; + --color-sidebar-link: #6ce48b; + --color-sidebar-divider: #1f3a2b; + --color-settings-item-border: #1f3a2b; + --color-settings-item-text: #a8e4b6; + --color-status-backdrop: rgba(5, 12, 8, 0.7); + --color-status-modal-bg: #0c1410; + --color-status-modal-border: #1f3a2b; + --color-status-modal-divider: #1f3a2b; + --color-status-modal-title: #c6f3d0; + --color-boosted-by: #7edc93; + --color-notification-actor: #7edc93; + --color-reply-info: #7edc93; + --color-character-count-normal: #a8e4b6; + --color-delete-button-bg: #b5463b; + --color-delete-button-text: #fff6f0; + --color-image-modal-delete-bg: #b5463b; + --color-image-modal-delete-text: #fff6f0; +} diff --git a/src/ui/styles/themes/light.css b/src/ui/styles/themes/light.css index 7a5a38f..411c26c 100644 --- a/src/ui/styles/themes/light.css +++ b/src/ui/styles/themes/light.css @@ -345,3 +345,122 @@ --color-image-modal-delete-bg: #c62828; --color-image-modal-delete-text: #fff5f5; } + +:root[data-theme="matcha-core"] { + --page-background: radial-gradient(circle at top left, #f0faf1, #eef8ef 55%, #f7fff8); + --color-text-primary: #0f3b22; + --scrollbar-thumb: #7fbf92; + --color-sidebar-description: #2f6b46; + --color-brand-text: #2f6b46; + --color-sidebar-description-link: #1f8f4b; + --color-sidebar-link: #1b6f3f; + --color-sidebar-divider: #cfe6d5; + --color-settings-backdrop: rgba(10, 40, 20, 0.55); + --color-status-backdrop: rgba(10, 40, 20, 0.65); + --color-status-modal-bg: #f6fff6; + --color-status-modal-border: #cfe6d5; + --shadow-status-modal: 0 20px 60px rgba(24, 84, 48, 0.14); + --color-status-modal-divider: #cfe6d5; + --color-status-modal-title: #0f3b22; + --color-overlay-backdrop: rgba(15, 60, 32, 0.12); + --color-settings-item-border: #cfe6d5; + --color-settings-item-text: #2f6b46; + --color-panel-border: #cfe6d5; + --shadow-panel: 0 18px 40px rgba(24, 84, 48, 0.08); + --color-account-add-button-bg: #1b7a3d; + --color-account-add-button-text: #effff4; + --color-account-add-panel-bg: rgba(246, 255, 246, 0.92); + --color-account-add-panel-text: #0f3b22; + --color-account-add-panel-border: #cfe6d5; + --shadow-account-add-panel: 0 18px 40px rgba(24, 84, 48, 0.12); + --color-avatar-bg: #f6fff6; + --color-avatar-border: #cfe6d5; + --color-avatar-fallback: #9bc8ab; + --color-account-selector-bg: #f6fff6; + --color-account-selector-border: #cfe6d5; + --shadow-account-selector: 0 18px 40px rgba(24, 84, 48, 0.12); + --color-account-selector-placeholder: #2f6b46; + --color-account-handle: #2f6b46; + --color-action-bg: #1f9a50; + --color-action-text: #f2fff6; + --color-action-danger-bg: #b13b3b; + --color-action-danger-text: #fff4f4; + --color-action-active-bg: #0f5a32; + --color-action-active-text: #eafff2; + --color-action-ghost-text: #1b6f3f; + --color-section-menu-bg: rgba(246, 255, 246, 0.92); + --color-section-menu-text: #0f3b22; + --color-section-menu-border: #cfe6d5; + --shadow-section-menu: 0 18px 40px rgba(24, 84, 48, 0.12); + --color-toast-success-bg: #e5f6ea; + --color-toast-success-border: #1b7a3d; + --color-toast-success-text: #0f3b22; + --color-toast-info-bg: #f6fff6; + --color-toast-info-border: #cfe6d5; + --color-toast-info-text: #0f3b22; + --color-toast-error-bg: #fde9e6; + --color-toast-error-border: #b13b3b; + --color-toast-error-text: #5b1f1f; + --color-timeline-column-bg: #f6fff6; + --color-timeline-column-border: #cfe6d5; + --shadow-timeline-column: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 12px 24px rgba(24, 84, 48, 0.06); + --color-status-bg: #f8fff8; + --color-status-border: #cfe6d5; + --color-status-header: #2f6b46; + --color-status-header-strong: #0f3b22; + --color-status-meta: #1b6f3f; + --color-status-time: #1b6f3f; + --color-status-warning-bg: #e9f5ec; + --color-status-warning-text: #2f6b46; + --color-link-preview-bg: #f6fff6; + --color-link-preview-border: #cfe6d5; + --color-link-preview-text: #2f6b46; + --color-link-preview-strong: #0f3b22; + --color-link-preview-url: #1f8f4b; + --color-status-link: #1f8f4b; + --color-reaction-text: #0f3b22; + --color-reaction-border: #cfe6d5; + --color-reaction-active-bg: #1b6f3f; + --color-reaction-active-border: #0f3b22; + --color-reaction-active-text: #f2fff6; + --color-file-button-bg: #e9f5ec; + --color-file-button-text: #2f6b46; + --color-secondary-button-bg: #e9f5ec; + --color-secondary-button-text: #2f6b46; + --color-secondary-button-border: #cfe6d5; + --color-emoji-panel-bg: #f6fff6; + --color-emoji-panel-border: #cfe6d5; + --color-emoji-toggle-bg: #e9f5ec; + --color-emoji-toggle-text: #2f6b46; + --color-emoji-toggle-border: #cfe6d5; + --color-emoji-count-bg: #cfe6d5; + --color-emoji-count-text: #0f3b22; + --color-emoji-button-bg: #e9f5ec; + --color-emoji-button-border: #cfe6d5; + --color-emoji-empty-text: #7aa58a; + --color-compose-busy-backdrop: rgba(15, 60, 32, 0.2); + --color-compose-busy-bg: #f6fff6; + --color-compose-busy-border: #cfe6d5; + --color-compose-busy-text: #2f6b46; + --color-compose-busy-spinner-border: #cfe6d5; + --color-compose-busy-spinner-active: #1f9a50; + --color-boosted-by: #1b6f3f; + --color-notification-actor: #1b6f3f; + --color-reply-info: #1b6f3f; + --color-input-bg: #f6fff6; + --color-input-border: #cfe6d5; + --color-input-text: #0f3b22; + --color-input-placeholder: #7aa58a; + --color-settings-select-bg: #f6fff6; + --color-settings-select-border: #cfe6d5; + --color-settings-select-text: #0f3b22; + --color-compose-input-bg: #f6fff6; + --color-attachments-bg: #e9f5ec; + --color-attachments-border: #cfe6d5; + --color-attachment-add-border: #a8cdb4; + --color-attachment-add-text: #2f6b46; + --color-delete-button-bg: #b13b3b; + --color-delete-button-text: #fff4f4; + --color-image-modal-delete-bg: #b13b3b; + --color-image-modal-delete-text: #fff4f4; +} From e7e74ba02407df5c6cbe8931a69ed3bc756ecae6 Mon Sep 17 00:00:00 2001 From: Euigyom Kim Date: Wed, 14 Jan 2026 20:53:42 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=EC=98=A4=EB=A5=98=20=ED=86=A0?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=85=B8=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 26 +++++++++++++++++++++++--- src/ui/components/AccountAdd.tsx | 9 ++++----- src/ui/components/ComposeBox.tsx | 18 +++++++++++++++++- src/ui/components/ProfileModal.tsx | 28 ++++++++++++++++++++++++---- src/ui/components/ReactionPicker.tsx | 16 ++++++++++++++++ src/ui/components/StatusModal.tsx | 15 ++++++++++----- 6 files changed, 94 insertions(+), 18 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 47dc3aa..fa7b957 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -403,6 +403,13 @@ const TimelineSection = ({ const actionsDisabled = timelineType === "notifications"; const emptyMessage = timelineType === "notifications" ? "표시할 알림이 없습니다." : "표시할 글이 없습니다."; + useEffect(() => { + if (!timeline.error) { + return; + } + showToast(timeline.error, { tone: "error" }); + }, [showToast, timeline.error]); + useEffect(() => { const el = scrollRef.current; if (!el) { @@ -475,6 +482,13 @@ const TimelineSection = ({ refreshNotifications(); }, [notificationsOpen, refreshNotifications]); + useEffect(() => { + if (!notificationsError) { + return; + } + showToast(notificationsError, { tone: "error" }); + }, [notificationsError, showToast]); + const handleToggleFavourite = async (status: Status) => { if (!account) { onError("계정을 선택해주세요."); @@ -649,7 +663,6 @@ const TimelineSection = ({