/*
 * SPDX-FileCopyrightText: 2026 Netori
 * SPDX-License-Identifier: AGPL-3.0-or-later
 *
 * Типографика и движение Netori Space.
 *
 * Файл грузится ДОПОЛНИТЕЛЬНО к штатному core/css/server.css (так устроен
 * механизм тем), поэтому здесь только переопределения — копировать исходный
 * файл не нужно и вредно.
 *
 * Разделение с apps/netori/css/netori.css: здесь общий хром (шрифт, движение),
 * там — точечные правки собственных экранов платформы.
 */

@import url('../fonts/inter.css');

/*
 * Шрифт.
 *
 * Ядро использует --font-face во всех правилах, но объявляет её приложение
 * theming — динамическим CSS вида [data-theme-default] { --font-face: ... },
 * который подключается ПОСЛЕ темы. Специфичности :root (0,1,0) не хватает:
 * специфичности побеждает то, что ниже, поэтому нужен body[data-theme-*] —
 * — (0,2,0).
 *
 * Тема opendyslexic перечислена намеренно НЕ: там шрифт подобран под дислексию,
 * это функция доступности, и перебивать её брендингом нельзя.
 *
 * Системный стек оставлен запасным: если woff2 не загрузился (закрытый контур,
 * блокировка), интерфейс не должен посыпаться.
 */
body[data-theme-default],
body[data-theme-light],
body[data-theme-dark],
body[data-theme-light-highcontrast],
body[data-theme-dark-highcontrast] {
	--font-face: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto,
		'Helvetica Neue', Arial, sans-serif, 'Apple Color Emoji',
		'Segoe UI Emoji';
}

:root {
	/* Пологая кривая: быстрый старт, мягкое торможение. */
	--netori-ease: cubic-bezier(0.2, 0, 0.2, 1);

	/* Согласовано со штатными $animation-quick / $animation-slow
	   (core/css/variables.scss:86-87) — чтобы наше движение не спорило
	   с движением ядра. */
	--netori-quick: 100ms;
	--netori-slow: 300ms;
}

/* Inter при мелких кеглях выигрывает от чуть плотнее набранных заголовков. */
h1, h2, h3,
.app-navigation__list .app-navigation-entry__title {
	letter-spacing: -0.011em;
}

/* Цифры одинаковой ширины: размеры файлов и даты в списках перестают
   «прыгать» при обновлении. */
.files-list__row-size,
.files-list__row-mtime,
td.filesize,
.column-size {
	font-variant-numeric: tabular-nums;
}

/*
 * Движение.
 *
 * Только transform и opacity: остальные свойства заставляют браузер
 * пересчитывать раскладку на каждом кадре и дают заметные рывки на
 * списках в тысячи файлов.
 */

.button-vue,
.app-navigation-entry-link,
.action-item__menutoggle,
.files-list__row {
	transition:
		background-color var(--netori-quick) var(--netori-ease),
		transform var(--netori-quick) var(--netori-ease);
}

.button-vue:active,
.action-item__menutoggle:active {
	/* Короткое «нажатие» — единственная анимация, которую пользователь
	   замечает осознанно, потому что она отвечает на его действие. */
	transform: scale(0.97);
}

@keyframes netori-rise {
	from {
		opacity: 0;
		transform: translateY(8px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

/* Появление карточки логина и модальных окон. */
.guest-box,
.modal-container {
	animation: netori-rise var(--netori-slow) var(--netori-ease) both;
}

/*
 * Уважение к настройке «уменьшить движение».
 *
 * В ядре Nextcloud этой обработки нет вообще (проверено по core/css), то есть
 * ответственность целиком на нас. Без неё продукт непригоден для людей с
 * вестибулярными расстройствами и не проходит аудит доступности —
 * а доступность мы декларируем на экране «Внешний вид и доступность».
 *
 * Анимации не отключаются, а схлопываются: так не ломаются обработчики,
 * ждущие события animationend.
 */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/*
 * Чат: убраны штатные иллюстрации пустых состояний.
 *
 * Это фирменная графика Nextcloud в его синей палитре — в продукте под нашим
 * брендом ей не место, и с янтарным акцентом она откровенно спорит.
 * Карточки остаются: они несут текст, который объясняет пустое состояние.
 *
 * Селектор намеренно заякорен на .talk-dashboard-wrapper: класс
 * .dashboard-section слишком общий, и без якоря правило задело бы виджеты
 * на главной странице.
 *
 * Заменить картинки своими можно позже через переопределение
 * themes/netori/apps/spreed/img/dashboard/ — механизм подмены картинок
 * темой это поддерживает (URLGenerator.php:202).
 */
.talk-dashboard-wrapper .dashboard-section__bar.image-container {
	display: none;
}


/* ==========================================================================
   Визуальный слой Netori Space
   ==========================================================================

   Направление взято от netori.store: там весь сайт построен на ТЁПЛЫХ
   нейтральных тонах (OKLCH hue 84), а не на чистом сером. Ядро Nextcloud
   использует нейтральный серый, и рядом с акцентом #b89af2 он
   выглядит грязноватым — акцент кажется случайным, а не частью системы.
   Потепление нейтралей — самая дешёвая правка с самым заметным эффектом.

   ПОЧЕМУ ТРИ БЛОКА. Светлые переменные приезжают в /apps/theming/theme/
   default.css, тёмные — отдельным файлом, подключённым через
   media="(prefers-color-scheme: dark)" (ThemeInjectionService.php:48).
   Плюс пользователь может выбрать тему явно. Поэтому нужны: светлый набор,
   системный тёмный и явный тёмный — иначе одна из веток останется серой.

   ПОЧЕМУ body[data-theme-*]. Атрибут висит на body, а не на html, а CSS
   приложения theming подключается ПОСЛЕ темы. :root не совпадёт вовсе,
   а одного [data-theme-*] не хватит по специфичности.

   Тема opendyslexic не трогается: там оформление подчинено доступности.
   ========================================================================== */

/* --- Светлая ------------------------------------------------------------ */
body[data-theme-default],
body[data-theme-light],
body[data-theme-light-highcontrast] {
	--color-main-background: #fbf9f6;
	--color-main-background-rgb: 251, 249, 246;

	/*
	 * Производные переменные приходится задавать самим.
	 *
	 * Ядро объявляет их НА :root как rgba(var(--color-main-background-rgb), …),
	 * а подстановка var() происходит там, где переменная ОБЪЯВЛЕНА. Наше
	 * значение живёт на body, поэтому до этих производных оно не доезжает:
	 * карточки оставались холодно-серыми при уже тёплом фоне страницы.
	 */
	--color-main-background-translucent: rgba(var(--color-main-background-rgb), 0.97);
	--color-main-background-blur: rgba(var(--color-main-background-rgb), 0.85);
	--gradient-main-background: var(--color-main-background) 0%, var(--color-main-background-translucent) 85%, transparent 100%;
	--color-background-hover: #f3efe7;
	--color-background-dark: #ece7dc;
	--color-background-darker: #ded7c8;
	--color-border: #eae5da;
	--color-border-dark: #d9d2c4;
	--color-main-text: #221c10;

	/* Цвет текста ПОВЕРХ фона страницы (приветствие на виджетах, экран входа).
	   Ядро вычисляет его из настройки theming background_color и ставит #000000,
	   потому что та светлая. Фактический фон мы задаём сами и по темам, поэтому
	   и текст обязаны задать сами — иначе в тёмной теме получаем чёрное
	   по чёрному. */
	--color-background-plain-text: #221c10;

	/* Фон страницы (экран входа, поле за приложением). Задаётся отдельной
	   переменной, а не --color-main-background: без неё тёмная тема показывала
	   светлый фон на логине. */
	--color-background-plain: #f7f4ee;

	--netori-surface: #ffffff;
	--netori-glow: rgb(239 186 65 / 12%);
	--netori-glow-soft: rgb(239 186 65 / 7%);
	--netori-shadow: 0 1px 2px rgb(34 28 16 / 5%), 0 4px 16px rgb(34 28 16 / 6%);
	--netori-shadow-raised: 0 2px 4px rgb(34 28 16 / 6%), 0 12px 32px rgb(34 28 16 / 10%);
}

/* --- Тёмная, выбранная системой ----------------------------------------- */
@media (prefers-color-scheme: dark) {
	body[data-theme-default] {
		--color-main-background: #17130d;
		--color-main-background-rgb: 23, 19, 13;

	/*
	 * Производные переменные приходится задавать самим.
	 *
	 * Ядро объявляет их НА :root как rgba(var(--color-main-background-rgb), …),
	 * а подстановка var() происходит там, где переменная ОБЪЯВЛЕНА. Наше
	 * значение живёт на body, поэтому до этих производных оно не доезжает:
	 * карточки оставались холодно-серыми при уже тёплом фоне страницы.
	 */
	--color-main-background-translucent: rgba(var(--color-main-background-rgb), 0.97);
	--color-main-background-blur: rgba(var(--color-main-background-rgb), 0.85);
	--gradient-main-background: var(--color-main-background) 0%, var(--color-main-background-translucent) 85%, transparent 100%;
		--color-background-hover: #221c13;
		--color-background-dark: #1e1810;
		--color-background-darker: #2a2318;
		--color-border: #2b2418;
		--color-border-dark: #3a3122;
		--color-main-text: #f3eee3;

		/* Цвет текста ПОВЕРХ фона страницы (приветствие на виджетах, экран входа).
		   Ядро вычисляет его из настройки theming background_color и ставит #000000,
		   потому что та светлая. Фактический фон мы задаём сами и по темам, поэтому
		   и текст обязаны задать сами — иначе в тёмной теме получаем чёрное
		   по чёрному. */
		--color-background-plain-text: #f3eee3;

		--color-background-plain: #14100b;

		--netori-surface: #1e1810;
		--netori-glow: rgb(239 186 65 / 10%);
		--netori-glow-soft: rgb(239 186 65 / 5%);
		--netori-shadow: 0 1px 2px rgb(0 0 0 / 40%), 0 4px 16px rgb(0 0 0 / 28%);
		--netori-shadow-raised: 0 2px 4px rgb(0 0 0 / 45%), 0 12px 32px rgb(0 0 0 / 38%);
	}
}

/* --- Тёмная, выбранная пользователем ------------------------------------ */
body[data-theme-dark],
body[data-theme-dark-highcontrast] {
	--color-main-background: #17130d;
	--color-main-background-rgb: 23, 19, 13;

	/*
	 * Производные переменные приходится задавать самим.
	 *
	 * Ядро объявляет их НА :root как rgba(var(--color-main-background-rgb), …),
	 * а подстановка var() происходит там, где переменная ОБЪЯВЛЕНА. Наше
	 * значение живёт на body, поэтому до этих производных оно не доезжает:
	 * карточки оставались холодно-серыми при уже тёплом фоне страницы.
	 */
	--color-main-background-translucent: rgba(var(--color-main-background-rgb), 0.97);
	--color-main-background-blur: rgba(var(--color-main-background-rgb), 0.85);
	--gradient-main-background: var(--color-main-background) 0%, var(--color-main-background-translucent) 85%, transparent 100%;
	--color-background-hover: #221c13;
	--color-background-dark: #1e1810;
	--color-background-darker: #2a2318;
	--color-border: #2b2418;
	--color-border-dark: #3a3122;
	--color-main-text: #f3eee3;

	/* Цвет текста ПОВЕРХ фона страницы (приветствие на виджетах, экран входа).
	   Ядро вычисляет его из настройки theming background_color и ставит #000000,
	   потому что та светлая. Фактический фон мы задаём сами и по темам, поэтому
	   и текст обязаны задать сами — иначе в тёмной теме получаем чёрное
	   по чёрному. */
	--color-background-plain-text: #f3eee3;

	--color-background-plain: #14100b;

	--netori-surface: #1e1810;
	--netori-glow: rgb(239 186 65 / 10%);
	--netori-glow-soft: rgb(239 186 65 / 5%);
	--netori-shadow: 0 1px 2px rgb(0 0 0 / 40%), 0 4px 16px rgb(0 0 0 / 28%);
	--netori-shadow-raised: 0 2px 4px rgb(0 0 0 / 45%), 0 12px 32px rgb(0 0 0 / 38%);
}

/* --- Объём вместо плоскости ---------------------------------------------
   Ядро рисует карточки заливкой без тени: на тёмном фоне они почти
   сливаются, на светлом выглядят как пятна. Мягкая тень отделяет карточку
   от фона и задаёт иерархию — это и читается как «современно». */

.dashboard-panel,
.panel,
.settings-section,
.app-settings-section,
.notecard {
	background-color: var(--netori-surface);
	border-radius: var(--border-radius-container, 12px);
	box-shadow: var(--netori-shadow);
}

.modal-container,
.popover__inner,
.v-popper__inner {
	border-radius: var(--border-radius-container-large, 16px);
	box-shadow: var(--netori-shadow-raised);
}

/* --- Фокус ---------------------------------------------------------------
   Видимое кольцо в акцентном цвете. Это не украшение: без внятного фокуса
   интерфейс непроходим с клавиатуры, а штатный контур у ядра местами
   теряется на тёмном фоне. :focus-visible, а не :focus, — чтобы кольцо
   не вспыхивало на каждый клик мышью. */

:focus-visible {
	outline: 2px solid var(--color-primary-element, #b89af2);
	outline-offset: 2px;
	border-radius: var(--border-radius-small, 4px);
}

/* --- Типографика ---------------------------------------------------------
   Inter при крупных кеглях набирается слишком разреженно. Поджимаем
   заголовки и задаём внятную ступень размеров — иерархия страницы
   считывается до чтения текста. */

h2 {
	font-size: 1.4rem;
	font-weight: 600;
	letter-spacing: -0.015em;
}

h3 {
	font-size: 1.1rem;
	font-weight: 600;
	letter-spacing: -0.01em;
}

/* Длинные абзацы в настройках читаются тяжело: строки почти во всю ширину
   экрана. Ограничение по мере — стандартный приём вёрстки текста. */
.settings-section__desc,
.settings-hint {
	max-width: 68ch;
	line-height: 1.55;
}

/* --- Поля ввода ----------------------------------------------------------
   Граница у ядра почти неразличима на тёплом фоне; поднимаем контраст
   и делаем реакцию на фокус явной. */

.input-field__input:not(:focus):not(:hover),
input[type='text']:not(:focus):not(:hover),
input[type='email']:not(:focus):not(:hover),
input[type='password']:not(:focus):not(:hover),
textarea:not(:focus):not(:hover) {
	border-color: var(--color-border-dark);
}


/* --- Фон страницы --------------------------------------------------------
   Кастомизация фона отключена (disable-user-theming), значит этот фон видят
   все и всегда: экран входа, поле вокруг приложения, публичные страницы.

   ПОЧЕМУ НА html, А НЕ НА body. Шапка (#header) и область контента
   позиционированы фиксированно и перекрывают фон body — под шапкой оставалась
   чёрная полоса со швом на границе. html — это канва, она рисуется под всем
   содержимым, включая фиксированные элементы, поэтому фон получается сплошным.
   body делаем прозрачным, чтобы канва просвечивала.

   ПОЧЕМУ :root, А НЕ body[data-theme-*]. До html атрибут темы не достаёт: он
   висит на body. Системную тему ловим медиазапросом, явно выбранную — через
   :has() по атрибуту на body.

   Свечение держим мягким, но различимым. Первая версия на 7% в светлой теме
   была не видна вовсе — незаметный градиент это просто мёртвый код. */

:root {
	--netori-plain: #f7f4ee;
	--netori-glow: rgb(239 186 65 / 26%);
	--netori-glow-soft: rgb(239 186 65 / 14%);
}

@media (prefers-color-scheme: dark) {
	:root {
		--netori-plain: #14100b;
		--netori-glow: rgb(239 186 65 / 15%);
		--netori-glow-soft: rgb(239 186 65 / 8%);
	}
}

:root:has(body[data-theme-light]),
:root:has(body[data-theme-light-highcontrast]) {
	--netori-plain: #f7f4ee;
	--netori-glow: rgb(239 186 65 / 26%);
	--netori-glow-soft: rgb(239 186 65 / 14%);
}

:root:has(body[data-theme-dark]),
:root:has(body[data-theme-dark-highcontrast]) {
	--netori-plain: #14100b;
	--netori-glow: rgb(239 186 65 / 15%);
	--netori-glow-soft: rgb(239 186 65 / 8%);
}

html {
	background-color: var(--netori-plain);
	background-image:
		radial-gradient(1100px 620px at 12% -6%, var(--netori-glow), transparent 62%),
		radial-gradient(900px 520px at 96% 108%, var(--netori-glow-soft), transparent 58%);
	background-attachment: fixed;
	background-repeat: no-repeat;
}

body {
	background-color: transparent;
}

/* На печать градиент не нужен: он съедает тонер и мешает читать. */
@media print {
	html {
		background-image: none;
	}
}
