From ec97bc186d16de6542cc0ae0d825e34de0fa7bc7 Mon Sep 17 00:00:00 2001 From: "Andrey K. Choi" Date: Tue, 11 Nov 2025 17:37:10 +0900 Subject: [PATCH] dark theme --- .../src/app/components/ThemeToggle.css | 21 +- frontend/linktree-frontend/src/app/layout.tsx | 1 + .../src/app/styles/night-comfort.css | 293 ++++++++++++++++++ 3 files changed, 308 insertions(+), 7 deletions(-) create mode 100644 frontend/linktree-frontend/src/app/styles/night-comfort.css diff --git a/frontend/linktree-frontend/src/app/components/ThemeToggle.css b/frontend/linktree-frontend/src/app/components/ThemeToggle.css index 909e700..05d347a 100644 --- a/frontend/linktree-frontend/src/app/components/ThemeToggle.css +++ b/frontend/linktree-frontend/src/app/components/ThemeToggle.css @@ -11,9 +11,11 @@ } .theme-toggle.dark { - background: linear-gradient(135deg, #7c3aed, #9333ea); - border: 2px solid #8b5cf6; - box-shadow: 0 4px 15px rgba(124, 58, 237, 0.25); + background: linear-gradient(135deg, #7c3aed 0%, #8b5cf6 50%, #9333ea 100%); + border: 2px solid rgba(139, 92, 246, 0.6); + box-shadow: + 0 4px 15px rgba(124, 58, 237, 0.25), + inset 0 1px 0 rgba(255, 255, 255, 0.1); } .theme-toggle-slider { @@ -33,8 +35,10 @@ .theme-toggle.dark .theme-toggle-slider { transform: translateX(30px); - background: linear-gradient(45deg, #f8fafc, #e2e8f0); - box-shadow: 0 3px 12px rgba(124, 58, 237, 0.3); + background: linear-gradient(145deg, #f8fafc, #e2e8f0); + box-shadow: + 0 3px 12px rgba(124, 58, 237, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.8); } .theme-toggle-icon { @@ -69,8 +73,11 @@ } .theme-toggle.dark:hover { - box-shadow: 0 6px 25px rgba(124, 58, 237, 0.35); - transform: scale(1.05); + box-shadow: + 0 6px 25px rgba(124, 58, 237, 0.4), + 0 0 20px rgba(139, 92, 246, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.15); + transform: scale(1.05) translateY(-1px); } .theme-toggle:active { diff --git a/frontend/linktree-frontend/src/app/layout.tsx b/frontend/linktree-frontend/src/app/layout.tsx index c6a3473..d94d1be 100644 --- a/frontend/linktree-frontend/src/app/layout.tsx +++ b/frontend/linktree-frontend/src/app/layout.tsx @@ -4,6 +4,7 @@ import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; import "./styles/themes.css"; import "./styles/comfort.css"; +import "./styles/night-comfort.css"; import { ReactNode } from "react"; import { LayoutWrapper } from "./components/LayoutWrapper"; import Providers from "./components/Providers"; diff --git a/frontend/linktree-frontend/src/app/styles/night-comfort.css b/frontend/linktree-frontend/src/app/styles/night-comfort.css new file mode 100644 index 0000000..8e90d0a --- /dev/null +++ b/frontend/linktree-frontend/src/app/styles/night-comfort.css @@ -0,0 +1,293 @@ +/* Специальные стили для максимального комфорта в ночное время */ + +/* Снижение напряжения глаз */ +[data-theme="dark"] { + /* Дополнительные переменные для ночного режима */ + --night-comfort-bg: #1c1c28; + --night-comfort-card: #242430; + --night-comfort-text: #e0e0e6; + --night-comfort-border: #35353f; + --warm-white: #f5f5dc; + --soft-purple: #8b5cf6; + --gentle-glow: rgba(139, 92, 246, 0.08); +} + +/* Фильтр синего света для комфортного чтения */ +[data-theme="dark"] body { + filter: hue-rotate(-10deg) brightness(0.95) contrast(1.05); +} + +/* Мягкие переходы для всех интерактивных элементов */ +[data-theme="dark"] button, +[data-theme="dark"] .btn, +[data-theme="dark"] a, +[data-theme="dark"] .nav-link, +[data-theme="dark"] .card, +[data-theme="dark"] .form-control, +[data-theme="dark"] .dropdown-item { + transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +/* Улучшенная читаемость текста */ +[data-theme="dark"] body, +[data-theme="dark"] .card, +[data-theme="dark"] .modal-content { + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Мягкие тени вместо резких границ */ +[data-theme="dark"] .card { + box-shadow: + 0 4px 20px rgba(0, 0, 0, 0.1), + 0 1px 3px rgba(0, 0, 0, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.03); + border: 1px solid rgba(139, 92, 246, 0.1); +} + +[data-theme="dark"] .card:hover { + box-shadow: + 0 8px 30px rgba(0, 0, 0, 0.15), + 0 2px 6px rgba(0, 0, 0, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.05), + 0 0 20px rgba(139, 92, 246, 0.1); +} + +/* Комфортные кнопки с мягким свечением */ +[data-theme="dark"] .btn-primary { + background: linear-gradient(135deg, #7c3aed 0%, #8b5cf6 50%, #9333ea 100%); + border: none; + box-shadow: + 0 4px 15px rgba(124, 58, 237, 0.25), + inset 0 1px 0 rgba(255, 255, 255, 0.1); +} + +[data-theme="dark"] .btn-primary:hover { + background: linear-gradient(135deg, #8b5cf6 0%, #9333ea 50%, #a855f7 100%); + box-shadow: + 0 6px 20px rgba(124, 58, 237, 0.35), + 0 0 25px rgba(139, 92, 246, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.15); + transform: translateY(-1px); +} + +[data-theme="dark"] .btn-primary:active { + transform: translateY(0); + box-shadow: + 0 2px 10px rgba(124, 58, 237, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.05); +} + +/* Успокаивающие формы ввода */ +[data-theme="dark"] .form-control, +[data-theme="dark"] .form-select { + background: linear-gradient(145deg, #1c1c28, #242430); + border: 1px solid #35353f; + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1); +} + +[data-theme="dark"] .form-control:focus, +[data-theme="dark"] .form-select:focus { + background: linear-gradient(145deg, #1c1c28, #242430); + border-color: #8b5cf6; + box-shadow: + inset 0 2px 4px rgba(0, 0, 0, 0.1), + 0 0 0 3px rgba(139, 92, 246, 0.15), + 0 0 20px rgba(139, 92, 246, 0.1); +} + +/* Мягкие модальные окна */ +[data-theme="dark"] .modal-content { + background: linear-gradient(145deg, #22222f, #2a2a3a); + border: 1px solid rgba(139, 92, 246, 0.2); + box-shadow: + 0 25px 50px rgba(0, 0, 0, 0.3), + 0 10px 25px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.05); +} + +[data-theme="dark"] .modal-backdrop { + background: linear-gradient(135deg, rgba(26, 26, 35, 0.8), rgba(26, 26, 35, 0.9)); + -webkit-backdrop-filter: blur(8px); + backdrop-filter: blur(8px); +} + +/* Навигация с мягким свечением */ +[data-theme="dark"] .navbar { + background: linear-gradient(145deg, #22222f, #2a2a3a); + border-bottom: 1px solid rgba(139, 92, 246, 0.1); + box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1); + -webkit-backdrop-filter: blur(10px); + backdrop-filter: blur(10px); +} + +[data-theme="dark"] .nav-link { + color: #b8b8c8; + transition: all 0.3s ease; +} + +[data-theme="dark"] .nav-link:hover { + color: #e8e8f0; + text-shadow: 0 0 10px rgba(139, 92, 246, 0.3); +} + +[data-theme="dark"] .nav-link.active { + color: #8b5cf6; + text-shadow: 0 0 15px rgba(139, 92, 246, 0.5); +} + +/* Dropdown с улучшенной видимостью */ +[data-theme="dark"] .dropdown-menu { + background: linear-gradient(145deg, #22222f, #2a2a3a); + border: 1px solid rgba(139, 92, 246, 0.2); + box-shadow: + 0 10px 30px rgba(0, 0, 0, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.05); + -webkit-backdrop-filter: blur(10px); + backdrop-filter: blur(10px); +} + +[data-theme="dark"] .dropdown-item { + color: #b8b8c8; + transition: all 0.2s ease; +} + +[data-theme="dark"] .dropdown-item:hover { + background: linear-gradient(135deg, rgba(139, 92, 246, 0.1), rgba(139, 92, 246, 0.05)); + color: #e8e8f0; + border-radius: 6px; +} + +/* Списки с мягкими границами */ +[data-theme="dark"] .list-group-item { + background: linear-gradient(145deg, #22222f, #2a2a3a); + border: 1px solid #35353f; + transition: all 0.3s ease; +} + +[data-theme="dark"] .list-group-item:hover { + background: linear-gradient(145deg, #2a2a3a, #32323f); + border-color: rgba(139, 92, 246, 0.3); + box-shadow: 0 4px 15px rgba(139, 92, 246, 0.1); +} + +/* Вкладки с плавными переходами */ +[data-theme="dark"] .nav-tabs { + border-bottom: 2px solid #35353f; +} + +[data-theme="dark"] .nav-tabs .nav-link { + background: transparent; + border: none; + color: #9090a0; + border-radius: 8px 8px 0 0; + transition: all 0.3s ease; +} + +[data-theme="dark"] .nav-tabs .nav-link:hover { + background: linear-gradient(145deg, rgba(139, 92, 246, 0.05), rgba(139, 92, 246, 0.1)); + color: #b8b8c8; +} + +[data-theme="dark"] .nav-tabs .nav-link.active { + background: linear-gradient(145deg, #22222f, #2a2a3a); + color: #8b5cf6; + border-bottom: 3px solid #8b5cf6; + box-shadow: 0 -2px 10px rgba(139, 92, 246, 0.2); +} + +/* Алерты с мягкими цветами */ +[data-theme="dark"] .alert { + border: none; + border-radius: 12px; + border-left-width: 4px; + border-left-style: solid; + -webkit-backdrop-filter: blur(10px); + backdrop-filter: blur(10px); +} + +/* Скроллбар с улучшенной видимостью */ +[data-theme="dark"] ::-webkit-scrollbar { + width: 14px; + height: 14px; +} + +[data-theme="dark"] ::-webkit-scrollbar-track { + background: #1c1c28; + border-radius: 8px; + margin: 2px; +} + +[data-theme="dark"] ::-webkit-scrollbar-thumb { + background: linear-gradient(135deg, #7c3aed, #8b5cf6); + border-radius: 8px; + border: 2px solid #1c1c28; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); +} + +[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { + background: linear-gradient(135deg, #8b5cf6, #9333ea); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.15), + 0 0 10px rgba(139, 92, 246, 0.3); +} + +/* Медиа-запросы для адаптации к предпочтениям пользователя */ +@media (prefers-reduced-motion: reduce) { + [data-theme="dark"] * { + transition: none !important; + animation: none !important; + } +} + +@media (prefers-contrast: high) { + [data-theme="dark"] { + --text: #f0f0f6; + --text-secondary: #c8c8d0; + --border: #4a4a5a; + } +} + +@media (prefers-color-scheme: dark) and (prefers-reduced-transparency: reduce) { + [data-theme="dark"] .modal-backdrop, + [data-theme="dark"] .navbar, + [data-theme="dark"] .dropdown-menu { + -webkit-backdrop-filter: none; + backdrop-filter: none; + } +} + +/* Специальные утилиты для ночного комфорта */ +.night-text { + color: var(--night-comfort-text) !important; + line-height: 1.7; +} + +.night-card { + background: var(--night-comfort-card) !important; + border: 1px solid var(--night-comfort-border) !important; + border-radius: 12px; +} + +.gentle-shadow { + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08) !important; +} + +.soft-glow { + box-shadow: 0 0 20px var(--gentle-glow) !important; +} + +/* Анимации для плавности */ +@keyframes gentle-pulse { + 0%, 100% { + opacity: 0.8; + } + 50% { + opacity: 1; + } +} + +[data-theme="dark"] .pulse-gentle { + animation: gentle-pulse 3s ease-in-out infinite; +} \ No newline at end of file