/* ============================================================
   КНОПКИ M3
   .menu-btn            → filled tonal button
   .menu-btn.primary    → filled button
   .menu-btn.danger     → error-tonal button
   .menu-btn.outlined   → outlined button
   .menu-btn.text       → text button
   ============================================================ */
.menu-btn,
.md-button {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    min-height: 40px;
    padding: 10px 24px;
    border: 0;
    border-radius: var(--md-sys-shape-corner-full);
    background: var(--md-sys-color-secondary-container);
    color: var(--md-sys-color-on-secondary-container);
    font-family: inherit;
    font-size: 0.875rem;
    line-height: 1.25rem;
    font-weight: 500;
    letter-spacing: 0.00625rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    text-align: center;
    /* Кнопка бывает и ссылкой (поддержка проекта на экране настроек) —
       подчёркивание из <a> тут лишнее, как у ссылок в списке лицензий. */
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
    transition: background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                box-shadow var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                border-radius var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-emphasized);
}
.menu-btn::before,
.md-button::before {
    content: '';
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
    z-index: -1;
}
.menu-btn:hover::before, .md-button:hover::before { opacity: var(--md-sys-state-hover-opacity); }
.menu-btn:focus-visible::before, .md-button:focus-visible::before { opacity: var(--md-sys-state-focus-opacity); }
.menu-btn:active, .md-button:active { border-radius: var(--md-sys-shape-corner-medium); }
.menu-btn:disabled, .md-button:disabled {
    background: color-mix(in srgb, var(--md-sys-color-on-surface) 12%, transparent);
    color: color-mix(in srgb, var(--md-sys-color-on-surface) 38%, transparent);
    cursor: not-allowed;
    box-shadow: none;
}
.menu-btn:disabled::before, .md-button:disabled::before { opacity: 0; }

.menu-btn.primary, .md-button--filled {
    background: var(--md-sys-color-primary);
    color: var(--md-sys-color-on-primary);
}
.menu-btn.primary:hover, .md-button--filled:hover { box-shadow: var(--md-sys-elevation-level1); }

.menu-btn.danger, .md-button--danger {
    background: var(--md-sys-color-error-container);
    color: var(--md-sys-color-on-error-container);
}
.menu-btn.danger-outlined {
    background: transparent;
    color: var(--md-sys-color-error);
    border: 1px solid var(--md-sys-color-outline);
    padding: 9px 23px;
}
.menu-btn.outlined, .md-button--outlined {
    background: transparent;
    color: var(--md-sys-color-primary);
    border: 1px solid var(--md-sys-color-outline);
    padding: 9px 23px;
}
.menu-btn.text, .md-button--text {
    background: transparent;
    color: var(--md-sys-color-primary);
    padding: 10px 12px;
}
.menu-btn.elevated, .md-button--elevated {
    background: var(--md-sys-color-surface-container-low);
    color: var(--md-sys-color-primary);
    box-shadow: var(--md-sys-elevation-level1);
}
.menu-btn.elevated:hover, .md-button--elevated:hover { box-shadow: var(--md-sys-elevation-level2); }
.menu-btn .msym, .md-button .msym { font-size: 18px; font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 20; }

/* выбор упражнения: подписанные группы пунктов меню */
.drill-group + .drill-group { margin-top: 8px; }
.drill-group + .drill-group .drill-group__label { padding-top: 16px; }
.drill-group__label {
    padding: 8px 4px 0;
    font-size: 0.875rem;
    line-height: 1.25rem;
    font-weight: 500;
    letter-spacing: 0.00625rem;
    color: var(--md-sys-color-primary);
}

/* сетка кнопок / действий */
.menu-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 8px;
    margin: 16px 0;
}
.md-button-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 12px 0;
}
/* Строка, где главное действие («Готово»/«Проверить») делит место с
   «Очистить» в выборе слов и переводах. Обе кнопки стоят у правого края —
   туда же, где «Далее» после ответа, — и растягиваются на ширину ряда
   поровну. На телефоне они только прижимаются вправо: тянуть их на всю
   ширину нельзя, «Готово»/«Очистить» стали бы на треть выше и съели
   вертикаль на самом узком экране. */
.md-button-row--split {
    justify-content: flex-end;
}
@media (min-width: 600px) {
    .md-button-row--split {
        flex-wrap: nowrap;
    }
    .md-button-row--split > .menu-btn {
        flex: 1 1 0;
    }
}

/* ============================================================
   СПИСОК УРОКОВ — M3 list item (внутри карточки)
   ============================================================ */
.lesson-list {
    display: flex;
    flex-direction: column;
}
.lesson-item {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 16px;
    width: 100%;
    min-height: 72px;
    padding: 12px 8px 12px 4px;
    border: 0;
    background: transparent;
    color: var(--md-sys-color-on-surface);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    border-radius: var(--md-sys-shape-corner-large);
    -webkit-tap-highlight-color: transparent;
}
/* однострочный list item (M3): без вспомогательного текста высота меньше */
.lesson-item--single { min-height: 56px; }
.lesson-item::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--md-sys-color-on-surface);
    opacity: 0;
    transition: opacity var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
    z-index: -1;
}
.lesson-item:hover::before { opacity: var(--md-sys-state-hover-opacity); }
.lesson-item:active::before { opacity: var(--md-sys-state-pressed-opacity); }
.lesson-item__avatar {
    width: 40px;
    height: 40px;
    border-radius: var(--md-sys-shape-corner-full);
    background: var(--md-sys-color-primary-container);
    color: var(--md-sys-color-on-primary-container);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.875rem;
    font-weight: 500;
    flex-shrink: 0;
}
/* тот же «аватар», но с иконкой вместо номера — меню разделов урока и упражнений */
.lesson-item__avatar .msym {
    font-size: 20px;
    font-variation-settings: 'FILL' 0, 'wght' 500, 'GRAD' 0, 'opsz' 20;
}
.lesson-item__text { flex: 1; min-width: 0; }
.lesson-item__headline, .lesson-item__supporting,
.md-feature-card__title, .md-feature-card__body { display: block; }
.lesson-item__headline {
    font-size: 1rem;
    line-height: 1.5rem;
    font-weight: 400;
    letter-spacing: 0.03125rem;
}
.lesson-item__supporting {
    font-size: 0.875rem;
    line-height: 1.25rem;
    letter-spacing: 0.015625rem;
    color: var(--md-sys-color-on-surface-variant);
}
.lesson-item__trailing { color: var(--md-sys-color-on-surface-variant); }

/* Найденные в уроке темы под строкой урока (результаты поиска, js/shell.js).
   Тема — самостоятельная цель: она открывает урок на этом разделе, поэтому
   у неё своя кнопка, а не подпись строки. Отступ слева выравнивает текст темы
   под названием урока (4px поля строки + аватар 40px + промежуток 16px). */
.lesson-topics { display: flex; flex-direction: column; }
.lesson-topic {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    min-height: 48px;
    padding: 8px 8px 8px 60px;
    border: 0;
    background: transparent;
    color: var(--md-sys-color-on-surface-variant);
    font-family: inherit;
    font-size: 0.875rem;
    line-height: 1.25rem;
    letter-spacing: 0.015625rem;
    text-align: left;
    cursor: pointer;
    border-radius: var(--md-sys-shape-corner-large);
    -webkit-tap-highlight-color: transparent;
}
.lesson-topic::before {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--md-sys-color-on-surface);
    opacity: 0;
    transition: opacity var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
    z-index: -1;
}
.lesson-topic:hover::before { opacity: var(--md-sys-state-hover-opacity); }
.lesson-topic:active::before { opacity: var(--md-sys-state-pressed-opacity); }
.lesson-topic .msym {
    font-size: 18px;
    flex-shrink: 0;
    font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 20;
}
.lesson-topic__text { flex: 1; min-width: 0; }
/* Знаки изучаемого языка в теме: кегль мелкий, поэтому как везде на мелком
   письме — ползунок языка и пол огласовки (см. «Text size» в AGENTS.md) */
.lesson-topic__text .script {
    font-size: calc(max(0.875rem, var(--md-ref-script-min-size)) * var(--md-ref-script-scale));
}
.md-divider {
    height: 1px;
    border: 0;
    background: var(--md-sys-color-outline-variant);
    margin: 0;
}
.decor-line { height: 1px; border: 0; background: var(--md-sys-color-outline-variant); margin: 24px 0; }

/* ============================================================
   КАРТОЧКИ M3
   ============================================================ */
.card {
    background: var(--md-sys-color-surface-container);
    border-radius: var(--md-sys-shape-corner-extra-large);
    padding: 20px;
    margin-bottom: 16px;
    transition: background-color var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-standard);
}
.card--elevated {
    background: var(--md-sys-color-surface-container-low);
    box-shadow: var(--md-sys-elevation-level1);
}
.card--outlined {
    background: var(--md-sys-color-surface);
    border: 1px solid var(--md-sys-color-outline-variant);
}
.card h3 {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 16px;
    font-size: 1.375rem;
    line-height: 1.75rem;
    color: var(--md-sys-color-on-surface);
}
.card h3 .msym { color: var(--md-sys-color-primary); }
.card > p { color: var(--md-sys-color-on-surface-variant); }

/* featured card («Отче наш») */
.md-feature-card {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    gap: 16px;
    width: 100%;
    padding: 16px 20px;
    border: 0;
    text-align: left;
    border-radius: var(--md-sys-shape-corner-extra-large);
    background: var(--md-sys-color-surface-container-high);
    color: var(--md-sys-color-on-surface);
    font-family: inherit;
    cursor: pointer;
    margin-bottom: 16px;
    -webkit-tap-highlight-color: transparent;
}
.md-feature-card__icon {
    width: 48px;
    height: 48px;
    border-radius: var(--md-sys-shape-corner-full);
    background: var(--md-sys-color-secondary-container);
    color: var(--md-sys-color-on-secondary-container);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.md-feature-card__text { flex: 1; min-width: 0; }
.md-feature-card__body { color: var(--md-sys-color-on-surface-variant); }
.md-feature-card__chevron { color: var(--md-sys-color-on-surface-variant); }
.md-feature-card::before {
    content: '';
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
    z-index: -1;
}
.md-feature-card:hover::before { opacity: var(--md-sys-state-hover-opacity); }
.md-feature-card:active::before { opacity: var(--md-sys-state-pressed-opacity); }
.md-feature-card__icon .msym { font-size: 24px; }
.md-feature-card__title { font-size: 1rem; font-weight: 500; line-height: 1.5rem; }
.md-feature-card__body { font-size: 0.875rem; line-height: 1.25rem; opacity: 0.85; }

/* ============================================================
   TABS (primary, scrollable, sliding indicator)
   ============================================================ */
.tab-bar {
    position: relative;
    display: flex;
    gap: 0;
    margin: 0 -16px 16px;
    padding: 0 8px;
    overflow-x: auto;
    scrollbar-width: none;
    border-bottom: 1px solid var(--md-sys-color-surface-variant);
    scroll-behavior: smooth;
}
.tab-bar::-webkit-scrollbar { display: none; }
.tab-bar button {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    flex: 0 0 auto;
    min-width: 76px;
    height: 48px;
    padding: 0 16px;
    border: 0;
    background: transparent;
    color: var(--md-sys-color-on-surface-variant);
    font-family: inherit;
    font-size: 0.875rem;
    line-height: 1.25rem;
    font-weight: 500;
    letter-spacing: 0.00625rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    white-space: nowrap;
    -webkit-tap-highlight-color: transparent;
    transition: color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.tab-bar button::before {
    content: '';
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
    z-index: -1;
}
.tab-bar button:hover::before { opacity: var(--md-sys-state-hover-opacity); }
.tab-bar button:active::before { opacity: var(--md-sys-state-pressed-opacity); }
.tab-bar button.active { color: var(--md-sys-color-primary); }
.tab-bar button .msym { font-size: 20px; }
.tab-bar button.active .msym { font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 20; }
.md-tabs__indicator {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 3px;
    width: 0;
    border-radius: 3px 3px 0 0;
    background: var(--md-sys-color-primary);
    transition: transform var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-emphasized),
                width var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-emphasized);
    pointer-events: none;
}

/* ============================================================
   SEARCH BAR M3
   ============================================================ */
.search-box {
    display: flex;
    align-items: center;
    gap: 16px;
    height: 56px;
    padding: 0 16px;
    background: var(--md-sys-color-surface-container-high);
    border-radius: var(--md-sys-shape-corner-full);
    margin-bottom: 16px;
    transition: background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                box-shadow var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.search-box:focus-within { box-shadow: var(--md-sys-elevation-level1); }
.search-box .search-icon { color: var(--md-sys-color-on-surface-variant); }
.search-box input {
    flex: 1;
    min-width: 0;
    border: 0;
    outline: none;
    background: transparent;
    font-family: inherit;
    font-size: 1rem;
    line-height: 1.5rem;
    letter-spacing: 0.03125rem;
    color: var(--md-sys-color-on-surface);
}
.search-box input::placeholder { color: var(--md-sys-color-on-surface-variant); }
.search-clear {
    display: none;
    width: 40px;
    height: 40px;
    margin-right: -8px;
    border: 0;
    background: transparent;
    color: var(--md-sys-color-on-surface-variant);
    border-radius: var(--md-sys-shape-corner-full);
    cursor: pointer;
    align-items: center;
    justify-content: center;
}
.search-clear.show { display: inline-flex; }
.search-clear:hover { background: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent); }
.search-empty {
    text-align: center;
    color: var(--md-sys-color-on-surface-variant);
    padding: 32px 16px;
    font-size: 0.875rem;
    line-height: 1.25rem;
}

/* Клавиатура изучаемого языка — вторая концевая кнопка строки поиска, одной
   меры с крестиком: 40×40, иконка 20px и у того же правого края (отрицательный
   отступ съедает 8px из 16px отступа самой строки). Класс — .md-icon-button:
   слои состояния и всплеск у него уже есть, и в RIPPLE_TARGETS он вписан;
   свои мера и цвет — у .keyboard-toggle. Нажатое состояние тональное:
   клавиатура на экране, и это видно не только по самой клавиатуре. */
.keyboard-toggle { width: 40px; height: 40px; margin-right: -8px; }
.keyboard-toggle[aria-pressed="true"] {
    background: var(--md-sys-color-secondary-container);
    color: var(--md-sys-color-on-secondary-container);
}

/* Клавиатура — отдельная поверхность над списком слов, а не часть строки
   поиска: у неё своя плашка, скругление и отступ до списка. */
.vocab-keyboard {
    margin-bottom: 16px;
    padding: 12px;
    border-radius: var(--md-sys-shape-corner-large);
    background: var(--md-sys-color-surface-container);
}
/* Столбцов столько, сколько влезет: 24 греческие буквы и 27 еврейских
   (22 плюс 5 конечных из HEBREW_ALPHABET.finals) в одну строку не встают ни
   на телефоне, ни на широком экране. Направление сетки — письмо курса тем же
   токеном, что у текста: в еврейском курсе א стоит справа, как в таблице
   алфавита пособия, а «стереть» уезжает на левый край, где ей и место. */
.vocab-keyboard__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));
    gap: 4px;
    direction: var(--md-ref-script-direction);
}
/* Клавиша. Гарнитура — письмо курса: в Noto Sans нет иврита вовсе, и буквы
   вышли бы пустыми клетками. Кегль — обязательно с множителем ползунка,
   иначе размер текста клавиатуру не трогал бы. Шага кегля
   (--md-ref-script-size) здесь нет намеренно: клавиша — знак, а не текст для
   чтения, и на шаге буква вылезала бы из клавиши.

   Тон клавиши — surface-container-lowest, а не соседний с плашкой
   «на ступень выше»: клавиша обязана читаться как клавиша, и разница тонов
   здесь важнее привычной лестницы. Со ступенью surface-container-highest
   разница выходила 1.09:1 в светлой теме и 1.08:1 в сепии — клавиши
   сливались с плашкой. Через низший тон пара даёт 1.16 и 1.14, а в тёмной
   теме клавиши уходят ниже плашки, как и положено ей в тёмной схеме. */
.vocab-key {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 0 4px;
    border: 0;
    border-radius: var(--md-sys-shape-corner-small);
    background: var(--md-sys-color-surface-container-lowest);
    color: var(--md-sys-color-on-surface);
    font-family: var(--md-ref-typeface-script);
    font-size: calc(1.25rem * var(--md-ref-script-scale));
    line-height: 1;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.vocab-key::before {
    content: '';
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
    z-index: -1;
}
.vocab-key:hover::before { opacity: var(--md-sys-state-hover-opacity); }
.vocab-key:focus-visible::before { opacity: var(--md-sys-state-focus-opacity); }
.vocab-key:active::before { opacity: var(--md-sys-state-pressed-opacity); }
/* Кольцо фокуса — как у чипов: слоя состояния при обходе с клавиатуры мало,
   а между клавишами всего 4px, поэтому кольцо нарисовано внутри клавиши. */
.vocab-key:focus-visible {
    outline: 3px solid var(--md-sys-color-secondary);
    outline-offset: -3px;
}
.vocab-key .msym { color: var(--md-sys-color-on-surface-variant); }

/* ============================================================
   TEXT FIELD (outlined)
   ============================================================ */
.input-group {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
    margin: 16px 0;
}
.input-group input {
    flex: 1;
    min-width: 180px;
    height: 56px;
    padding: 0 16px;
    border: 1px solid var(--md-sys-color-outline);
    border-radius: var(--md-sys-shape-corner-extra-small);
    background: transparent;
    font-family: inherit;
    font-size: 1rem;
    letter-spacing: 0.03125rem;
    color: var(--md-sys-color-on-surface);
    transition: border-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                box-shadow var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.input-group input::placeholder { color: var(--md-sys-color-on-surface-variant); }
.input-group input:focus {
    outline: none;
    border-color: var(--md-sys-color-primary);
    box-shadow: inset 0 0 0 1px var(--md-sys-color-primary);
}
.input-group button {
    min-height: 56px;
    padding: 0 24px;
    border: 0;
    border-radius: var(--md-sys-shape-corner-full);
    background: var(--md-sys-color-primary);
    color: var(--md-sys-color-on-primary);
    font-family: inherit;
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: 0.00625rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    transition: box-shadow var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.input-group button:hover { box-shadow: var(--md-sys-elevation-level1); }

/* ============================================================
   CHIPS M3
   ============================================================ */

/* filter chip: ряд прокручивается по горизонтали, как scrollable tabs.
   Кнопка высотой 48dp — это область касания; сама «пилюля» (32dp) живёт
   во вложенном .filter-chip__body, иначе её overflow:hidden (нужен для
   ripple) обрезал бы расширенную область касания. */
.chip-set {
    display: flex;
    gap: 8px;
    margin: 0 -16px 8px;
    padding: 0 16px;
    overflow-x: auto;
    scrollbar-width: none;
    scroll-behavior: smooth;
}
.chip-set::-webkit-scrollbar { display: none; }
.filter-chip {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    height: 48px;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.filter-chip__body {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 32px;
    padding: 0 16px;
    border: 1px solid var(--md-sys-color-outline);
    border-radius: var(--md-sys-shape-corner-small);
    background: transparent;
    color: var(--md-sys-color-on-surface-variant);
    font-family: var(--font-ru);
    font-size: 0.875rem;
    line-height: 1.25rem;
    font-weight: 500;
    letter-spacing: 0.00625rem;
    white-space: nowrap;
    transition: background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                border-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.filter-chip__body::before {
    content: '';
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
    z-index: -1;
}
.filter-chip:hover .filter-chip__body::before { opacity: var(--md-sys-state-hover-opacity); }
.filter-chip:active .filter-chip__body::before { opacity: var(--md-sys-state-pressed-opacity); }
.filter-chip:focus-visible { outline: none; }
.filter-chip:focus-visible .filter-chip__body::before { opacity: var(--md-sys-state-focus-opacity); }
.filter-chip:focus-visible .filter-chip__body {
    outline: 3px solid var(--md-sys-color-secondary);
    outline-offset: 2px;
}
.filter-chip[aria-pressed="true"] .filter-chip__body {
    background: var(--md-sys-color-secondary-container);
    border-color: transparent;
    color: var(--md-sys-color-on-secondary-container);
}
/* галочка появляется только у выбранного чипа — это её роль в M3 */
.filter-chip__check {
    width: 0;
    font-size: 18px;
    opacity: 0;
    transform: scale(0.8);
    transition: width var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-emphasized),
                opacity var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard),
                transform var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-emphasized);
}
.filter-chip[aria-pressed="true"] .filter-chip__check {
    width: 18px;
    opacity: 1;
    transform: scale(1);
}
/* счётчик — та же роль цвета, что и метка: приглушать его нечем,
   любое понижение прозрачности уводит текст ниже 4.5:1 */
.filter-chip__count {
    margin-left: 4px;
    color: inherit;
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}

/* Банк слов и поле сборки бывают на двух языках: в одну сторону упражнение
   собирает фразу изучаемого языка, в другую — русскую. Модификатор --script
   ставит тот, кто раскладывает фишки (js/translation.js, js/exercises.js,
   js/test.js): без него фишки остаются русскими и слева направо.

   Направление здесь — это порядок фишек, а не только начертание букв: у
   письма справа налево первое выбранное слово встаёт в поле сборки справа.
   Порядок в state при этом не меняется — chosen[0] так и остаётся первым
   словом ответа, и проверка сравнения не знает о направлении вовсе. */
.word-bank {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 16px 0;
}
.word-bank .chip {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    min-height: 32px;
    padding: 6px 16px;
    border: 1px solid var(--md-sys-color-outline);
    border-radius: var(--md-sys-shape-corner-small);
    background: transparent;
    color: var(--md-sys-color-on-surface-variant);
    font-family: var(--font-ru);
    font-size: 0.9375rem;
    line-height: 1.25rem;
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    transition: background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                border-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                transform var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-emphasized),
                opacity var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard);
}
.word-bank .chip::before {
    content: '';
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
    z-index: -1;
}
.word-bank .chip:hover::before { opacity: var(--md-sys-state-hover-opacity); }
.word-bank .chip.picked {
    background: var(--md-sys-color-secondary-container);
    border-color: transparent;
    color: var(--md-sys-color-on-secondary-container);
    opacity: 0.45;
    transform: scale(0.94);
    cursor: default;
}

/* область сборки предложения */
.build-area {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    min-height: 64px;
    margin: 16px 0;
    padding: 12px 16px;
    border: 1px dashed var(--md-sys-color-outline);
    border-radius: var(--md-sys-shape-corner-medium);
    background: var(--md-sys-color-surface-container-lowest);
    transition: border-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.build-area:empty::before {
    content: 'Выберите слова по порядку';
    color: var(--md-sys-color-on-surface-variant);
    font-size: 0.875rem;
    letter-spacing: 0.015625rem;
}
.build-area .token {
    min-height: 32px;
    padding: 6px 16px;
    border-radius: var(--md-sys-shape-corner-small);
    background: var(--md-sys-color-secondary-container);
    color: var(--md-sys-color-on-secondary-container);
    font-family: var(--font-ru);
    font-size: 0.9375rem;
    line-height: 1.25rem;
    display: inline-flex;
    align-items: center;
    animation: md-token-in var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-emphasized-decelerate);
}
@keyframes md-token-in {
    from { transform: scale(0.7); opacity: 0; }
    to   { transform: scale(1);   opacity: 1; }
}

/* Модификатор идёт после обоих базовых правил: у него та же специфичность,
   и объявленный раньше он проиграл бы им шрифт. */
.word-bank--script, .build-area--script {
    direction: var(--md-ref-script-direction);
}
.word-bank--script .chip, .build-area--script .token {
    font-family: var(--md-ref-typeface-script);
    /* Фишка банка слов — это ответ: из них собирают фразу, и кегль у них
       такой же, как у вариантов ответа (styles/screens.css), с теми же двумя
       множителями. Нижний предел кегля остаётся на месте: именно на нём
       стоит мелкий текст изучаемого языка, а у иврита он поднимает основание
       до 1.25rem — отсюда 38px у иврита против 27px у греческого. */
    font-size: calc(max(1.125rem, var(--md-ref-script-min-size)) * var(--md-ref-script-size) * var(--md-ref-script-scale));
    /* Высота строки числом: кегль вырос, а 1.25rem из базового правила
       оставили бы строки фишки налезающими друг на друга. */
    line-height: 1.3;
}

/* ============================================================
   ПРИМЕРЫ УПОТРЕБЛЕНИЯ В СЛОВАРЕ + «В СЛОВОСОЧЕТАНИИ» В КАРТОЧКАХ
   Добавить в конец styles/components.css.
   Использует только уже существующие в проекте M3-токены.
   ============================================================ */

/* --- строка слова в общем словаре: делаем явно кликабельной --- */
.word-item .word-row {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    cursor: pointer;
    border-radius: var(--md-sys-shape-corner-medium);
    -webkit-tap-highlight-color: transparent;
    transition: color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard);
}
.word-item .word-row::before {
    content: '';
    position: absolute;
    inset: 0;
    background: currentColor;
    opacity: 0;
    transition: opacity var(--md-sys-motion-duration-short2) var(--md-sys-motion-easing-standard);
    z-index: -1;
}
.word-item .word-row:hover::before { opacity: var(--md-sys-state-hover-opacity); }
.word-item .word-row:active::before { opacity: var(--md-sys-state-pressed-opacity); }
.word-item .word-row:focus-visible::before { opacity: var(--md-sys-state-focus-opacity); }
/* .word-item обрезает всё, что за краем (overflow: hidden), и общее кольцо
   фокуса с outline-offset: 2px срезалось бы по трём сторонам — рисуем его внутри. */
.word-item .word-row:focus-visible { outline-offset: -3px; }

.word-item .vocab-chevron {
    /* Без margin-left: auto — строка уже имеет его на самом переводе
       (.word-row > span, styles/screens.css), а два автоматических отступа
       делят свободное место поровну и оставляют переводу половину строки:
       «Яхве, Господь» переносилось на две строки. Шеврон просто идёт следом
       за переводом и упирается в правый край вместе с ним. */
    color: var(--md-sys-color-on-surface-variant);
    font-size: 20px;
    transition: transform var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-emphasized);
}
.word-item.open .vocab-chevron { transform: rotate(180deg); }

/* --- выезжающий блок статьи словаря: примеры сразу, формы — по желанию --- */
.word-item .word-details {
    max-height: 0;
    overflow: hidden;
    transition: max-height var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-emphasized);
}
.word-item .word-details.open { max-height: 600px; }
/* Раскрытая таблица форм выше блока примеров: поднимаем потолок тела, иначе
   готовая парадигма обрезалась бы по высоте примеров. */
.word-item .word-details.open.forms-open { max-height: 1600px; }

/* Кнопка «Показать формы» — второстепенное действие текстовой кнопкой M3,
   под примерами. */
.word-item .vocab-forms-toggle { margin: 0 0 4px; }
/* Таблица форм свёрнута до нажатия — тем же приёмом, что и весь блок:
   max-height: 0 → .open. Класс стоит на самой полосе прокрутки, а не на
   обёртке, чтобы .word-details > .md-table-scroll (разворот таблицы вместе с
   письмом, styles/screens.css) оставался её прямым родителем. */
.word-item .md-table-scroll.vocab-forms {
    max-height: 0;
    margin: 0;
    overflow: hidden;
    opacity: 0;
    transition: max-height var(--md-sys-motion-duration-long1) var(--md-sys-motion-easing-emphasized),
                opacity var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-standard);
}
.word-item .md-table-scroll.vocab-forms.open {
    max-height: 1200px;
    margin: 4px 0 0;
    overflow-x: auto;
    opacity: 1;
}

/* --- статья слова: чтение под словом, остальные значения — под переводом --- */
/* Верх статьи — одна строка в две колонки: слева чтение слова, справа
   значения, которых не хватило строке. Так каждая половина стоит под тем, к
   чему относится: слово в строке слева, перевод справа. Если места мало,
   колонка значений переносится под чтение и там остаётся справа — flex-wrap
   и margin-left: auto. Общий ползунок размера текста их двигает (кегли в rem),
   множители изучаемого языка — нет: это русские буквы и латиница, подсказка
   к слову, а не само слово (.script им не ставится). */
.vocab-entry-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 4px 16px;
    padding: 4px 4px 2px;
}
.vocab-translit {
    font-size: 0.9375rem;
    line-height: 1.4;
    color: var(--md-sys-color-on-surface);
}
.vocab-glosses {
    margin-left: auto;
    text-align: right;
}
.vocab-gloss {
    font-size: 0.875rem;
    line-height: 1.25rem;
    color: var(--md-sys-color-on-surface);
}

.vocab-examples {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 4px 4px 12px;
}
.vocab-example {
    background: var(--md-sys-color-surface-container-low);
    border-radius: var(--md-sys-shape-corner-medium);
    padding: 10px 14px;
}
.vocab-example__script {
    font-family: var(--md-ref-typeface-script);
    direction: var(--md-ref-script-direction);
    unicode-bidi: isolate;
    /* Пример употребления — второй из двух закреплённых кеглей изучаемого
       языка (первый — статья словаря, styles/screens.css), и по той же
       причине: его читают в списке, а не листают. Кегль задан токеном в
       px со своим значением у каждого письма (styles/tokens.css), поэтому
       ни общий ползунок, ни языковой сюда не доезжают.
       Этим правилом живут оба места показа примера — раскрытая словарная
       статья (js/vocab.js) и «В словосочетании» под карточкой
       (js/flashcards.js), поэтому отдельного правила для статьи больше
       нет: раньше оно поднимало пример шагом кегля до 40.8px, то есть
       пример был крупнее самого слова. */
    font-size: var(--md-ref-script-example-size);
    /* Числом, а не в rem: строка обязана следовать за своим кеглем, а не
       за общим ползунком — 1.5rem на 80% общего дал бы 19.2px строки на
       22px кегля. */
    line-height: 1.4;
    color: var(--md-sys-color-on-surface);
    margin-bottom: 4px;
}
/* Тот же пример употребления, но в раскрытой словарной статье: своего кегля
   у него больше нет — им живёт базовое правило .vocab-example__script выше,
   и это намеренно. Пока кегли были разными, статья набирала пример шагом
   кегля (до 40.8px), а карточка — только множителем ползунка, и один и тот
   же компонент выглядел по-разному без причины. Теперь оба места читаются
   одинаково и не слушают ползунки размера. */
.vocab-example__script strong {
    color: var(--md-sys-color-primary);
    font-weight: 600;
}
.vocab-example__ru {
    font-size: 0.875rem;
    line-height: 1.25rem;
    color: var(--md-sys-color-on-surface-variant);
}
/* Ссылка на стих — только у примеров из Библии (data/hebrew-examples.js).
   Мелкая и приглушённая: она объясняет, откуда пример, а не участвует в чтении. */
.vocab-example__ref {
    font-size: 0.75rem;
    line-height: 1rem;
    margin-top: 2px;
    color: var(--md-sys-color-on-surface-variant);
}
.vocab-examples-empty {
    padding: 4px 4px 14px;
    font-size: 0.875rem;
    line-height: 1.25rem;
    color: var(--md-sys-color-on-surface-variant);
}

/* --- «Показать в словосочетании» на карточках --- */
.flashcard-context-btn {
    margin: 0 auto;
    display: flex;
}
.flashcard-context {
    margin: 12px auto 0;
    max-width: 420px;
    animation: md-token-in var(--md-sys-motion-duration-medium2) var(--md-sys-motion-easing-emphasized-decelerate);
}
.flashcard-context .vocab-example {
    background: var(--md-sys-color-surface-container-high);
}
/* ============================================================
   Токены в build-area стали кликабельными — убирают слово по клику.
   Добавить в конец styles/components.css (не переопределяет
   .build-area .token, а дополняет уже существующее правило).
   ============================================================ */
.build-area .token {
    cursor: pointer;
    gap: 6px;
    -webkit-tap-highlight-color: transparent;
    transition: background-color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                color var(--md-sys-motion-duration-short4) var(--md-sys-motion-easing-standard),
                opacity var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard);
}
.build-area .token:hover,
.build-area .token:focus-visible {
    background: var(--md-sys-color-error-container);
    color: var(--md-sys-color-on-error-container);
    outline: none;
}
.build-area .token::after {
    content: '✕';
    font-size: 0.6875rem;
    opacity: 0.55;
}
.build-area .token:hover::after,
.build-area .token:focus-visible::after {
    opacity: 0.85;
}