/* Интерфейс приложения. Цвета и формы — тема HeroUI v3 по умолчанию
   (токены @heroui/styles, Apache-2.0), взяты из эскиза docs/эскиз
   мини-приложения.html. Страница учебника красится движком отдельно:
   она как бумага и от темы не зависит. */
:root {
  --hu-accent: oklch(0.6204 0.195 253.83);
  --bg: oklch(0.9702 0 0); --surface: oklch(100% 0 0); --surface-2: oklch(0.9524 0.0013 286.37);
  --border: oklch(92% 0.004 286.32); --fg: oklch(0.2103 0.0059 285.89); --muted: oklch(0.5517 0.0138 285.94);
  --accent: var(--hu-accent); --accent-fg: oklch(0.9911 0 0);
  --accent-weak: color-mix(in oklab, var(--hu-accent) 14%, var(--surface));
  --default: oklch(94% 0.001 286.375);
  --good: color-mix(in oklab, oklch(0.7329 0.1935 150.81) 72%, black);
  --good-bg: color-mix(in oklab, oklch(0.7329 0.1935 150.81) 16%, var(--surface));
  --warn: color-mix(in oklab, oklch(0.7819 0.1585 72.33) 70%, black);
  --bad: oklch(0.6532 0.2328 25.74);
  --scrim: rgba(0, 0, 0, .5);
  --shadow: 0 0 0 1px oklch(0 0 0 / .03), 0 2px 4px oklch(0 0 0 / .04), 0 1px 2px oklch(0 0 0 / .03);
  --r-card: 24px; --r-field: 12px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
  --bg: oklch(12% 0.005 285.823); --surface: oklch(0.2103 0.0059 285.89); --surface-2: oklch(0.257 0.0037 286.14);
  --border: oklch(25% 0.006 286.033); --fg: oklch(0.9911 0 0); --muted: oklch(70.5% 0.015 286.067);
  --accent-weak: color-mix(in oklab, var(--hu-accent) 24%, var(--surface));
  --default: oklch(27.4% 0.006 286.033);
  --good: oklch(0.7329 0.1935 150.81); --good-bg: color-mix(in oklab, oklch(0.7329 0.1935 150.81) 18%, var(--surface));
  --warn: oklch(0.8203 0.1388 76.34); --bad: oklch(0.70 0.19 24.63);
  --shadow: 0 0 0 1px oklch(1 0 0 / .05); color-scheme: dark; } }
:root[data-theme="dark"] {
  --bg: oklch(12% 0.005 285.823); --surface: oklch(0.2103 0.0059 285.89); --surface-2: oklch(0.257 0.0037 286.14);
  --border: oklch(25% 0.006 286.033); --fg: oklch(0.9911 0 0); --muted: oklch(70.5% 0.015 286.067);
  --accent-weak: color-mix(in oklab, var(--hu-accent) 24%, var(--surface));
  --default: oklch(27.4% 0.006 286.033);
  --good: oklch(0.7329 0.1935 150.81); --good-bg: color-mix(in oklab, oklch(0.7329 0.1935 150.81) 18%, var(--surface));
  --warn: oklch(0.8203 0.1388 76.34); --bad: oklch(0.70 0.19 24.63);
  --shadow: 0 0 0 1px oklch(1 0 0 / .05); color-scheme: dark; }

* { box-sizing: border-box; }
html, body { height: 100%; }
body { margin: 0; background: var(--bg); color: var(--fg); font: 14px/1.5 var(--font); letter-spacing: -.005em; -webkit-font-smoothing: antialiased; }
button, input, textarea { font: inherit; color: inherit; }
h1, h2, h3 { margin: 0; line-height: 1.15; font-weight: 600; letter-spacing: -.02em; text-wrap: balance; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
[hidden] { display: none !important; }
.muted { color: var(--muted); } .small { font-size: .83rem; }
.label { font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); font-weight: 600; }

.app { max-width: 480px; margin: 0 auto; min-height: 100%; display: flex; flex-direction: column; }
.appbar { position: sticky; top: 0; z-index: 10; padding: calc(12px + env(safe-area-inset-top, 0px)) 16px 10px; display: flex; align-items: center; gap: 10px;
  background: color-mix(in srgb, var(--bg) 92%, transparent); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.back { display: none; border: none; background: var(--default); width: 44px; height: 44px; border-radius: 999px; cursor: pointer; font-size: 1.1rem; flex: none; }
.app.sub .back { display: grid; place-items: center; }
.brand { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.logo { width: 28px; height: 28px; border-radius: 10px; background: var(--accent); color: var(--accent-fg); display: grid; place-items: center; font-weight: 700; flex: none; }
.app.sub .logo { display: none; }
.brand h1 { font-size: 1.15rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.net { font-size: .72rem; font-weight: 600; padding: 4px 9px; border-radius: 999px; background: var(--good-bg); color: var(--good); white-space: nowrap; }
.net.off { background: var(--default); color: var(--muted); }

main { flex: 1; padding: 4px 16px 110px; }
.screen { display: flex; flex-direction: column; gap: 14px; }
.search { display: flex; align-items: center; gap: 8px; background: var(--surface); box-shadow: var(--shadow); border-radius: var(--r-field); padding: 0 12px; }
.search input { flex: 1; min-width: 0; border: none; background: transparent; padding: 12px 0; outline: none; font-size: 16px; }
.empty { text-align: center; padding: 24px 8px; color: var(--muted); grid-column: 1 / -1; margin: 0; }
.example { font-size: .78rem; color: var(--muted); background: var(--surface-2); border-radius: 14px; padding: 8px 10px; margin: 0; }

/* Подсказка внутри Telegram на компьютере: полная раскладка живёт в браузере. */
.laptop-hint { background: var(--surface); box-shadow: var(--shadow); border-radius: var(--r-card); padding: 12px 14px 2px; }
.laptop-hint p { margin: 0; font-size: .83rem; color: var(--muted); }
.hint-row { display: flex; gap: 18px; }
.link.quiet { color: var(--muted); }

/* ---- учебники: обложка настоящая, из самого учебника */
.books { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.book { background: var(--surface); border: none; box-shadow: var(--shadow); border-radius: var(--r-card); overflow: hidden; cursor: pointer; text-align: left; padding: 0; display: flex; flex-direction: column; }
.cover, .thumb, .hero-cover { position: relative; overflow: hidden; background: var(--accent-weak); color: var(--accent); display: grid; place-items: center; }
.cover { aspect-ratio: 3 / 4; }
.cover img, .thumb img, .hero-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cover-fallback { padding: 10px; font-weight: 700; text-align: center; line-height: 1.1; font-size: .95rem; }
.has-img .cover-fallback { display: none; }
.lvl { position: absolute; left: 8px; top: 8px; font-size: .7rem; font-weight: 700; color: #fff; background: rgba(0, 0, 0, .45); padding: 2px 8px; border-radius: 999px; }
.thumb .lvl, .hero-cover .lvl { display: none; }
.ok { position: absolute; left: 6px; top: 6px; z-index: 1; width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; font-size: .75rem; font-weight: 800; line-height: 1; color: #fff; background: #1f9d55; box-shadow: 0 1px 3px rgba(0, 0, 0, .35); }
.thumb .ok, .post .pcover .ok { left: 3px; top: 3px; width: 16px; height: 16px; font-size: .6rem; }
.ok ~ .lvl { left: 32px; }
.book-body { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 3px; flex: 1; }
.book-title { font-weight: 600; font-size: .92rem; line-height: 1.25; }
.meta { font-size: .78rem; color: var(--muted); }
.meta.good { color: var(--good); font-weight: 600; } .meta.warn { color: var(--warn); }
.state { margin-top: 6px; font-size: .75rem; font-weight: 600; display: flex; align-items: center; gap: 5px; }
.state.on { color: var(--good); } .state.get { color: var(--accent); }
.state .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

.shelf { display: flex; flex-direction: column; gap: 10px; }
.lcard { background: var(--surface); border: none; box-shadow: var(--shadow); border-radius: var(--r-card); padding: 12px; display: flex; gap: 12px; cursor: pointer; text-align: left; width: 100%; align-items: center; }
.thumb { width: 62px; height: 82px; border-radius: 12px; flex: none; }
.thumb .cover-fallback { font-size: .6rem; padding: 4px; }
.lbody { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.lbody b { font-weight: 600; font-size: .95rem; line-height: 1.25; }
.dlbox { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
.dl { height: 4px; background: var(--default); border-radius: 99px; overflow: hidden; }
.dl span { display: block; height: 100%; width: 0; background: var(--accent); transition: width .25s linear; }

.hero { border-radius: var(--r-card); padding: 14px; background: var(--surface); box-shadow: var(--shadow); display: flex; gap: 14px; align-items: center; }
.hero-cover { width: 96px; aspect-ratio: 3 / 4; border-radius: 14px; flex: none; }
.hero-cover .cover-fallback { font-size: .7rem; }
.hero-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.hero h2 { font-size: 1.3rem; }
.hero p { margin: 0; color: var(--muted); font-size: .86rem; }
.card { background: var(--surface); box-shadow: var(--shadow); border-radius: var(--r-card); padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.card h3 { font-size: 1rem; } .card p { margin: 0; }
.list { background: var(--surface); box-shadow: var(--shadow); border-radius: var(--r-card); overflow: hidden; }
.row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; min-height: 52px; border: none; border-top: 1px solid var(--border); background: none; width: 100%; text-align: left; cursor: pointer; }
.row:first-child { border-top: none; }
.row .n { min-width: 34px; height: 28px; padding: 0 6px; border-radius: 9px; background: var(--default); display: grid; place-items: center; font-weight: 700; font-size: .78rem; flex: none; }
.row .t { flex: 1; min-width: 0; }
.row .t b { display: block; font-weight: 600; font-size: .93rem; }
.row .t span { font-size: .79rem; color: var(--muted); }
.row.wait { opacity: .5; }
.go { color: var(--muted); }
.unit-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 4px; }
.link { border: none; background: none; color: var(--accent); font-weight: 600; font-size: .82rem; cursor: pointer; padding: 8px 0; min-height: 44px; }
.link:disabled { color: var(--muted); }
.kv { display: flex; justify-content: space-between; gap: 12px; padding: 11px 14px; border-top: 1px solid var(--border); font-size: .92rem; }
.kv:first-child { border-top: none; }
.kv span:last-child { font-weight: 600; text-align: right; }
.kv.head { font-weight: 600; font-size: .86rem; color: var(--muted); }
.kv .link { padding: 0; min-height: 0; }
/* Подписка (ACCESS 4–5): полоска «продлите» и карточка заявки. Тихо, как остальная оболочка. */
.banner { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; border-radius: 16px; font-size: .84rem; line-height: 1.35;
  background: color-mix(in oklab, var(--warn) 16%, var(--surface)); color: var(--fg); }
.banner.bad { background: color-mix(in oklab, var(--bad) 14%, var(--surface)); }
.banner .link { flex: none; padding: 0; min-height: 0; }
.pay .pay-head { display: flex; justify-content: space-between; align-items: baseline; }
.pay p { font-size: .88rem; } .pay p.warn { color: var(--bad); }
.book.locked { opacity: .62; }
@media (prefers-contrast: more) { .banner { border: 1px solid var(--fg); } }

.btn { border: none; background: var(--accent); color: var(--accent-fg); font-weight: 500; border-radius: 999px; padding: 13px 18px; min-height: 48px; cursor: pointer; text-align: center; }
.btn.ghost { background: var(--default); color: var(--fg); }
.btn.block { width: 100%; }
.btn:disabled { opacity: .6; }
/* Контрольный код входа: тот же, что назовёт бот. */
.login-check { display: flex; flex-direction: column; align-items: center; gap: 4px; margin: 16px 0 8px; }
.login-check b { font-size: 2rem; letter-spacing: .18em; font-variant-numeric: tabular-nums; }

/* ---- урок: панель инструментов над страницей */
.screen.lesson { gap: 8px; }
/* Авторский HTML-урок: встроенное окно на весь экран под шапкой. */
.html-lesson { width: 100%; flex: 1; min-height: 70vh; border: 0; border-radius: 12px; background: #fff; }
/* Обложка настоящей карточки в ленте главной. */
.post .pcover { position: relative; width: 44px; height: 58px; border-radius: 8px; overflow: hidden; flex: none; background: var(--chip, #eee); }
.post .pcover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.post .pcover .cover-fallback, .post .pcover .lvl { display: none; }
/* Кнопки урока переносятся, а не уезжают вбок, и держатся у верха экрана:
   «Ошибка» видна, где бы на странице ни был палец. */
.tools { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 -16px; padding: 6px 16px; position: sticky; top: 0; z-index: 5; background: var(--bg); }
.tools::-webkit-scrollbar { display: none; }
.tool { flex: none; min-width: 44px; min-height: 44px; padding: 0 14px; border: none; border-radius: 999px; background: var(--default); font-weight: 600; cursor: pointer; }
.tool.on { background: var(--accent); color: var(--accent-fg); }
.tool:disabled { opacity: .4; }
/* Диктовка косяка: кнопка-тумблер в панели, живая строка распознавания —
   внизу экрана, лист остаётся видимым целиком и не перекрывается. */
.tool.dict.on { background: var(--bad); color: #fff; }
.dict-live { position: fixed; left: 50%; bottom: calc(14px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%); z-index: 30;
  width: calc(100% - 24px); max-width: 456px; box-sizing: border-box; display: flex; align-items: center; gap: 8px;
  background: color-mix(in srgb, var(--surface) 92%, transparent); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--shadow); border-radius: 14px; padding: 8px 12px; font-size: 14px; line-height: 1.35; pointer-events: none; }
.dict-live .dot { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--bad); animation: dict-pulse 1.1s ease-in-out infinite; }
.dict-live span { overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
@keyframes dict-pulse { 50% { opacity: .35; } }
.lesson-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 22px; }
.score { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; margin-left: auto; }
/* Страница учебника шире узких полей приложения: каждый пиксель ширины — это читаемость печатного текста. */
.stage { margin: 0 -12px; }

/* ---- нижний лист */
.scrim { position: fixed; inset: 0; background: var(--scrim); z-index: 40; }
.sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 41; max-width: 480px; margin: 0 auto; background: var(--surface); border-radius: 28px 28px 0 0;
  padding: 10px 16px calc(16px + env(safe-area-inset-bottom, 0px)); max-height: 86vh; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; }
.grab { width: 40px; height: 5px; border-radius: 99px; background: var(--border); margin: 0 auto 4px; }
.sheet-body { display: flex; flex-direction: column; gap: 10px; }
.sheet-body p { margin: 0; }
.field { width: 100%; padding: 12px; border-radius: var(--r-field); border: none; background: var(--default); font-size: 16px; outline: none; }
.field:focus { box-shadow: inset 0 0 0 2px var(--accent); }
.code { min-height: 110px; font: 13px/1.3 ui-monospace, Consolas, monospace; word-break: break-all; resize: none; }
.result { font-weight: 700; margin: 0; }
.result.ok { color: var(--good); } .result.bad { color: var(--bad); }

/* ---- плавающая навигация */
.tabs { position: fixed; left: 50%; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%); z-index: 20; max-width: calc(100% - 24px);
  border-radius: 999px; padding: 6px; background: color-mix(in srgb, var(--surface) 88%, transparent); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .14), 0 0 0 1px var(--border); }
.tabs-in { display: flex; gap: 2px; }
.tab { border: none; background: none; display: flex; align-items: center; gap: 7px; padding: 10px 13px; min-height: 44px; border-radius: 999px; cursor: pointer; color: var(--muted); font-size: .92rem; font-weight: 600; white-space: nowrap; }
.tab svg { width: 22px; height: 22px; flex: none; }
.tab .tl { display: none; }
.tab[aria-current="page"] { background: var(--default); color: var(--fg); padding: 10px 16px; }
.tab[aria-current="page"] .tl { display: inline; }
/* В уроке навигация не нужна и закрывает низ страницы учебника. */
.app.sub .tabs { display: none; }
.toast { position: fixed; left: 50%; bottom: calc(86px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%); background: var(--fg); color: var(--bg);
  padding: 10px 16px; border-radius: 18px; font-size: .88rem; z-index: 60; max-width: calc(100% - 32px); text-align: center; }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* Ученическая оболочка (С3): крупная кнопка входа в урок, тихое приветствие. */
.pupil-hi { font-size: 1.5rem; line-height: 1.15; letter-spacing: -0.01em; margin: 4px 0 0; }
.btn.pupil-go { min-height: 56px; font-size: 1.05rem; font-weight: 600; }
.pupil-access { display: flex; flex-direction: column; gap: 10px; }
/* Системная подсветка нажатия (квадрат на телефоне) не нужна: у кнопок своё состояние нажатия. */
.tab, .row, .btn, .link, .nav-it, .chip, .lcard, .book { -webkit-tap-highlight-color: transparent; }

/* ── Витрина и перенос (С7): ленты, значки проверки, книги из переноса ── */
.fd-seg { margin: 4px 0 12px; }
.fd-row { width: 100%; border: none; background: none; cursor: pointer; text-align: left; color: inherit; }
.fd-row .t { flex: 1; min-width: 0; } .fd-row .t b { display: block; font-weight: 600; font-size: .93rem; } .fd-row .t span { font-size: .79rem; color: var(--muted); }
.fd-thumb { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; font-weight: 700; flex: none; font-size: .9rem; }
.fd-thumb.green, .chk.green { background: var(--good-bg); color: var(--good); }
.fd-thumb.yellow, .chk.yellow { background: color-mix(in oklab, var(--warn) 18%, var(--surface)); color: var(--warn); }
.chk.red { background: color-mix(in oklab, var(--bad) 16%, var(--surface)); color: var(--bad); }
.chk { display: inline-block; font-size: .72rem; font-weight: 600; padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.fd-right { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex: none; }
.fd-tag { font-size: .72rem; font-weight: 600; padding: 3px 8px; border-radius: 999px; background: var(--default); color: var(--muted); white-space: nowrap; }
.fd-price { font-weight: 600; white-space: nowrap; font-size: .9rem; }
.fd-note { margin: 12px 2px 0; }
.post .fd-thumb { width: 44px; height: 44px; align-self: center; }
.lib-thumb.book-imp { background: var(--accent-weak); color: var(--accent); }
.lib-pub { color: var(--accent); }
.lib-reason { margin: 0; padding: 8px 10px; background: var(--surface-2); border-radius: 10px; }
.imp-progress { font-variant-numeric: tabular-nums; min-height: 1.2em; }

/* Темы оболочки для сайтов учителей (С6; библиотека — server/tenants.mjs THEMES).
   Меняются только токены оболочки; страница учебника — бумага движка, тема её
   не трогает. Акцент учителя ставится отдельно (--hu-accent на :root). */
:root[data-shell="ink"] {
  --bg: oklch(16% 0.01 270); --surface: oklch(22% 0.012 270); --surface-2: oklch(27% 0.012 270);
  --border: oklch(30% 0.012 270); --fg: oklch(97% 0 0); --muted: oklch(72% 0.015 270);
  --accent-weak: color-mix(in oklab, var(--hu-accent) 26%, var(--surface));
  --default: oklch(29% 0.01 270);
  --good: oklch(0.7329 0.1935 150.81); --good-bg: color-mix(in oklab, oklch(0.7329 0.1935 150.81) 18%, var(--surface));
  --warn: oklch(0.8203 0.1388 76.34); --bad: oklch(0.70 0.19 24.63);
  --shadow: 0 0 0 1px oklch(1 0 0 / .06); color-scheme: dark;
}
:root[data-shell="warm"] {
  --bg: oklch(96% 0.02 80); --surface: oklch(99% 0.01 85); --surface-2: oklch(94% 0.02 80);
  --border: oklch(90% 0.02 80); --fg: oklch(25% 0.02 60); --muted: oklch(52% 0.03 60);
  --default: oklch(93% 0.02 80); --r-card: 28px; --r-field: 14px;
  --shadow: 0 1px 2px oklch(0.3 0.05 60 / .06), 0 6px 18px oklch(0.3 0.05 60 / .06); color-scheme: light;
}
:root[data-shell="mint"] {
  --bg: oklch(97% 0.014 165); --surface: oklch(100% 0 0); --surface-2: oklch(95% 0.016 165);
  --border: oklch(91% 0.016 165); --fg: oklch(22% 0.01 170); --muted: oklch(52% 0.02 170);
  --default: oklch(94% 0.012 165); color-scheme: light;
}

/* Оформление разделов из эскиза (docs/эскиз мини-приложения.html), которых
   ещё нет в рабочем приложении: главная, уроки, слова, выдача. Собрано из
   стилей эскиза: взяты правила, которых нет в app.css. */
.chips { display:flex;gap:7px;overflow-x:auto;scrollbar-width:none;margin:0 -16px;padding:0 16px }
.chips::-webkit-scrollbar { display:none }
.chip { flex:none;border:1.5px solid var(--border);background:var(--surface);padding:5px 12px;border-radius:99px;cursor:pointer;font-size:.86rem;font-weight:500 }
.chip[aria-pressed="true"] { background:var(--fg);border-color:var(--fg);color:var(--bg) }
.fgroup { display:flex;flex-direction:column;gap:6px }
.count { font-size:.85rem;color:var(--muted) }
.tags { display:flex;flex-wrap:wrap;gap:5px;margin-top:3px }
.tag { font-size:.7rem;font-weight:600;padding:1px 7px;border-radius:6px;background:var(--surface-2);color:var(--muted) }
.tag.lv { background:var(--accent-weak);color:var(--accent) }
.btns { display:flex;gap:8px }
.btns .btn { flex:1 }
.flash { background:var(--surface);border:1px solid var(--border);border-radius:18px;padding:18px;display:flex;flex-direction:column;gap:12px;align-items:stretch }
.botline { display:flex;align-items:center;gap:8px;font-size:.82rem;color:var(--muted) }
.botava { width:24px;height:24px;border-radius:50%;background:var(--accent);color:var(--accent-fg);display:grid;place-items:center;font-weight:700;font-size:.75rem }
.word { font-family:var(--font-display);font-size:2rem;font-weight:700;text-align:center }
.ipa { text-align:center;color:var(--muted);margin-top:-8px }
.answers { display:grid;grid-template-columns:1fr 1fr;gap:8px }
.ans { border:1.5px solid var(--border);background:var(--surface-2);border-radius:12px;padding:10px;cursor:pointer;font-weight:500 }
.ans.ok { background:var(--good-bg);border-color:var(--good) }
.ans.no { background:var(--bad-bg);border-color:var(--bad) }
.dots { display:flex;gap:4px;justify-content:center }
.dots i { width:22px;height:5px;border-radius:99px;background:var(--surface-2) }
.dots i.on { background:var(--accent) }
.stat { display:flex;align-items:center;gap:10px;padding:10px 14px;border-top:1px solid var(--border) }
.stat:first-child { border-top:none }
.bar { flex:1;height:6px;border-radius:99px;background:var(--surface-2);overflow:hidden }
.bar span { display:block;height:100%;background:var(--good) }
.avatar { width:32px;height:32px;border-radius:50%;display:grid;place-items:center;font-weight:700;color:#fff;flex:none;font-size:.85rem }
.streak { font-size:.78rem;font-weight:700;color:var(--warn);white-space:nowrap }
.score.hi { background:var(--good-bg);color:var(--good) }
.score.mid { background:var(--warn-bg);color:var(--warn) }
.score.lo { background:var(--bad-bg);color:var(--bad) }
.ch { font-size:.68rem;font-weight:700;color:#fff;padding:2px 7px;border-radius:6px;white-space:nowrap }
.ch.tg { background:var(--tg) }
.ch.max { background:var(--max) }
.ch.vk { background:var(--vk) }
.ch.sms { background:var(--sms) }
.on-dot { font-size:.8rem;font-weight:600;color:var(--good) }
.off-dot { font-size:.8rem;font-weight:600;color:var(--muted) }
.pick { display:flex;align-items:center;gap:10px;padding:9px 2px;border-top:1px solid var(--border);cursor:pointer }
.pick:first-of-type { border-top:none }
.pick input { width:20px;height:20px;accent-color:var(--accent);flex:none }
.pick .t { flex:1;min-width:0 }
.pick .t b { display:block;font-weight:600;font-size:.93rem }
.pick .t span { font-size:.78rem;color:var(--muted) }
.seg { display:flex;background:var(--surface-2);border-radius:11px;padding:3px }
.seg button { flex:1;border:none;background:none;padding:7px 4px;border-radius:9px;cursor:pointer;font-size:.85rem;font-weight:600;color:var(--muted) }
.seg button[aria-pressed="true"] { background:var(--surface);color:var(--fg);box-shadow:0 1px 3px rgba(0,0,0,.12) }
.chip { border:none;background:var(--default);font-size:.86rem;font-weight:500;padding:6px 12px;border-radius:999px }
.chip[aria-pressed="true"] { background:var(--accent);color:var(--accent-fg) }
.tag { border-radius:999px;background:var(--default);padding:1px 8px;font-weight:500 }
.tag.lv { background:var(--accent-weak);color:var(--accent) }
.seg { background:var(--default);border-radius:999px;padding:3px }
.seg button { border-radius:999px }
.flash { border:none;box-shadow:var(--shadow);border-radius:var(--r-card) }
.stat { border-top-color:var(--border) }
.ans { border:none;background:var(--default);border-radius:16px }
.ans.ok { background:var(--good-bg);box-shadow:inset 0 0 0 1.5px var(--good) }
.ans.no { background:var(--bad-bg);box-shadow:inset 0 0 0 1.5px var(--bad) }
.tab[aria-current="page"] svg { stroke-width:2.2 }
.pick input { accent-color:var(--accent) }
.pics { display:grid;grid-template-columns:repeat(4,1fr);gap:3cqw;padding-left:1.4cqw }
.app.home .appbar { display:none }
.app.home main { padding-top:calc(14px + env(safe-area-inset-top,0px)) }
.hello { display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:14px;border-bottom:1px solid var(--border) }
.hello-t { font-size:1.65rem;font-weight:600;letter-spacing:-.025em }
.hello-t span { color:var(--muted) }
.ava { width:48px;height:48px;border-radius:50%;flex:none;background:var(--accent);color:var(--accent-fg);display:grid;place-items:center;font-weight:600;font-size:1.05rem;overflow:hidden }
.ava img { width:100%;height:100%;object-fit:cover }
.rail { display:flex;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;margin:0 -16px;padding:2px 16px 4px;scroll-padding:0 16px }
.rail::-webkit-scrollbar { display:none }
.slide { flex:0 0 86%;scroll-snap-align:start;display:flex;flex-direction:column;gap:2px;cursor:pointer;text-align:left;border:none;background:none;padding:0 }
.slide .eb { font-size:.74rem;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);font-weight:500 }
.slide .st { font-size:1.45rem;font-weight:600;letter-spacing:-.025em;line-height:1.15 }
.slide .ss { color:var(--muted);font-size:.95rem;margin-bottom:10px }
.tile { position:relative;aspect-ratio:1.38;max-width:100%;border-radius:26px;overflow:hidden;color:#fff;display:flex;flex-direction:column;justify-content:flex-end;padding:16px 16px 14px }
.tile svg.art { position:absolute;inset:0;width:100%;height:100% }
.tile .tb { position:relative;display:flex;align-items:center;gap:10px }
.tile .tn { font-size:.95rem;font-weight:500;opacity:.92 }
.tile .ta { opacity:.8;margin-right:auto }
.tile .open { background:rgba(255,255,255,.2);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);border-radius:999px;padding:8px 16px;font-weight:600;font-size:.92rem }
.raildots { display:flex;gap:5px;justify-content:center;margin-top:-4px }
.raildots i { width:6px;height:6px;border-radius:99px;background:var(--border);transition:width .2s,background .2s }
.raildots i.on { width:16px;background:var(--fg) }
.feedtabs .chip { background:transparent;color:var(--muted);font-size:.95rem;padding:6px 12px }
.feedtabs .chip[aria-pressed="true"] { background:var(--fg);color:var(--bg) }
.plus { display:flex;align-items:center;gap:12px;background:var(--surface-2);border-radius:18px;padding:12px 14px;font-size:.88rem }
.plus-b { flex:none;background:var(--accent);color:var(--accent-fg);font-weight:700;font-size:.72rem;letter-spacing:.06em;padding:5px 11px;border-radius:999px }
.feed { display:flex;flex-direction:column }
.post { display:flex;gap:12px;padding:14px 0;border-bottom:1px solid var(--border);cursor:pointer;text-align:left;background:none;border-left:none;border-right:none;border-top:none;width:100% }
.post .pa { width:40px;height:40px;border-radius:50%;flex:none;display:grid;place-items:center;color:#fff;font-weight:600 }
.post .pb { flex:1;min-width:0;display:flex;flex-direction:column;gap:4px }
.post .ph { font-size:.88rem }
.post .ph b { font-weight:600 }
.post .ph span { color:var(--muted) }
.post .pt { font-size:1rem;line-height:1.35;font-weight:500 }
.post .pwhy { margin-top:4px;font-size:.82rem;line-height:1.3;font-weight:500;letter-spacing:.005em;color:var(--accent);overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical }

/* С6: белая этикетка и «Своя платформа». Логотип учителя встаёт на место буквы. */
.logo img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }
.logo:has(img) { background: transparent; }
.tenant .nav-it[data-tab="trends"], .tenant .trends-card { display: none; }
.wl .row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.wl .row .btn { flex: 1; text-decoration: none; display: inline-grid; place-items: center; }
.wl-form .wl-field { display: block; margin: 0 0 14px; }
.wl-form .wl-field > span { display: block; margin-bottom: 6px; }
.wl-swatches { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.wl-swatch { width: 34px; height: 34px; border-radius: 50%; border: none; cursor: pointer; box-shadow: var(--shadow); transition: transform .12s ease-out; }
.wl-swatch:active { transform: scale(.94); }
.wl-swatch.on { outline: 2px solid var(--fg); outline-offset: 3px; }
.wl-custom { width: 34px; height: 34px; border: none; border-radius: 50%; padding: 0; background: none; cursor: pointer; overflow: hidden; }
.wl-custom::-webkit-color-swatch-wrapper { padding: 0; }
.wl-custom::-webkit-color-swatch { border: none; border-radius: 50%; }
.wl-themes { display: grid; gap: 8px; }
.wl-theme { display: grid; text-align: left; gap: 2px; padding: 12px 14px; border-radius: var(--r-field); border: 1px solid var(--border); background: var(--surface); color: var(--fg); cursor: pointer; font: inherit; transition: transform .12s ease-out; }
.wl-theme:active { transform: scale(.985); }
.wl-theme.on { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.wl-theme:disabled { opacity: .5; cursor: default; }
.wl-logo { display: flex; align-items: center; gap: 12px; }
.wl-logo-prev { width: 56px; height: 56px; border-radius: 16px; font-size: 1.4rem; }
.btn.danger { color: var(--bad); }
.post .pimg { margin-top:6px;aspect-ratio:2.2;max-width:100%;border-radius:16px;display:flex;align-items:flex-end;padding:10px 12px;color:#fff;font-weight:600;font-size:.85rem }
.ulist { display:flex;flex-direction:column;gap:10px }
.step { display:flex;gap:12px;align-items:flex-start }
.step .sn { width:28px;height:28px;border-radius:50%;background:var(--accent-weak);color:var(--accent);font-weight:700;display:grid;place-items:center;flex:none;font-size:.85rem }
.step b { display:block }
.drop { border:2px dashed var(--border);border-radius:20px;padding:22px 16px;text-align:center;display:flex;flex-direction:column;gap:6px;align-items:center;cursor:pointer;background:var(--surface) }
.drop b { font-size:1rem }

/* Свои добавки к перенесённому из эскиза. Карточки и «шапки» примеров носят
   отдельные имена: одноимённые классы рабочих экранов (.lcard, .thumb, .hero)
   выглядят иначе, и примеры не должны их ломать. */
.dhero { border-radius: var(--r-card); padding: 18px; color: #fff; display: flex; flex-direction: column; gap: 6px; }
.dhero h2 { margin: 0; font-size: 1.55rem; color: #fff; }
.dhero p { margin: 0; opacity: .92; font-size: .9rem; }
.dlessons { display: flex; flex-direction: column; gap: 10px; }
.dcard { background: var(--surface); border: none; box-shadow: var(--shadow); border-radius: var(--r-card); padding: 12px; display: flex; gap: 12px; cursor: pointer; text-align: left; width: 100%; color: inherit; font: inherit; }
.dthumb { width: 56px; height: 56px; border-radius: 16px; flex: none; display: grid; place-items: center; color: #fff; font-weight: 700; font-size: 1.3rem; }
.stat-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.list.flat { box-shadow: none; border-radius: 0; }
.score.pill { padding: 3px 9px; border-radius: 9px; flex: none; margin-left: 0; }
.dsheet { display: flex; flex-direction: column; gap: 10px; }
/* Шесть вкладок в плавающем меню: подпись только у открытой, остальные — значки. */
.tab { padding: 10px 9px; }
.tab[aria-current="page"] { padding: 10px 13px; }
@media (max-width: 380px) { .tab { padding: 10px 6px; } .tab svg { width: 20px; height: 20px; } .tab[aria-current="page"] { padding: 10px 11px; } }
/* Шесть цветов палитры эскиза: аватары, плашки, шапки примеров. */
:root { --c1: #6c5ef0; --c2: #13998f; --c3: #d0623a; --c4: #3a78dc; --c5: #9b48bb; --c6: #4a8a46; }

/* Пометки об ошибках: в этом режиме поля обведены, нажатие открывает лист. */
.stage.marking [data-field] { outline:2px dashed var(--warn);outline-offset:1px;cursor:pointer }
.stage.marking .tl-sheet { cursor:crosshair }
.sheet-body .chips { flex-wrap:wrap;overflow:visible;margin:0;padding:0 }
.sheet-body .chip { min-height:40px }

/* Листочек для заметок учителя — правый нижний угол страницы. Пустой едва
   заметен, с заметкой — жёлтый. Кнопка крупнее рисунка: пальцу нужно 40 px. */
.note-pin { position:absolute; right:0; bottom:0; z-index:3; width:40px; height:40px; padding:0; border:0;
  background:none; cursor:pointer; -webkit-tap-highlight-color:transparent }
.note-pin i { position:absolute; right:8px; bottom:8px; width:22px; height:22px; border-radius:2px;
  background:linear-gradient(-45deg, transparent 5px, #fdf3c4 0); filter:drop-shadow(0 1px 1.5px rgba(0,0,0,.28));
  opacity:.55; transition:opacity .15s, transform .15s }
.note-pin i::before { content:""; position:absolute; left:4px; right:6px; top:6px; height:9px;
  background:repeating-linear-gradient(#a8915a 0 1px, transparent 1px 4px); opacity:.6 }
.note-pin i::after { content:""; position:absolute; right:0; bottom:0; width:7px; height:7px;
  background:linear-gradient(-45deg, transparent 50%, #e2c76a 0) }
.note-pin:hover i, .note-pin:focus-visible i { opacity:.9 }
.note-pin:active i { transform:scale(.92) }
.note-pin.has i { opacity:1; background:linear-gradient(-45deg, transparent 5px, #fde68a 0) }
.note-pin.has i::before { opacity:1; background:repeating-linear-gradient(#8a6d1f 0 1.2px, transparent 1.2px 4px) }
.stage.pupil .note-pin, .stage.marking .note-pin { display:none }
.field.note { min-height:160px; resize:vertical; line-height:1.4 }

/* Карандаш учителя — левый нижний угол страницы. Выключенный слой штрихов
   пропускает касания к полям; включённый забирает их себе. */
.tl-sheet > .ink { position:absolute; inset:0; width:100%; height:100%; z-index:3; pointer-events:none; overflow:visible }
.tl-sheet > .ink path { fill:none; stroke:#d6312b; stroke-width:5; stroke-linecap:round; stroke-linejoin:round; opacity:.85; mix-blend-mode:multiply }
.tl-sheet.inking > .ink { pointer-events:auto; touch-action:none; cursor:crosshair }
.tl-sheet.inking { box-shadow:0 0 0 2px #d6312b55 }
.tl-sheet > .note-pin { z-index:4 }
.ink-bar { position:absolute; left:0; bottom:0; z-index:4; display:flex; align-items:center }
.ink-pen, .ink-act { width:40px; height:40px; padding:0; border:0; background:none; cursor:pointer;
  display:grid; place-items:center; -webkit-tap-highlight-color:transparent; line-height:1 }
.ink-pen svg { width:22px; height:22px; fill:#fdf3c4; stroke:#7d6a3a; stroke-width:1.4; stroke-linejoin:round;
  filter:drop-shadow(0 1px 1.5px rgba(0,0,0,.28)); opacity:.55; transition:opacity .15s, transform .15s }
.ink-pen:hover svg, .ink-pen:focus-visible svg { opacity:.9 }
.ink-pen:active svg { transform:scale(.92) }
.ink-act { display:none; width:34px; height:34px; margin-left:2px; border-radius:50%; font-size:17px;
  color:#5b4a1f; background:#fdf3c4; box-shadow:0 1px 3px rgba(0,0,0,.25) }
.ink-act.sure { background:#d6312b; color:#fff }
.tl-sheet.inking .ink-act { display:grid }
.tl-sheet.inking .ink-pen svg { opacity:1; fill:#d6312b; stroke:#7a1512 }
.stage.pupil .ink-bar, .stage.marking .ink-bar { display:none }

/* ---- библиотека с метками (С4, LIBRARY.md): строка, чипы, выдача */
.lib { gap: 10px }
.lib-bar { display:flex; align-items:center; gap:10px; min-width:0 }
.lib-chips { flex:1; min-width:0; margin:0; padding:0 }
.lib-chip { max-width:60vw; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-height:36px }
.lib-mine { flex:none; display:flex; align-items:center; gap:8px; font-size:.85rem; color:var(--muted); cursor:pointer; user-select:none; -webkit-tap-highlight-color:transparent }
.lib-mine input { appearance:none; -webkit-appearance:none; flex:none; width:44px; height:26px; margin:0; border-radius:99px; background:var(--default); position:relative; cursor:pointer; transition:background 200ms ease }
.lib-mine input::after { content:""; position:absolute; top:2px; left:2px; width:22px; height:22px; border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.25); transition:transform 250ms cubic-bezier(.3,1.3,.5,1) }
.lib-mine input:checked { background:var(--accent) }
.lib-mine input:checked::after { transform:translateX(18px) }
.lib-mine input:focus-visible { outline:2px solid var(--accent); outline-offset:2px }
.lib-status { display:flex; justify-content:space-between; align-items:center; gap:10px; min-height:32px }
.lib-count { display:flex; align-items:baseline; gap:12px; min-width:0 }
.lib-reset { padding:0; min-height:0; font-size:.85rem }
.lib-list { display:flex; flex-direction:column; gap:8px }
.lib-item { display:flex; align-items:stretch; gap:6px }
.lib-item .lib-row { flex:1; min-width:0 }
.lib-row { display:flex; align-items:center; gap:12px; text-align:left; border:none; background:var(--surface); box-shadow:var(--shadow); border-radius:16px; padding:10px 12px; cursor:pointer; color:var(--fg); min-height:60px; width:100%; -webkit-tap-highlight-color:transparent; transition:transform 100ms ease-out }
.lib-row:active { transform:scale(.98) }
.lib-thumb { flex:none; width:40px; height:40px; border-radius:10px; display:grid; place-items:center; font-size:.72rem; font-weight:700; letter-spacing:.02em; background:var(--default); color:var(--muted) }
.lib-thumb.material { background:var(--accent); color:var(--accent-fg) }
.lib-thumb.book { font-size:1.2rem }
.lib-body { display:flex; flex-direction:column; gap:2px; min-width:0 }
.lib-body b { font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.lib-body .meta { overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.lib-warn { color:#c2410c }
.lib-more { flex:none; width:44px; border:none; border-radius:16px; background:var(--default); color:var(--fg); font-size:1.1rem; cursor:pointer }
.lib-tools { display:flex; gap:8px; flex-wrap:wrap; padding-top:4px }
.lib-tools .btn { flex:1 1 140px }
.lib-empty { display:flex; flex-direction:column; align-items:center; gap:10px }
.lib-pick { display:flex; flex-direction:column; gap:10px }
.lib-pick-lists { display:flex; flex-direction:column; gap:8px }
.lib-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(64px, 1fr)); gap:6px }
.lib-grid .chip { min-height:40px; padding:6px 4px; text-align:center }
.lib-pick .need { border-radius:14px; box-shadow:0 0 0 2px #f59e0b66; padding:4px }
.lib-prompt { min-height:180px; font-size:12px }
.lib-del { color:#dc2626 }
@media (prefers-reduced-motion: reduce) { .lib-mine input, .lib-mine input::after { transition:none } }

/* Нижний лист тянется вниз пальцем (main.ts, sheetDrag). */
.sheet { will-change: transform; touch-action: pan-y }
.sheet.dragging { user-select: none }
.sheet > .grab { position:relative; width:120px; height:24px; margin:-8px auto 0; background:none; cursor:grab; touch-action:none }
.sheet > .grab::before { content:""; position:absolute; left:40px; right:40px; top:8px; height:5px; border-radius:99px; background:var(--border) }
.sheet > #shTitle { touch-action:none; cursor:grab }
@media (prefers-reduced-motion: reduce) { .lib-row { transition:none } }

/* Десктоп-оболочка (MVP, станция С1). Всё поведение — за порогом 1024px:
   мобильная и телеграмная раскладки этих правил не видят. Стиль — скилл
   apple-design: оболочка тихая, системный шрифт, плотный крупный заголовок,
   движение короткое и только в ответ на руку. */

.side { display: none; }

/* ---- ученики и расписание (students-ui.ts): листы и раздел, любая ширина */
.sdot { width: 10px; height: 10px; border-radius: 50%; background: var(--ev, var(--accent)); flex: none; }
.sheet-sec { margin: 0; font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.sheet-head .link { padding: 0; min-height: 0; }
.sheet-row { display: flex; gap: 8px; }
.sheet-row .field { flex: 1; min-width: 0; }
.sheet .chips.wrap { margin: 0; padding: 0; flex-wrap: wrap; overflow: visible; }
.sheet-links { display: flex; justify-content: space-between; gap: 12px; }
.sheet-links .link { min-height: 36px; padding: 4px 0; }
.link.danger { color: var(--bad); }
.live-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 12px; border-radius: 12px; background: var(--accent-weak); color: var(--accent); font-size: .84rem; font-weight: 500; }
.live-bar .link { padding: 0; min-height: 0; flex: none; }
.lesson-chip { display: inline-flex; align-items: center; gap: 6px; padding: 3px 4px 3px 10px; border-radius: 999px; background: var(--accent-weak); color: var(--accent); font-size: .8rem; font-weight: 600; white-space: nowrap; }
.lesson-chip button { border: none; background: none; color: inherit; cursor: pointer; font: inherit; font-weight: 500; padding: 3px 8px; border-radius: 999px; min-height: 0; transition: background .15s ease-out; }
.lesson-chip button:hover { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.cal-ev.live { box-shadow: 0 0 0 2px var(--accent); }

@media (min-width: 1024px) {
  .app {
    display: grid;
    grid-template-columns: 248px minmax(0, 1fr);
    grid-template-rows: auto 1fr;
    max-width: 1440px;
    column-gap: 0;
  }

  /* Экран входа прячет панель (разделы без учётки не нужны) — колонка
     панели тогда не резервируется, контент по центру окна. */
  .app:has(> .side[hidden]) { grid-template-columns: 0 minmax(0, 1fr); }

  /* ---- панель: структурный слой, чуть плотнее фона (apple-design §12) */
  .side {
    display: flex;
    flex-direction: column;
    gap: 2px;
    grid-row: 1 / 3;
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    overflow-y: auto;
    padding: 14px 12px 18px;
    background: var(--surface);
    border-right: 1px solid var(--border);
  }
  .side-brand { display: flex; align-items: center; gap: 10px; padding: 8px 10px 18px; font-size: 1.05rem; letter-spacing: -.02em; }
  .nav-it {
    display: flex; align-items: center; gap: 11px;
    width: 100%; padding: 9px 12px; min-height: 40px;
    border: none; border-radius: 12px; background: none; cursor: pointer;
    color: var(--muted); font-size: .92rem; font-weight: 500; text-align: left;
    transition: background .15s ease-out, color .15s ease-out, transform .1s ease-out;
  }
  .nav-it:hover { background: var(--default); color: var(--fg); }
  .nav-it:active { transform: scale(.985); }
  .nav-it[aria-current="page"] { background: var(--default); color: var(--fg); font-weight: 600; }
  .nav-it svg { width: 20px; height: 20px; flex: none; }
  .nav-it span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .nav-beta { margin-left: auto; font-size: .62rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); background: var(--accent-weak); border-radius: 999px; padding: 2px 7px; flex: none; }
  .nav-gap { flex: 1; }

  /* ---- содержимое: шапка проще (бренд уже в панели), низ без вкладок */
  .appbar { grid-column: 2; padding-left: 32px; padding-right: 32px; }
  .appbar .logo { display: none; }
  main { grid-column: 2; padding: 4px 32px 56px; }
  .screen { max-width: 1120px; gap: 16px; }
  .tabs { display: none; }
  .brand h1 { font-size: 1.3rem; }

  /* Каталог дышит: больше колонок, прежняя карточка */
  .books { grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: 14px; }

  /* Нижний лист на большом экране — окно по центру, тот же механизм */
  .sheet {
    left: 50%; right: auto; bottom: auto; top: 50%;
    transform: translate(-50%, -50%);
    width: 480px; max-height: 80vh;
    border-radius: 24px;
    padding: 16px 20px 20px;
    box-shadow: 0 24px 64px rgba(0, 0, 0, .22), 0 0 0 1px var(--border);
  }
  .sheet .grab { display: none; }
  .toast { bottom: 28px; }

  /* ---- главная: календарь ~2/3, правая колонка одна (решение 21.10) */
  .dgrid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(300px, 1fr); gap: 16px; align-items: start; }
  .dmain { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
  .dcol { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
  .hello-t { font-size: 1.7rem; letter-spacing: -.025em; }

  /* Неделя с часами в духе Calendar.app. Высота — до низа окна: календарь
     растёт вниз, часы листаются внутри. --hour = HOUR в desktop.ts. */
  .cal { --hour: 56px; --times: 56px; --now: #ff3b30; --ev-text: 72%; gap: 0; padding-bottom: 8px; }
  .cal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 2px 2px 12px; }
  .cal-title { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
  .cal-head h2 { font-size: 1.35rem; font-weight: 700; line-height: 1.1; letter-spacing: -.02em; white-space: nowrap; }
  .cal-head h2 span { font-weight: 400; color: var(--muted); }
  .cal-range { font-size: .86rem; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

  /* Сегментированный переключатель ‹ Сегодня › */
  .cal-nav { display: flex; gap: 2px; padding: 2px; border-radius: 10px; background: var(--default); }
  .cal-btn {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 30px; height: 28px; padding: 0; border-radius: 8px;
    border: none; background: none; color: var(--fg);
    font-size: .84rem; font-weight: 500; cursor: pointer;
    transition: background .15s ease-out, transform .1s ease-out;
  }
  .cal-btn svg { width: 16px; height: 16px; }
  .cal-today { padding: 0 12px; }
  .cal-btn:hover { background: color-mix(in srgb, var(--surface) 60%, transparent); }
  .cal-btn:active { transform: scale(.95); background: var(--surface); }

  .cal-top, .cal-grid { display: grid; grid-template-columns: var(--times) repeat(7, minmax(0, 1fr)); }
  .cal-top { border-bottom: 1px solid var(--border); overflow: hidden; }
  .cal-cap { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 2px 0 8px; }
  .cal-cap span { font-size: .68rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
  .cal-cap b { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; font-size: 1.2rem; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
  .cal-cap.today span { color: var(--accent); }
  .cal-cap.today b { background: var(--accent); color: var(--accent-fg, #fff); }

  .cal-scroll {
    height: max(480px, calc(100dvh - 260px));
    overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
    margin-right: -6px; padding-right: 6px;
  }
  .cal-hours { position: relative; display: flex; flex-direction: column; }
  .cal-hours span {
    height: var(--hour); flex: none; padding-right: 8px; text-align: right;
    font-size: .7rem; line-height: 1; color: var(--muted); font-variant-numeric: tabular-nums;
    transform: translateY(-.5em); transition: opacity .15s ease-out;
  }
  .cal-hours span.near { opacity: 0; }
  .cal-hours .cal-now-time { position: absolute; right: 0; left: 0; height: auto; color: var(--now); font-weight: 600; transition: none; }
  .cal-col { position: relative; display: flex; flex-direction: column; border-left: 1px solid var(--border); min-width: 0; }
  .cal-slot {
    height: var(--hour); flex: none; width: 100%; border: none; border-top: 1px solid var(--border);
    border-radius: 0; background: none; cursor: pointer; padding: 0;
    transition: background .12s ease-out;
  }
  .cal-slot:hover { background: color-mix(in srgb, var(--fg) 4%, transparent); }
  .cal-slot:active { background: var(--accent-weak); }

  /* Урок — сплошная плашка цвета ученика, текст тем же цветом темнее: как в Calendar.app, без полоски слева. */
  .cal-ev {
    position: absolute; left: 2px; right: 3px; z-index: 1; overflow: hidden;
    display: flex; flex-direction: column; align-items: flex-start;
    border: none; border-radius: 6px;
    background: color-mix(in srgb, var(--ev, var(--accent)) 18%, var(--surface));
    padding: 3px 6px; cursor: pointer; text-align: left;
    font-size: .75rem; line-height: 1.3;
    color: color-mix(in srgb, var(--ev, var(--accent)) var(--ev-text), var(--fg));
    transition: background .15s ease-out, transform .1s ease-out;
  }
  .cal-ev:hover { background: color-mix(in srgb, var(--ev, var(--accent)) 26%, var(--surface)); }
  .cal-ev:active { transform: scale(.98); }
  .cal-ev b, .cal-ev span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
  .cal-ev b { font-weight: 600; }
  .cal-ev span { opacity: .8; font-variant-numeric: tabular-nums; }

  .cal-now { position: absolute; left: 0; right: 0; height: 2px; background: var(--now); z-index: 2; pointer-events: none; }
  .cal-now::before { content: ""; position: absolute; left: -5px; top: -3px; width: 8px; height: 8px; border-radius: 50%; background: var(--now); }

  :root[data-theme="dark"] .cal { --now: #ff453a; --ev-text: 45%; }
  @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .cal { --now: #ff453a; --ev-text: 45%; } }

  .card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
  .login-card { max-width: 440px; margin: 10vh auto 0; }
  .list.flat { box-shadow: none; border-radius: 0; background: none; }
  .list.flat .kv { padding: 10px 2px; }
  .feed.tight { gap: 8px; }
}

/* Узкие десктопные окна: колонка оплат уходит под календарь, панель остаётся */
@media (min-width: 1024px) and (max-width: 1220px) {
  .dgrid { grid-template-columns: 1fr; }
}

/* Слоты-артефакты (ARTIFACTS.md, app/artifacts.ts). Оболочка, а не страница:
   слой фиксирован над уроком и стоит у краёв колонки приложения, одинаково
   для страниц учебника и для HTML-урока. Телефон: маскоты выглядывают из-за
   края на половину, при чтении уходят за край, на остановке возвращаются.
   Движение — пружина без отскока (apple-design §4), по нажатию — сразу. */

.art {
  position: fixed; inset: 0; z-index: 15; pointer-events: none;
  --col-l: max(0px, (100vw - 480px) / 2);
  --col-r: max(0px, (100vw - 480px) / 2);
  --bot-w: 56px; --bot-h: 72px;
  --peek: 50%;
  --glide: 420ms cubic-bezier(.23, 1, .32, 1);
}
.art-col {
  position: absolute;
  top: calc(124px + env(safe-area-inset-top, 0px));
  bottom: calc(28px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column; justify-content: center; gap: 14px;
}
.art-col.l { left: var(--col-l); }
.art-col.r { right: var(--col-r); }

.art-slot {
  position: relative; display: block; flex: none;
  width: var(--bot-w); height: var(--bot-h); padding: 0; border: 0; background: none;
  pointer-events: auto; cursor: pointer;
  touch-action: manipulation; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
  transition: transform var(--glide), opacity 200ms ease-out;
}
.art-col.l .art-slot { transform: translateX(calc(-1 * var(--peek))); }
.art-col.r .art-slot { transform: translateX(var(--peek)); }
/* Нажимается только видимая половина: поля учебника бывают у самого края
   страницы, и невидимая зона маскота отняла бы у них палец. Цель у кромки
   экрана палец находит и так — дальше края он не промахнётся. */
.art-slot::before { content: ""; position: absolute; top: -6px; bottom: -6px; }
.art-col.l .art-slot::before { left: 50%; right: 0; }
.art-col.r .art-slot::before { right: 50%; left: 0; }
/* Под пальцем маскот подаётся наружу — нажатие видно на касании, не на отпускании. */
.art-col.l .art-slot:active { transform: translateX(calc(-1 * var(--peek) + 10px)) scale(.96); transition-duration: 120ms; }
.art-col.r .art-slot:active { transform: translateX(calc(var(--peek) - 10px)) scale(.96); transition-duration: 120ms; }
.art.hid .art-col.l .art-slot { transform: translateX(-115%); }
.art.hid .art-col.r .art-slot { transform: translateX(115%); }
/* Карандаш и пометки «Ошибка» работают у краёв страницы — маскоты на это время уходят. */
body:has(.tl-sheet.inking, .stage.marking) .art { opacity: 0; visibility: hidden; transition: opacity 200ms ease-out, visibility 0s 200ms; }

.art-bot {
  display: block; width: 100%; height: 100%;
  background-repeat: no-repeat; background-size: 1400% 100%; background-position: 0 0;
  transform-origin: 50% 100%;
}
.art-col.l .art-bot { transform: rotate(9deg); }
.art-col.r .art-bot { transform: rotate(-9deg); }
.art[data-mode="nosub"] .art-bot, .art-bot.gray { filter: grayscale(1); opacity: .6; }
.art[data-mode="offline"] .art-bot { filter: grayscale(.5); opacity: .8; }
.art[data-mode="loading"] .art-slot, .art[data-mode="error"] .art-slot { opacity: .7; }

.art-chip {
  position: absolute; bottom: -2px; pointer-events: none;
  font-size: 9.5px; line-height: 1; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap;
  padding: 3px 6px; border-radius: 999px;
  background: var(--surface); color: var(--muted); box-shadow: var(--shadow), 0 1px 3px oklch(0 0 0 / .12);
}
/* Плашка начинается там, где маскот выходит из-за края, — целиком на экране. */
.art-col.l .art-chip { left: var(--peek); }
.art-col.r .art-chip { right: var(--peek); }
.art-slot:not(.soon) .art-chip { background: var(--accent); color: var(--accent-fg); min-width: 18px; text-align: center; }

@media (hover: hover) and (pointer: fine) {
  .art-col.l .art-slot:hover, .art-col.r .art-slot:hover, .art-slot:focus-visible { transform: translateX(0); }
}
.art-slot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 16px; }

/* Ноутбук: панель разделов слева, колонка до 1440 px. Маскоты крупнее и
   выглядывают на три четверти: поле у края контента шире пальца. */
@media (min-width: 1024px) {
  .art {
    --col-l: calc(max(0px, (100vw - 1440px) / 2) + 248px);
    --col-r: max(0px, (100vw - 1440px) / 2);
    --bot-w: 64px; --bot-h: 82px; --peek: 30%;
  }
  .art-col { top: 140px; bottom: 40px; gap: 22px; }
  .art.hid .art-col.l .art-slot { transform: translateX(calc(-1 * var(--peek))); }
  .art.hid .art-col.r .art-slot { transform: translateX(var(--peek)); }
}

@media (prefers-reduced-motion: reduce) {
  .art-slot { transition: opacity 200ms ease-out; }
  .art.hid .art-col.l .art-slot, .art.hid .art-col.r .art-slot { opacity: 0; }
  .art.hid .art-col.l .art-slot { transform: translateX(calc(-1 * var(--peek))); }
  .art.hid .art-col.r .art-slot { transform: translateX(var(--peek)); }
}

/* ---- игры урока: последний блок экрана, под страницами */
.art-games { display: flex; flex-direction: column; gap: 12px; margin-top: 12px; }
.art-games[hidden] { display: none; }
.art-games-h { margin: 4px 0 0; font-size: 1.05rem; letter-spacing: -.01em; }
.art-game { background: var(--surface); box-shadow: var(--shadow); border-radius: var(--r-card, 18px); overflow: hidden; }
.art-game-top { display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 14px; }
.art-game-top .link { margin-left: auto; }
.art-dot { width: 9px; height: 9px; border-radius: 50%; background: #4aa8e8; flex: none; }
.art-frame { display: block; width: 100%; height: min(72vh, 560px); border: 0; background: #fff; }
.art-ph { padding: 28px 16px; text-align: center; color: var(--muted); font-size: .9rem; }

/* ---- листы */
.art-sheet { display: flex; flex-direction: column; gap: 10px; }
.art-sheet p { margin: 0; line-height: 1.45; }
.art-hero { display: flex; justify-content: center; padding: 2px 0 4px; }
.art-hero .art-bot { width: 96px; height: 123px; }
.art-warn { background: var(--accent-weak); border-radius: 12px; padding: 10px 12px; }
.art-err { color: var(--bad); font-size: .86rem; font-weight: 600; }
.art-err[hidden] { display: none; }
.art-input { resize: vertical; min-height: 84px; font: inherit; font-size: 16px; line-height: 1.35; }
.art-list { display: flex; flex-direction: column; background: var(--surface-2); border-radius: 14px; padding: 2px 4px 2px 12px; }
.art-row { display: flex; align-items: center; gap: 10px; min-height: 44px; }
.art-row + .art-row { border-top: 1px solid var(--border); }
.art-row-t { flex: 1; font-weight: 600; }

/* Уроки из брифа (app/lessons.ts). Токены — из app.css, движение — по скиллу
   apple-design: отклик на нажатии, ничего не блокирует ввод, бережно к
   prefers-reduced-motion и prefers-reduced-transparency. */
.lg-form { display: flex; flex-direction: column; gap: 10px; }
.lg-form textarea.field { min-height: 120px; resize: vertical; font-family: inherit; line-height: 1.45; }
.lg-label { font-size: .8rem; color: var(--muted); margin: 2px 0 -4px; }
/* Все варианты видны сразу: ряд фишек переносится, а не уезжает за край. */
.lg-form .chips { flex-wrap: wrap; margin: 0; padding: 0; overflow: visible; }
.lg-note { font-size: .82rem; color: var(--muted); margin: 0; }
.lg-two { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.lg-kv { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.lg-kv b { font-weight: 600; }

/* ход сборки: строка на блок, точка — состояние */
.lg-steps { background: var(--surface); box-shadow: var(--shadow); border-radius: var(--r-card); overflow: hidden; }
.lg-step { display: flex; align-items: center; gap: 12px; padding: 11px 14px; border-top: 1px solid var(--border); font-size: .93rem; }
.lg-step:first-child { border-top: none; }
.lg-step .t { flex: 1; min-width: 0; }
.lg-step .t span { display: block; font-size: .79rem; color: var(--muted); }
.lg-step .st { font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.lg-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--border); flex: none; transition: background .2s; }
.lg-step.run .lg-dot { background: var(--accent); animation: lg-pulse 1.2s ease-in-out infinite; }
.lg-step.done .lg-dot { background: var(--good); }
.lg-step.fail .lg-dot { background: var(--bad); }
@keyframes lg-pulse { 50% { opacity: .3; } }

/* панель под уроком: стекло поверх содержимого, как док в теме урока */
.lg-tools { position: sticky; bottom: calc(84px + env(safe-area-inset-bottom, 0px)); z-index: 5; align-self: center; max-width: 100%;
  display: flex; align-items: center; gap: 6px; padding: 6px; border-radius: 999px;
  background: color-mix(in oklab, var(--surface) 78%, transparent); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%);
  box-shadow: var(--shadow), 0 8px 24px oklch(0 0 0 / .08); }
.lg-tools .btn { min-height: 38px; padding: 7px 14px; font-size: .88rem; }
.lg-tools .btn.icon { width: 38px; padding: 0; font-size: 1.1rem; }
.lg-ver { font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; padding: 0 8px; white-space: nowrap; }
.lg-frame { width: 100%; flex: 1; min-height: 70vh; border: 0; border-radius: 12px; background: #fff; }

/* списки в шторке: блоки, версии, темы */
.lg-rows { background: var(--default); border-radius: 16px; overflow: hidden; }
.lg-row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px 14px; border: 0; border-top: 1px solid var(--border); background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.lg-row:first-child { border-top: none; }
.lg-row .n { min-width: 28px; font-size: .8rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.lg-row .t { flex: 1; min-width: 0; }
.lg-row .t b { display: block; font-weight: 600; font-size: .93rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lg-row .t span { font-size: .79rem; color: var(--muted); }
.lg-row.current { background: var(--accent-weak); }
.lg-row[disabled] { opacity: .5; cursor: default; }
.lg-row .ok { color: var(--good); font-weight: 700; }

/* ручки блока */
.lg-knob { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 6px 0; }
.lg-stepper { display: flex; align-items: center; gap: 6px; }
.lg-stepper button { width: 36px; height: 36px; border-radius: 50%; border: 0; background: var(--default); color: inherit; font-size: 1.15rem; line-height: 1; cursor: pointer; }
.lg-stepper button:disabled { opacity: .35; }
.lg-stepper b { min-width: 2.4ch; text-align: center; font-variant-numeric: tabular-nums; }
.lg-status { font-size: .86rem; color: var(--muted); min-height: 1.3em; margin: 0; }
.lg-status.bad { color: var(--bad); }
.lg-danger { color: var(--bad); }

/* отклик на нажатии — мгновенный, на самом нажатии */
.lg-row:active, .lg-tools .btn:active, .lg-stepper button:active, .lg-form .chip:active { transform: scale(.97); transition: transform .1s ease-out; }

@media (prefers-reduced-motion: reduce) { .lg-step.run .lg-dot { animation: none; opacity: 1; } .lg-row:active, .lg-tools .btn:active, .lg-stepper button:active { transform: none; } }
@media (prefers-reduced-transparency: reduce) { .lg-tools { background: var(--surface); backdrop-filter: none; -webkit-backdrop-filter: none; } }
@media (min-width: 1024px) { .lg-tools { bottom: 16px; } }

/* урок в рамке: «Исправить» в правом верхнем углу; сгенерированный — красная рамка (решение владельца 30.10) */
.lg-stage { position: relative; flex: 1; display: flex; flex-direction: column; min-height: 70vh; }
.lg-stage > iframe { flex: 1; }
.lg-stage.gen { border: 2px solid var(--bad); border-radius: 14px; }
.lg-stage.gen > iframe { border-radius: 0 0 12px 12px; }
.lg-head { display: flex; align-items: center; gap: 6px; padding: 6px 6px 6px 12px; }
.lg-head .lg-ver { flex: 1; min-width: 0; padding: 0; overflow: hidden; text-overflow: ellipsis; }
.lg-fix, .lg-more { min-height: 36px; border: 0; border-radius: 999px; font: inherit; font-size: .88rem; font-weight: 600; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.lg-fix { padding: 6px 16px; background: var(--bad); color: #fff; }
.lg-more { width: 36px; padding: 0; background: var(--default); color: inherit; font-size: 1.1rem; }
.lg-fix:active, .lg-more:active { transform: scale(.97); transition: transform .1s ease-out; }
.lg-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.lg-banner p { flex: 1 1 100%; margin: 0; font-size: .88rem; }
@media (prefers-reduced-motion: reduce) { .lg-fix:active, .lg-more:active { transform: none; } }

/* Правка прямо в уроке: «Готово» вместо «Исправить», полоса подсказки, поля ручной правки части. */
.lg-fix.on { background: var(--accent); color: var(--accent-fg); }
.lg-edit { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 0 8px 8px 12px; }
.lg-edit p { flex: 1 1 100%; margin: 0; font-size: .84rem; color: var(--muted); }
.lg-edit .btn { min-height: 36px; padding: 6px 14px; font-size: .86rem; }
.lg-form textarea.field.lg-wish { min-height: 84px; }
.lg-form textarea.field.lg-in { min-height: 0; resize: vertical; }
.lg-fld, .lg-obj, .lg-list, .lg-items { display: flex; flex-direction: column; gap: 8px; }
.lg-obj.card-in { padding: 10px; border: 1px solid var(--border); border-radius: 14px; }
.lg-item { display: flex; align-items: flex-start; gap: 6px; }
.lg-item > :first-child { flex: 1; min-width: 0; }
.lg-num { max-width: 6rem; }
.lg-x { flex: none; width: 36px; height: 36px; margin-top: 4px; border: 0; border-radius: 50%; background: var(--default); color: var(--muted); font: inherit; cursor: pointer; }
.lg-add { align-self: flex-start; min-height: 36px; padding: 6px 4px; border: 0; background: none; color: var(--accent); font: inherit; font-weight: 600; cursor: pointer; }
.lg-save { position: sticky; bottom: 0; z-index: 1; }
.lg-x:active, .lg-add:active, .lg-edit .btn:active { transform: scale(.97); transition: transform .1s ease-out; }
@media (prefers-reduced-motion: reduce) { .lg-x:active, .lg-add:active, .lg-edit .btn:active { transform: none; } }

/* Страница учебника — как бумага: свои цвета, от темы интерфейса не зависят.
   Тема приложения красит только то, что вокруг страницы (плеер, панель ввода). */
.tl-engine {
  --tl-ink: #1f2328;
  --tl-line: #8a94a6;
  --tl-pick: #1f6feb;
  --tl-pick-soft: rgba(31, 111, 235, .16);
  --tl-ok: #1a7f37;
  --tl-ok-soft: rgba(26, 127, 55, .18);
  --tl-err: #cf222e;
  --tl-err-soft: rgba(207, 34, 46, .16);
  --tl-ui-bg: #ffffff;
  --tl-ui-fg: #1f2328;
  --tl-ui-muted: #656d76;
  --tl-ui-border: #d0d7de;
  --tl-ui-soft: #f3f4f6;
  position: relative;
  -webkit-tap-highlight-color: transparent;
}
.tl-engine[data-theme="dark"] {
  --tl-ui-bg: #1c1f24;
  --tl-ui-fg: #e6e8eb;
  --tl-ui-muted: #9aa1ab;
  --tl-ui-border: #343a42;
  --tl-ui-soft: #262a31;
}
.tl-engine *, .tl-engine *::before, .tl-engine *::after { box-sizing: border-box; }

.tl-page { margin: 0 0 16px; }
/* Приближение — шириной листа, а не transform: растянутый растр мылит и
   текст, и фото, а так браузер рисует картинку в нужном размере заново. */
.tl-scroll { overflow: auto; -webkit-overflow-scrolling: touch; border-radius: 8px; }
.tl-sheet {
  position: relative; background: #fff; line-height: 0; font-size: 16px;
  user-select: none; -webkit-user-select: none; color: var(--tl-ink);
}
.tl-bg { display: block; width: 100%; height: 100%; object-fit: contain; pointer-events: none; }
/* Подпись учителя поверх издательской страницы (ACCESS 7): две бледные
   строки по диагонали и одна читаемая в углу. Указателя не ловит, печатается
   вместе со страницей; размер — в em листа, растёт с приближением. */
.tl-sign { position: absolute; inset: 0; pointer-events: none; overflow: hidden; display: flex; flex-direction: column; justify-content: space-evenly; align-items: center; }
.tl-sign-t { font: 600 1.7em/1 var(--tl-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif); color: rgba(28, 36, 72, .12); transform: rotate(-22deg); white-space: nowrap; letter-spacing: .02em; }
.tl-sign-t:last-child { position: absolute; right: .7em; bottom: .55em; transform: none; font-size: .68em; font-weight: 500; color: rgba(28, 36, 72, .5); }
.tl-f {
  position: absolute; margin: 0; padding: 0; line-height: 1.1; font: inherit;
  font-size: 1em; color: inherit; appearance: none; -webkit-appearance: none;
}
button.tl-f { background: none; border: 0; cursor: pointer; }

/* ---- вписывание */
.tl-text, .tl-select {
  border: .12em dashed var(--tl-line); border-radius: .3em;
  background: rgba(255, 255, 255, .62); text-align: center;
  color: var(--tl-pick); font-weight: 600; font-size: .95em; padding: 0 .2em;
  outline: 0; min-width: 0;
}
.tl-text.tl-one { padding: 0; border-width: .08em; border-radius: .2em; }
textarea.tl-text { text-align: left; resize: none; line-height: 1.25; padding: .2em .3em; }
.tl-text.tl-own { color: var(--tl-ink); }
.tl-text:focus { border-style: solid; border-color: var(--tl-pick); background: rgba(255, 255, 255, .92); }
.tl-select { text-align-last: center; }

.is-right.tl-text, .is-right.tl-select, .is-right.tl-drop {
  border-color: var(--tl-ok); border-style: solid; color: var(--tl-ok); background: var(--tl-ok-soft);
}
.is-wrong.tl-text, .is-wrong.tl-select, .is-wrong.tl-drop {
  border-color: var(--tl-err); border-style: solid; color: var(--tl-err); background: var(--tl-err-soft);
}
/* Показанный ответ: зелёный, но пунктиром — видно, что его дал движок. */
.is-given.tl-text, .is-given.tl-select, .is-given.tl-drop {
  border-color: var(--tl-ok); border-style: dashed; color: var(--tl-ok); background: var(--tl-ok-soft);
}
.is-key.tl-text, .is-key.tl-select, .is-key.tl-drop {
  border-color: var(--tl-pick); border-style: dotted; color: var(--tl-pick); background: var(--tl-pick-soft);
}
/* Счётчик ошибок на поле: точки в правом верхнем углу. */
.tl-f[data-tries]::after {
  content: ""; position: absolute; right: -.15em; top: -.35em; width: .5em; height: .5em;
  border-radius: 50%; background: var(--tl-err); pointer-events: none;
}
.tl-f[data-tries="2"]::after { box-shadow: -.65em 0 0 var(--tl-err); }
.tl-f[data-tries="3"]::after { box-shadow: -.65em 0 0 var(--tl-err), -1.3em 0 0 var(--tl-err); }
input.tl-f[data-tries], select.tl-f[data-tries] { outline: .12em solid var(--tl-err); outline-offset: .1em; }

/* ---- кроссворд: буква по центру клетки, клетка книги видна насквозь */
button.tl-cell {
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  border: .1em dashed var(--tl-line); border-radius: .12em; background: rgba(255, 255, 255, .35);
  color: var(--tl-pick); font-weight: 800; line-height: 1; text-transform: uppercase; padding: 0;
}
button.tl-cell:empty { background: rgba(255, 255, 255, .1); }
button.tl-cell.is-on { border-style: solid; border-color: var(--tl-pick); background: var(--tl-pick-soft); }
.is-right.tl-cell { color: var(--tl-ok); border-color: var(--tl-ok); border-style: solid; background: var(--tl-ok-soft); }
.is-wrong.tl-cell { color: var(--tl-err); border-color: var(--tl-err); border-style: solid; background: var(--tl-err-soft); }
.is-given.tl-cell { color: var(--tl-ok); border-color: var(--tl-ok); background: var(--tl-ok-soft); }
.is-key.tl-cell { color: var(--tl-pick); border-color: var(--tl-pick); border-style: dotted; background: var(--tl-pick-soft); }

/* ---- обводка: круг по высоте строки, а не рамка по боксу глифа */
.tl-opt::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -54%); height: 118%; min-width: 100%; aspect-ratio: 1;
  border: .13em solid transparent; border-radius: 50%; pointer-events: none;
}
.tl-opt.is-right::before { border-color: var(--tl-ok); background: var(--tl-ok-soft); }
.tl-opt.is-wrong::before { border-color: var(--tl-err); background: var(--tl-err-soft); }
.tl-opt.is-given::before { border-color: var(--tl-ok); border-style: dashed; background: var(--tl-ok-soft); }
.tl-opt.is-key::before { border-color: var(--tl-pick); border-style: dotted; background: var(--tl-pick-soft); }
.tl-opt.is-example::before { background: none; }
.tl-opt.is-locked { cursor: default; }
@media (hover: hover) { .tl-opt:not(.is-locked):hover::before { background: var(--tl-pick-soft); } }

/* ---- банк и пропуск */
.tl-drop {
  border: .12em dashed var(--tl-line); border-radius: .3em; background: rgba(255, 255, 255, .6);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  color: var(--tl-pick); font-weight: 700; font-size: .92em; white-space: nowrap; cursor: pointer;
}
.tl-drop.is-over { border-style: solid; border-color: var(--tl-pick); background: var(--tl-pick-soft); }
.tl-drop.is-example { border: 0; background: none; color: var(--tl-ink); cursor: default; }
.tl-src { cursor: grab; touch-action: none; border-radius: .25em; }
.tl-src.is-picked { background: var(--tl-pick-soft); outline: .12em solid var(--tl-pick); }
.tl-src.is-used { background: rgba(255, 255, 255, .7); cursor: default; }
.tl-bank { position: absolute; display: flex; flex-wrap: wrap; gap: .35em; line-height: 1.1; }
.tl-card {
  padding: .3em .6em; border-radius: .4em; background: #fff; border: .1em solid var(--tl-line);
  font-weight: 600; font-size: .95em; line-height: 1.1; cursor: grab; touch-action: none;
  color: var(--tl-ink); white-space: nowrap;
}
.tl-card.is-picked { border-color: var(--tl-pick); background: var(--tl-pick-soft); }
.tl-card.is-used { opacity: .35; cursor: default; }
.tl-ghost {
  position: fixed; z-index: 1000; pointer-events: none; transform: translate(-50%, -120%);
  font: 600 16px/1.1 system-ui, sans-serif; padding: 6px 12px; box-shadow: 0 6px 18px rgba(0, 0, 0, .25);
}

/* ---- галочка */
.tl-tick {
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 1.15em; color: var(--tl-pick); border-radius: .25em;
}
.tl-tick.is-right { color: var(--tl-ok); background: var(--tl-ok-soft); }
.tl-tick.is-wrong { color: var(--tl-err); background: var(--tl-err-soft); }
.tl-tick.is-key { color: var(--tl-pick); background: var(--tl-pick-soft); }

/* ---- линии */
.tl-lines { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
/* Стрелка чёрная, пока её тянут; цвет она получает только после проверки. */
.tl-line { fill: none; stroke: var(--tl-ink); stroke-width: 1.6; stroke-linecap: round; }
.tl-head { fill: var(--tl-ink); stroke: none; }
.tl-line.is-right { stroke: var(--tl-ok); }
.tl-head.is-right { fill: var(--tl-ok); }
.tl-line.is-wrong { stroke: var(--tl-err); }
.tl-head.is-wrong { fill: var(--tl-err); }
.tl-line.is-given { stroke: var(--tl-ok); stroke-dasharray: 5 4; }
.tl-head.is-given { fill: var(--tl-ok); }
.tl-line.is-key { stroke: var(--tl-pick); stroke-dasharray: 1.5 4; }
.tl-head.is-key { fill: var(--tl-pick); }
/* Точка-хвост: чёрная, размером с печатную точку книги. */
.tl-dot {
  width: .62em; height: .62em; transform: translate(-50%, -50%); border-radius: 50%;
  border: 0 !important; background: var(--tl-ink) !important;
  touch-action: none; cursor: crosshair;
}
/* Палец толще точки: зона нажатия шире видимого кружка. */
.tl-dot::before { content: ""; position: absolute; inset: -.9em; }
.tl-dot.is-picked, .tl-dot.is-over { box-shadow: 0 0 0 .12em var(--tl-pick), 0 0 0 .4em var(--tl-pick-soft); }
.tl-dot.is-right { background: var(--tl-ok) !important; }
.tl-dot.is-given { background: var(--tl-ok) !important; opacity: .6; }

/* ---- краска: умножение, чтобы контур рисунка остался виден сквозь цвет */
.tl-paint { border-radius: .4em; border: .1em dashed var(--tl-line) !important; }
.tl-paint::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--tl-fill, transparent); mix-blend-mode: multiply; opacity: .75;
}
.tl-paint[data-color]:not([data-color=""]) { border-style: solid !important; border-color: transparent !important; }
.tl-paint.is-right { outline: .14em solid var(--tl-ok); }
.tl-paint.is-wrong { outline: .14em solid var(--tl-err); }
.tl-paint.is-given { outline: .14em dashed var(--tl-ok); }
.tl-paint.is-key { outline: .14em dotted var(--tl-pick); }
.tl-palette {
  position: sticky; bottom: 8px; z-index: 5; display: flex; flex-wrap: wrap; gap: 8px;
  justify-content: center; padding: 8px; margin: 8px auto 0; width: fit-content; max-width: 100%;
  background: var(--tl-ui-bg); border: 1px solid var(--tl-ui-border); border-radius: 999px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .12);
}
.tl-swatch {
  width: 32px; height: 32px; border-radius: 50%; border: 2px solid var(--tl-ui-border);
  padding: 0; cursor: pointer;
}
.tl-swatch.is-picked { outline: 3px solid var(--tl-pick); outline-offset: 2px; }

/* ---- строка по нажатию */
.tl-line-zone { border-bottom: .14em dashed var(--tl-line) !important; border-radius: .2em; }
/* Открытый ответ места на листе не занимает: пунктир через всю строку
   задания читался как лишнее поле. Остаётся маленькая метка в начале строки,
   черта появляется, когда ученик что-то написал. */
.tl-line-zone.tl-free { border-bottom-color: transparent !important; }
/* Карандаш стоит после строки, а не перед ней (правило владельца 14 октября):
   слева он налезал на номер задания и читался как часть инструкции. */
.tl-line-zone.tl-free::after {
  content: "✎"; position: absolute; right: -1.5em; top: 50%; translate: 0 -50%;
  font-size: 1.15em; line-height: 1; color: var(--tl-line); opacity: .85;
}
.tl-line-zone.tl-free.is-filled::after { color: var(--tl-pick); opacity: 1; }
.tl-line-zone.is-filled { border-bottom-style: solid !important; border-bottom-color: var(--tl-pick) !important; }
.tl-line-zone.is-right { border-bottom-color: var(--tl-ok) !important; border-bottom-style: solid !important; background: var(--tl-ok-soft); }
.tl-line-zone.is-wrong { border-bottom-color: var(--tl-err) !important; border-bottom-style: solid !important; background: var(--tl-err-soft); }
.tl-line-zone.is-given { border-bottom-color: var(--tl-ok) !important; background: var(--tl-ok-soft); }
.tl-note {
  height: auto; padding: .15em .35em; border-radius: .3em; font-size: .8em; line-height: 1.2;
  background: #fff; border: .08em dashed var(--tl-ok); color: var(--tl-ok); z-index: 2;
}
.tl-note.is-key { border-color: var(--tl-pick); color: var(--tl-pick); }

/* ---- трек на странице
   Кнопка прозрачна: иконка динамика напечатана в учебнике, она и есть
   кнопка. Синий кружок поверх неё закрывал печатное и выглядел наклейкой.
   Наше здесь только состояние: тонкое кольцо цветом типографской краски,
   пока трек играет. */
.tl-audio { border-radius: 50%; color: transparent !important; }
.tl-audio::before {
  content: ""; position: absolute; inset: -18%; border-radius: 50%;
  border: .1em solid transparent; pointer-events: none;
}
@media (hover: hover) { .tl-audio:hover::before { border-color: rgba(31, 35, 40, .28); } }
.tl-audio.is-on::before { border-color: rgba(31, 35, 40, .55); animation: tl-ring 1.6s ease-in-out infinite; }
@keyframes tl-ring {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.14); opacity: .45; }
}
@media (prefers-reduced-motion: reduce) { .tl-audio.is-on::before { animation: none; } }

/* ---- видео к заданию
   Как у трека: напечатанный значок и есть кнопка, наше — только кольцо под
   пальцем. Где значка в книге нет (`badge`), рисуем кружок ▶ — у издателя
   там тоже своя накладная иконка. Зона нажатия шире значка: он мелкий. */
.tl-video { border-radius: 50%; color: transparent !important; }
.tl-video::before {
  content: ""; position: absolute; inset: -18%; border-radius: 50%;
  border: .1em solid transparent; pointer-events: none;
  transition: transform 100ms ease-out;
}
.tl-video::after { content: ""; position: absolute; inset: -25%; }
.tl-video:disabled::after { display: none; }
@media (hover: hover) { .tl-video:not(:disabled):hover::before { border-color: rgba(31, 35, 40, .28); } }
.tl-video:active::before { border-color: rgba(31, 35, 40, .45); transform: scale(.94); }
.tl-video-badge::before {
  inset: 0; border: 0; box-shadow: 0 .12em .4em rgba(0, 0, 0, .25);
  background: #1f6feb url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 6.8v10.4a.6.6 0 0 0 .9.5l8.2-5.2a.6.6 0 0 0 0-1L9.9 6.3a.6.6 0 0 0-.9.5z' fill='%23fff'/%3E%3C/svg%3E") center / 62% no-repeat;
}
.tl-video:disabled { cursor: default; }
.tl-video:disabled::before { display: none; }

/* Плеер поверх страницы: затемнение фокусирует, карточка вырастает из
   кнопки (анимация — в video.ts). */
.tl-video-layer {
  position: fixed; inset: 0; z-index: 950; display: flex; align-items: center; justify-content: center;
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
}
.tl-video-layer[hidden] { display: none; }
.tl-video-scrim { position: absolute; inset: 0; background: rgba(0, 0, 0, .55); }
.tl-video-card {
  position: relative; width: min(960px, 100%); max-height: 100%; display: flex; flex-direction: column;
  border-radius: 16px; overflow: hidden; background: #0e1014; color: #f2f3f5;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);
  will-change: transform, opacity; transform-origin: center;
  font: 500 14px/1.3 system-ui, -apple-system, "Segoe UI", sans-serif;
}
.tl-video-bar { display: flex; align-items: center; gap: 12px; padding: 8px 8px 8px 16px; }
.tl-video-title {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 600; letter-spacing: -.005em;
}
.tl-video-close {
  flex: none; width: 36px; height: 36px; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 255, 255, .12); color: inherit; font-size: 16px; line-height: 1;
  transition: transform 100ms ease-out, background-color 100ms ease-out;
}
.tl-video-close:active { transform: scale(.92); background: rgba(255, 255, 255, .2); }
@media (hover: hover) { .tl-video-close:hover { background: rgba(255, 255, 255, .18); } }
.tl-video-frame { position: relative; aspect-ratio: 16 / 9; max-height: calc(100dvh - 140px); background: #000; }
.tl-video-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.tl-video-off {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  padding: 24px; text-align: center; color: #c9ccd1;
}
.tl-video-note { padding: 8px 16px 12px; color: #9aa1ab; font-size: 12px; letter-spacing: .01em; }
@media (prefers-reduced-transparency: reduce) { .tl-video-scrim { background: rgba(0, 0, 0, .8); } }

.tl-shake { animation: tl-shake .32s; }
@keyframes tl-shake {
  25% { translate: -4px 0; } 50% { translate: 4px 0; } 75% { translate: -2px 0; }
}
@media (prefers-reduced-motion: reduce) { .tl-shake { animation: none; } }

/* ---------------------------------------------------------------- плеер */
.tl-player {
  margin-top: 8px; padding: 10px 12px; border-radius: 12px; font: 14px/1.3 system-ui, sans-serif;
  background: var(--tl-ui-bg); color: var(--tl-ui-fg); border: 1px solid var(--tl-ui-border);
}
.tl-player-row { display: flex; align-items: center; gap: 8px; }
.tl-player-row + .tl-player-row { margin-top: 8px; }
.tl-player-label, .tl-player-track { font-weight: 600; margin-right: auto; color: inherit; }
.tl-player-track {
  background: var(--tl-ui-soft); border: 1px solid var(--tl-ui-border); border-radius: 8px;
  padding: 8px; font: inherit; font-weight: 600; min-height: 44px;
}
.tl-btn {
  min-width: 44px; min-height: 44px; padding: 0 10px; border-radius: 10px; cursor: pointer;
  background: var(--tl-ui-soft); color: var(--tl-ui-fg); border: 1px solid var(--tl-ui-border);
  font: 600 14px/1 system-ui, sans-serif;
}
.tl-btn.is-on { background: var(--tl-pick); border-color: var(--tl-pick); color: #fff; }
.tl-play { background: var(--tl-pick); border-color: var(--tl-pick); color: #fff; min-width: 52px; }
.tl-seek { flex: 1; min-width: 0; height: 28px; accent-color: var(--tl-pick); }
.tl-time { font-variant-numeric: tabular-nums; color: var(--tl-ui-muted); font-size: 12px; white-space: nowrap; }
.tl-script { margin-top: 8px; }
.tl-script summary { cursor: pointer; font-weight: 600; padding: 6px 0; }
.tl-script-text { white-space: pre-wrap; color: var(--tl-ui-muted); padding-bottom: 4px; }
/* Скрипт трека — подсказка учителя, ученик его не видит. */
.tl-engine[data-role="student"] .tl-script { display: none; }

/* ------------------------------------------------------- нижняя панель ввода */
.tl-composer {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 900;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: var(--tl-ui-bg); color: var(--tl-ui-fg);
  border-top: 1px solid var(--tl-ui-border); box-shadow: 0 -6px 20px rgba(0, 0, 0, .14);
  font: 16px/1.3 system-ui, sans-serif;
}
.tl-composer[hidden] { display: none; }
.tl-composer-title { font-size: 13px; color: var(--tl-ui-muted); margin-bottom: 6px; }
.tl-composer-row { display: flex; gap: 8px; align-items: stretch; }
.tl-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.tl-chips[hidden] { display: none; }
.tl-chip {
  min-height: 44px; padding: 6px 14px; border-radius: 999px; font: 16px/1.2 system-ui, sans-serif;
  border: 1px solid var(--tl-pick); background: var(--tl-ui-bg); color: var(--tl-ui-fg); cursor: pointer;
}
.tl-chip.is-used { opacity: .4; border-style: dashed; }
.tl-chip-undo { margin-left: auto; border-color: var(--tl-ui-border); }
/* 16 px и больше: при меньшем кегле iOS рывком приближает страницу при фокусе. */
.tl-composer-input {
  flex: 1; min-width: 0; font: 18px/1.3 system-ui, sans-serif; padding: 10px 12px; border-radius: 10px;
  border: 1px solid var(--tl-ui-border); background: var(--tl-ui-soft); color: var(--tl-ui-fg); outline: 0;
}
textarea.tl-composer-input { min-height: 92px; resize: none; }
.tl-composer-input:focus { border-color: var(--tl-pick); }
.tl-ok { background: var(--tl-pick); border-color: var(--tl-pick); color: #fff; padding: 0 16px; }

/* ---- ссылка на страницу
   «p.132» напечатано в книге — это и есть кнопка. Наше здесь только тонкая
   черта под ним: видно, что нажимается, а печатное не закрыто. */
.tl-link { border-radius: .25em; }
.tl-link::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: -.12em;
  border-bottom: .1em solid var(--tl-pick); opacity: .6; pointer-events: none;
}
@media (hover: hover) { .tl-link:not(:disabled):hover { background: var(--tl-pick-soft); } }
.tl-link:active { background: var(--tl-pick-soft); }
.tl-link:disabled { cursor: default; }
.tl-link:disabled::before { display: none; }

.tl-ref {
  position: fixed; inset: 0; z-index: 800; display: flex; flex-direction: column;
  background: var(--tl-ui-soft); color: var(--tl-ui-fg);
}
.tl-ref[hidden] { display: none; }
.tl-ref-bar {
  display: flex; align-items: center; gap: 12px; flex: none;
  padding: 8px 12px; padding-top: max(8px, env(safe-area-inset-top));
  background: var(--tl-ui-bg); border-bottom: 1px solid var(--tl-ui-border);
  font: 600 14px/1.2 system-ui, -apple-system, "Segoe UI", sans-serif;
}
.tl-ref-title { color: var(--tl-ui-muted); }
.tl-ref-body {
  flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch; padding: 8px;
  padding-bottom: max(8px, env(safe-area-inset-bottom));
}
.tl-ref-body .tl-page { max-width: 1000px; margin: 0 auto 16px; }
.tl-ref-pill {
  position: fixed; left: 12px; bottom: max(12px, env(safe-area-inset-bottom)); z-index: 700;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .22);
}
.tl-ref-pill[hidden] { display: none; }

/* ---- плашка для письма: видимая, но лёгкая — страница остаётся бумагой */
.tl-pad {
  display: flex; align-items: center; gap: .3em; padding: 0 .45em; overflow: hidden;
  border: .09em dashed var(--tl-line) !important; border-radius: .9em;
  background: rgba(255, 255, 255, .86) !important; color: var(--tl-line);
  font-size: .78em; line-height: 1; text-align: left; white-space: nowrap;
}
.tl-pad-icon { flex: none; }
.tl-pad-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--tl-ink); }
.tl-pad.is-filled { border-style: solid !important; border-color: var(--tl-pick) !important; color: var(--tl-pick); }
@media (hover: hover) { .tl-pad:hover { border-color: var(--tl-pick) !important; color: var(--tl-pick); } }

/* ---- галочка или крестик: тот же квадрат, что напечатан в книге */
.tl-tickx {
  display: flex; align-items: center; justify-content: center; padding: 0;
  border: .1em solid var(--tl-line) !important; border-radius: .2em;
  background: rgba(255, 255, 255, .55) !important; color: var(--tl-pick);
  font-size: 1.15em; font-weight: 700; line-height: 1;
}
.tl-tickx[data-sign="cross"] { color: var(--tl-ink); }
.tl-tickx.is-right { color: var(--tl-ok); border-color: var(--tl-ok) !important; background: var(--tl-ok-soft) !important; }
.tl-tickx.is-wrong { color: var(--tl-err); border-color: var(--tl-err) !important; background: var(--tl-err-soft) !important; }
.tl-tickx.is-given { color: var(--tl-ok); border-style: dashed !important; }
.tl-tickx.is-key { color: var(--tl-pick); border-color: var(--tl-pick) !important; }

/* ---- подчеркнуть слово в тексте: прозрачная кнопка поверх слова, отметка — черта снизу */
.tl-mark {
  padding: 0; border: 0 !important; background: transparent !important; border-radius: .15em;
  box-shadow: none !important;
}
.tl-mark.is-marked { box-shadow: inset 0 -.14em 0 var(--tl-pick) !important; }
.tl-mark.is-right { box-shadow: inset 0 -.14em 0 var(--tl-ok) !important; background: var(--tl-ok-soft) !important; }
.tl-mark.is-wrong { box-shadow: inset 0 -.14em 0 var(--tl-err) !important; background: var(--tl-err-soft) !important; }
.tl-mark.is-given { box-shadow: inset 0 -.14em 0 var(--tl-ok) !important; }
.tl-mark.is-key { box-shadow: inset 0 -.14em 0 var(--tl-pick) !important; }

/* выбор без ключа: отмечено, но не проверено */
.tl-opt.is-picked::before { border-color: var(--tl-pick); background: var(--tl-pick-soft); }
