/*
 * ЕДИНСТВЕННОЕ МЕСТО, ГДЕ ЖИВУТ ЦВЕТА.
 *
 * Ни во вьюхах, ни в контроллерах, ни в JS цветов быть не должно —
 * это правило аудита, и оно проверяется поиском. Отсюда бесплатно
 * получаются три вещи: white label, тёмная тема и смена фирменного
 * цвета на всём проекте правкой одной строки.
 *
 * Фирменная пара приходит из brand.css классом на <html>.
 * Здесь она раскладывается по ролям, и роли разные в светлой и тёмной:
 * яркий #59ff3a читаем на тёмном фоне и нечитаем на белом, поэтому для
 * текста берётся --brand-ink, а сам --brand остаётся для заливок.
 *
 * Тема имеет три состояния, а не два:
 *   :root                                    — светлая, полный набор
 *   @media dark + :root:not([data-theme=light]) — системная тёмная
 *   :root[data-theme="dark"]                 — выбор пользователя
 * Цвет, определённый только внутри media или [data-theme], в третьем
 * состоянии не применится — это классическая причина нечитаемой страницы.
 */

:root {
    /* ---- Роли фирменного цвета (светлая тема) ---- */
    --accent:            var(--brand-ink);
    --accent-fill:       var(--brand);
    --accent-fill-2:     var(--brand-2);
    --accent-on-fill:    var(--on-brand);
    --accent-gradient:   linear-gradient(135deg, var(--brand), var(--brand-2));
    --accent-soft:       var(--brand-soft);
    --accent-border:     var(--brand-border);
    --accent-hover:      var(--brand-hover);

    /* ---- Поверхности ---- */
    --bg-page:           #f8fafc;
    --bg-card:           #ffffff;
    --bg-subtle:         #f1f5f9;
    --bg-sunk:           #eef2f7;
    --bg-inverse:        #111725;
    --text-on-inverse:   #e8ecf4;

    /*
     * Приглушённый текст на обратной поверхности — свой, а не общий.
     *
     * `--text-muted` подобран под страницу и карточку. На тёмной полосе
     * он даёт 3.3:1 при пороге 4.5, и под это подпадает то, чего меньше
     * всего хочется потерять: невыбранные пункты меню и имя человека в
     * шапке. Третий раз за проект цвет проверялся не на том фоне —
     * поэтому у обратной поверхности теперь своя роль.
     */
    --text-muted-on-inverse: #9aa6bd;

    /* Граница на обратной поверхности: обычная `--border` подобрана под
       светлую страницу и на тёмной подложке не видна вовсе. */
    --border-on-inverse: #2b3550;

    /*
     * ---- Текст ----
     *
     * Приглушённый — не значит бледный. Все три уровня проходят WCAG AA
     * (4.5:1) на самом тёмном из фонов, на которые ложатся: странице,
     * карточке и серой подложке. Обычные для макетов #94a3b8 и #6f7a92
     * дают 2.3 и 3.5 — подсказку под полем на планшете при боковом свете
     * не прочитать. Проверка: public/dev/_a11y.js на отрисованной странице.
     */
    --text-primary:      #2d3748;
    --text-secondary:    #475569;
    --text-muted:        #5c6b80;

    /* ---- Границы ---- */
    --border:            #e2e8f0;
    --border-strong:     #cbd5e1;

    /* ---- Семантика: не зависит от бренда и не меняется white label ---- */
    --success:           #0f7a5a;
    --success-soft:      #e6f6f0;
    --danger:            #c62828;
    --danger-soft:       #fdeaea;
    /* Текст поверх заливки «опасно». В светлой теме заливка тёмно-красная и
       белый на ней читается, в тёмной она светлая — там нужен тёмный текст. */
    --on-danger:         #ffffff;
    --warning:           #97620a;
    --warning-soft:      #fdf1dc;
    --info:              #0369a1;
    --info-soft:         #e4f2fb;

    /* ---- Тени ---- */
    --shadow-sm:         0 1px 2px rgba(15, 23, 42, .06);
    --shadow-md:         0 4px 12px rgba(15, 23, 42, .08);
    --shadow-lg:         0 12px 28px rgba(15, 23, 42, .12);
    --shadow-focus:      0 0 0 3px rgba(var(--brand-rgb), .38);

    /* ---- Радиусы ---- */
    --radius-sm:         8px;
    --radius-md:         12px;
    --radius-lg:         16px;
    --radius-pill:       999px;

    /* ---- Отступы ---- */
    --space-1:           4px;
    --space-2:           8px;
    --space-3:           12px;
    --space-4:           16px;
    --space-5:           20px;
    --space-6:           24px;
    --space-8:           32px;
    --space-10:          40px;

    /* ---- Шрифты ----

       Монсеррат — фирменный шрифт winclass.ru, и он же здесь. Лежит
       локально, а не грузится с гугл-CDN: в школе интернет тонкий и
       фильтрованный, а шрифт с чужого домена приходит последним — текст
       успевает моргнуть системным. Плюс политика содержимого у нас
       `font-src 'self'`, и ослаблять её ради шрифта не стоит.

       Запасные подобраны не случайно: пока файл летит, страница рисуется
       ими, и чем ближе их метрики к Монсеррату, тем меньше прыгает
       текст. */
    --font-sans:         "Montserrat", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    --font-mono:         ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

    /*
     * Шкала размеров.
     *
     * Была почти плоской: 13-15-18 — соседние ступени различаются на
     * два пункта, и глаз их не различает вовсе. Экран от этого читается
     * как одно полотно, где всё одинаково важно.
     *
     * Стало заметнее: подпись мельче, заголовок крупнее, между ними
     * настоящая разница. Основной текст остался 15 — на планшете это
     * нижняя граница читаемого с расстояния вытянутой руки.
     */
    --text-xs:           12px;
    --text-sm:           13px;
    --text-base:         15px;
    --text-lg:           20px;
    --text-xl:           28px;
    --text-2xl:          38px;

    /*
     * Роли шкалы: чем набран заголовок страницы и крупное число.
     *
     * Заведены отдельно от самой шкалы ради одной вещи — детского
     * кабинета. Половина наших учеников первоклассники, и у них
     * заголовки на ступень крупнее. Раньше это делалось точечными
     * правками для двух компонентов, и выглядело не как решение, а как
     * несогласованность: третий компонент про неё бы не знал.
     *
     * Теперь разница объявлена одна: детский кабинет переопределяет две
     * роли, а компоненты берут размер отсюда и укрупняются вместе.
     */
    --size-page-title:   var(--text-xl);
    --size-stat-value:   var(--text-xl);

    --weight-normal:     400;
    --weight-medium:     500;
    --weight-semibold:   600;
    --weight-bold:       700;
    --leading:           1.55;

    /* Заголовки живут теснее текста: полтора интервала на крупном
       кегле разваливает строку на отдельные слова. */
    --leading-tight:     1.15;

    /* Разрядка у мелких прописных подписей. Без неё «ОРГАНИЗАЦИЯ»
       читается как одно длинное слово. */
    --tracking-caps:     .06em;

    /* ---- Кабинет ребёнка ----
       Космос сдержанный: подсветка сверху и редкие звёзды. Полная
       сцена начинается в плеере, и переход туда должен ощущаться
       входом, а не продолжением того же экрана.

       В светлой теме звёзд почти нет: на белом они превращаются в
       грязь, а подсветка фирменного цвета работает и так. */
    --kid-glow:  rgba(var(--brand-rgb), .10);
    --kid-star:  rgba(70, 90, 130, .18);

    /* ---- Сцена страницы входа ----
       Куб рисуется фирменными цветами логотипа — это марка, она не
       меняется. А обводка и орбиты зависят от темы, поэтому живут здесь:
       тёмная обводка на тёмном фоне не видна. */
    --scene-line:       #2d3748;
    --scene-orbit-far:  rgba(70, 210, 210, .13);
    --scene-orbit-near: rgba(70, 210, 210, .40);

    /* ---- Раскладка ---- */
    --sidebar-w:         236px;
    --page-max:          1440px;
    --tap-target:        44px;   /* планшет — главное устройство */
    --bottom-nav-h:      68px;   /* меню внизу телефона; всё, что липнет
                                    к низу, отступает на эту высоту */

    /* ---- Прочее ---- */
    --transition:        .18s cubic-bezier(.4, 0, .2, 1);
    --z-header:          100;
    --z-sidebar:         90;
    --z-overlay:         200;
    --z-toast:           300;

    /* ---- Словарь тренажёров ----
     *
     * `trainers.css` перенесён из winclass.kz и говорит именами тамошних
     * токенов: `--color-primary`, `--bg-surface`, `--border-default`. У
     * нас роли называются иначе, и 37 правил переноса молча не работали:
     * незнакомая переменная в `var()` без запасного значения обнуляет
     * всё объявление — кнопка оставалась без фона, карточка без границы.
     *
     * Это не второй набор цветов, а перевод одного словаря в другой:
     * значения берутся из ролей выше, поэтому тема и белый лейбл
     * доходят до тренажёров сами.
     */
    --color-primary:       var(--accent);
    --color-primary-hover: var(--accent-hover);
    --color-primary-soft:  var(--accent-soft);
    --text-on-brand:       var(--accent-on-fill);
    --bg-surface:          var(--bg-card);
    --bg-muted:            var(--bg-subtle);
    --border-default:      var(--border);
    --radius-full:         var(--radius-pill);
    --color-success:       var(--success);
    --color-warning:       var(--warning);
    --color-info:          var(--info);
    --transition-fast:     var(--transition);
    --leading-tight:       1.25;
    --leading-normal:      var(--leading);
}

/*
 * Телевизор и большие панели: смотрят с трёх метров, а не с полуметра.
 * Меняются только размеры — ни одного цвета здесь нет, иначе он не
 * применился бы на остальных экранах.
 */
@media (min-width: 1800px) {
    :root {
        --text-xs:    14px;
        --text-sm:    16px;
        --text-base:  18px;
        --text-lg:    22px;
        --text-xl:    30px;
        --text-2xl:   40px;
        --sidebar-w:  288px;
        --page-max:   1760px;
        --tap-target: 52px;
        --radius-sm:  10px;
        --radius-md:  14px;
        --radius-lg:  20px;
    }
}

/*
 * Бумага — третья тема, не исключение из правил.
 *
 * Лист с логинами раздают по классу, и печатают его чаще всего на
 * чёрно-белом принтере: приглушённый текст на сером фоне там пропадает
 * совсем. Поэтому роли переопределяются целиком, а не подкрашиваются
 * по месту в components.css. Заодно правило «цвета только здесь»
 * остаётся без исключений.
 */
@media print {
    :root {
        --bg-page:        #ffffff;
        --bg-card:        #ffffff;
        --bg-subtle:      #ffffff;
        --bg-sunk:        #ffffff;

        --text-primary:   #000000;
        --text-secondary: #000000;
        --text-muted:     #333333;

        --border:         #999999;
        --border-strong:  #000000;

        --accent:         #000000;
        --accent-soft:    #ffffff;

        --shadow-sm:      none;
        --shadow-md:      none;
        --shadow-lg:      none;
    }
}
/*
 * Космо-палитра тренажёров.
 *
 * Единственный набор, который НЕ зависит от темы платформы, и это не
 * упущение: по документу 4.1 сцена игры — тёмный космос всегда. Ребёнок
 * в светлой теме кабинета всё равно попадает в космос, потому что игра
 * это отдельное место, а не продолжение интерфейса.
 *
 * Поэтому цвета здесь заданы один раз и не переопределяются ни в
 * @media dark, ни в [data-theme]. Меняются они вместе с оформлением
 * игры, а не вместе с white label школы.
 *
 * Живут в tokens.css по правилу 7: цвет должен меняться в одном месте,
 * даже если он фиксированный. В trainers.css остаётся только раскладка.
 */
:root {
    --trc-bg:       #0A0E27;
    --trc-bg-2:     #1A1F4E;
    --trc-blue:     #4D6FFF;
    --trc-purple:   #7B5CFF;
    --trc-teal:     #00E0D6;
    --trc-gold:     #FFB800;
    --trc-red:      #FF4D6D;
    --trc-white:    #FFFFFF;
    --trc-text-dim: rgba(255, 255, 255, 0.65);
    --trc-line:     rgba(255, 255, 255, 0.10);
    --trc-radius:   16px;

    /* Церемония награждения. Тёмная всегда, как и игровое поле, и
       по той же причине: её показывают проектором на белую доску,
       где светлый экран превращается в засвеченное пятно. */
    --cel-bg:   #0b1020;
    --cel-card: #161d33;
    --cel-line: rgba(255, 255, 255, 0.10);
    --cel-text: #ffffff;
    --cel-dim:  rgba(255, 255, 255, 0.66);
    --cel-gold: #FFC93C;
    /* Тень победителя: на тёмном фоне обычная --shadow-lg не видна. */
    --cel-shadow: 0 18px 50px rgba(0, 0, 0, .45);
}
/* ---------- Родные элементы браузера ----------

   `color-scheme` говорит браузеру, в какой теме рисовать то, что рисует
   он сам: список вариантов у `<select>`, полосы прокрутки, календарь.

   Без этого в тёмной теме выпадающий список открывался белым, а текст в
   нём наследовал наш светлый цвет — варианты становились белым по
   белому и читались только под выделением. На снимке от заказчика KK и
   EN не видно вовсе.

   Правило стоит рядом с ролями цвета и повторяет их три состояния:
   выбор пользователя сильнее системы. */
:root { color-scheme: light; }
/* Системная тёмная тема. Не применяется, если пользователь выбрал светлую. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --accent:          var(--brand-ink-dark);
        --accent-soft:     var(--brand-soft-dark);
        --accent-border:   var(--brand-border-dark);

        /*
         * Фон темнее, карточка светлее.
         *
         * Было #0f1420 против #171d2b — разница меньше процента
         * яркости, и глаз её не различает: экран читался как одно
         * серое полотно, где непонятно, что на чём лежит.
         *
         * Фон уведён в синеву космо-палитры: тёмный кабинет и
         * тёмная игра теперь одного рода, а не два разных серых.
         */
        --bg-page:         #090e1a;
        --bg-card:         #161d30;
        --bg-subtle:       #1f2740;
        --bg-sunk:         #05080f;
        --bg-inverse:      #e8ecf4;
        --text-on-inverse: #111725;
        --text-muted-on-inverse: #4d5a6e;
    --border-on-inverse: #c7cede;

        --text-primary:    #e8ecf4;
        --text-secondary:  #a3adc2;
        --text-muted:      #8590a6;

        /* Граница видна, а не угадывается: на тёмном .10 сливается
           с фоном, и карточка теряет края. */
        /* На тёмном звёзды белые и настоящие. */
        --kid-glow: rgba(var(--brand-rgb), .16);
        --kid-star: rgba(255, 255, 255, .55);

        /* На тёмном звёзды белые и настоящие. */
    --kid-glow: rgba(var(--brand-rgb), .16);
    --kid-star: rgba(255, 255, 255, .55);

    --border:          rgba(255, 255, 255, .14);
        --border-strong:   rgba(255, 255, 255, .26);

        --success:         #4ade80;
        --success-soft:    rgba(74, 222, 128, .14);
        --danger:          #ff8085;
        --danger-soft:     rgba(255, 128, 133, .14);
        --on-danger:       #111725;
        --warning:         #fbbf47;
        --warning-soft:    rgba(251, 191, 71, .14);
        --info:            #6cb6ef;
        --info-soft:       rgba(108, 182, 239, .14);

        --shadow-sm:       0 1px 2px rgba(0, 0, 0, .4);
        --shadow-md:       0 4px 14px rgba(0, 0, 0, .5);
        --shadow-lg:       0 14px 34px rgba(0, 0, 0, .6);

        --scene-line:       #cfd8e6;
        --scene-orbit-far:  rgba(70, 210, 210, .18);
        --scene-orbit-near: rgba(70, 210, 210, .55);
    }
}

/* Явный выбор пользователя — побеждает системную настройку в обе стороны. */
:root[data-theme="dark"] {
    color-scheme: dark;
    --accent:          var(--brand-ink-dark);
    --accent-soft:     var(--brand-soft-dark);
    --accent-border:   var(--brand-border-dark);

    --bg-page:         #090e1a;
    --bg-card:         #161d30;
    --bg-subtle:       #1f2740;
    --bg-sunk:         #05080f;
    --bg-inverse:      #e8ecf4;
    --text-on-inverse: #111725;
    --text-muted-on-inverse: #4d5a6e;
    --border-on-inverse: #c7cede;

    --text-primary:    #e8ecf4;
    --text-secondary:  #a3adc2;
    --text-muted:      #8590a6;

    /* На тёмном звёзды белые и настоящие. */
    --kid-glow: rgba(var(--brand-rgb), .16);
    --kid-star: rgba(255, 255, 255, .55);

    --border:          rgba(255, 255, 255, .14);
    --border-strong:   rgba(255, 255, 255, .26);

    --success:         #4ade80;
    --success-soft:    rgba(74, 222, 128, .14);
    --danger:          #ff8085;
    --danger-soft:     rgba(255, 128, 133, .14);
    --on-danger:       #111725;
    --warning:         #fbbf47;
    --warning-soft:    rgba(251, 191, 71, .14);
    --info:            #6cb6ef;
    --info-soft:       rgba(108, 182, 239, .14);

    --shadow-sm:       0 1px 2px rgba(0, 0, 0, .4);
    --shadow-md:       0 4px 14px rgba(0, 0, 0, .5);
    --shadow-lg:       0 14px 34px rgba(0, 0, 0, .6);

    --scene-line:       #cfd8e6;
    --scene-orbit-far:  rgba(70, 210, 210, .18);
    --scene-orbit-near: rgba(70, 210, 210, .55);
}
