Реализовано переключение темной и светлой темы в интерфейсе

- Добавлены функции для переключения между темной и светлой темами с использованием localStorage.
- Обновлены стили для поддержки темной темы, включая цвета фона, текста и иконок.
- Добавлены кнопки для переключения темы на страницах входа, профиля, заметок и настроек.
- Оптимизирован код для предотвращения мерцания темы при загрузке страницы.
This commit is contained in:
Fovway 2025-10-25 17:14:04 +07:00
parent 283e8cad63
commit 8fd529302f
13 changed files with 691 additions and 135 deletions

View File

@ -1,13 +0,0 @@
# This is an example configuration file
# To learn more, see the full config.yaml reference: https://docs.continue.dev/reference
name: Example Config
version: 1.0.0
schema: v1
models:
- name: qwen/qwen3-235b-a22b:free
provider: openrouter
model: qwen/qwen3-235b-a22b:free
apiBase: https://openrouter.ai/api/v1
apiKey: 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

View File

@ -1,10 +0,0 @@
name: New MCP server
version: 0.0.1
schema: v1
mcpServers:
- name: New MCP server
command: npx
args:
- -y
- <your-mcp-server>
env: {}

View File

@ -14,7 +14,7 @@ async function cacheAvatar(avatarUrl) {
const cacheData = { const cacheData = {
base64: base64, base64: base64,
timestamp: Date.now(), timestamp: Date.now(),
url: avatarUrl url: avatarUrl,
}; };
localStorage.setItem(AVATAR_CACHE_KEY, JSON.stringify(cacheData)); localStorage.setItem(AVATAR_CACHE_KEY, JSON.stringify(cacheData));
@ -475,7 +475,7 @@ function insertMarkdown(tag) {
// Определяем, какие теги оборачивают текст (нуждаются в двойных тегах) // Определяем, какие теги оборачивают текст (нуждаются в двойных тегах)
const wrappingTags = ["**", "*", "`"]; const wrappingTags = ["**", "*", "`"];
const isWrappingTag = wrappingTags.some(wrapTag => tag.startsWith(wrapTag)); const isWrappingTag = wrappingTags.some((wrapTag) => tag.startsWith(wrapTag));
if (isWrappingTag && selected.startsWith(tag) && selected.endsWith(tag)) { if (isWrappingTag && selected.startsWith(tag) && selected.endsWith(tag)) {
// Если оборачивающие теги уже есть, удаляем их // Если оборачивающие теги уже есть, удаляем их
@ -619,7 +619,7 @@ function insertMarkdownForEdit(textarea, tag) {
// Определяем, какие теги оборачивают текст (нуждаются в двойных тегах) // Определяем, какие теги оборачивают текст (нуждаются в двойных тегах)
const wrappingTags = ["**", "*", "`"]; const wrappingTags = ["**", "*", "`"];
const isWrappingTag = wrappingTags.some(wrapTag => tag.startsWith(wrapTag)); const isWrappingTag = wrappingTags.some((wrapTag) => tag.startsWith(wrapTag));
if (isWrappingTag && selected.startsWith(tag) && selected.endsWith(tag)) { if (isWrappingTag && selected.startsWith(tag) && selected.endsWith(tag)) {
// Если оборачивающие теги уже есть, удаляем их // Если оборачивающие теги уже есть, удаляем их
@ -815,11 +815,11 @@ headerBtn.addEventListener("click", function (event) {
// Если меню выходит за правую границу, позиционируем его слева // Если меню выходит за правую границу, позиционируем его слева
if (rect.right > viewportWidth) { if (rect.right > viewportWidth) {
headerDropdown.style.left = 'auto'; headerDropdown.style.left = "auto";
headerDropdown.style.right = '0'; headerDropdown.style.right = "0";
} else { } else {
headerDropdown.style.left = '0'; headerDropdown.style.left = "0";
headerDropdown.style.right = 'auto'; headerDropdown.style.right = "auto";
} }
headerDropdown.classList.toggle("show"); headerDropdown.classList.toggle("show");
@ -1412,7 +1412,9 @@ async function renderNotes(notes) {
const updated = parseSQLiteUtc(note.updated_at); const updated = parseSQLiteUtc(note.updated_at);
dateDisplay = `${formatLocalDateTime( dateDisplay = `${formatLocalDateTime(
created created
)} <span class="iconify" data-icon="mdi:pencil" style="font-size: 12px; margin-left: 8px;"></span> ${formatLocalDateTime(updated)}`; )} <span class="date-separator"> | </span> <span class="iconify" data-icon="mdi:pencil" style="font-size: 12px; margin: 0 2px;"></span> ${formatLocalDateTime(
updated
)}`;
} else { } else {
dateDisplay = formatLocalDateTime(created); dateDisplay = formatLocalDateTime(created);
} }
@ -1626,7 +1628,11 @@ function addNoteEventListeners() {
const markdownButtons = [ const markdownButtons = [
{ id: "editBoldBtn", icon: "mdi:format-bold", tag: "**" }, { id: "editBoldBtn", icon: "mdi:format-bold", tag: "**" },
{ id: "editItalicBtn", icon: "mdi:format-italic", tag: "*" }, { id: "editItalicBtn", icon: "mdi:format-italic", tag: "*" },
{ id: "editStrikethroughBtn", icon: "mdi:format-strikethrough", tag: "~~" }, {
id: "editStrikethroughBtn",
icon: "mdi:format-strikethrough",
tag: "~~",
},
{ id: "editColorBtn", icon: "mdi:palette", tag: "color" }, { id: "editColorBtn", icon: "mdi:palette", tag: "color" },
{ id: "editHeaderBtn", icon: "mdi:format-header-pound", tag: "header" }, { id: "editHeaderBtn", icon: "mdi:format-header-pound", tag: "header" },
{ id: "editListBtn", icon: "mdi:format-list-bulleted", tag: "- " }, { id: "editListBtn", icon: "mdi:format-list-bulleted", tag: "- " },
@ -1686,7 +1692,8 @@ function addNoteEventListeners() {
// Обработчик открытия/закрытия dropdown // Обработчик открытия/закрытия dropdown
headerBtn.addEventListener("click", function (e) { headerBtn.addEventListener("click", function (e) {
e.stopPropagation(); e.stopPropagation();
headerDropdown.style.display = headerDropdown.style.display === "none" ? "block" : "none"; headerDropdown.style.display =
headerDropdown.style.display === "none" ? "block" : "none";
headerBtn.classList.toggle("active"); headerBtn.classList.toggle("active");
}); });
@ -2741,7 +2748,7 @@ async function loadUserInfo() {
// Загружаем аватарку с сервера и кэшируем // Загружаем аватарку с сервера и кэшируем
userAvatar.src = user.avatar; userAvatar.src = user.avatar;
// Кэшируем в фоне // Кэшируем в фоне
cacheAvatar(user.avatar).then(success => { cacheAvatar(user.avatar).then((success) => {
if (success) { if (success) {
console.log("Аватарка закэширована (notes)"); console.log("Аватарка закэширована (notes)");
} }
@ -3530,3 +3537,65 @@ function initSearchMobile() {
} }
}); });
} }
// Логика переключения темы
function initThemeToggle() {
const themeToggleBtn = document.getElementById("theme-toggle-btn");
if (!themeToggleBtn) return;
// Загружаем сохраненную тему или используем системную
const savedTheme = localStorage.getItem("theme");
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
const currentTheme = savedTheme || systemTheme;
// Применяем тему
applyTheme(currentTheme);
// Обработчик клика на переключатель
themeToggleBtn.addEventListener("click", () => {
const currentTheme = document.documentElement.getAttribute("data-theme");
const newTheme = currentTheme === "dark" ? "light" : "dark";
applyTheme(newTheme);
localStorage.setItem("theme", newTheme);
});
// Слушаем изменения системной темы
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (e) => {
if (!localStorage.getItem("theme")) {
applyTheme(e.matches ? "dark" : "light");
}
});
}
function applyTheme(theme) {
document.documentElement.setAttribute("data-theme", theme);
// Обновляем meta теги для PWA
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
if (themeColorMeta) {
themeColorMeta.setAttribute(
"content",
theme === "dark" ? "#1a1a1a" : "#007bff"
);
}
// Обновляем иконку переключателя
const themeToggleBtn = document.getElementById("theme-toggle-btn");
if (themeToggleBtn) {
const icon = themeToggleBtn.querySelector(".iconify");
if (icon) {
icon.setAttribute(
"data-icon",
theme === "dark" ? "mdi:weather-sunny" : "mdi:weather-night"
);
}
}
}
// Инициализируем переключатель темы при загрузке страницы
document.addEventListener("DOMContentLoaded", initThemeToggle);

View File

@ -17,6 +17,23 @@
} catch (e) {} } catch (e) {}
</script> </script>
<!-- Предотвращение мерцания темы -->
<script>
(function () {
try {
const savedTheme = localStorage.getItem("theme");
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
const theme = savedTheme || (systemPrefersDark ? "dark" : "light");
if (theme === "dark") {
document.documentElement.setAttribute("data-theme", "dark");
}
} catch (e) {}
})();
</script>
<!-- PWA Meta Tags --> <!-- PWA Meta Tags -->
<meta <meta
name="description" name="description"
@ -94,7 +111,25 @@
<body> <body>
<div class="container"> <div class="container">
<header> <header>
<span class="iconify" data-icon="mdi:login"></span> Вход в систему <div
style="
display: flex;
align-items: center;
justify-content: space-between;
"
>
<span
><span class="iconify" data-icon="mdi:login"></span> Вход в
систему</span
>
<button
id="theme-toggle-btn"
class="theme-toggle-btn"
title="Переключить тему"
>
<span class="iconify" data-icon="mdi:theme-light-dark"></span>
</button>
</div>
</header> </header>
<div class="login-form"> <div class="login-form">
<form id="loginForm"> <form id="loginForm">

View File

@ -1,5 +1,67 @@
// Логика переключения темы
function initThemeToggle() {
const themeToggleBtn = document.getElementById("theme-toggle-btn");
if (!themeToggleBtn) return;
// Загружаем сохраненную тему или используем системную
const savedTheme = localStorage.getItem("theme");
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
const currentTheme = savedTheme || systemTheme;
// Применяем тему
applyTheme(currentTheme);
// Обработчик клика на переключатель
themeToggleBtn.addEventListener("click", () => {
const currentTheme = document.documentElement.getAttribute("data-theme");
const newTheme = currentTheme === "dark" ? "light" : "dark";
applyTheme(newTheme);
localStorage.setItem("theme", newTheme);
});
// Слушаем изменения системной темы
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (e) => {
if (!localStorage.getItem("theme")) {
applyTheme(e.matches ? "dark" : "light");
}
});
}
function applyTheme(theme) {
document.documentElement.setAttribute("data-theme", theme);
// Обновляем meta теги для PWA
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
if (themeColorMeta) {
themeColorMeta.setAttribute(
"content",
theme === "dark" ? "#1a1a1a" : "#007bff"
);
}
// Обновляем иконку переключателя
const themeToggleBtn = document.getElementById("theme-toggle-btn");
if (themeToggleBtn) {
const icon = themeToggleBtn.querySelector(".iconify");
if (icon) {
icon.setAttribute(
"data-icon",
theme === "dark" ? "mdi:weather-sunny" : "mdi:weather-night"
);
}
}
}
// Инициализируем переключатель темы при загрузке страницы
document.addEventListener("DOMContentLoaded", initThemeToggle);
// Проверяем, не авторизован ли уже пользователь // Проверяем, не авторизован ли уже пользователь
if (localStorage.getItem('isAuthenticated') === 'true') { if (localStorage.getItem("isAuthenticated") === "true") {
window.location.href = "/notes"; window.location.href = "/notes";
} }
@ -40,8 +102,8 @@ if (loginForm) {
if (response.ok) { if (response.ok) {
// Успешный вход - сохраняем состояние аутентификации // Успешный вход - сохраняем состояние аутентификации
localStorage.setItem('isAuthenticated', 'true'); localStorage.setItem("isAuthenticated", "true");
localStorage.setItem('username', username); localStorage.setItem("username", username);
window.location.href = "/notes"; window.location.href = "/notes";
} else { } else {
// Ошибка входа // Ошибка входа

View File

@ -8,6 +8,23 @@
/> />
<title>Заметки - NoteJS</title> <title>Заметки - NoteJS</title>
<!-- Предотвращение мерцания темы -->
<script>
(function () {
try {
const savedTheme = localStorage.getItem("theme");
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
const theme = savedTheme || (systemPrefersDark ? "dark" : "light");
if (theme === "dark") {
document.documentElement.setAttribute("data-theme", "dark");
}
} catch (e) {}
})();
</script>
<!-- PWA Meta Tags --> <!-- PWA Meta Tags -->
<meta <meta
name="description" name="description"
@ -239,6 +256,13 @@
> >
<span class="iconify" data-icon="mdi:account"></span> <span class="iconify" data-icon="mdi:account"></span>
</div> </div>
<button
id="theme-toggle-btn"
class="theme-toggle-btn"
title="Переключить тему"
>
<span class="iconify" data-icon="mdi:theme-light-dark"></span>
</button>
<button <button
id="settings-btn" id="settings-btn"
class="settings-icon-btn" class="settings-icon-btn"

View File

@ -8,6 +8,23 @@
/> />
<title>Личный кабинет - NoteJS</title> <title>Личный кабинет - NoteJS</title>
<!-- Предотвращение мерцания темы -->
<script>
(function () {
try {
const savedTheme = localStorage.getItem("theme");
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
const theme = savedTheme || (systemPrefersDark ? "dark" : "light");
if (theme === "dark") {
document.documentElement.setAttribute("data-theme", "dark");
}
} catch (e) {}
})();
</script>
<!-- PWA Meta Tags --> <!-- PWA Meta Tags -->
<meta <meta
name="description" name="description"
@ -58,6 +75,13 @@
кабинет</span кабинет</span
> >
<div class="user-info"> <div class="user-info">
<button
id="theme-toggle-btn"
class="theme-toggle-btn"
title="Переключить тему"
>
<span class="iconify" data-icon="mdi:theme-light-dark"></span>
</button>
<a href="/notes" class="back-btn"> <a href="/notes" class="back-btn">
<span class="iconify" data-icon="mdi:note-text"></span> К заметкам <span class="iconify" data-icon="mdi:note-text"></span> К заметкам
</a> </a>

View File

@ -1,3 +1,65 @@
// Логика переключения темы
function initThemeToggle() {
const themeToggleBtn = document.getElementById("theme-toggle-btn");
if (!themeToggleBtn) return;
// Загружаем сохраненную тему или используем системную
const savedTheme = localStorage.getItem("theme");
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
const currentTheme = savedTheme || systemTheme;
// Применяем тему
applyTheme(currentTheme);
// Обработчик клика на переключатель
themeToggleBtn.addEventListener("click", () => {
const currentTheme = document.documentElement.getAttribute("data-theme");
const newTheme = currentTheme === "dark" ? "light" : "dark";
applyTheme(newTheme);
localStorage.setItem("theme", newTheme);
});
// Слушаем изменения системной темы
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (e) => {
if (!localStorage.getItem("theme")) {
applyTheme(e.matches ? "dark" : "light");
}
});
}
function applyTheme(theme) {
document.documentElement.setAttribute("data-theme", theme);
// Обновляем meta теги для PWA
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
if (themeColorMeta) {
themeColorMeta.setAttribute(
"content",
theme === "dark" ? "#1a1a1a" : "#007bff"
);
}
// Обновляем иконку переключателя
const themeToggleBtn = document.getElementById("theme-toggle-btn");
if (themeToggleBtn) {
const icon = themeToggleBtn.querySelector(".iconify");
if (icon) {
icon.setAttribute(
"data-icon",
theme === "dark" ? "mdi:weather-sunny" : "mdi:weather-night"
);
}
}
}
// Инициализируем переключатель темы при загрузке страницы
document.addEventListener("DOMContentLoaded", initThemeToggle);
// DOM элементы // DOM элементы
const avatarImage = document.getElementById("avatarImage"); const avatarImage = document.getElementById("avatarImage");
const avatarPlaceholder = document.getElementById("avatarPlaceholder"); const avatarPlaceholder = document.getElementById("avatarPlaceholder");
@ -28,7 +90,7 @@ async function cacheAvatar(avatarUrl) {
const cacheData = { const cacheData = {
base64: base64, base64: base64,
timestamp: Date.now(), timestamp: Date.now(),
url: avatarUrl url: avatarUrl,
}; };
localStorage.setItem(AVATAR_CACHE_KEY, JSON.stringify(cacheData)); localStorage.setItem(AVATAR_CACHE_KEY, JSON.stringify(cacheData));
@ -165,7 +227,7 @@ async function loadProfile() {
// Загружаем аватарку с сервера и кэшируем // Загружаем аватарку с сервера и кэшируем
avatarImage.src = user.avatar; avatarImage.src = user.avatar;
// Кэшируем в фоне // Кэшируем в фоне
cacheAvatar(user.avatar).then(success => { cacheAvatar(user.avatar).then((success) => {
if (success) { if (success) {
console.log("Аватарка закэширована"); console.log("Аватарка закэширована");
} }
@ -232,7 +294,7 @@ avatarInput.addEventListener("change", async function (event) {
deleteAvatarBtn.style.display = "inline-block"; deleteAvatarBtn.style.display = "inline-block";
// Обновляем кэш с новой аватаркой // Обновляем кэш с новой аватаркой
cacheAvatar(result.avatar).then(success => { cacheAvatar(result.avatar).then((success) => {
if (success) { if (success) {
console.log("Новая аватарка закэширована"); console.log("Новая аватарка закэширована");
} }

View File

@ -16,6 +16,23 @@
} catch (e) {} } catch (e) {}
</script> </script>
<!-- Предотвращение мерцания темы -->
<script>
(function () {
try {
const savedTheme = localStorage.getItem("theme");
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
const theme = savedTheme || (systemPrefersDark ? "dark" : "light");
if (theme === "dark") {
document.documentElement.setAttribute("data-theme", "dark");
}
} catch (e) {}
})();
</script>
<!-- PWA Meta Tags --> <!-- PWA Meta Tags -->
<meta <meta
name="description" name="description"
@ -93,7 +110,25 @@
<body> <body>
<div class="container"> <div class="container">
<header> <header>
<span class="iconify" data-icon="mdi:account-plus"></span> Регистрация <div
style="
display: flex;
align-items: center;
justify-content: space-between;
"
>
<span
><span class="iconify" data-icon="mdi:account-plus"></span>
Регистрация</span
>
<button
id="theme-toggle-btn"
class="theme-toggle-btn"
title="Переключить тему"
>
<span class="iconify" data-icon="mdi:theme-light-dark"></span>
</button>
</div>
</header> </header>
<div class="login-form"> <div class="login-form">
<form id="registerForm"> <form id="registerForm">

View File

@ -1,5 +1,67 @@
// Логика переключения темы
function initThemeToggle() {
const themeToggleBtn = document.getElementById("theme-toggle-btn");
if (!themeToggleBtn) return;
// Загружаем сохраненную тему или используем системную
const savedTheme = localStorage.getItem("theme");
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
const currentTheme = savedTheme || systemTheme;
// Применяем тему
applyTheme(currentTheme);
// Обработчик клика на переключатель
themeToggleBtn.addEventListener("click", () => {
const currentTheme = document.documentElement.getAttribute("data-theme");
const newTheme = currentTheme === "dark" ? "light" : "dark";
applyTheme(newTheme);
localStorage.setItem("theme", newTheme);
});
// Слушаем изменения системной темы
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (e) => {
if (!localStorage.getItem("theme")) {
applyTheme(e.matches ? "dark" : "light");
}
});
}
function applyTheme(theme) {
document.documentElement.setAttribute("data-theme", theme);
// Обновляем meta теги для PWA
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
if (themeColorMeta) {
themeColorMeta.setAttribute(
"content",
theme === "dark" ? "#1a1a1a" : "#007bff"
);
}
// Обновляем иконку переключателя
const themeToggleBtn = document.getElementById("theme-toggle-btn");
if (themeToggleBtn) {
const icon = themeToggleBtn.querySelector(".iconify");
if (icon) {
icon.setAttribute(
"data-icon",
theme === "dark" ? "mdi:weather-sunny" : "mdi:weather-night"
);
}
}
}
// Инициализируем переключатель темы при загрузке страницы
document.addEventListener("DOMContentLoaded", initThemeToggle);
// Проверяем, не авторизован ли уже пользователь // Проверяем, не авторизован ли уже пользователь
if (localStorage.getItem('isAuthenticated') === 'true') { if (localStorage.getItem("isAuthenticated") === "true") {
window.location.href = "/notes"; window.location.href = "/notes";
} }
@ -53,8 +115,8 @@ if (registerForm) {
if (response.ok) { if (response.ok) {
// Успешная регистрация - сохраняем состояние аутентификации // Успешная регистрация - сохраняем состояние аутентификации
localStorage.setItem('isAuthenticated', 'true'); localStorage.setItem("isAuthenticated", "true");
localStorage.setItem('username', username); localStorage.setItem("username", username);
window.location.href = "/notes"; window.location.href = "/notes";
} else { } else {
// Ошибка регистрации // Ошибка регистрации

View File

@ -8,6 +8,23 @@
/> />
<title>Настройки - NoteJS</title> <title>Настройки - NoteJS</title>
<!-- Предотвращение мерцания темы -->
<script>
(function () {
try {
const savedTheme = localStorage.getItem("theme");
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
const theme = savedTheme || (systemPrefersDark ? "dark" : "light");
if (theme === "dark") {
document.documentElement.setAttribute("data-theme", "dark");
}
} catch (e) {}
})();
</script>
<!-- PWA Meta Tags --> <!-- PWA Meta Tags -->
<meta <meta
name="description" name="description"
@ -56,6 +73,13 @@
<header class="notes-header"> <header class="notes-header">
<span><span class="iconify" data-icon="mdi:cog"></span> Настройки</span> <span><span class="iconify" data-icon="mdi:cog"></span> Настройки</span>
<div class="user-info"> <div class="user-info">
<button
id="theme-toggle-btn"
class="theme-toggle-btn"
title="Переключить тему"
>
<span class="iconify" data-icon="mdi:theme-light-dark"></span>
</button>
<a href="/notes" class="back-btn"> <a href="/notes" class="back-btn">
<span class="iconify" data-icon="mdi:note-text"></span> К заметкам <span class="iconify" data-icon="mdi:note-text"></span> К заметкам
</a> </a>

View File

@ -1,3 +1,65 @@
// Логика переключения темы
function initThemeToggle() {
const themeToggleBtn = document.getElementById("theme-toggle-btn");
if (!themeToggleBtn) return;
// Загружаем сохраненную тему или используем системную
const savedTheme = localStorage.getItem("theme");
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light";
const currentTheme = savedTheme || systemTheme;
// Применяем тему
applyTheme(currentTheme);
// Обработчик клика на переключатель
themeToggleBtn.addEventListener("click", () => {
const currentTheme = document.documentElement.getAttribute("data-theme");
const newTheme = currentTheme === "dark" ? "light" : "dark";
applyTheme(newTheme);
localStorage.setItem("theme", newTheme);
});
// Слушаем изменения системной темы
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (e) => {
if (!localStorage.getItem("theme")) {
applyTheme(e.matches ? "dark" : "light");
}
});
}
function applyTheme(theme) {
document.documentElement.setAttribute("data-theme", theme);
// Обновляем meta теги для PWA
const themeColorMeta = document.querySelector('meta[name="theme-color"]');
if (themeColorMeta) {
themeColorMeta.setAttribute(
"content",
theme === "dark" ? "#1a1a1a" : "#007bff"
);
}
// Обновляем иконку переключателя
const themeToggleBtn = document.getElementById("theme-toggle-btn");
if (themeToggleBtn) {
const icon = themeToggleBtn.querySelector(".iconify");
if (icon) {
icon.setAttribute(
"data-icon",
theme === "dark" ? "mdi:weather-sunny" : "mdi:weather-night"
);
}
}
}
// Инициализируем переключатель темы при загрузке страницы
document.addEventListener("DOMContentLoaded", initThemeToggle);
// Переменные для пагинации логов // Переменные для пагинации логов
let logsOffset = 0; let logsOffset = 0;
const logsLimit = 50; const logsLimit = 50;

View File

@ -1,17 +1,73 @@
:root { :root {
--accent-color: #007bff; --accent-color: #007bff;
/* Светлая тема (по умолчанию) */
--bg-primary: #f5f5f5;
--bg-secondary: #ffffff;
--bg-tertiary: #f8f9fa;
--bg-quaternary: #e9ecef;
--bg-hover: #e7f3ff;
--text-primary: #333333;
--text-secondary: #666666;
--text-muted: #999999;
--text-light: #757575;
--border-primary: #e0e0e0;
--border-secondary: #dddddd;
--border-focus: #007bff;
--shadow-light: rgba(0, 0, 0, 0.1);
--shadow-medium: rgba(0, 0, 0, 0.15);
/* Цвета иконок */
--icon-search: #2196f3;
--icon-tags: #4caf50;
--icon-notes: #ff9800;
--icon-user: #9c27b0;
--icon-danger: #dc3545;
}
/* Темная тема */
[data-theme="dark"] {
--bg-primary: #1a1a1a;
--bg-secondary: #2d2d2d;
--bg-tertiary: #3a3a3a;
--bg-quaternary: #4a4a4a;
--bg-hover: #2a4a6b;
--text-primary: #ffffff;
--text-secondary: #cccccc;
--text-muted: #999999;
--text-light: #aaaaaa;
--border-primary: #404040;
--border-secondary: #555555;
--border-focus: #4a9eff;
--shadow-light: rgba(0, 0, 0, 0.3);
--shadow-medium: rgba(0, 0, 0, 0.4);
/* Цвета иконок в темной теме */
--icon-search: #64b5f6;
--icon-tags: #81c784;
--icon-notes: #ffb74d;
--icon-user: #ba68c8;
--icon-danger: #f44336;
} }
body { body {
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
padding: 0; padding: 0;
margin: 0; margin: 0;
background: #f5f5f5; background: var(--bg-primary);
color: var(--text-primary);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: flex-start; align-items: flex-start;
gap: 30px; gap: 30px;
padding: 0 15px; padding: 0 15px;
transition: background-color 0.3s ease, color 0.3s ease;
} }
/* /*
@ -77,26 +133,58 @@ header .iconify {
/* Цветные иконки */ /* Цветные иконки */
/* Иконка поиска - синий */ /* Иконка поиска - синий */
.search-title .iconify[data-icon="mdi:magnify"] { .search-title .iconify[data-icon="mdi:magnify"] {
color: #2196f3; color: var(--icon-search);
} }
/* Иконка тегов - зеленый */ /* Иконка тегов - зеленый */
.tags-title .iconify[data-icon="mdi:tag"] { .tags-title .iconify[data-icon="mdi:tag"] {
color: #4caf50; color: var(--icon-tags);
} }
/* Иконка заметок - оранжевый */ /* Иконка заметок - оранжевый */
header .iconify[data-icon="mdi:note-text"] { header .iconify[data-icon="mdi:note-text"] {
color: #ff9800; color: var(--icon-notes);
} }
/* Иконка пользователя - фиолетовый */ /* Иконка пользователя - фиолетовый */
header .iconify[data-icon="mdi:account"], header .iconify[data-icon="mdi:account"],
.username-clickable .iconify[data-icon="mdi:account"] { .username-clickable .iconify[data-icon="mdi:account"] {
color: #9c27b0; color: var(--icon-user);
} }
/* Цвет иконки выхода задается в стилях .logout-btn .iconify */ /* Переключатель темы */
.theme-toggle-btn {
width: 40px;
height: 40px;
border-radius: 50%;
border: none;
background: var(--bg-secondary);
color: var(--text-secondary);
cursor: pointer;
font-size: 18px;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.theme-toggle-btn:hover {
background-color: var(--accent-color, #007bff);
color: white;
transform: scale(1.1);
}
.theme-toggle-btn .iconify {
font-size: 18px;
color: var(--text-secondary);
transition: color 0.3s ease;
margin: 0;
}
.theme-toggle-btn:hover .iconify {
color: white;
}
/* Иконка входа - синий */ /* Иконка входа - синий */
header .iconify[data-icon="mdi:login"] { header .iconify[data-icon="mdi:login"] {
@ -110,11 +198,11 @@ header .iconify[data-icon="mdi:account-plus"] {
/* Markdown кнопки - разные цвета */ /* Markdown кнопки - разные цвета */
.btnMarkdown .iconify[data-icon="mdi:format-bold"] { .btnMarkdown .iconify[data-icon="mdi:format-bold"] {
color: #424242; color: var(--text-primary);
} }
.btnMarkdown .iconify[data-icon="mdi:format-italic"] { .btnMarkdown .iconify[data-icon="mdi:format-italic"] {
color: #757575; color: var(--text-primary);
} }
.btnMarkdown .iconify[data-icon="mdi:palette"] { .btnMarkdown .iconify[data-icon="mdi:palette"] {
@ -142,7 +230,7 @@ header .iconify[data-icon="mdi:account-plus"] {
} }
.btnMarkdown .iconify[data-icon="mdi:format-strikethrough"] { .btnMarkdown .iconify[data-icon="mdi:format-strikethrough"] {
color: #9c27b0; color: var(--text-primary);
} }
.btnMarkdown .iconify[data-icon="mdi:format-list-numbered"] { .btnMarkdown .iconify[data-icon="mdi:format-list-numbered"] {
@ -191,7 +279,7 @@ header {
.search-section { .search-section {
margin-top: 15px; margin-top: 15px;
padding-top: 15px; padding-top: 15px;
border-top: 1px solid #e0e0e0; border-top: 1px solid var(--border-primary);
} }
.search-header { .search-header {
@ -201,7 +289,7 @@ header {
.search-title { .search-title {
font-size: 12px; font-size: 12px;
font-weight: bold; font-weight: bold;
color: #333; color: var(--text-primary);
} }
.search-container { .search-container {
@ -212,18 +300,19 @@ header {
.search-input { .search-input {
width: 100%; width: 100%;
padding: 6px 30px 6px 10px; padding: 6px 30px 6px 10px;
border: 1px solid #ddd; border: 1px solid var(--border-secondary);
border-radius: 15px; border-radius: 15px;
font-size: 12px; font-size: 12px;
background-color: #f8f9fa; background-color: var(--bg-tertiary);
color: var(--text-primary);
transition: all 0.3s ease; transition: all 0.3s ease;
box-sizing: border-box; box-sizing: border-box;
} }
.search-input:focus { .search-input:focus {
outline: none; outline: none;
border-color: var(--accent-color, #007bff); border-color: var(--border-focus);
background-color: white; background-color: var(--bg-secondary);
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25); box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
} }
@ -243,26 +332,26 @@ header {
} }
.clear-search-btn:hover { .clear-search-btn:hover {
background-color: #e9ecef; background-color: var(--bg-quaternary);
color: #666; color: var(--text-secondary);
} }
.filter-indicator { .filter-indicator {
display: inline-block; display: inline-block;
margin-top: 5px; margin-top: 5px;
padding: 4px 10px; padding: 4px 10px;
background-color: #e7f3ff; background-color: var(--bg-hover);
border: 1px solid var(--accent-color, #007bff); border: 1px solid var(--border-focus);
border-radius: 15px; border-radius: 15px;
font-size: 12px; font-size: 12px;
color: var(--accent-color, #007bff); color: var(--border-focus);
font-weight: 500; font-weight: 500;
} }
.filter-indicator button { .filter-indicator button {
background: none; background: none;
border: none; border: none;
color: #dc3545; color: var(--icon-danger);
cursor: pointer; cursor: pointer;
margin-left: 8px; margin-left: 8px;
font-weight: bold; font-weight: bold;
@ -271,7 +360,7 @@ header {
} }
.filter-indicator button:hover { .filter-indicator button:hover {
color: #a71d2a; color: #ff6b6b;
} }
.user-info { .user-info {
@ -331,7 +420,8 @@ header {
height: 40px; height: 40px;
border-radius: 50%; border-radius: 50%;
border: none; border: none;
background: white; background: var(--bg-secondary);
color: var(--text-secondary);
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center; align-items: center;
@ -365,7 +455,8 @@ header {
height: 40px; height: 40px;
border-radius: 50%; border-radius: 50%;
border: none; border: none;
background: white; background: var(--bg-secondary);
color: var(--text-secondary);
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center; align-items: center;
@ -411,15 +502,17 @@ header {
.container { .container {
width: 90%; width: 90%;
max-width: 600px; max-width: 600px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); box-shadow: 0 0 10px var(--shadow-light);
border-radius: 8px; border-radius: 8px;
padding: 15px; padding: 15px;
margin-top: 20px; margin-top: 20px;
background: white; background: var(--bg-secondary);
color: var(--text-primary);
box-sizing: border-box; box-sizing: border-box;
word-wrap: break-word; word-wrap: break-word;
overflow-wrap: break-word; overflow-wrap: break-word;
overflow: visible; overflow: visible;
transition: background-color 0.3s ease, color 0.3s ease, box-shadow 0.3s ease;
} }
.login-form { .login-form {
@ -434,28 +527,34 @@ header {
display: block; display: block;
margin-bottom: 5px; margin-bottom: 5px;
font-weight: bold; font-weight: bold;
color: var(--text-primary);
} }
.form-group input { .form-group input {
width: 100%; width: 100%;
padding: 10px; padding: 10px;
border: 1px solid #ddd; border: 1px solid var(--border-secondary);
border-radius: 5px; border-radius: 5px;
font-size: 16px; font-size: 16px;
background-color: var(--bg-tertiary);
color: var(--text-primary);
box-sizing: border-box; box-sizing: border-box;
transition: all 0.3s ease;
} }
.form-group input:focus { .form-group input:focus {
outline: none; outline: none;
border-color: var(--accent-color, #007bff); border-color: var(--border-focus);
background-color: var(--bg-secondary);
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
} }
.error-message { .error-message {
color: #dc3545; color: var(--icon-danger);
margin-top: 10px; margin-top: 10px;
padding: 10px; padding: 10px;
background-color: #f8d7da; background-color: rgba(220, 53, 69, 0.1);
border: 1px solid #f5c6cb; border: 1px solid rgba(220, 53, 69, 0.3);
border-radius: 5px; border-radius: 5px;
} }
@ -464,9 +563,11 @@ textarea {
min-height: 50px; min-height: 50px;
resize: none; resize: none;
border: none; border: none;
background: white; background: var(--bg-secondary);
color: var(--text-primary);
margin-bottom: 5px; margin-bottom: 5px;
overflow-y: hidden; overflow-y: hidden;
transition: background-color 0.3s ease, color 0.3s ease;
} }
textarea:focus { textarea:focus {
@ -489,7 +590,9 @@ textarea:focus {
padding: 10px 20px; padding: 10px 20px;
cursor: pointer; cursor: pointer;
border-width: 1px; border-width: 1px;
background: white; background: var(--bg-secondary);
color: var(--text-primary);
border: 1px solid var(--border-secondary);
border-radius: 5px; border-radius: 5px;
font-family: "Open Sans", sans-serif; font-family: "Open Sans", sans-serif;
transition: all 0.3s ease; transition: all 0.3s ease;
@ -518,14 +621,20 @@ textarea:focus {
text-overflow: ellipsis; text-overflow: ellipsis;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 4px;
flex-wrap: wrap; flex-wrap: wrap;
} }
.date-separator {
color: #999;
font-weight: normal;
margin: 0 2px;
}
.note-actions { .note-actions {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 4px;
flex-wrap: wrap; flex-wrap: wrap;
} }
@ -535,37 +644,37 @@ textarea:focus {
justify-content: center; justify-content: center;
gap: 4px; gap: 4px;
cursor: pointer; cursor: pointer;
color: black; color: var(--text-primary);
font-weight: bold; font-weight: bold;
white-space: nowrap; white-space: nowrap;
padding: 4px 8px; padding: 2px 4px;
border-radius: 4px; border-radius: 4px;
transition: all 0.2s ease; transition: all 0.2s ease;
font-size: 11px; font-size: 10px;
} }
.notesHeaderBtn:hover { .notesHeaderBtn:hover {
background: rgba(0, 0, 0, 0.05); background: var(--bg-quaternary);
} }
#pinBtn:hover { #pinBtn:hover {
background: #fff3cd; background: rgba(255, 193, 7, 0.2);
color: #856404; color: #ffc107;
} }
#archiveBtn:hover { #archiveBtn:hover {
background: #e2e3e5; background: var(--bg-quaternary);
color: #383d41; color: var(--text-primary);
} }
#editBtn:hover { #editBtn:hover {
background: #d1ecf1; background: rgba(13, 202, 240, 0.2);
color: #0c5460; color: #0dcaf0;
} }
#deleteBtn:hover { #deleteBtn:hover {
background: #f8d7da; background: rgba(220, 53, 69, 0.2);
color: #721c24; color: var(--icon-danger);
} }
.textNote { .textNote {
@ -590,7 +699,7 @@ textarea:focus {
left: 0; left: 0;
right: 0; right: 0;
height: 80px; height: 80px;
background: linear-gradient(to bottom, transparent, white); background: linear-gradient(to bottom, transparent, var(--bg-primary));
pointer-events: none; pointer-events: none;
} }
@ -816,8 +925,9 @@ textarea:focus {
padding: 5px 10px; padding: 5px 10px;
margin-right: 5px; margin-right: 5px;
cursor: pointer; cursor: pointer;
border: 1px solid #ddd; border: 1px solid var(--border-secondary);
background-color: #f0f0f0; background-color: var(--bg-tertiary);
color: var(--text-primary);
border-radius: 5px; border-radius: 5px;
font-size: 14px; font-size: 14px;
/* Улучшения для мобильных устройств */ /* Улучшения для мобильных устройств */
@ -829,10 +939,12 @@ textarea:focus {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
transition: all 0.3s ease;
} }
.markdown-buttons .btnMarkdown:hover { .markdown-buttons .btnMarkdown:hover {
background-color: #e0e0e0; background-color: var(--bg-quaternary);
border-color: var(--border-focus);
} }
/* Выпадающее меню заголовков */ /* Выпадающее меню заголовков */
@ -847,10 +959,10 @@ textarea:focus {
position: absolute; position: absolute;
top: 100%; top: 100%;
right: 0; right: 0;
background: white; background: var(--bg-secondary);
border: 1px solid #ddd; border: 1px solid var(--border-secondary);
border-radius: 5px; border-radius: 5px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); box-shadow: 0 2px 8px var(--shadow-medium);
z-index: 1000; z-index: 1000;
margin-top: 2px; margin-top: 2px;
min-width: 60px; min-width: 60px;
@ -871,12 +983,12 @@ textarea:focus {
cursor: pointer; cursor: pointer;
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
color: #333; color: var(--text-primary);
transition: background 0.2s ease; transition: background 0.2s ease;
} }
.header-dropdown-menu button:hover { .header-dropdown-menu button:hover {
background: #f0f0f0; background: var(--bg-quaternary);
} }
.header-dropdown-menu button:first-child { .header-dropdown-menu button:first-child {
@ -959,8 +1071,9 @@ textarea:focus {
.btn-delete { .btn-delete {
padding: 8px 16px; padding: 8px 16px;
cursor: pointer; cursor: pointer;
border: 1px solid #ddd; border: 1px solid var(--border-secondary);
background-color: #f8f9fa; background-color: var(--bg-tertiary);
color: var(--text-primary);
border-radius: 5px; border-radius: 5px;
font-size: 14px; font-size: 14px;
transition: all 0.3s ease; transition: all 0.3s ease;
@ -996,13 +1109,13 @@ textarea:focus {
.profile-form h3 { .profile-form h3 {
margin-bottom: 15px; margin-bottom: 15px;
color: #333; color: var(--text-primary);
} }
.separator { .separator {
margin: 30px 0; margin: 30px 0;
border: none; border: none;
border-top: 1px solid #e0e0e0; border-top: 1px solid var(--border-primary);
} }
.message-container { .message-container {
@ -1046,11 +1159,11 @@ textarea:focus {
.back-btn { .back-btn {
padding: 8px 16px; padding: 8px 16px;
border: 1px solid #ddd; border: 1px solid var(--border-secondary);
background-color: #f8f9fa; background-color: var(--bg-tertiary);
border-radius: 5px; border-radius: 5px;
font-size: 14px; font-size: 14px;
color: var(--accent-color, #007bff); color: var(--border-focus);
text-decoration: none; text-decoration: none;
transition: all 0.3s ease; transition: all 0.3s ease;
display: inline-block; display: inline-block;
@ -1085,11 +1198,13 @@ textarea:focus {
width: 200px; width: 200px;
height: auto; height: auto;
max-width: 200px; max-width: 200px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); box-shadow: 0 0 10px var(--shadow-light);
border-radius: 8px; border-radius: 8px;
padding: 12px; padding: 12px;
margin-top: 20px; margin-top: 20px;
background: white; background: var(--bg-secondary);
color: var(--text-primary);
transition: background-color 0.3s ease, color 0.3s ease, box-shadow 0.3s ease;
} }
/* Мини-календарь */ /* Мини-календарь */
@ -1107,7 +1222,7 @@ textarea:focus {
.calendar-month-year { .calendar-month-year {
font-size: 13px; font-size: 13px;
font-weight: bold; font-weight: bold;
color: #333; color: var(--text-primary);
} }
.calendar-nav { .calendar-nav {
@ -1135,7 +1250,7 @@ textarea:focus {
text-align: center; text-align: center;
font-size: 9px; font-size: 9px;
font-weight: bold; font-weight: bold;
color: #666; color: var(--text-secondary);
padding: 3px 0; padding: 3px 0;
} }
@ -1154,14 +1269,14 @@ textarea:focus {
cursor: pointer; cursor: pointer;
border-radius: 3px; border-radius: 3px;
transition: all 0.2s ease; transition: all 0.2s ease;
color: #333; color: var(--text-primary);
padding: 1px; padding: 1px;
font-weight: 500; font-weight: 500;
position: relative; position: relative;
} }
.calendar-day:hover { .calendar-day:hover {
background-color: #e7f3ff; background-color: var(--bg-hover);
} }
.calendar-day.today { .calendar-day.today {
@ -1171,7 +1286,7 @@ textarea:focus {
} }
.calendar-day.other-month { .calendar-day.other-month {
color: #ccc; color: var(--text-muted);
} }
.calendar-day.selected { .calendar-day.selected {
@ -1261,7 +1376,7 @@ textarea:focus {
.tags-section { .tags-section {
margin-top: 15px; margin-top: 15px;
padding-top: 15px; padding-top: 15px;
border-top: 1px solid #e0e0e0; border-top: 1px solid var(--border-primary);
} }
.tags-header { .tags-header {
@ -1271,7 +1386,7 @@ textarea:focus {
.tags-title { .tags-title {
font-size: 12px; font-size: 12px;
font-weight: bold; font-weight: bold;
color: #333; color: var(--text-primary);
} }
.tags-container { .tags-container {
@ -2148,15 +2263,16 @@ textarea:focus {
} }
.archived-note-item { .archived-note-item {
background: #f8f9fa; background: var(--bg-secondary);
border: 1px solid #dee2e6; border: 1px solid var(--border-primary);
border-radius: 8px; border-radius: 8px;
padding: 15px; padding: 15px;
transition: all 0.3s ease; transition: all 0.3s ease;
color: var(--text-primary);
} }
.archived-note-item:hover { .archived-note-item:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 8px var(--shadow-light);
} }
.archived-note-header { .archived-note-header {
@ -2170,7 +2286,7 @@ textarea:focus {
.archived-note-date { .archived-note-date {
font-size: 12px; font-size: 12px;
color: #999; color: var(--text-muted);
} }
.archived-note-actions { .archived-note-actions {
@ -2181,9 +2297,10 @@ textarea:focus {
.btn-restore, .btn-restore,
.btn-delete-permanent { .btn-delete-permanent {
padding: 6px 12px; padding: 6px 12px;
border: 1px solid #ddd; border: 1px solid var(--border-secondary);
border-radius: 5px; border-radius: 5px;
background: white; background: var(--bg-tertiary);
color: var(--text-primary);
cursor: pointer; cursor: pointer;
font-size: 13px; font-size: 13px;
transition: all 0.3s ease; transition: all 0.3s ease;
@ -2214,7 +2331,7 @@ textarea:focus {
.archived-note-content { .archived-note-content {
font-size: 14px; font-size: 14px;
color: #333; color: var(--text-primary);
line-height: 1.5; line-height: 1.5;
max-height: 100px; max-height: 100px;
overflow: hidden; overflow: hidden;
@ -2226,7 +2343,7 @@ textarea:focus {
.archived-note-images { .archived-note-images {
margin-top: 10px; margin-top: 10px;
font-size: 12px; font-size: 12px;
color: #666; color: var(--text-secondary);
font-style: italic; font-style: italic;
} }
@ -2242,9 +2359,11 @@ textarea:focus {
flex: 1; flex: 1;
min-width: 200px; min-width: 200px;
padding: 8px 12px; padding: 8px 12px;
border: 1px solid #ddd; border: 1px solid var(--border-secondary);
border-radius: 5px; border-radius: 5px;
font-size: 14px; font-size: 14px;
background-color: var(--bg-tertiary);
color: var(--text-primary);
} }
.log-filter-select:focus { .log-filter-select:focus {
@ -2260,34 +2379,35 @@ textarea:focus {
.logs-table { .logs-table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
background: white; background: var(--bg-secondary);
color: var(--text-primary);
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 3px var(--shadow-light);
} }
.logs-table thead { .logs-table thead {
background: #f8f9fa; background: var(--bg-tertiary);
} }
.logs-table th { .logs-table th {
padding: 12px; padding: 12px;
text-align: left; text-align: left;
font-weight: bold; font-weight: bold;
color: #333; color: var(--text-primary);
border-bottom: 2px solid #dee2e6; border-bottom: 2px solid var(--border-primary);
font-size: 14px; font-size: 14px;
} }
.logs-table td { .logs-table td {
padding: 12px; padding: 12px;
border-bottom: 1px solid #dee2e6; border-bottom: 1px solid var(--border-primary);
font-size: 13px; font-size: 13px;
color: #666; color: var(--text-secondary);
} }
.logs-table tbody tr:hover { .logs-table tbody tr:hover {
background: #f8f9fa; background: var(--bg-quaternary);
} }
.log-action-badge { .log-action-badge {
@ -2354,7 +2474,7 @@ textarea:focus {
/* Стили для закрепленных заметок */ /* Стили для закрепленных заметок */
.note-pinned { .note-pinned {
border-left: 4px solid #ffc107; border-left: 4px solid #ffc107;
background: #fffbf0; background: var(--bg-secondary);
} }
.pin-indicator { .pin-indicator {