+
diff --git a/src/components/atoms/theme-icon.tsx b/src/components/atoms/theme-icon.tsx
new file mode 100644
index 0000000..ebd2cf0
--- /dev/null
+++ b/src/components/atoms/theme-icon.tsx
@@ -0,0 +1,49 @@
+import { useEffect, useState } from 'react';
+
+import Icon from './icon';
+
+const STORAGE_THEME_KEY = 'theme';
+const DARK_THEME_KEY = 'dark';
+const LIGHT_THEME_KEY = 'light';
+
+type ThemeVariant = typeof DARK_THEME_KEY | typeof LIGHT_THEME_KEY;
+
+const getInitialTheme = (): ThemeVariant => {
+ if (typeof localStorage !== 'undefined' && localStorage.getItem(STORAGE_THEME_KEY)) {
+ return localStorage.getItem(STORAGE_THEME_KEY) === LIGHT_THEME_KEY ? LIGHT_THEME_KEY : DARK_THEME_KEY;
+ }
+ if (window.matchMedia(`(prefers-color-scheme: ${DARK_THEME_KEY})`).matches) {
+ return DARK_THEME_KEY;
+ }
+ return LIGHT_THEME_KEY;
+};
+
+const ThemeToggle = () => {
+ const [theme, setTheme] = useState
(() => getInitialTheme());
+
+ const handleClick = () => {
+ setTheme((prev) => (prev === LIGHT_THEME_KEY ? DARK_THEME_KEY : LIGHT_THEME_KEY));
+ };
+
+ useEffect(() => {
+ if (theme === DARK_THEME_KEY) {
+ document.documentElement.classList.add(DARK_THEME_KEY);
+ }
+ if (theme === LIGHT_THEME_KEY) {
+ document.documentElement.classList.remove(DARK_THEME_KEY);
+ }
+ localStorage.setItem(STORAGE_THEME_KEY, theme);
+ }, [theme]);
+
+ return (
+
+ );
+};
+
+export default ThemeToggle;
diff --git a/src/components/atoms/tooltip.tsx b/src/components/atoms/tooltip.tsx
index 7f4c308..cbe8e6e 100644
--- a/src/components/atoms/tooltip.tsx
+++ b/src/components/atoms/tooltip.tsx
@@ -11,7 +11,10 @@ const Tooltip = ({ children, content, placement = 'top' }: TooltipProps) => {
return (
(
-
+
{content}
)}
diff --git a/src/components/atoms/typography.astro b/src/components/atoms/typography.astro
index 9a5535d..7742a18 100644
--- a/src/components/atoms/typography.astro
+++ b/src/components/atoms/typography.astro
@@ -25,16 +25,16 @@ const variantToElement = {
} as const;
const variantToClassName = {
- 'main-title': 'text-3xl sm:text-4xl font-extrabold text-gray-900',
- 'main-subtitle': 'text-md sm:text-lg font-medium text-gray-700',
- 'section-title': 'text-3xl font-extrabold text-gray-900',
- 'section-subtitle': 'text-lg font-extrabold text-gray-900',
- 'item-title': 'text-xl font-extrabold text-gray-900',
- 'item-title-suffix': 'text-xl font-medium text-gray-700',
- 'item-subtitle': 'text-md font-medium text-gray-700',
- 'tile-title': 'text-sm font-medium text-gray-700',
- 'tile-subtitle': 'text-sm font-normal text-gray-500',
- paragraph: 'text-sm sm:text-base leading-relaxed font-normal text-gray-500',
+ 'main-title': 'text-3xl sm:text-4xl font-extrabold text-gray-900 dark:text-gray-100',
+ 'main-subtitle': 'text-md sm:text-lg font-medium text-gray-700 dark:text-gray-100',
+ 'section-title': 'text-3xl font-extrabold text-gray-900 dark:text-gray-100',
+ 'section-subtitle': 'text-lg font-extrabold text-gray-900 dark:text-gray-100',
+ 'item-title': 'text-xl font-extrabold text-gray-900 dark:text-gray-100',
+ 'item-title-suffix': 'text-xl font-medium text-gray-700 dark:text-gray-100',
+ 'item-subtitle': 'text-md font-medium text-gray-700 dark:text-gray-100',
+ 'tile-title': 'text-sm font-medium text-gray-700 dark:text-gray-200',
+ 'tile-subtitle': 'text-sm font-normal text-gray-500 dark:text-gray-300',
+ paragraph: 'text-sm sm:text-base leading-relaxed font-normal text-gray-500 dark:text-gray-300',
};
export interface Props extends Omit
{
diff --git a/src/components/organisms/sidebar.astro b/src/components/organisms/sidebar.astro
index 46bd799..73c8ee6 100644
--- a/src/components/organisms/sidebar.astro
+++ b/src/components/organisms/sidebar.astro
@@ -5,6 +5,6 @@ export interface Props {
const { className } = Astro.props;
---
-