/* Froggish поверх IDS (site/ids — копия Intuition Design System, MIT).

   Вёрстка — таблицами, как в старом HTML: страница — таблица «шапка /
   подпись и цели дня / меню | заголовок над содержимым / подвал», где
   каждая ячейка — «пузырь» (раздел «Каркас»); карточка — таблица «картинка
   | слово», разбор произношения — таблица букв и процентов, у них сетка
   1px solid серым (--ids__grid). Из IDS — шрифт, флюидная типографика,
   цвета, ссылки, темы.

   Правила — как в IDS: цвета только семантическими токенами, размеры
   компонента — в em, отступы страницы — в rem и токенами шкал. Поля ввода —
   нативные, кнопки — зелёные «таблетки» цвета логотипа (раздел «Кнопки»). */

/* ── Все таблицы: сетка 1px solid серым, внешние углы чуть скруглены ─── */

/* Скруглению нужна раздельная модель рамок (с collapse radius не
   работает), поэтому линии рисуются без удвоения: у каждой ячейки —
   справа и снизу, у первого столбца ещё слева, у первой строки — сверху.
   Скругляются углы крайних ячеек. Шапка (froggish__bar), плашка целей
   дня (froggish__goals) и каркас (froggish__layout — пузыри, ниже) — без
   сетки; :where() держит вес селекторов вровень с IDS. */
.ids table:where(:not(.froggish__bar, .froggish__goals, .froggish__layout)) {
  --froggish__radius: 0.4em;
  border-collapse: separate;
  border-spacing: 0;
  margin-bottom: var(--ids__gap-s);

  & tr th,
  & tr td {
    border: 0 solid var(--ids__grid);
    border-width: 0 var(--ids__border-width-s) var(--ids__border-width-s) 0;
    padding: 0.45em 0.7em;
    vertical-align: top;
    text-align: left;
  }
  /* IDS снимает нижнюю линию у ячеек под любой последней строкой — в том
     числе под строкой каркаса, в которой стоит содержимое страницы, то есть
     у всех строк вложенной таблицы. Возвращаем; :nth-child(n) — вес выше,
     чем у правила IDS. */
  & tr:nth-child(n) td {
    border-bottom: var(--ids__border-width-s) solid var(--ids__grid);
  }
  & tr > :first-child {
    border-left-width: var(--ids__border-width-s);
  }
  & tr:first-child > * {
    border-top-width: var(--ids__border-width-s);
  }
  & tr:first-child > :first-child {
    border-top-left-radius: var(--froggish__radius);
  }
  & tr:first-child > :last-child {
    border-top-right-radius: var(--froggish__radius);
  }
  & tr:last-child > :first-child {
    border-bottom-left-radius: var(--froggish__radius);
  }
  & tr:last-child > :last-child {
    border-bottom-right-radius: var(--froggish__radius);
  }

  & tr th {
    position: static;
    padding-bottom: 0.45em;
    font-weight: 600;
    background-color: var(--ids__surface);
  }

  & td.num,
  & th.num {
    text-align: right;
    white-space: nowrap;
  }
}

/* ── Каркас страницы: пузыри ─────────────────────────────────────────────

   Страница — во всю ширину окна, без полей вокруг. Каждый блок — свой
   «пузырь»: рамка 1px серым и крупное скругление (на высоте шапки и баров
   — почти полная «таблетка»). Пузыри стоят вплотную, как слипшиеся мыльные
   пузыри: шапка; подпись «Тренажёр…» и три бара целей; меню | заголовок
   страницы над содержимым; подвал. */

:root {
  --froggish__bubble: 1.6rem;
}
/* Фон страницы — тот же серый, что рамки пузырей: пузыри — светлые капли
   на сером, рамка сливается с фоном. */
body.ids {
  background-color: var(--ids__grid);
}
.ids .froggish__page {
  width: 100%;
}
.ids table.froggish__layout {
  width: 100%;
  font-size: inherit;
  margin: 0;
  border-collapse: separate;
  border-spacing: 0;

  & > tbody > tr > td {
    padding: 1em 1.25em;
    border: var(--ids__border-width-s) solid var(--ids__grid);
    border-radius: var(--froggish__bubble);
    background-color: var(--ids__background);
    vertical-align: top;
  }

  /* Колонка меню — ровно по самому длинному пункту, на всех страницах одна;
     фон серый; во всю высоту заголовка и содержимого. */
  & .froggish__nav {
    width: 1%;
    white-space: nowrap;
    background-color: var(--ids__surface);
  }
  /* Заголовок страницы — тем же фоном, что меню. */
  & > tbody > tr > td.froggish__title {
    padding: 0.8em 1.4em;
    vertical-align: middle;
    background-color: var(--ids__surface);
  }
  & .froggish__main {
    padding-bottom: 2em;
  }
}

/* Строка шапки — вложенная таблица без сетки (так раньше и верстали). */
.ids table.froggish__bar {
  width: 100%;
  font-size: inherit;

  & tr td,
  & tr:last-child td {
    border: 0;
    padding: 0;
    vertical-align: middle;
  }
  & td.right {
    text-align: right;
    white-space: nowrap;
  }
}

/* Логотип — шрифт Pilowlava (Антон Мольян и Жереми
   Ланд, Velvetyne; кириллица — Максим Кобузан; SIL OFL — site/fonts/, там же
   лицензия): латиница и кириллица в одном файле. Начертание одно, обычное:
   жирным его не делаем, иначе браузер нарисует фальшивый жирный. Заголовок
   страницы — рукописным (ниже), остальные — обычным шрифтом IDS (Inter). */
@font-face {
  font-family: "Pilowlava";
  src: url("../fonts/pilowlava.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: block;
}

/* Подпись «Тренажёр…» под шапкой — Roboto Mono (The Roboto Mono Project
   Authors, SIL OFL — site/fonts/, там же лицензия; файлы — Fontsource):
   кириллица и латиница (точка, пробел) обычного начертания. */
@font-face {
  font-family: "Roboto Mono";
  src: url("../fonts/roboto-mono-cyrillic-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Roboto Mono";
  src: url("../fonts/roboto-mono-latin-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Логотип — ссылка на главную: зелёный, при наведении другой зелёный. */
.ids .froggish__logo {
  color: var(--ids__brand);
  font-family: "Pilowlava", "Inter", sans-serif;
  /* Pilowlava широкий и пухлый — кегль меньше обычного, на телефоне ещё меньше. */
  font-size: 1.4em;
  font-weight: 400;
  text-decoration: none;
  white-space: nowrap;

  &:hover {
    color: var(--ids__brand-hover);
  }
}

/* Рукописный шрифт — подпись «Тренажёр…» и заголовки страниц: First Time Writing! (GGBotNet,
   CC0 — общественное достояние; site/fonts/, там же лицензия). Файл урезан
   до латиницы, кириллицы и знаков препинания (2 МБ → 94 КБ). */
@font-face {
  font-family: "First Time Writing";
  src: url("../fonts/first-time-writing.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Заголовок страницы — свой пузырь над содержимым: говорит, чем тут
   заняты; серым, как подписи IDS. Шрифт — рукописный First Time Writing!
   (тонкий — крупнее обычного). */
.ids .froggish__title h1.S {
  color: var(--ids__text-caption);
  font-family: "First Time Writing", "Inter", sans-serif;
  font-size: 1.9em;
  font-weight: 400;
  line-height: 1.1;
  margin: 0;
}

/* Лягушка в центре шапки выглядывает из-за нижней линии и машет лапками:
   два кадра пиксельной лягушки из прежней версии (img/frog-wave-*.png,
   61×62 — пиксель в пиксель) сменяются по кругу. Ячейка шапки обрезает
   всё, что ниже её края, — видны голова и лапки. Над линией лягушка
   всегда занимает 3/4 высоты шапки (размер — ниже, у .froggish__frog).

   Лягушка стоит сразу за «Froggish»: ячейка логотипа — по ширине слова,
   у лягушки — своя узкая ячейка, всё остальное место — правой части
   (язык, микрофон, тема). Сама лягушка спозиционирована от ячейки шапки
   (по вертикали — от её нижнего края), а по горизонтали остаётся на месте
   в своей ячейке. */
.ids table.froggish__layout .froggish__head {
  position: relative;
  overflow: hidden;
}
.ids table.froggish__bar {
  & td:first-child {
    width: 1%;
    white-space: nowrap;
  }
  & td.froggish__frog-cell {
    width: 7.5rem;
    text-align: center;
  }
}
/* Размер — от высоты шапки (проценты считаются от её ячейки): над линией
   всегда 3/4 высоты шапки, а нижние ~32% лягушки (туловище и лапы)
   спрятаны за линией. Вся лягушка — 0.75 / 0.68 ≈ 110% высоты шапки,
   низ — на 32% от этого (≈ 35% шапки) ниже линии. Ширина — по пропорциям
   кадра 61×62. */
.ids .froggish__frog {
  position: absolute;
  bottom: -35%;
  height: 110%;
  aspect-ratio: 61 / 62;
  transform: translateX(-50%);
  pointer-events: none;

  /* Кадры с прозрачным фоном, поэтому виден всегда ровно один: оба мигают
     одной анимацией, первый — со сдвигом на полпериода. */
  & img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: none;
    image-rendering: pixelated;
    animation: froggish-wave 0.84s step-end infinite;
  }
  & img:first-child {
    animation-delay: -0.42s;
  }
}
@keyframes froggish-wave {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
}
@media (width < 768px) {
  /* Ячейка лягушки — по самой лягушке (место в шапке занял флаг); сама
     лягушка чуть правее — в невидимый отступ кнопки микрофона, чтобы не
     прилипала к «Froggish». */
  .ids table.froggish__bar td.froggish__frog-cell {
    width: 4.4rem;
  }
  /* Шапка на телефоне высокая, а места в ширину нет: лягушка — своего
     размера, не от высоты шапки, и так же выглядывает из-за нижней линии
     (низ — на ~32% её роста ниже линии). */
  .ids .froggish__frog {
    height: 4.4rem;
    bottom: -1.4rem;
    transform: translateX(calc(-50% + 0.3rem));
  }
}
@media (prefers-reduced-motion: reduce) {
  .ids .froggish__frog img {
    animation: none;
  }
  .ids .froggish__frog img + img {
    opacity: 0;
  }
}

/* ── Говорящая лягушка (common.js, speak) ────────────────────────────────
   Пока звучит озвучка, снизу ОКНА (fixed, а не низ страницы) выглядывает
   пиксельная лягушка: «окно» с overflow: hidden прижато к нижнему краю, в
   нём спрайт ездит по вертикали — спрятан целиком ниже края → выглядывает
   по голову (~46% роста). Выезд — с подпрыгиванием (запас сверху, чтобы
   голову не срезало), заезд — плавно вниз. Рот: два кадра, второй
   показывается классом is-open. Кадры — в двух наборах: на светлой теме
   контур белый, на тёмной — чёрный (как нарисовано). Нажатия проходят
   сквозь лягушку. */
.froggish__talker {
  --talker-w: 11rem;
  --talker-h: calc(var(--talker-w) * 64 / 63);
  --talker-peek: calc(var(--talker-h) * 0.46);
  --talker-headroom: 2.5rem;
  position: fixed;
  left: 50%;
  bottom: 0;
  z-index: 50;
  width: var(--talker-w);
  height: calc(var(--talker-peek) + var(--talker-headroom));
  overflow: hidden;
  pointer-events: none;
  transform: translateX(-50%);
}
.froggish__talker-sprite {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: var(--talker-h);
  transform: translateY(calc(var(--talker-peek) + var(--talker-headroom)));
  transition: transform 320ms cubic-bezier(0.55, 0, 1, 0.45);

  & .froggish__talker-set {
    position: absolute;
    inset: 0;
  }
  & img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: none;
    image-rendering: pixelated;
  }
  & img + img {
    opacity: 0;
  }
}
html:not(.dark) .froggish__talker-set[data-theme="dark"],
html.dark .froggish__talker-set[data-theme="light"] {
  display: none;
}
.froggish__talker.is-out .froggish__talker-sprite {
  transform: translateY(var(--talker-headroom));
  transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
}
.froggish__talker.is-open .froggish__talker-sprite {
  & img:first-child {
    opacity: 0;
  }
  & img + img {
    opacity: 1;
  }
}
@media (width < 768px) {
  .froggish__talker {
    --talker-w: 8.5rem;
  }
}
@media (prefers-reduced-motion: reduce) {
  .froggish__talker-sprite {
    transition: none;
  }
}

/* ── Под шапкой: подпись и три цели дня ────────────────────────────────
   Строка каркаса сама не пузырь — пузыри внутри: подпись «Тренажёр…» и
   каждый бар отдельно, вплотную друг к другу. Бар — ссылка на свой раздел
   и заливает свой пузырь целиком: пастельная дорожка, насыщенная заливка
   до доли сделанного, поверх — «5/10 новых слов». На телефоне — друг под
   другом. */
.ids table.froggish__layout > tbody > tr > td.froggish__today {
  padding: 0;
  border: 0;
  border-radius: 0;
  background-color: transparent;
}
.ids table.froggish__goals {
  width: 100%;
  table-layout: fixed;
  margin: 0;
  font-size: 0.9em;
  border-collapse: separate;
  border-spacing: 0;

  & tr td {
    padding: 0;
    border: 0;
    vertical-align: middle;
  }
  & tr td.froggish__tagline {
    width: 31%;
    padding: 0.6em 1.4em;
    color: var(--ids__text-caption);
    border: var(--ids__border-width-s) solid var(--ids__grid);
    border-radius: var(--froggish__bubble);
    background-color: var(--ids__head);
  }
  /* Слоган — рукописным First Time Writing!, как заголовок админки;
     шрифт тонкий — крупнее обычного текста. */
  & tr td.froggish__tagline > span {
    font-family: "First Time Writing", "Roboto Mono", ui-monospace, monospace;
    font-size: 1.5em;
    line-height: 1.1;
  }
  /* «меню ↓» — только на телефоне (там меню в конце страницы). */
  & tr td.froggish__tagline .froggish__to-menu {
    display: none;
  }
  /* Ячейка бара — только место: высота по строке (подпись в две строки),
     но не ниже пальца; пузырь — сама ссылка-бар. */
  & tr td.froggish__goal-cell {
    position: relative;
    height: 2.75rem;
  }
}

.ids a.froggish__goal {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  overflow: hidden;
  border: var(--ids__border-width-s) solid var(--ids__grid);
  border-radius: var(--froggish__bubble);
  background-color: var(--froggish__track);
  color: var(--ids__text);
  text-decoration: none;
  white-space: nowrap;

  &:hover {
    color: var(--ids__text);

    & .froggish__goal-text {
      text-decoration: underline;
      text-underline-offset: 0.2em;
    }
  }
  &[data-goal="newWords"] {
    --froggish__track: var(--ids__goal-new-track);
    --froggish__fill: var(--ids__goal-new);
  }
  &[data-goal="reviews"] {
    --froggish__track: var(--ids__goal-review-track);
    --froggish__fill: var(--ids__goal-review);
  }
  &[data-goal="phrases"] {
    --froggish__track: var(--ids__goal-phrase-track);
    --froggish__fill: var(--ids__goal-phrase);
  }
}
.ids .froggish__goal-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  background-color: var(--froggish__fill);
  transition: width 0.4s var(--ids__easing-base);
}
.ids .froggish__goal-text {
  position: relative;
  padding: 0 1.4em;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
@media (prefers-reduced-motion: reduce) {
  .ids .froggish__goal-fill {
    transition: none;
  }
}

/* «вверх ↑» — только на телефоне. */
.ids .froggish__to-top {
  display: none;
}

/* Флаг изучаемого языка — вплотную к правому краю шапки, во всю её высоту:
   скругление пузыря обрезает ему углы. Ссылка на смену языка. Флаги —
   flag-icons (Panayiotis Lipiridis, MIT; site/flags/, там же лицензия),
   пропорции 4:3. Размеры явные: высота шапки задана (--froggish__head),
   ширина флага посчитана из неё — без aspect-ratio у абсолютного
   элемента (Safari на телефоне его не тянул, и флаг пропадал). Место
   под флаг правая часть шапки держит отступом. */
:root {
  --froggish__head: 5.9rem;
  --froggish__flag: calc((var(--froggish__head) - 2 * var(--ids__border-width-s)) * 4 / 3);
}
/* Шапка — фоном цвета шалфея (как и подпись «Тренажёр…» под ней). */
.ids table.froggish__layout > tbody > tr > td.froggish__head {
  background-color: var(--ids__head);
  height: var(--froggish__head);
  padding-top: 0;
  padding-bottom: 0;
  vertical-align: middle;
}
.ids table.froggish__layout > tbody > tr > td.froggish__head:has(> .froggish__flag) {
  padding-right: calc(var(--froggish__flag) + 1.25em);
}
.ids .froggish__head > .froggish__flag {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: var(--froggish__flag);

  & img {
    display: block;
    width: 100%;
    height: 100%;
    max-width: none;
    object-fit: cover;
  }
  &:hover {
    filter: brightness(1.08);
  }
}

/* Флаги-овалы — в карточках фразы и в выборе языка: вытянутый эллипс 2:1.
   Флаги — flag-icons, продлённые до 2:1 по своему рисунку (site/flags/oval/:
   полосы продолжены, у Испании и Китая флаг посередине), — овал заполнен
   целиком, ничего не растянуто и не срезано. Тонкий контур — белые полосы
   не сливаются с фоном. */
.ids img.froggish__flag-oval {
  display: inline-block;
  width: 2em;
  height: 1em;
  max-width: none;
  border-radius: 50%;
  box-shadow: 0 0 0 var(--ids__border-width-s) color-mix(in srgb, var(--ids__grid) 60%, transparent);
  vertical-align: -0.15em;
}

/* Микрофон в шапке: учиться с произношением или без. Выключен — иконка
   серая и зачёркнута (состояние — html[data-speak], см. common.js). */
.ids .froggish__speak {
  appearance: none;
  background: none;
  border: 0;
  padding: 0.2em;
  margin-left: 0.5em;
  color: var(--ids__text);
  line-height: 0;
  vertical-align: middle;
  cursor: pointer;

  & svg {
    width: 1.3em;
    height: 1.3em;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  & .slash {
    display: none;
  }
}
html[data-speak="off"] .ids .froggish__speak {
  color: var(--ids__text-caption);

  & .slash {
    display: inline;
  }
}

/* Переключатель темы — в шапке, а не прибит к углу экрана, как в IDS, и не
   ползунок, а иконка: на светлой — оранжевое солнце, на тёмной — лимонный
   полумесяц. Переключает скрипт IDS, состояние — класс .dark у <html>: он
   стоит до первой отрисовки, так что иконка верная сразу, без анимации при
   загрузке. При переключении солнце растёт в диск, лучи с поворотом
   втягиваются, на диск наезжает тень (маска) — остаётся серп. */
.ids .froggish__bar .froggish__theme {
  position: static;
  padding: 0.2em;
  margin-left: 0.6em;
  color: var(--ids__theme-icon);
  line-height: 0;
  vertical-align: middle;

  & svg {
    width: 1.4em;
    height: 1.4em;
  }
  & .froggish__theme-disc {
    fill: currentColor;
    transform-origin: 12px 12px;
    transition: transform var(--ids__duration-base) var(--ids__easing-base);
  }
  & .froggish__theme-shade {
    transform: translate(10px, -10px);
    transition: transform var(--ids__duration-base) var(--ids__easing-base);
  }
  & .froggish__theme-rays {
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    transform-origin: 12px 12px;
    transition:
      transform var(--ids__duration-base) var(--ids__easing-base),
      opacity var(--ids__duration-base) var(--ids__easing-base);
  }
  &:hover svg {
    filter: brightness(1.1);
  }
}
.dark .ids .froggish__bar .froggish__theme {
  & .froggish__theme-disc {
    transform: scale(1.6);
  }
  & .froggish__theme-shade {
    transform: none;
  }
  & .froggish__theme-rays {
    opacity: 0;
    transform: rotate(90deg) scale(0.4);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ids .froggish__bar .froggish__theme :is(.froggish__theme-disc, .froggish__theme-shade, .froggish__theme-rays) {
    transition: none;
  }
}

/* Справа в шапке: микрофон и тема, дальше — язык перед флагом: название,
   под ним «сменить». Две строки заходят в поля шапки (отрицательные
   отступы) и не делают её выше — иначе вырос бы и флаг. */
.ids .froggish__bar .froggish__lang-title {
  display: inline-block;
  margin: -0.6em 0 -0.6em 1.5em;
  line-height: 1.25;
  text-align: left;
  vertical-align: middle;
}

/* Меню — простой столбик ссылок, текущий раздел — жирным без ссылки. */
.ids .froggish__nav ul {
  margin: 0;

  & li {
    padding-left: 0;
    margin-bottom: 0.4em;

    &::before {
      content: none;
    }
  }
  /* Пункт текущей страницы — не ссылка: серым, как подписи. */
  & li > b {
    color: var(--ids__text-caption);
  }
}


/* Колонки и строки только для широкого экрана или только для телефона. */
.froggish__narrow {
  display: none;
}

/* Атрибут hidden скрывает всегда, даже если стили задали элементу display. */
.ids [hidden] {
  display: none !important;
}

/* ── Вход: подписи над полями, поля одной ширины ──────────────────────── */

.ids form.froggish__auth {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--ids__gap-s);
  max-width: 20em;
  margin-bottom: var(--ids__gap-m);

  & label {
    display: flex;
    flex-direction: column;
    gap: 0.2em;
    width: 100%;
  }
  & input {
    width: 100%;
    font-size: 1.1em;
    padding: 0.25em 0.4em;
  }
}

/* ── Цвет оценки и статусов ───────────────────────────────────────────── */

.ids .good {
  color: var(--ids__success);
}
.ids .warn {
  color: var(--ids__warning);
}
.ids .bad {
  color: var(--ids__error);
}
.ids .caption {
  color: var(--ids__text-caption);
}

/* ── Сегментные ссылки IDS как переключатель: без стрелки «↓» ─────────── */

.ids .ids__promo-link {
  flex-wrap: wrap;
  row-gap: var(--ids__gap-s);
  margin-bottom: var(--ids__gap-s);

  &.no-arrow a.active::after {
    content: none;
  }
}

/* ── Карточка: таблица в две строки — сверху картинка, снизу слово ────── */

.ids table.froggish__card {
  font-size: inherit;
  width: min(100%, 20em);
  margin-bottom: var(--ids__gap-m);

  & tr td {
    vertical-align: middle;
  }
  /* Картинка — пока заглушка: серая плашка (у слов с эмодзи — эмодзи). */
  & tr td.froggish__pic {
    height: 7.5em;
    padding: 0;
    text-align: center;
    background-color: var(--ids__surface);
  }
  & .emoji {
    font-size: 4em;
    line-height: 1;
  }
  /* Часть речи — маленькими серыми буквами под словом. */
  & .pos {
    font-size: 0.8em;
    color: var(--ids__text-caption);
    margin-bottom: 0;
  }
  /* Длинное слово или перевод переносится, а не распирает карточку вбок. */
  & :is(.froggish__word, .loud) {
    overflow-wrap: anywhere;
    hyphens: auto;
  }
}

/* ── Крупное слово (иностранное или русское) ──────────────────────────── */

.ids .froggish__word {
  font-size: 2.2em;
  font-weight: 650;
  line-height: 1.1;
  margin-bottom: 0.2em;

  & .article {
    color: var(--ids__text-caption);
    font-weight: 400;
  }

  /* Транскрипция — строкой под словом, мелко и серым, как в словаре. */
  & .froggish__ipa {
    display: block;
    margin-top: 0.35em;
    font-size: 0.5em;
    font-weight: 400;
  }
}

/* Значения разных частей речи: каждое строкой, подпись части речи — под ним. */
.ids .froggish__senses > div + div {
  margin-top: 0.5em;
}
.ids .froggish__senses p {
  margin-bottom: 0;
}

/* Подпись части речи в строке таблицы (картотека, итоги сессии). */
.ids td .pos {
  color: var(--ids__text-caption);
  font-size: 0.85em;
}

/* Транскрипция (под крупным словом и в картотеке рядом со словом). */
.ids .froggish__ipa {
  color: var(--ids__text-caption);
  font-weight: 400;
  white-space: nowrap;
}

/* ── Поле ответа: крупнее обычного текста, в остальном нативное ─────── */

.ids .froggish__answer {
  font-size: 1.5em;
  width: 100%;
  max-width: 14em;
  padding: 0.25em 0.6em;
  border-radius: 0.6em;
}

/* Поля ввода — без синей обводки фокуса из IDS (reset.css): где печатать,
   и так видно по курсору. У кнопок, ссылок и галочек обводка остаётся —
   она нужна тем, кто ходит по странице клавиатурой. */
.ids :is(input[type="text"], input[type="search"], input[type="password"], textarea):is(:focus, :focus-visible) {
  outline: none;
}

.ids form.froggish__form,
.ids .froggish__keys,
.ids .froggish__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ids__gap-s);
  margin-bottom: var(--ids__gap-m);
}

.ids .froggish__keys button {
  min-width: 2.2em;
}

/* ── Разбор произношения: по таблице на слово — буквы и проценты ──────── */

.froggish__board {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--ids__gap-s);
  margin-bottom: var(--ids__gap-m);

  & table {
    font-size: inherit;
  }
  & table tr td {
    text-align: center;
    padding: 0.2em 0.35em;
  }
  & .letters {
    font-size: 2.2em;
    font-weight: 650;
    line-height: 1.1;
  }
  & .score {
    font-size: 0.75em;
    white-space: nowrap;
  }
}

/* ── Фраза: две карточки со стрелкой — сверху русская, снизу перевод ── */

.ids .froggish__phrase {
  max-width: 36em;
  margin-bottom: var(--ids__gap-m);
}
/* Под полем ответа фразы — попытки, «Какие слова?», «показать ответ»:
   столбиком, плотно. */
.ids .froggish__controls p {
  margin-bottom: 0.35em;

  &:last-child {
    margin-bottom: 0;
  }
}

/* Карточки фразы — скруглены, как пузыри каркаса; поля шире, чтобы текст
   не упирался в скругление. */
.ids .froggish__box {
  background-color: var(--ids__background);
  border: var(--ids__border-width-s) solid var(--ids__grid);
  border-radius: var(--froggish__bubble);
  padding: 1.2em 1.5em;

  & > :last-child {
    margin-bottom: 0;
  }
  & .froggish__box-flag {
    font-size: 1.8em;
    line-height: 1;
    margin-bottom: 0.35em;

    & img.froggish__flag-oval {
      width: 1.6em;
      height: 0.8em;
      vertical-align: top;
    }
  }
  & p.loud {
    margin-bottom: 0;
  }
}
/* Стрелка — не линия, а объёмная фигура: белая заливка и рамка ровно той
   же толщины и цвета, что у карточек (линия не масштабируется с фигурой). */
.ids .froggish__arrow {
  display: block;
  width: 2.6em;
  height: 2.6em;
  margin: 0.4em auto;

  & path {
    fill: var(--ids__background);
    stroke: var(--ids__grid);
    stroke-width: var(--ids__border-width-s);
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
  }
}

/* Ряд стрелок между карточками во всю ширину: столбцов — сколько влезет
   (auto-fill), лишние стрелки уходят на вторую строку и прячутся (высота
   ряда — одна строка). Два положения, без плавного перехода: нечётные
   вверху — чётные внизу, и скачком наоборот; в такт лягушке в шапке —
   на каждый второй её взмах (1.68 с на круг, 0.84 с на положение). */
.ids .froggish__arrows {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(3.2em, 1fr));
  grid-auto-rows: 3.4em;
  height: 3.4em;
  overflow: hidden;
  justify-items: center;
  align-items: center;
  margin: 0.2em 0;

  & .froggish__arrow {
    width: 2.2em;
    height: 2.2em;
    margin: 0;
    animation: froggish-arrow-flip 1.68s step-end infinite;
  }
  & .froggish__arrow:nth-child(even) {
    animation-delay: -0.84s;
  }
}
@keyframes froggish-arrow-flip {
  0% {
    transform: translateY(-0.15em);
  }
  50% {
    transform: translateY(0.15em);
  }
}
/* «Уменьшить движение» — стрелки стоят: нечётные выше, чётные ниже. */
@media (prefers-reduced-motion: reduce) {
  .ids .froggish__arrows .froggish__arrow {
    animation: none;
    transform: translateY(-0.15em);
  }
  .ids .froggish__arrows .froggish__arrow:nth-child(even) {
    transform: translateY(0.15em);
  }
}

/* ── Разбор фразы или ответа: «фрагмент — пояснение» ─────────────────── */

.ids table.froggish__notes {
  width: 100%;
  max-width: 40em;
  margin-bottom: var(--ids__gap-m);

  & tr td:first-child {
    width: 32%;
  }
}

/* ── Широкие таблицы (картотека) прокручиваются сами, а не страница ───── */

/* Ячейка каркаса растягивается под самое широкое содержимое, поэтому
   прокрутке задана нулевая собственная ширина (таблица каркаса её не
   видит), а min-width: 100% растягивает её на всю ячейку. */
.froggish__scroll {
  overflow-x: auto;
  width: 0;
  min-width: 100%;
}

/* ── Кнопка ▶ в строке таблицы (картотека) ────────────────────────────── */

.ids .froggish__play {
  padding: 0.1em 0.55em;
}

/* ── Кнопки: цветом логотипа, скруглённые ───────────────────────────────

   Все кнопки действий («Знаю», «Проверить», «● Произнести», «Дальше →»…)
   — «таблетки» сплошного зелёного цвета логотипа «Froggish», без
   градиента. Мелкие (▶ в картотеке, буквы ä/ö/ü) — мягкие: бледно-зелёный
   фон и текст цвета логотипа, чтобы таблица не рябила. Микрофон и тема в
   шапке — свои, их не трогаем. Неактивная кнопка — серая. */
.ids button:not(.froggish__speak, .ids__theme-toggle) {
  appearance: none;
  border: 0;
  border-radius: 999px;
  padding: 0.45em 1.15em;
  font: inherit;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ids__button-text);
  background-color: var(--ids__button);
  cursor: pointer;
  transition:
    filter 0.15s var(--ids__easing-base),
    transform 0.05s;

  &:hover {
    filter: brightness(1.12);
  }
  &:active {
    transform: translateY(1px);
    filter: brightness(0.92);
  }
  &:focus-visible {
    outline: 2px solid var(--ids__button);
    outline-offset: 2px;
  }
  &:disabled {
    cursor: default;
    transform: none;
    filter: grayscale(1) opacity(0.5);
  }
}
.ids .froggish__keys button,
.ids button.froggish__play {
  color: var(--ids__button);
  background-color: var(--ids__button-soft);
}
.ids .froggish__keys button {
  padding: 0.25em 0.6em;
}
.ids button.froggish__play {
  padding: 0.1em 0.55em;
}

/* ── Подглядывание в русской фразе ──────────────────────────────────────
   Слово русской фразы (пунктир снизу) можно нажать: прямо над ним мелкими
   зелёными буквами (цвет логотипа) появляется то, что от тебя хотят на
   изучаемом языке. Над строками фразы — запас места, чтобы подсказка не
   налезала на строку выше; появляется поверх — текст не двигается. */
/* .ids p — не слабее IDS-правила крупного текста (.ids p.loud, line-height 1.2). */
.ids p.froggish__peekable {
  line-height: 1.9;
}
/* Пунктир — нижней рамкой, а не text-decoration: Safari на iPhone пунктирное
   подчёркивание с толщиной и отступом не рисовал. */
.ids .froggish__peek {
  position: relative;
  cursor: pointer;
  border-bottom: 1.5px dotted var(--ids__grid);
  -webkit-tap-highlight-color: transparent;

  /* Открытое слово — пунктир цвета логотипа. При наведении — тоже, но только
     с мышью: на телефоне «наведение» залипает после касания, и закрытое
     слово оставалось зелёным. */
  &[aria-expanded="true"] {
    border-bottom-color: var(--ids__brand);
  }
  @media (hover: hover) {
    &:hover {
      border-bottom-color: var(--ids__brand);
    }
  }
  &:focus-visible {
    outline: 2px solid var(--ids__brand);
    outline-offset: 2px;
  }
}
.ids .froggish__peek-tip {
  position: absolute;
  left: 50%;
  bottom: 88%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 0.5em;
  font-weight: 600;
  line-height: 1;
  color: var(--ids__brand);
  pointer-events: none;

  &[hidden] {
    display: none;
  }
}

/* ── Касания ──────────────────────────────────────────────────────────── */

/* Телефон не раздувает шрифт при повороте; двойное касание по кнопке —
   это два нажатия, а не зум. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
.ids :is(a, button, summary, select, label, input) {
  touch-action: manipulation;
}

/* ── Телефон ──────────────────────────────────────────────────────────────

   Пузыри каркаса встают друг под друга во всю ширину экрана. Шапка —
   одной строкой, меню всегда развёрнуто списком. Всё, во что попадают
   пальцем, — не меньше 44px. */

@media (width < 768px) {
  /* Пузыри — друг под другом во всю ширину экрана, вплотную; пузатые —
     с просторными полями, и шрифт в них чуть крупнее (кроме шапки: там
     и так тесно). */
  .ids table.froggish__layout > tbody > tr > td,
  .ids table.froggish__layout .froggish__nav {
    display: block;
    width: auto;
    white-space: normal;
    padding: 1.1em 1.25em;
  }
  .ids table.froggish__layout > tbody > tr > td:not(.froggish__head) {
    font-size: 1.08em;
  }
  .ids table.froggish__layout > tbody > tr > td.froggish__title {
    padding: 1.1em 1.25em;
  }
  /* «меню ↓» прокручивает к меню плавно — если не просили меньше движения. */
  @media (prefers-reduced-motion: no-preference) {
    html {
      scroll-behavior: smooth;
    }
  }
  /* Меню — в конце, после содержимого страницы (подвал — ещё ниже):
     каркас становится колонкой, строки таблицы не мешают порядку. */
  .ids table.froggish__layout,
  .ids table.froggish__layout > tbody {
    display: flex;
    flex-direction: column;
  }
  .ids table.froggish__layout > tbody > tr {
    display: contents;
  }
  .ids table.froggish__layout .froggish__nav {
    order: 1;
  }
  .ids table.froggish__layout .froggish__foot {
    order: 2;
  }
  .ids table.froggish__layout .froggish__main {
    padding-bottom: 2em;
  }

  /* Подпись — во всю ширину (слоган мельче, всё так же в две строки),
     справа — «меню ↓»; под ней три бара в один ряд: в каждом сверху
     счётчик, под ним название — столбиком. Верх страницы до содержимого —
     ниже. Барам — ненулевая основа ширины, иначе flex уместит их в строку
     подписи по 0px. */
  .ids table.froggish__goals {
    &,
    & tbody {
      display: block;
      width: auto;
    }
    & tr {
      display: flex;
      flex-wrap: wrap;
    }
    & tr td {
      display: block;
      width: auto;
    }
    & tr td.froggish__tagline {
      display: flex;
      flex: 1 0 100%;
      align-items: center;
      justify-content: space-between;
      gap: 0.75em;
      padding: 0.6em 1.25em;

      & > span {
        font-size: 1.35em;
      }
    }
    /* У другого края подписи — «меню ↓»: прокрутка к меню в конце страницы. */
    & tr td.froggish__tagline .froggish__to-menu {
      display: block;
      padding: 0.8em 0;
      margin: -0.8em 0;
      white-space: nowrap;
    }
    & tr td.froggish__goal-cell {
      flex: 1 1 30%;
      min-width: 0;
      height: 3.4rem;
    }
  }
  .ids a.froggish__goal {
    justify-content: center;
  }
  .ids .froggish__goal-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 0.4em;
    line-height: 1.2;
    white-space: nowrap;
  }
  .ids .froggish__goal-name {
    font-size: 0.85em;
    font-weight: 400;
  }

  /* «вверх ↑» — в пузыре меню своей строкой над первым пунктом, справа;
     от него до первого пункта — тот же шаг, что между пунктами. */
  .ids .froggish__to-top {
    display: block;
    width: fit-content;
    margin: 0 1.25em 0 auto;
    padding: 0.8em 0 0;
  }
  .ids .froggish__to-top + .froggish__menu ul {
    padding-top: 0.6em;
  }

  /* Шапка: «Froggish» и лягушка слева, микрофон и тема справа, у края —
     флаг. */
  .ids .froggish__bar .froggish__logo {
    font-size: 1.15em;
  }
  /* Заголовок страницы — чуть меньше: длинный не должен занять полэкрана. */
  .ids .froggish__title h1.S {
    font-size: 1.6em;
  }
  .ids table.froggish__bar .froggish__lang-title {
    display: none;
  }
  /* Шапка — своей высоты (флаг — от неё); содержимое — по центру по
     вертикали. Зазор до флага меньше: шапке на телефоне тесно, поэтому и
     у микрофона с темой поля по бокам уже (по высоте — те же 44px). */
  /* Флаг — прежней ширины, а не от высоты шапки (в ширину шапке на
     телефоне тесно): по бокам он обрезан, у США, Китая и Испании —
     прижат влево, к звёздам и гербу; полосатые — сжаты (ниже). */
  :root {
    --froggish__head: 6rem;
    --froggish__flag: 5.2rem;
  }
  .ids .froggish__head > .froggish__flag img:is([data-country="us"], [data-country="cn"], [data-country="es"]) {
    object-position: left;
  }
  /* Полосатые — не обрезаны, а сжаты по ширине: у Франции иначе остался
     бы почти один белый; на полосах сжатие не видно. */
  .ids .froggish__head > .froggish__flag img:is([data-country="fr"], [data-country="de"], [data-country="ru"]) {
    object-fit: fill;
  }
  .ids table.froggish__layout > tbody > tr > td.froggish__head {
    padding-left: 1em;
  }
  .ids table.froggish__layout > tbody > tr > td.froggish__head:has(> .froggish__flag) {
    padding-right: calc(var(--froggish__flag) + 0.5em);
  }
  .ids table.froggish__layout .froggish__head > table.froggish__bar {
    height: 100%;
  }
  .ids .froggish__bar .froggish__speak {
    min-height: 0;
    font-size: 1.1rem;
    padding: 0.45em 0.35em;
    margin: -0.45em 0 -0.45em 0.1em;
  }
  .ids .froggish__bar .froggish__theme {
    font-size: 1.1rem;
    padding: 0.45em 0.35em;
    margin: -0.45em 0 -0.45em 0.1em;
  }

  /* Меню на телефоне всегда развёрнуто: пункты списком, под палец. */
  .ids table.froggish__layout .froggish__nav {
    padding: 0;
  }
  .ids .froggish__nav ul {
    padding: 0.8em 1.25em 0.7em;

    & li {
      margin: 0;
      padding: 0.6em 0;
    }
    & li a {
      display: block;
      margin: -0.6em 0;
      padding: 0.6em 0;
    }
  }

  /* Отступы — компактнее: экран короткий. */
  .ids .froggish__main .ids__space.M {
    height: var(--ids__spacer-s);
  }
  .ids .froggish__main .ids__space.L {
    height: var(--ids__spacer-m);
  }

  /* Кнопки — под палец; в ряду действий растягиваются на всю ширину. */
  .ids button {
    min-height: 2.75rem;
    padding: 0.35em 1em;
  }
  .ids :is(.froggish__actions, form.froggish__form) > button {
    flex: 1 1 auto;
  }
  .ids .froggish__keys button {
    min-width: 2.75rem;
    padding: 0.35em 0.5em;
  }
  .ids .froggish__play {
    min-width: 2.75rem;
  }
  .ids .froggish__answer {
    max-width: none;
    font-size: 1.4em;
  }
  .ids :is(select, input[type="search"], input[type="text"], input[type="password"]) {
    min-height: 2.75rem;
  }
  .ids .froggish__actions :is(select, input[type="search"], input[type="text"]) {
    flex: 1 1 12em;
  }
  .ids input[type="checkbox"] {
    width: 1.4em;
    height: 1.4em;
  }

  /* Ссылки-действия в подписях («не помню», «показать ответ») — поле
     касания выше строки. */
  .ids .caption a {
    display: inline-block;
    padding: 0.6em 0;
    margin: -0.6em 0;
  }

  /* Сегментные переключатели (фильтр картотеки, язык, цель дня): на узком
     экране они переносятся на вторую строку, поэтому каждый пункт — с
     полной рамкой, отдельной «таблеткой». */
  .ids .ids__promo-link {
    gap: var(--ids__gap-s);
  }
  .ids .ids__promo-link > a:nth-child(n) {
    padding: 0.7em 0.9em;
    border-right: var(--ids__border-width-s) solid color-mix(in srgb, var(--ids__text) 50%, transparent);
    border-radius: var(--ids__radius-m);
  }

  /* Таблицы: IDS на телефоне ужимает их до 0.7em — это мелко. */
  .ids table {
    font-size: 0.9em;

    & tr th,
    & tr td {
      padding: 0.5em 0.55em;
    }
  }
  /* Разбор произношения — не «таблица данных»: свой размер и отступы. */
  .ids .froggish__board table {
    font-size: inherit;

    & tr td {
      padding: 0.2em 0.35em;
    }
  }
  /* Картинка на телефоне ниже — чтобы слово и поле ответа помещались над
     клавиатурой. */
  .ids table.froggish__card tr td.froggish__pic {
    height: 6em;
  }
  .ids table.froggish__card .emoji {
    font-size: 3.2em;
  }
  .ids .froggish__word {
    font-size: 2em;
  }
  .ids .froggish__main p.loud {
    font-size: 1.5em;
  }

  .froggish__wide {
    display: none;
  }
  .froggish__narrow {
    display: block;
  }
  /* Последние столбцы картотеки и наборов на телефоне скрыты — правые углы
     скругляем у последнего видимого. */
  .ids .froggish__scroll table tr:first-child > :nth-last-child(1 of :not(.froggish__wide)) {
    border-top-right-radius: var(--froggish__radius);
  }
  .ids .froggish__scroll table tr:last-child > :nth-last-child(1 of :not(.froggish__wide)) {
    border-bottom-right-radius: var(--froggish__radius);
  }
}
